InitUndistortRectifyMap和Remap

时间:2012-12-13 14:31:21

标签: c++ opencv camera

我目前正在为一对立体相机编写openCV程序。 完成了摄像机校准和立体声校准。

下一步是从我得到的2张图片中找到一个特征在空间中的位置。这就是为什么我需要Stereo整理图像并在之后进行计算。

我面临initUndistortRectifyMap的问题如下:

- 如果我将stereoRectify()计算的R1或R2传递给initUndistortRectifyMap(),我会在重新映射后获得黑色图像。

- 如果我将r(空矩阵)传递给initUndistortRectifyMap(),我会在重新映射后得到未经校正的图像。我得到的图像虽然有点扭曲。

我需要将R1和R2传递给initUndistortRectifyMap()来纠正2个摄像头,否则当传递空矩阵时,立体声头不会旋转到同一个平面。

以下是我的代码:

stereoRectify(intrinsic[0], distCoeffs[0], intrinsic[1], distCoeffs[1], imageSize, 
    R, T_Stereo, R1, R2, newP1, newP2, Q, CV_CALIB_ZERO_DISPARITY, -1, imageSize);

if (x_Cam.GetSerial()=="4002678487")
{
    initUndistortRectifyMap(intrinsic[0], distCoeffs[0], R1, newP1, imageSize,        
        CV_16SC2 , mapx1,  mapy1);
    remap(x_Image, imageRectified[0],mapx1, mapy1, INTER_LINEAR);

    return imageRectified[0];
}   

if (x_Cam.GetSerial()=="4002702131")
{
    //flip(in, in, -1);
    initUndistortRectifyMap(intrinsic[1], distCoeffs[1], R2, newP2, imageSize, 
        CV_16SC2 , mapx2,  mapy2);
    remap(x_Image, imageRectified[1],mapx2, mapy2, INTER_LINEAR, BORDER_CONSTANT, 0);

    return imageRectified[1];
}

我检查了进入stereoRectify()的所有矩阵值,它们是正确的。旋转矩阵R1和R2似乎也是正确的。我只是将黑色图像作为输出。

我尝试将垃圾值传递给InitUndistortRectifyMap()以获取R1和R2(例如R1 * R2)以简单地看到效果,并且我确实获得了奇怪的结果但不是黑色图像。

2 个答案:

答案 0 :(得分:8)

好吧,我解决了这个问题并且认为我会分享解决方案,任何人都可以使用它。

InitUndistortRectifyMap在使用Rotation Matrices R1和StereoRectify生成的R2时输出了空白图像。

因此,我尝试使用StereoRectifyUncalibrated,它产生2个Homography矩阵H1和H2,并且我根据OpenCV文档计算了旋转:

R1 = inv(CamMatrix1)* H1 * CamMatrix1 R2 = inv(CamMatrix2)* H2 * CamMatrix2

我将新的R1和R2传递给InitUndistortRectifyMap并重新映射,结果令人满意。

答案 1 :(得分:4)

我要去挖掘这篇旧帖子,因为我最近在研究这个问题上做了一些努力。也就是说,我已经面临同样的问题 - 经过适当的立体声校准和整改(所有opencv提供的立体视觉机器),最终“扭曲”了#39;图像是黑色的。让我解释一下为什么会如此。

首先,重映射(src,dst,mapX,mapY)的工作原理。如果你转到documentation,你可以看到

enter image description here

如果mapX(x,y)或mapY(x,y)中的一个值在src之外,则dst(x,y)= 0(黑色!)。这意味着,所有对(x,y)在mapX或mapY中都具有无效值。例如,在我的情况下,根据我无法解释的原因,我在mapY中有所有值为负。

但其原因仅在于特定的立体视觉配置。我做了几个相机对齐的例子,它们之间的旋转角度很小(高达几度)。在这种情况下,opencv程序运行良好。黑色'当两个欧拉角相同而一个角度(绕Y旋转)为17度时,输出问题。在那种情况下,我做了一些实验 - 我按照以下方式翻译了mapX和mapY:

for(int i=0;i<_imageSize.width;i++)
        for(int j=0;j<_imageSize.height;j++) {
            _mapXA.at<float>(j, i) -= 1200;
            _mapYA.at<float>(j, i) -= 1200;
            _mapXB.at<float>(j, i) += 2500;
            _mapYB.at<float>(j, i) += 2500;
        }

(因为我看到_mapXA 太大而_mapYB的负值大约为-1500)。令人惊讶的是, remap()之后的输出并非黑色。图像看起来像是围绕某个角度旋转(17可能是,我没有确切地检查),但它根本没有被纠正。

opencv可能无法很好地处理立体视觉中的非平行相机。我的意思是,它适用于一些例子,而有些则没有 - 但这意味着这种方法不可行。此外,你可以找到这样的信息Gary Bradski和Adrian Kaehler 学习OpenCV

再一次,这就是为什么如果安排你的话,你会倾向于获得更好的结果的一个原因 相机尽可能近似平行(至少在你成为专家之前) 立体视觉)