gpt4 book ai didi

c++ - OpenCV undistortPoints 和 triangulatePoint 给出奇怪的结果(立体声)

转载 作者:IT老高 更新时间:2023-10-28 12:14:36 28 4
gpt4 key购买 nike

我正在尝试获取空间中几个点的 3D 坐标,但我从 undistortPoints()triangulatePoints() 都得到了奇怪的结果。

由于两个相机的分辨率不同,我分别校准,得到0,340,43的RMS误差,然后使用stereoCalibrate( ) 得到更多的矩阵,得到 0,708 的 RMS,然后使用 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;

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

`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`

我尝试在整个帧上使用 undistort(),但得到的结果同样奇怪。 B 点和 C 点之间的距离应该在任何时候都几乎没有变化,但这就是我得到的:

7502,42     
4876,46
3230,13
2740,67
2239,95

逐帧。

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

角度:

ABC angle

另外,undistortPoints()undistort() 是否应该给出相同的结果(此处是另一组视频)?
enter image description here

最佳答案

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

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

如果你通过矩阵 R1,P1 分别。 R2, P2 来自 cv::stereoCalibrate(),输入点将不失真和校正。校正意味着图像以某种方式转换,使得对应点具有相同的 y 坐标。图像校正没有唯一的解决方案,因为您可以对两个图像应用任何平移或缩放,而无需更改对应点的对齐方式。话虽如此, cv::stereoCalibrate() 可以使投影中心偏移很多(例如 300 像素)。如果你想要纯粹的不失真,你可以传递一个身份矩阵(而不是 R1)和原始相机矩阵 K(而不是 P1)。这应该会导致像素坐标与原始坐标相似。

关于c++ - OpenCV undistortPoints 和 triangulatePoint 给出奇怪的结果(立体声),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32227595/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com