我正在使用Opencv和python 2.7。
我已经获得了内在的相机矩阵,以及相机暂停的外在矩阵,以及棋盘:
(ret, mtx, dist, rvecs, tvecs) = cv2.calibrateCamera(objpoints, imgpoints, grayImg.shape[::-1],None,None)
[ret, rvec, tvec] = cv2.solvePnP(objp, corners, mtx, distCoeff)
然后,我使用cv.projectPoints
在图像中绘制世界坐标轴 axes = chess_board_square_sz * np.float32([[1,0,0], [0,1,0], [0,0,-1]]).reshape(-1,3)
[axes_proj, jac] = cv2.projectPoints(axes, rvec, tvec, mtx, distCoeff)
img = draw_axes(img, corners2, axes_coor)
到目前为止,一切正常:世界轴在图像上以3d显示,原点位于棋盘的一角,两个轴平行于棋盘的一侧,第三个轴与之后正交
我还将rvec矢量转换为旋转矩阵:
Rmat = cv2.Rodrigues(rvec)[0] #rotation matrix of the camera pause
现在,我想要想象相机轴在图像上的投影;更准确地说,我想绘制相机轴系统中坐标为[1,0,1],[0,1,1]和[0,0,1]的点的投影。
NORMALLY:我应该观察到一个直角三角形,其两个正交边平行于图像的边,因为摄像机坐标轴是以这种方式定义的。
根据我所读到的所有内容,世界坐标和相机坐标与X_cam = Rmat * X_world + tvec相关,因此X_world = Rmat ^ -1(X_cam - tvec)。因此,下面的代码应该显示一个直角三角形,角落可能位于图像中心附近:
cam_axes = chess_board_square_sz * np.float32([1,0,1], [0,1,1], [0,0,1]);
world_cam_axes = n.dot(Rmat.T, (cam_axes - tvec))
[proj_cam_axes, jac] = cv2.projectPoints(world_cam_axes, rvec, tvec, mtx, dist)
img = cv2.imread(calibr_img_name)
img = cv2.line(img, tuple(rproj_cam_axes[0].ravel(), tuple(rproj_cam_axes[1].ravel()), [255,0,0], 5)
img = cv2.line(img, tuple(rproj_cam_axes[0].ravel(), tuple(rproj_cam_axes[2].ravel()), [0,255,0], 5)
img = cv2.line(img, tuple(rproj_cam_axes[1].ravel(), tuple(rproj_cam_axes[2].ravel()), [0,0,255], 5)
fig, ax2 = plt.subplot(1)
ax2.imshow(img2, interpolation = 'bicubic')
但是图像上显示的内容与直角三角形有很大不同(即使三角形的一个角靠近图像的中心)。 有人可以解释一下这里发生了什么吗?
答案 0 :(得分:0)
这只是cv.projectPoints的输入参数问题:这应该是
[proj_cam_axes,jac] = cv2.projectPoints(world_cam_axes.T,rvec,tvec,mtx,distCoeffs)
为了将world_cam_axes矩阵转换为对象点(用opencv的话来说)