OpenCV中的重映射函数如何在不失真的图像中起作用?

时间:2016-02-12 16:04:57

标签: c++ opencv camera-calibration remap

出于调试目的,我试图重新实现OpenCV的重映射功能。不考虑插值,它应该看起来像这样:

for( int j = 0; j < height; j++ )
{
    for( int i = 0; i < width; i++ )
    {
        undistortedImage.at<double>(mapy.at<float>(j,i),mapx.at<float>(j,i)) = distortedImage.at<double>(j,i);
    }
}

为了对此进行测试,我使用了以下地图来围绕y轴镜像图像:

int width = distortedImage.cols;
int height = distortedImage.rows;
cv::Mat mapx = Mat(height, width, CV_32FC1);
cv::Mat mapy = Mat(height, width, CV_32FC1);
for( int j = 0; j < height; j++)
{
    for( int i = 0; i < width; i++)
    {
        mapx.at<float>(j,i) = width - i - 1;
        mapy.at<float>(j,i) = j;
    }
}

但插值的工作方式与

完全相同
cv::remap( distortedImage, undistortedImage, mapx, mapy, CV_INTER_LINEAR);

现在我尝试在OCamCalib Toolbox创建的地图上应用此功能,以实现无失真的图像。这与OpenCV undistortion所做的基本相同。 我的实现现在显然没有考虑源图像中的几个像素被映射到目标图像中的相同像素。但情况更糟。实际上,看起来我的源图像在目标图像中的较小版本中出现了三次。否则,remap命令工作正常。

经过详尽的调试后,我决定请你们帮忙。任何人都可以向我解释我做错了什么或提供了在OpenCV中重映射实现的链接吗?

1 个答案:

答案 0 :(得分:0)

我自己想通了。我最初的实现有两个基本错误:

  1. 误解了地图的使用方式。
  2. 误解如何提取强度值。
  3. 如何正确地做到:

    for( int j = 0; j < height; j++ )
    {
        for( int i = 0; i < width; i++ )
        {
            undistortedImage.at<uchar>(mapy.at<float>(j,i),mapx.at<float>(j,i)) = distortedImage.at<uchar>(j,i);
        }
    }
    

    我想强调一下,现在使用.at&lt; uchar&gt;提取图像的强度值。而不是.at&lt; double&gt;。此外,地图的索引也会被切换。