c++ 如何在opencv中获得重新Map后像素的原始位置

vyu0f0g1  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(137)

假设我有一组这样的重Map:(假设图像设置和代码工作)

for(int i=0; i<NumberOfImages; i++)
{
    remap( inputImage, outImages[i], m_mapX[i], m_mapY[i], CV_INTER_NN );
}

字符串
现在我想在outputImages上找到输入图像上的像素(X,Y)的位置(假设remap是以一种输入图像上的任何像素都只Map到一个输出图像的方式)
最简单的方法是在所有m_mapX和m_mapY上进行搜索并查找所需的像素,但这非常耗时。有更好的方法吗?
假设我有一个很大的点列表,我需要转换,所以可能创建一个反向Map是更好的,但如何创建一个反向Map?

s8vozzvw

s8vozzvw1#

对于重新Map的图像,OpenCV(版本4.7和更高版本)提供了一种更直接的方法,使用函数[cv::initInverseRectificationMap][1]。(K)、失真系数和校正(R)和投影(P)矩阵,通常从相机校准或立体校正中获得。您可以使用这些参数来计算逆校正图,这将允许您在重新Map后找到未失真图像中像素的原始位置。
此函数生成两个MapinvMapXinvMapY,可与cv::remap一起使用以执行逆校正。Map类型CV_16SC2是OpenCV中使用的预定义格式,用于为每个像素存储两个16位有符号整数。使用此类型时,invMapXinvMapY中的每个像素就像指向其在原始图像中的对应位置的固定索引一样工作。
下面是正确的代码:

#include <opencv2/opencv.hpp>

// Assuming these variables are already initialized with valid data:
// k - Camera matrix
// DistCoeff - Distortion coefficients
// R - Rotation matrix (rectification)
// P - Projection matrix
// Ncols, Nrows - Size of the image

cv::Mat invMapX, invMapY;
cv::initInverseRectificationMap(k, DistCoeff, R, P, cv::Size(Ncols, Nrows), CV_16SC2, invMapX, invMapY);

// Now, to find the original position of a pixel from a remapped image, you can do the following:
cv::Vec2s pixel = invMapX.at<cv::Vec2s>(row_from_RemappedImage, col_from_RemappedImage);

// pixel[0] is the x-coordinate, and pixel[1] is the y-coordinate in the original (undistorted) image.

字符串
确保矩阵k, DistCoeff, R,P使用相机校准的结果正确初始化。

相关问题