"手动"在openCV中不失真的图像

时间:2014-07-11 12:58:16

标签: c++ opencv

编辑:我通过查看initUndistortRectifyMap的文档解决了我的问题(并在下面的代码中对其进行了更改),但我不完全确定我在这里做了什么。如果有人想解释来回变换,我将不胜感激。

我正在使用来自the opencv cookbook的这种来自同伴的人。从失真矩阵和相机矩阵中打印系数我现在想通过仅使用这些值来解决这些问题,如文档[由于信誉低而删除链接]中所述。

问题是它不起作用,但是当我将“手动”创建的矩阵提供给cv :: undistort时,它可以工作! 我在这里做错了什么?

int main(void)
{
cv::Mat distortMat = (cv::Mat_<double>(1, 5) << -0.0688081, 0.101627, -0.000487848, -0.00172756, -0.0388046);
cv::Mat cameraMatrix = (cv::Mat_<double>(3, 3) << 893.035, 0, 623.697, 0, 895.748, 526.612, 0, 0, 1);

cv::Mat img = cv::imread("photo.jpg", 1);
cv::cvtColor(img, img, CV_BGR2GRAY);
img.convertTo(img, CV_8UC1);
cv::Mat uPhoto = img.clone();

double k1 = distortMat.at<double>(0, 0);
double k2 = distortMat.at<double>(0, 1);
double p1 = distortMat.at<double>(0, 2);
double p2 = distortMat.at<double>(0, 3);
double k3 = distortMat.at<double>(0, 4);
double  fx = cameraMatrix.at<double>(0, 0);
double  cx = cameraMatrix.at<double>(0, 2);
double  fy = cameraMatrix.at<double>(1, 1);
double  cy = cameraMatrix.at<double>(1, 2);
double z = 1.;

for (int i = 0; i < img.cols; i++)
{
    for (int j = 0; j < img.rows; j++)
    {
        /* Solved by removing this...
        double x = (double)i*fx + cx*z;
        double y = (double)j*fy + cy*z;
        double r2 = x*x + y*y;

        double dx = 2 * p1*i*j + p2*(r2 + 2 * i*i);
        double dy = p1*(r2 + 2 * j*j) + 2 * p2*i*j;
        double scale = 1. + k1*r2 + k2*r2*r2 + k3*r2*r2*r2;

        double xCorr = x*scale + dx;
        double yCorr = y*scale + dy;*/

        // ...and adding this:
        double x = (i - cx) / fx;
        double y = (j - cy) / fy;
        double r2 = x*x + y*y;

        double dx = 2 * p1*x*y + p2*(r2 + 2 * x*x);
        double dy = p1*(r2 + 2 * y*y) + 2 * p2*x*y;
        double scale = (1 + k1*r2 + k2*r2*r2 + k3*r2*r2*r2);

        double xBis = x*scale + dx;
        double yBis = y*scale + dy;

        double xCorr = xBis*fx + cx;
        double yCorr = yBis*fy + cy;

        if (xCorr >= 0 && xCorr < uPhoto.cols && yCorr >= 0 && yCorr < uPhoto.rows)
        {
            uPhoto.at<uchar>(yCorr, xCorr) = img.at<uchar>(j, i);
        }
    }
}

cv::imwrite("uPhotoManual.jpg", uPhoto);

cv::Mat uPhotoAuto;
cv::undistort(img, uPhotoAuto, cameraMatrix, distortMat);
cv::imwrite("uPhotoAuto.jpg", uPhotoAuto);

return 0;
}

0 个答案:

没有答案