我正在使用以下代码估算单个摄像机的平移和旋转。
E, mask = cv2.findEssentialMat(k1, k2,
focal = SCALE_FACTOR * 2868
pp = (1920/2 * SCALE_FACTOR, 1080/2 * SCALE_FACTOR),
method = cv2.RANSAC,
prob = 0.999,
threshold = 1.0)
points, R, t, mask = cv2.recoverPose(E, k1, k2)
其中k1
和k2
是我匹配的关键点集,它们是Nx2矩阵,其中第一列是x坐标,第二列是y坐标。
我收集了几帧中的所有译文,并生成了一条像这样行进的路径。
def generate_path(rotations, translations):
path = []
current_point = np.array([0, 0, 0])
for R, t in zip(rotations, translations):
path.append(current_point)
# don't care about rotation of a single point
current_point = current_point + t.reshape((3,)
return np.array(path)
所以,我对此有一些疑问。
plt.plot(path[:,0], path[:,2])
这是完全错误的。
但是,如果我改写这个
plt.plot(path[:,0], path[:,1])
经过一些平均后,我得到了以下内容
这条路基本上是完美的。
因此,也许我误解了cv2.recoverPose
使用的坐标系惯例?为什么相机路径的“鸟瞰”应该沿着XY平面而不是XZ平面?
我很确定代码中存在错误,因为这些问题似乎是系统性的-但我想确保自己对坐标系的理解是正确的,以便可以限制搜索空间以进行调试。
答案 0 :(得分:0)
实际上,在一开始,您的方法并没有产生真实的路径。由recoverPose()产生的转换t始终是单位向量。因此,在您的“路径”中,每帧都距上一帧正好1个“米”。正确的方法是:1)初始化:(featureMatch,findEssentialMatrix,recoverPose),然后2)跟踪:(triangluate,featureMatch,solvePnP)。如果您想进一步研究,找到有关Monocular Visual SLAM的教程会有所帮助。
第二,您可能已经弄乱了相机坐标系和世界坐标系。如果要绘制轨迹,可以使用世界坐标系而不是摄影机坐标系。此外,recoverPose()的结果也位于世界坐标系中。世界坐标系是:x轴指向右侧,y轴指向前方,z轴指向上方。因此,当您要绘制``鸟瞰图''时,应该沿着XY方向绘制是正确的飞机。