首页 文章

在OpenCV中生成子像素精度视差图

提问于
浏览
0

目的是为校准的立体图像生成视差图 .

通过使用OpenCV函数cv :: projectPoints()将3D模型投影到一对校准的立体图像(左/右)上 . cv :: projectPoints()在cv :: Point2f中的2D图像坐标上给出点,这是子像素精度 .

由于一些3D点被投影到相同的像素区域上,因此我只保留具有较小深度/ Z的点,因为更近的点遮挡了其他点 .

通过这样做,我可以分别获得左右图像的两个索引图像 . 索引图像的每个像素指的是它在3D模型中的位置(存储在std :: vector中)或2D(std :: vector)中的位置 .

以下片段应简要说明一下程序:

std::vector<cv::Point3f> model_3D;
std::vector<cv::point2f> projectedPointsL, projectedPointsR;
cv::projectPoints(model_3D, rvec, tvec, P1.colRange(0,3), cv::noArray(), projectedPointsL);
cv::projectPoints(model_3D, rvec, tvec, P2.colRange(0,3), cv::noArray(), projectedPointsR);


// Each pixel in indexImage is a index pointing to a position in the vector of projected points 
cv::Mat indexImageL, indexImageR;
// This function filter projected points and return the index image
filterProjectedPoints(projectedPointsL, model_3D, indexImageL);
filterProjectedPoints(projectedPointsR, model_3D, indexImageR);

为了生成视差图,我可以:

1.对于视差图中的每个像素,在左/右索引图像中找到对应的像素位置并减去它们的位置 . 这种方式给出整数视差(不是亚像素精度);

2.对于视差图中的每个像素,在左/右投影点上找到其2D(浮动精度)位置,并将x轴上的差计算为视差 . 这种方式给出了亚像素精度差异 .

第一种方法很简单,并且由于忽略子像素投影点而引入误差 . 然而,第二种方式也引入误差,因为一对投影像素(来自相同的3D点)可以投影到像素内的不同位置 . 例如,左图像中的投影点是(115.289,80.393),右图像中的投影点是(145.686,79.883) . 它在视差图中的位置将是(115,80),并且差异可以是:145.686 - 115.289 = 30.397 . 如您所见,它们可能不完全行对齐以具有相同的y坐标 .

问题是:1 . 两种方法都是正确的(引入错误除外)吗? 2.如果第二种方式是正确的,如果在计算子像素精度差异时误差是可忽略的 .

那么,您也可以告诉我在这种情况下如何计算子像素视差图 .

1 回答

  • 0

    在经校正的图像对中,视差仅为 d=f*b/(z+f) ,其中f是焦距,b是两个相机之间的基线,z是垂直于图像平面的物体的距离 . 这假设一个基本的针孔相机型号 .

    通过近似z >> f,这变为d = f * b / z,即d到z的倒数性质 .

    因此,您可以分析地计算视差图 .

相关问题