我一直在做一个姿势估计项目,其中一个步骤是使用OpenCV的recoverPose
函数找到姿势。
int cv::recoverPose(InputArray E,
InputArray points1,
InputArray points2,
InputArray cameraMatrix,
OutputArray R,
OutputArray t,
InputOutputArray mask = noArray()
)
我有所有必需的信息:基本矩阵E
、图像1中的关键点points1
、图像2中的相应关键点points2
和cameraMatrix
。然而,有一件事仍然让我很困惑,那就是函数返回的int
值(即内列数(。根据文件:
使用检查从估计的基本矩阵和两个图像中的对应点恢复相机的相对旋转和平移。返回通过检查的内联数。
然而,我还不完全理解这一点。我之所以担心这一点,是因为在某个时刻,偏航角(使用输出旋转矩阵R
计算(突然跳跃了150度。对于该特定帧,内联器的数量为0
。因此,根据文件,没有任何分数通过支票检查。但是,它到底意味着什么?这会是偏航角突然跳变的原因吗?如果是,我有什么选择来避免这种情况?由于这个过程是迭代的,一次突然的跳跃会影响所有进一步的姿势!
此函数将基本矩阵E
分解为R
和t
。但是,您最多可以得到4个解决方案,即R
和t
对。在这4个中,只有一个在物理上是可实现的,这意味着其他3个在一个或两个相机后面投影3D点。
检查是用来找到一个物理上可实现的解决方案的,这就是为什么你需要将匹配点传递到函数中。它将使用匹配的2D点,使用4个R
和t
对中的每一个对相应的3D点进行三角测量,并选择在两个相机前面获得最多3D点的一个。这就解释了一些积分匹配可能是错误的。最终出现在两个摄像头前面的点的数量是函数返回的inlier的数量。
所以,如果inlier的数量是0,那么就出了问题。要么你的E
错了,要么积分匹配错了,或者两者都错。在这种情况下,您根本无法从这两张图像中估计相机的运动。
你可以检查几件事。
- 调用
findEssentialMat
后,您将从RANSAC获得用于查找E
的入口。确保您只将那些较内的点传递到recoverPose
中。你不想把你传给findEssentialMat
的所有分数都传进去 - 在将
E
传递到recoverPose
之前,请检查它是否为级别2。如果不是,则可以对E
强制执行秩2约束。可以取E
的SVD,将最小特征值设置为0,然后重建E
- 从
recoverPose
得到R
和t
后,可以检验R
确实是一个行列式等于1的旋转矩阵。如果行列式等于-1,那么R
就是一个反射,事情就出了问题