OpenCV undistortPoints和triangulatePoint给出奇数结果(立体声)

Pet*_*ber 64 c++ opencv triangulation

我试图让几个点的三维坐标空间,但我得到来自两个奇怪的结果undistortPoints()triangulatePoints().

由于这两款相机有不同的分辨率,我已经分别校准他们,得到的均方根误差0,340,43,然后用stereoCalibrate()获得更多的矩阵,得到的RMS 0,708,然后用stereoRectify()获得的剩余矩阵.有了这个,我已经开始了收集坐标的工作,但我得到了奇怪的结果.

例如,输入是:(935, 262),undistortPoints()输出是(1228.709125, 342.79841)一个点,而另一个是(934, 176)(1227.9016, 292.4686).这很奇怪,因为这两个点都非常接近框架的中间,其中扭曲是最小的.我没想到它会将它们移动300像素.

传递给traingulatePoints()结果时,结果甚至更奇怪 - 我测量了现实生活中三点之间的距离(用尺子),并计算了每张图片上像素之间的距离.因为这次点在一个非常平坦的平面上,这两个长度(像素和实际)匹配,如| AB |/| BC | 两种情况都是4/9左右.但是,triangulatePoints()通过| AB |/| BC |给我带来了结果 是3/2或4/2.

这是我的代码:

double pointsBok[2] = { bokList[j].toFloat()+xBok/2, bokList[j+1].toFloat()+yBok/2 };
cv::Mat imgPointsBokProper = cv::Mat(1,1, CV_64FC2, pointsBok);

double pointsTyl[2] = { tylList[j].toFloat()+xTyl/2, tylList[j+1].toFloat()+yTyl/2 };
//cv::Mat imgPointsTyl = cv::Mat(2,1, CV_64FC1, pointsTyl);
cv::Mat imgPointsTylProper = cv::Mat(1,1, CV_64FC2, pointsTyl);

cv::undistortPoints(imgPointsBokProper, imgPointsBokProper, 
      intrinsicOne, distCoeffsOne, R1, P1);
cv::undistortPoints(imgPointsTylProper, imgPointsTylProper, 
      intrinsicTwo, distCoeffsTwo, R2, P2);

cv::triangulatePoints(P1, P2, imgWutBok, imgWutTyl, point4D);

double wResult = point4D.at<double>(3,0);
double realX = point4D.at<double>(0,0)/wResult;
double realY = point4D.at<double>(1,0)/wResult;
double realZ = point4D.at<double>(2,0)/wResult;
Run Code Online (Sandbox Code Playgroud)

点之间的角度有点好,但通常不是:

`7,16816    168,389 4,44275` vs `5,85232    170,422 3,72561` (degrees)
`8,44743    166,835 4,71715` vs `12,4064    158,132 9,46158`
`9,34182    165,388 5,26994` vs `19,0785    150,883 10,0389`
Run Code Online (Sandbox Code Playgroud)

我试图undistort()在整个框架上使用,但结果却很奇怪.B和C点之间的距离应始终保持不变,但这是我得到的:

7502,42     
4876,46 
3230,13 
2740,67 
2239,95 
Run Code Online (Sandbox Code Playgroud)

一帧一帧.

像素距离(底部)与实际距离(顶部) - 应该非常相似: | BC |  距离

角度:

ABC角度

此外,不应该两个undistortPoints()undistort()给出相同的结果(这里的另一组视频)?
在此输入图像描述

小智 3

函数 cv::unactor 一次性完成去畸变和重投影。它执行以下操作列表:

  1. 撤消相机投影(与相机矩阵的逆矩阵相乘)
  2. 应用畸变模型来消除畸变
  3. 按提供的旋转矩阵 R1/R2 旋转
  4. 使用提供的投影矩阵 P1/P2 将点投影到图像

如果您分别传递矩阵 R1、P1。来自 cv::stereoCalibrate() 的 R2、P2,输入点将被不失真并校正。校正是指对图像进行变换,使对应点具有相同的 y 坐标。图像校正没有独特的解决方案,因为您可以对两个图像应用任何平移或缩放,而无需更改相应点的对齐方式。话虽如此,cv::stereoCalibrate() 可以将投影中心移动相当多(例如 300 像素)。如果您想要纯粹的不失真,您可以传递单位矩阵(而不是 R1)和原始相机矩阵 K(而不是 P1)。这应该会导致像素坐标与原始像素坐标相似。