MikeTeX
MikeTeX

Reputation: 529

Unexpected results using camera pause functions of opencv

I am using Opencv with python 2.7.

I have obtained intrinsic camera matrix, and extrinsic matrix of the camera pause, with a chess board :

(ret, mtx, dist, rvecs, tvecs) = cv2.calibrateCamera(objpoints, imgpoints, grayImg.shape[::-1],None,None)

[ret, rvec, tvec] = cv2.solvePnP(objp, corners, mtx, distCoeff)

Then, I ploted the world coordinate axes in the image using 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)    

Up to now, everything works fine : the world axes appear in 3d on the image, with origin located at a corner of the chess board, two axes parallel to the side of the chess board, and the third orthogonal to this later.

I have also converted the rvec vector into a rotation matrix:

Rmat = cv2.Rodrigues(rvec)[0] #rotation matrix of the camera pause

Now, I want to visualize the projection of the camera axes on the image; more precisely, I want to plot the projection of the points whose coordinates in the camera axes system are [1,0,1], [0,1,1] and [0,0,1].

NORMALLY: I should observe a right angle triangle, whose two orthogonal sides are parallel to the sides of the image, since the camera coordinate axes are defined in this way.

According to all what I have read, the world coordinates and the camera coordinates are related by X_cam = Rmat * X_world + tvec, so X_world = Rmat^-1 (X_cam - tvec). Consequently, the following piece of code should have shown a right angle triangle, with corner probably located near the center of the image:

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')

But what is displayed on the image is very different from a right angle triangle (even though one corner of the triangle is near the centre of the image).
Can someone explain me what happens here ?

Upvotes: 0

Views: 261

Answers (1)

MikeTeX
MikeTeX

Reputation: 529

This is simply a problem of input argument of cv.projectPoints : this should be

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

in order to convert the world_cam_axes matrix to an object points (in the words of opencv)

Upvotes: 0

Related Questions