立体三角测量出现奇怪问题:两个有效解决方案

3

我目前在进行一个姿态估计相关的项目,使用OpenCV进行操作。我需要在一对之间三角化点以进行重建和尺度因子估计。但是,在使用OpenCV函数recoverPose()和triangulatePoints()时,我遇到了一个奇怪的问题。

假设我有两个相机,称为相机1和相机2,它们在X轴上间隔一定距离。相机1坐标为(0,0,0),相机2位于右侧(正X轴方向)。我有两个数组points1和points2,它们包含了这两张图像中匹配的特征点。根据OpenCV文档和代码,我已经注意到了两个重要点:

  1. recoverPose() assumes that points1 belong to the camera at (0,0,0).
  2. triangulatePoints() is called twice: one from recoverPose() to tell us which of the four R/t combinations is valid, and then again from my code, and the documentation says:

    cv::triangulatePoints(P1, P2, points1, points2, points3D)  : points1 -> P1 and points2 -> P2. 
    
因此,与recoverPose()的情况一样,安全地假定P1为[I|0]且P2为[R|t]。
实际上我发现:事实并非如此。虽然我的相机1在0,0,0处,相机2在1,0,0处(1代表比例),但只有当我运行...
recoverPose(E, points2, points1...)
triangulatePoints([I|0], [R|t], points2, points1, pts3D) 

这应该是不正确的,因为points2是来自R|t的集合,而不是points1。我测试了我的房间里有三个显眼物体的场景图像对进行三角化:一个显示器和墙上的两张海报。以下是从三角化中得出的点云结果(请原谅MS Paint)

如果按照OpenCV的规定方式进行操作:(分散在空间中的海报点,结果看起来很奇怪)

错误

如果按照我的(错误?)方式进行操作:

正确

能否有人分享一下他们对这里发生的事情的看法?从技术上讲,两种解决方案都是有效的,因为所有点都在两个相机的前面:我不知道该选择哪个,直到将其呈现为点云。我做错了什么,还是文档中存在错误?我对计算机视觉理论并不太了解,所以可能会遗漏一些基本的东西。感谢您的时间!


你最终解决了这个问题吗?你使用的OpenCV版本是哪个(确切地说)? - Derek Simkowiak
老实说,没有。我只是采用了能够得出正确结果的方法。我正在使用C++中的2.4.11版本。 - HighVoltage
你是如何追踪第二帧中匹配的特征的?你使用了 cv::calcOpticalFlowPyrLK 吗?我对你在问题中提到的特征检测和跟踪部分感到困惑。 - Farid Alijani
2个回答

1
我遇到了类似的问题。我认为OpenCV定义的平移向量与人们期望的相反。对于您的相机配置,平移向量将是[-1, 0, 0]。这很不直观,但RecoverPose和stereoCalibrate都提供了这个平移向量。
我发现当我使用不正确但直观的平移向量(例如[1, 0, 0])时,除非我交换points1和points2,否则我无法获得正确的结果,就像你一样。
我怀疑平移向量实际上是将点转换为另一个相机坐标系,而不是用于转换相机姿态的向量。OpenCV Documentation似乎暗示了这一点:
引用: “联合旋转-平移矩阵[R|t]称为外部参数矩阵。它用于描述相机在静态场景周围的运动,或者反之,静止相机前的物体的刚体运动。也就是说,[R|t]将点(X,Y,Z)的坐标转换为相对于相机固定的坐标系。”

维基百科对坐标轴平移有一个很好的描述:

在新的坐标系中,点P将会看起来向相反方向平移。例如,如果xy坐标系向右平移了h距离并向上平移了k距离,则在x'y'坐标系中,P将会看起来向左平移了h距离并向下平移了k距离。


0

那么旋转矩阵 R 也应该被反转吗? - dexter2406

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接