【问题标题】:InitUndistortRectifyMap and RemapInitUndistortRectifyMap 和重映射
【发布时间】:2012-12-13 14:31:21
【问题描述】:

我目前正在为一对立体相机编写一个 openCV 程序。 相机校准以及立体校准已完成。

下一步是从我得到的 2 张图像中找到一个特征在空间中的位置。这就是为什么我必须对图像进行立体校正并在之后进行计算。

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 似乎也是正确的。我只是得到黑色图像作为输出。

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

【问题讨论】:

  • 我假设您的问题是:“为什么initUndistortRectifyMap() 返回黑色图像而不仅仅是奇怪的结果?”下次尝试明确您的具体问题。
  • 您需要校准相机才能使用initUndistortRectifyMap(),显然您还没有这样做。请在您校准相机的地方发布代码:aishack.in/2010/07/…
  • 单个摄像头和两个摄像头都使用 StereoCalibrate() 进行校准。我检查了 StereoCalibratoin 中的 R 和 T 矩阵,它们是正确的。
  • 代码太长,交织在一起无法发布。我会早点发布的。。
  • 根据观看次数、投票数和您提出问题的方式,这个帖子很可能会死在这里。如果您得到答案,请在此处发布,您将获得支持,您的声誉越高,人们就越有可能帮助您。

标签: c++ opencv camera


【解决方案1】:

嗯,我有点绕过这个问题,并认为我会分享解决方案,以防任何人都可以使用它。

InitUndistortRectifyMap 在使用 StereoRectify 生成的旋转矩阵 R1 和 R2 时确实输出了空白图像。

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

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

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

【讨论】:

    【解决方案2】:

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

    首先,remap(src,dst,mapX, mapY) 是如何工作的。如果你去documentation,你可以看到

    如果 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 Learning OpenCV:

    再一次,这也是为什么如果你安排你的计划你会获得更好的结果的原因之一 相机尽可能接近正面平行(至少在您成为专家之前) 立体视觉)

    【讨论】:

    • 谢谢@marol。这正是我正在处理的:我的立体相机不是正面平行的,我重新映射的图像是黑色的。鉴于这是目前的情况,而且我的实验已经完成,您对解决方法有什么建议吗?
    • 函数icvGetRectangles 中的https://github.com/opencv/opencv/blob/master/modules/calib3d/src/calibration.cpp 中有一条注释:该代码可能不适用于极端旋转矩阵(R) (>45%)。此函数由cvStereoCalibrate 调用,而StereoCalibrate 又调用此函数。这并没有真正帮助,但表明问题与使用的算法有关并且已知。我不知道为什么这似乎已经发生了 17°。
    猜你喜欢
    • 2010-09-18
    • 2012-07-11
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 2010-11-17
    • 2019-02-10
    • 1970-01-01
    相关资源
    最近更新 更多