如何正确使用 cv::triangulatePoints()

新手上路,请多包涵

我试图用 OpenCV 对一些点进行三角测量,我发现了这个 cv::triangulatePoints() 函数。问题是几乎没有文档或示例。

我对此有些怀疑。

  1. 它使用什么方法? 我对三角测量进行了一项小型研究,有几种方法(线性、线性 LS、特征、迭代 LS、迭代特征,…),但我找不到它在 OpenCV 中使用的方法。

  2. 我应该如何使用它? 似乎作为输入,它需要一个投影矩阵和 3xN 齐次 2D 点。我将它们定义为 std::vector<cv::Point3d> pnts ,但作为输出它需要 4xN 数组,显然我无法创建 std::vector<cv::Point4d> 因为它不存在,所以我应该如何定义输出向量?

对于我尝试的第二个问题: cv::Mat pnts3D(4,N,CV_64F);cv::Mat pnts3d; 似乎都不起作用(它引发异常)。

原文由 Ander Biguri 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.1k
2 个回答

1.- 使用的方法 是最小二乘法。还有比这更复杂的算法。它仍然是最常见的一种,因为其他方法在某些情况下可能会失败(即,如果点在平面上或无限上,则其他方法会失败)。

该方法可以在 Richard Hartley 和 Andrew Zisserman 的计算机视觉中的多视图几何中 找到 (p312)

2.- 用法

 cv::Mat pnts3D(1,N,CV_64FC4);
cv::Mat cam0pnts(1,N,CV_64FC2);
cv::Mat cam1pnts(1,N,CV_64FC2);

用图像中的点填充 2 个 chanel 点矩阵。

cam0cam1Mat3x4 相机矩阵(内在和外在参数)。您可以通过乘以 A*RT 来构造它们,其中 A 是内在参数矩阵,RT 是旋转平移 3x4 姿势矩阵。

 cv::triangulatePoints(cam0,cam1,cam0pnts,cam1pnts,pnts3D);


注意pnts3D 需要是 4 通道 1xN cv::Mat 定义时,如果没有则抛出异常,但结果是 cv::Mat(4,N,cv_64FC1) 。真的很混乱,但这是我没有例外的唯一方法。


更新:从 3.0 版或更早的版本开始,这不再适用,并且 pnts3D 也可以是 Mat(4,N,CV_64FC1) 类型,或者可能完全为空(像往常一样,它是在内部创建的功能)。

原文由 Ander Biguri 发布,翻译遵循 CC BY-SA 4.0 许可协议

感谢安德·比古里!他的回答对我帮助很大。但我总是更喜欢 std::vector 的替代方案,我编辑了他的解决方案:

 std::vector<cv::Point2d> cam0pnts;
std::vector<cv::Point2d> cam1pnts;
// You fill them, both with the same size...

// You can pick any of the following 2 (your choice)
// cv::Mat pnts3D(1,cam0pnts.size(),CV_64FC4);
cv::Mat pnts3D(4,cam0pnts.size(),CV_64F);

cv::triangulatePoints(cam0,cam1,cam0pnts,cam1pnts,pnts3D);

所以你只需要在积分中做 emplace_back 。主要优点:在开始填充它们之前,您不需要知道尺寸 N 。可惜没有cv::Point4f,所以pnts3D一定是cv::Mat…

原文由 Ginés Hidalgo 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题