简体   繁体   English

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

[英]Generate subpixel accuracy disparity map in OpenCV

The purpose is to generate disparity map for a calibrated stereo images. 目的是为校准后的立体图像生成视差图。

A 3D model is projected onto a pair of calibrated stereo images (left/right) by using OpenCV function cv::projectPoints(). 使用OpenCV函数cv :: projectPoints()将3D模型投影到一对校准的立体图像(左/右)上。 The cv::projectPoints() gives points on the 2D image coordinate in cv::Point2f which is subpixel accuracy. cv :: projectPoints()在cv :: Point2f中的2D图像坐标上给出点,这是亚像素精度。

As some 3D points are projected onto same pixel region, I only keep the point that have smaller depth/Z due to the fact that further points are occluded by the closer point. 由于某些3D点投影到相同的像素区域上,因此,由于其他点被较近的点遮挡,因此我仅保留深度/ Z较小的点。

By doing this, I can get two index images for left and right image respectively. 通过这样做,我可以分别获得左右图像的两个索引图像。 Each pixel of the index image refer to its position in the 3D model (stored in std::vector) or in 2D (std::vector). 索引图像的每个像素都引用其在3D模型(存储在std :: vector中)或2D(std :: vector)中的位置。

Following snippet should briefly explain the procedures: 以下代码段应简要说明程序:

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);

In order to generate the disparity map, I can either: 为了生成视差图,我可以:

1.For each pixel in the disparity map, find the corresponding pixel position in the left/right index images and subtract their position. 1.对于视差图中的每个像素,在左/右索引图像中找到相应的像素位置,然后减去它们的位置。 This way gives integer disparity (not subpixel accuracy); 这种方式给出整数视差(不是子像素精度);

2.For each pixel in the disparity map, find its 2D (floating accuracy) position on both left/right projected points and calculate the difference in x axis as disparity. 2.对于视差图中的每个像素,在左右两个投影点上找到其2D(浮动精度)位置,并计算x轴上的差异作为视差。 This way gives subpixel accuracy disparity. 这种方式产生了亚像素精度差异。

The first way is straightforward and introduces error due to ignoring subpixel projected points. 第一种方法很简单,并且由于忽略了子像素投影点而引入了误差。 However, the second way also introduces error as a pair of projected pixels (from same 3D points) may be projected into different location within a pixel. 但是,第二种方式也会引入误差,因为一​​对投影像素(来自相同3D点)可能会投影到像素内的不同位置。 For example, a projected point in left image is (115.289, 80.393), in right image is (145.686, 79.883). 例如,左图像中的投影点是(115.289,80.393),右图像中的投影点是(145.686,79.883)。 Its position in disparity map will be (115, 80) and disparity can be: 145.686 - 115.289 = 30.397. 其在视差图中的位置将为(115,80),视差可以为:145.686-115.289 = 30.397。 As you can see, they may not be exactly row aligned to have same y coordinate. 如您所见,它们可能未完全按行对齐以具有相同的y坐标。

Questions are: 1. Are both ways correct (except introducing error)? 问题是:1.两种方法都是正确的(引入错误除外)吗? 2. If the 2nd way is correct, if the error is ignoble when computing subpixel accuracy disparity. 2.如果第二种方法是正确的,则在计算子像素精度差异时错误可以忽略。

Well, you can also tell me how would you calculate subpixel disparity map in this scenario. 好吧,您也可以告诉我在这种情况下如何计算亚像素视差图。

In a rectified image pair, the disparity is simply d=f*b/(z+f) , where f is the focal length, b is the baseline between the two cameras and z is the distance to the object normal to the image planes. 在经过校正的图像对中,视差仅为d=f*b/(z+f) ,其中f是焦距,b是两个摄像机之间的基线,z是到垂直于图像平面的物体的距离。 This assumes a basic pin hole camera model. 假设使用基本的针孔摄像机型号。

By approximating z >> f, this turns to d=f*b/z, ie the reciprocal nature of d to z. 通过近似z >> f,这将变为d = f * b / z,即d与z的倒数性质。

So you can just calculate the disparity map analytically. 因此,您只需分析计算出视差图即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM