我有一点问题 . 我写了一个程序,使用相机和深度信息在每个帧中提取一组三维点 . 这些点位于 camera coordinate system 中,这意味着原点位于摄像机中心,x是水平距离,y是垂直距离,z是距摄像机的距离(沿光轴) . 一切都以米为单位 . 即点(2,-1,5)沿着摄像机的光轴向右两米,一米和五米 .
我在每个时间帧中计算这些点并且也知道对应关系,就像我知道 t-1
中的哪个点属于 t
中的哪个3d点 .
我现在的目标是在我的世界坐标系中计算每个时间帧中摄像机的运动(z指向上方表示高度) . 我想计算相对运动,但也计算从一些起始位置开始的绝对运动,以可视化摄像机的轨迹 .
这是一帧的示例数据集,其中包含相机坐标中点的当前(左)和前一个3D位置(右):
-0.174004 0.242901 3.672510 | -0.089167 0.246231 3.646694
-0.265066 -0.079420 3.668801 | -0.182261 -0.075341 3.634996
0.092708 0.459499 3.673029 | 0.179553 0.459284 3.636645
0.593070 0.056592 3.542869 | 0.675082 0.051625 3.509424
0.676054 0.517077 3.585216 | 0.763378 0.511976 3.555986
0.555625 -0.350790 3.496224 | 0.633524 -0.354710 3.465260
1.189281 0.953641 3.556284 | 1.274754 0.938846 3.504309
0.489797 -0.933973 3.435228 | 0.561585 -0.935864 3.404614
由于我想在可能的情况下使用OpenCV,我在OpenCV 2.3中找到了 estimateAffine3D()
函数,该函数接受两个3D点输入向量并使用RANSAC计算它们之间的仿射变换 .
作为输出,我得到一个3x4变换矩阵 .
我已经尝试通过设置RANSAC参数使计算更准确,但很多时候trnasformation矩阵显示了相当大的平移运动 . 正如您在样本数据中看到的那样,运动通常非常小 .
所以我想问一下是否有人对我可以尝试的内容有另一个想法? OpenCV是否为此提供其他解决方案?
此外,如果我在每个时间帧内都有相机的相对运动,我将如何将其转换为世界坐标?另外,我如何获得从点(0,0,0)开始的绝对位置,所以我有每个时间帧的相机位置(和方向)?
如果有人能给我一些建议,那会很棒!
谢谢!
UPDATE 1:
在@Michael Kupchick很好的回答后,我试着检查一下OpenCV中的estimateAffine3D()函数的运行情况 . 所以我创建了两个6个点对的小测试集,它们只有一个平移,而不是一个旋转,看看结果转换矩阵:
Test set 1:
1.5 2.1 6.7 | 0.5 1.1 5.7
6.7 4.5 12.4 | 5.7 3.5 11.4
3.5 3.2 1.2 | 2.5 2.2 0.2
-10.2 5.5 5.5 | -11.2 4.5 4.5
-7.2 -2.2 6.5 | -8.2 -3.2 5.5
-2.2 -7.3 19.2 | -3.2 -8.3 18.2
转换矩阵:
1 -1.0573e-16 -6.4096e-17 1
-1.3633e-16 1 2.59504e-16 1
3.20342e-09 1.14395e-09 1 1
Test set 2:
1.5 2.1 0 | 0.5 1.1 0
6.7 4.5 0 | 5.7 3.5 0
3.5 3.2 0 | 2.5 2.2 0
-10.2 5.5 0 | -11.2 4.5 0
-7.2 -2.2 0 | -8.2 -3.2 0
-2.2 -7.3 0 | -3.2 -8.3 0
转换矩阵:
1 4.4442e-17 0 1
-2.69695e-17 1 0 1
0 0 0 0
-
这给了我两个看起来正确的转换矩阵......
假设这是正确的,当我在每个时间步长中有这个变换矩阵时,我将如何重新计算这个轨迹?
任何人有任何提示或想法为什么这么糟糕?
1 回答
这个问题与图像处理有很大关系 .
您要做的是注册知识3d,因为对于所有帧,存在相同的3d点 - >相机关系,从注册计算的变换将是相机运动变换 .
为了解决这个问题,您可以使用PCL . 这是opencv的三维相关任务的姐妹项目 . http://www.pointclouds.org/documentation/tutorials/template_alignment.php#template-alignment这是一个关于点 Cloud 对齐的好教程 .
基本上它是这样的:
对于每对连续帧,3d点对应是已知的,因此您可以使用在其中实现的SVD方法
http://docs.pointclouds.org/trunk/classpcl_1_1registration_1_1_transformation_estimation_s_v_d.html
你应该至少有3个对应点 .
您可以按照教程或实现自己的ransac算法 . 这将只为您提供一些粗略的变换估计(如果噪声不是太大,可能会非常好),为了获得准确的变换,您应该使用上一步计算的猜测变换应用ICP算法 . ICP在这里描述:
http://www.pointclouds.org/documentation/tutorials/iterative_closest_point.php#iterative-closest-point
这两个步骤应该可以准确估计帧之间的转换 .
所以你应该逐步进行成对注册 - 注册第一对帧得到从第一帧到第二帧1-> 2的转换 . 将第二个注册到第三个(2-> 3),然后将1-> 2转换添加到2-> 3,依此类推 . 这样,您将在全局坐标系中获得第一帧为原点的变换 .