使用OpenCV Python计算摄像机的世界位置

15

我想计算我的相机在世界坐标系中的位置。这应该很容易,但我得到的结果与我期望的不同。我相信我已经阅读了关于这个主题的所有内容,但我的代码并没有起作用。这是我所做的:

我有一个看着一个区域的相机。

1)我绘制了该区域的地图。

2)我使用cv2.getPerspectiveTransform将4个图像点与我的地图上的4个点匹配来计算单应性矩阵H。

3)单应性矩阵H将每个世界坐标转换为相机坐标;这部分正常工作。

4)为了计算相机矩阵,我遵循了this的方法:

translation = np.zeros((3,1)) 
translation[:,0] = homography[:,2]

rotation = np.zeros((3,3))
rotation[:,0] = homography[:,0]
rotation[:,1] = homography[:,1]
rotation[:,2] = np.cross(homography[0:3,0],homography[0:3,1])

cameraMatrix = np.zeros((3,4))
cameraMatrix[:,0:3] = rotation
cameraMatrix[:,3] = homography[:,2]

cameraMatrix = cameraMatrix/cameraMatrix[2][3] #normalize the matrix

5) 根据this,摄像机的位置应该按照以下方式计算:

x,y,z = np.dot(-np.transpose(rotation),translation)

我得到的坐标完全错误。问题应该是在第4或第5步,我想知道我的方法哪里出了问题。


你知道那四个点的世界坐标吗? - Hammer
是的,我知道世界坐标。 - b_m
如果您已经在使用OpenCV,那么您可以直接使用solvePnP吗?它会直接给出您的世界位置... - Hammer
这些表示相机世界位置的值,难道不是你想要的吗?你在将它们转换成3x4矩阵方面遇到了困难吗? - Hammer
1
我建议您提出有关问题的问题,solvePnP比getPerspectiveTransform更适合找到您的世界位置。 - Hammer
显示剩余2条评论
1个回答

21

我想现在我懂了。问题出在第4步描述的方法上。仅从单独的单应性矩阵中无法计算相机位置,还需要相机内参矩阵。因此,正确的步骤如下:

1)绘制区域地图

2)使用棋盘图像进行相机标定,并使用cv2.findChessboardCorners函数获得相机矩阵和畸变系数

3)使用世界坐标(3D)和图像坐标(2D)进行solvePnP求解。solvePnP返回物体在相机坐标系中的原点,给定4个对应点和相机矩阵。

4)现在需要计算相机在世界坐标系中的位置。旋转矩阵为:rotM = cv2.Rodrigues(rvec)[0]

5)相机的x、y、z位置为:cameraPosition = -np.matrix(rotM).T * np.matrix(tvec)


1
我和你的情况一样,但是我在第5点有些卡住了。我很难找到将numpy转换为c/++的细节... 你的最后一行类似于... TransMatrix = inverse( rotM.Transpose() ) .PostMult ( TransMatrix ) 还是除了inverse之外还有其他东西? - Soylent Graham
1
这是在世界空间中的位置,对吗?如果要在OpenGL中使用cameraPositionrotM作为视图矩阵,我需要取其逆矩阵,对吗? - nkint
@b_m 我们需要传递给 solvePnP 函数的“世界坐标(3D)”到底是什么?它已知吗?我该如何找到它? - Clive
@b_m,请问计算cameraPosition需要rotM的大小是多少?在rotM中,您分配了值cv2.Rodrigues(rvec)[0],它指的是Rodrigues生成的3x3旋转矩阵的第一行(因此它的大小为1x3)?我卡在这里,正在尝试计算相机在世界坐标系中的旋转和位置。我正在使用OpenCV(C ++)与Unity3D(C#)结合使用。 - techguy18985

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