Why does OpenCV think I am using a nonplanar calibration setup?
I am playing with a simulated camera to try and understand how the OpenCV calib3d module works and works.
I created an artificial set of object points in 3D space corresponding to a flat grid of nine points at z = 50:
obj_pts = np.zeros((9, 3), dtype='float32')
obj_pts[0] = np.array([40, 40, 50], dtype='float32')
obj_pts[1] = np.array([50, 40, 50], dtype='float32')
obj_pts[2] = np.array([60, 40, 50], dtype='float32')
obj_pts[3] = np.array([40, 50, 50], dtype='float32')
obj_pts[4] = np.array([50, 50, 50], dtype='float32')
obj_pts[5] = np.array([60, 50, 50], dtype='float32')
obj_pts[6] = np.array([40, 60, 50], dtype='float32')
obj_pts[7] = np.array([50, 60, 50], dtype='float32')
obj_pts[8] = np.array([60, 60, 50], dtype='float32')
What I then depicted with the help cv2.projectPoints()
after creating the artificial camera:
rvec = (0, 0, 0) # rotation relative to the frame
tvec = (0, 0, 0) # translation relative to the frame
distCoeffs = (0, 0, 0, 0)
cameraMatrix = np.zeros((3, 3))
focalLength = 50
cx = 0
cy = 0
setupCameraMatrix(cameraMatrix, focalLength, cx, cy) # my own routine
img_pts, jacobian = cv2.projectPoints(obj_pts, rvec, tvec, cameraMatrix, distCoeffs)
Projected onto the image plane using the above parameters, the image points look like this (the red dot only indicates the lower left corner for orientation):
And finally, I'm trying to restore the original camera calibration:
obj_pts_list = [obj_pts] img_pts_list = [img_pts] ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_pts_list, img_pts_list, (200, 200), None, None)
However, this last step gives this error:
OpenCV Error: Bad argument (For non-planar calibration rigs the initial intrinsic matrix must be specified) in cvCalibrateCamera2, file /tmp/opencv20150527-4924-hjrvz/opencv-2.4.11/modules/calib3d/src/calibration.cpp, line 1592
My question is not how to fix this error as such, but why is it being thrown in the first place? Why is this setup a nonplanar setup when all points of the object lie in the same plane? Did I get it wrong?
source to share
OpenCV expects z = 0
, as is the case for planar calibration purposes.
Looking through the code, it OpenCV
checks this value as follows:
Scalar mean, sdv;
meanStdDev(matM, mean, sdv);
if( fabs(mean[2]) > 1e-5 || fabs(sdv[2]) > 1e-5 )
CV_Error( CV_StsBadArg,
"For non-planar calibration rigs the initial intrinsic matrix must be specified" );
which means setting z other than 0 throws an error. Then you should use z = 0
if not using a non-planar calibration target.
source to share