我有一辆车,上面有一个摄像头、一个 imu 和一个 gps。相机一边开车一边拍照。图片和gps坐标是同步的。现在,我试图从图片中获取相机姿势(相对于 imu),但solvePnP
最终没有得到与我预期结果相似的外部相机校准。
更多背景信息:我正在使用 Python (3.6.8) 和 OpenCV 4.0.0。
我知道的以下数据:
- 我有 8 个标记及其在世界坐标中的确切位置。
- 我在世界坐标中有imu的轨迹。
- 我有几张图片(6576 x 4384 px)的标记的像素坐标。
- 我有内在的相机校准。
In [4]: image_points
Out[4]:
array([[1911., 2115.],
[2443., 2631.],
[1427., 2570.],
[1409., 2271.],
[1396., 1912.],
[1549., 1770.],
[2247., 1787.],
[2606., 1794.]], dtype=float32)
In [5]: world_points
Out[5]:
array([[-1.5156984e+00, -1.3494657e+00, 0.0000000e+00],
[-2.9987667e+00, 0.0000000e+00, 0.0000000e+00],
[-9.3132257e-10, 0.0000000e+00, 0.0000000e+00],
[ 0.0000000e+00, -8.5239327e-01, 0.0000000e+00],
[-1.5532847e-02, -1.8538033e+00, 0.0000000e+00],
[-5.0486135e-01, -2.2495930e+00, 0.0000000e+00],
[-2.5055323e+00, -2.2484162e+00, 0.0000000e+00],
[-3.4857810e+00, -2.2520051e+00, 0.0000000e+00]], dtype=float32)
In [6]: cameraMatrix
Out[6]:
matrix([[ 2.81923164e+03, -1.36877792e+00, 3.26989822e+03],
[ 0.00000000e+00, 2.81857995e+03, 2.24198230e+03],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
In [7]: distCoeffs
Out[7]: array([ 0.0278163 , -0.01819595, -0.01031101, -0.0023199 , -0.02813449])
目前,我的流程包括:
- 我将所有世界坐标转换为本地标记坐标系,以便所有标记的 z 坐标为 0(参见代码示例中的 Out[4])。起初,我在没有这一步的情况下尝试过,但我阅读了很多教程,似乎校准以某种方式假设了这一点,但我不确定。如果我错了,请纠正我。
- 我
solvePnP
用来获取rvec
和tvec
。 - 我申请
cv2.Rogrigues(rvec)
获得rotationMatrix
- 然后,标记坐标中的相机位置由下式计算
camPos = -np.matrix(rotationMatrix).T * np.matrix(tvec)
之后,我比较了 imu 和估计的相机位置之间的距离,结果大约是 1m,但甚至不一致。这些是 5 个样本图像的结果。
array([[0.65556006],
[1.19668318],
[1.37138227],
[0.64020471],
[0.55105675]])
但是,imu 和摄像头之间的距离应该是 2.4m(手动测量)并且完全没有变化(因为两者都固定在车顶)。
solvePnP 是否有可能输出错误的结果,或者我是否在我的过程中的其他地方犯了错误?
类似的问题,但没有答案将是this。