【问题标题】:How does the remap function in OpenCV for undistorting images work?OpenCV 中用于不失真图像的重映射功能如何工作?
【发布时间】:2016-05-23 20:45:17
【问题描述】:

出于调试目的,我尝试重新实现 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 所做的基本相同。 我现在的实现显然不考虑源图像中的几个像素映射到目标图像中的相同像素。但情况更糟。实际上,看起来我的源图像在目标图像中以较小的版本出现了 3 次。否则 remap 命令可以完美运行。

经过详尽的调试后,我决定向你们寻求帮助。谁能解释我做错了什么或提供在 OpenCV 中实现重映射的链接?

【问题讨论】:

标签: c++ opencv camera-calibration remap


【解决方案1】:

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

  1. 对地图的使用方式存在误解。
  2. 关于如何提取强度值的误解。

如何正确操作:

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 而不是 .at 从图像中提取强度值。此外,地图的索引也会切换。

【讨论】:

  • 对于类型 16(CV_8UC3,即 BGR - 无 alpha 通道)Mat 对象,您将使用 而不是使用 。由于您使用的是 CV_32FC1 图像(只有一个通道),因此 适合您。
  • undistortedImage和distortedImage的索引也不应该翻转吗?
猜你喜欢
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
相关资源
最近更新 更多