图像镜头失真校正

时间:2015-08-07 13:31:40

标签: image-processing distortion

我正在使用Aptina 5Mp传感器和鱼眼镜头拍摄图像。

我正在使用以下算法来纠正镜头失真。

http://www.tannerhelland.com/4743/simple-algorithm-correcting-lens-distortion/

这不能正确纠正图像。

任何帮助将不胜感激。

//code----
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdio.h>
#include <math.h>

using namespace cv;
using namespace std;


// globals
Mat src, dst;
Mat map_x, map_y;
#define REMAP_WINDOW "Remap Circle"

void make_circle_map(float , float , float , float );

int main(int argc, char** argv) {
        // load image
        src = imread(argv[1], 1);
        float qvDepth = atof(argv[2]);
    float fixStrength = atof(argv[3]);
    float fixZoom = atof(argv[4]);
    float lensRadius = atof(argv[5]);
        // create destination and the maps
        dst.create(src.size(), src.type());
        map_x.create(src.size(), CV_32FC1);
        map_y.create(src.size(), CV_32FC1);

        // create window
       // namedWindow(REMAP_WINDOW, CV_WINDOW_AUTOSIZE);

        make_circle_map(qvDepth, fixStrength, fixZoom, lensRadius);
        remap(src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0));
        //imshow(REMAP_WINDOW, dst);
        imwrite("got1.jpg",dst);
       // while(27 != waitKey()) {
                // just wait
      //  }
      //  cvDestroyWindow(REMAP_WINDOW);
        return 0;
}

void make_circle_map(float qvDepth, float fixStrength, float fixZoom, float lensRadius ) {

//ApplyLensCorrection(double fixStrength, double fixZoom, double lensRadius, long long edgeHandling, long long superSamplingAmount

cout<<"qvDepth :"<<qvDepth<<" fixStrength :"<<fixStrength<<" fixZoom :"<<fixZoom<<" lensRadius :"<<lensRadius<<endl;
//float qvDepth = 32;//24;
//float fixStrength = 4.5; // has to utilized further
//float fixZoom = 0.5;
//float lensRadius =2;

//Calculate the center of the image
    //double midX = 0;
    //double midY = 0;
long tWidth = 1944;
long tHeight = 2580;

// the center 
        double midX = (double)src.cols/2;
        double midY = (double)src.rows/2;

//Rotation values
    double theta = 0;
    double sRadius = 0;
    double sRadius2 = 0;
    double sDistance = 0;
    double radius = 0;


    double j = 0;
    double k = 0;
//X and Y values, remapped around a center point of (0, 0)
    double nX = 0;
    double nY = 0;
    double QuickVal =0;
    float ssX;
    float ssY;

//Source X and Y values, which may or may not be used as part of a bilinear interpolation function
    double srcX = 0;
    double srcY = 0;

    sRadius = sqrt(tWidth * tWidth + tHeight * tHeight) / 2;
cout<<"sRadius :"<<sRadius<<endl;

    double refDistance = 0;//modified 0 to 2
    if (fixStrength == 0)
    {
        fixStrength = 0.00000001;
    }
    refDistance = sRadius * 2 / fixStrength;

    sRadius = sRadius * (lensRadius / 100);
    sRadius2 = sRadius * sRadius;
cout<<"refDistance :"<<refDistance<<" sRadius :"<<sRadius<<" sRadius2 :"<<sRadius2<<endl;
float sampleIndex =1; //has to be changed in future
for (int x = 0; x <= tWidth; x++)
    {
        QuickVal = x * qvDepth;
    for (int y = 0; y <= tHeight; y++)
    {

//Remap the coordinates around a center point of (0, 0)
        nX = x - midX;
        nY = y - midY;

//Offset the pixel amount by the supersampling lookup table
 for(int ii = 1; ii<4;ii++){
            j = nX + ii;
            k = nY + ii;

            //Calculate distance automatically
            sDistance = (j * j) + (k * k);
//cout<<"nx :"<<nX<<" ny :"<<nY<<" j :"<<j<<" k :"<<k<<" sDistance :"<<sDistance<<" sRadius2 :"<<sRadius2<<endl;
            if (sDistance <= sRadius2)
            {

                sDistance = sqrt(sDistance);
                radius = sDistance / refDistance;

                if (radius == 0)
                {
                    theta = 1;
                }
                else
                {
                    theta = atan(radius) / radius;
                }

//srcX = midX + theta * j * fixZoom;
//srcY = midY + theta * k * fixZoom;

     map_x.at<float>(x,y) = midX + cos(fabs(theta)) * j * fixZoom;

     map_y.at<float>(x,y) = midY + sin(fabs(theta)) * k * fixZoom;
            }

else
            {

            map_x.at<float>(x,y) = x + cos(fabs(theta))  ;//* fixZoom;//x;
            map_y.at<float>(x,y) = y + sin(fabs(theta)) ;//* fixZoom;//y;

            }
}


}
}
}

图片

enter image description here

1 个答案:

答案 0 :(得分:1)

替换以下行。

  map_x.at<float>(x,y) = midX + theta * j * fixZoom;

     map_y.at<float>(x,y) = midY + theta * k * fixZoom;
            }

else
            {

            map_x.at<float>(x,y) = x   ;//* fixZoom;//x;
            map_y.at<float>(x,y) = y  ;//* fixZoom;//y;

使用参数可执行文件[图像名称],BBP,校正参数,缩放参数,应用比率。

EX-&GT; ./lensdistortcorrect image.jpg 24 6.2 2.2 100

enter image description here