InitUndistortRectifyMap和Remap

use*_*213 7 c++ camera opencv

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

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

我面临的问题initUndistortRectifyMap如下:

- 如果我通过计算的R1或R2 stereoRectify(),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];
}
Run Code Online (Sandbox Code Playgroud)

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

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

use*_*213 8

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

使用Rotation Matrices R1和StereoRectify生成的R2时,InitUndistortRectifyMap会输出空白图像.

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

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

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


mar*_*rol 5

我将挖掘这篇旧文章,因为我最近花了一些精力研究这个问题。也就是说,我遇到了同样的问题 - 经过适当的立体校准和校正(所有 opencv 都提供立体视觉机制),最终“扭曲”图像是黑色的。让我解释一下为什么会这样。

首先,remap(src,dst,mapX,mapY)是如何工作的。如果您查看文档,您可以看到

在此输入图像描述

如果值 mapX(x,y) 或 mapY(x,y) 之一位于 src 之外,则 dst(x,y) = 0(黑色!)。这意味着,所有对 (x,y) 在mapX 或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;
        }
Run Code Online (Sandbox Code Playgroud)

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

opencv 可能无法很好地处理立体视觉中的非并行相机。我的意思是,它对于某些示例有效,而对于某些示例则无效 - 但这意味着该方法不可靠。另外,您还可以找到此类信息 Gary Bradski 和 Adrian Kaehler 学习 OpenCV

再次强调,这就是为什么如果您将相机布置得尽可能接近正面平行,您往往会获得更好的结果的原因之一(至少在您成为立体视觉专家之前)