使用opencv

时间:2015-10-30 07:59:54

标签: python image opencv camera calibration

我正在使用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')

但是图像上显示的内容与直角三角形有很大不同(即使三角形的一个角靠近图像的中心)。 有人可以解释一下这里发生了什么吗?

1 个答案:

答案 0 :(得分:0)

这只是cv.projectPoints的输入参数问题:这应该是

[proj_cam_axes,jac] = cv2.projectPoints(world_cam_axes.T,rvec,tvec,mtx,distCoeffs)

为了将world_cam_axes矩阵转换为对象点(用opencv的话来说)