鱼眼畸变校正

时间:2016-02-15 13:34:23

标签: c++ opencv image-processing computer-vision fisheye

我在这个链接http://www.tannerhelland.com/4743/simple-algorithm-correcting-lens-distortion/上看到了一个取消鱼眼镜头失真的算法,我尝试用C ++用opencv实现它。当参数强度接近于零时,输​​出图像与输入图像完全相同,并且随着值越高,我得到的结果越差。如果有人知道可能是什么问题(在我的代码中,或者更一般地说,在算法中),这将是非常有帮助的。 非常感谢你。

#include "opencv2\core\core.hpp"
#include "opencv2\highgui\highgui.hpp"
#include "opencv2\calib3d\calib3d.hpp"
#include <stdio.h>
#include <iostream>
#include <math.h>

using namespace std;
using namespace cv;

int main() {

    cout << " Usage: display_image ImageToLoadAndDisplay" << endl;
    Mat_<Vec3b> eiffel;
    eiffel = imread("C:/Users/Administrator/Downloads/TestFisheye.jpg", CV_LOAD_IMAGE_COLOR);   // Read the file
    if (!eiffel.data)                              // Check for invalid input
    {
        cout << "Could not open or find the image" << endl;
        return -1;
    }
    cout << "Input image depth: " << eiffel.depth() << endl;

    namedWindow("Display window", WINDOW_AUTOSIZE);// Create a window for display.
    imshow("Display window", eiffel);                   // Show our image inside it.

    //waitKey(0);                                          // Wait for a keystroke in the window

    int halfWidth = eiffel.rows / 2;
    int halfHeight = eiffel.cols / 2;
    double strength = 0.0001;
    double correctionRadius = sqrt(pow(eiffel.rows, 2) + pow(eiffel.cols, 2)) / strength;
    Mat_<Vec3b> dstImage = eiffel;

    int newX, newY;
    double distance; 
    double theta; 
    int sourceX; 
    int sourceY; 
    double r;
    for (int i = 0; i < dstImage.rows; ++i)
    {
        for (int j = 0; j < dstImage.cols; j++)
        {
            newX = i - halfWidth; 
            newY = j - halfHeight;
            distance = sqrt(pow(newX, 2) + pow(newY, 2));
            r = distance / correctionRadius;
            if (r == 0.0)
                theta = 1;
            else
                theta = atan(r) / r;

            sourceX = round(halfWidth + theta*newX);
            sourceY = round(halfHeight + theta * newY);

            dstImage(i, j)[0] = eiffel(sourceX, sourceY)[0];
            dstImage(i, j)[1] = eiffel(sourceX, sourceY)[1];
            dstImage(i, j)[2] = eiffel(sourceX, sourceY)[2];
        }
    }

    namedWindow("Display window 2", WINDOW_AUTOSIZE);
    imshow("Display window 2", dstImage);                   // Show our image inside it.
    waitKey(0);

    return 0;
}

PS:我目前正在处理链接中发布的第一张图片。

1 个答案:

答案 0 :(得分:2)

这里有2个问题:

1 - 您需要将强度从0.0001增加到更合理的值(尝试5)。

2 - 您使用的是相同的起点和终点矩阵。此Mat_<Vec3b> dstImage = eiffel;不会自动分配任何新内存。 dstImage只是指向原始图像的智能指针。因此,当您修改它时,您正在同时修改源图像。这会给你很差的结果。而是Mat_<Vec3b> dstImage = eiffel.clone()

通过这些更改,我得到以下图片: enter image description here

不是很好,但很快&amp;至少简单。