The full trace of the error I'm encountering:
in stereo_calibrate ret, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F, perViewErrors, _, _= cv2.stereoCalibrateExtended( cv2.error: OpenCV(4.10.0) /io/opencv/modules/calib3d/src/calibration.cpp:1682: error: (-5:Bad argument) For non-planar calibration rigs the initial intrinsic matrix must be specified in function 'cvCalibrateCamera2Internal'
Here's my code:
def stereo_calibrate(img, correspondences_left, correspondences_right, camera_matrix_L, camera_matrix_R, baseline=4.1, dist_coeffs=None):
if dist_coeffs is None:
dist_coeffs = np.zeros((4, 1))
# Extract image points and object points from correspondences
image_points_left = correspondences_left[:, :2].astype(np.float32)
image_points_right = correspondences_right[:, :2].astype(np.float32)
object_points = correspondences_left[:, 2:].astype(np.float32) # Assuming object points are the same for both sets
rvec_L, tvec_L = np.array([0., 0., 0.]), np.array([0, 0., 0.])
rvec_R, tvec_R = np.array([-0.00637872, 0.00102092, 0.000673804]), np.array([0., 0., 0.])
# Convert rotation vectors to rotation matrices
R_L, _ = cv2.Rodrigues(rvec_L)
R_R, _ = cv2.Rodrigues(rvec_R)
print("after converting via Rodrigues:", R_L, R_R)
# Initialize rotation and translation vectors
R_init = R_R @ R_L.T
# T_init = tvec_R - R_init @ tvec_L
T_init = np.array([0., 0., 0.])
print("R_init", R_init)
print("T_init", T_init)
# Stereo calibration to refine the extrinsic parameters
ret, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F, perViewErrors, _, _= cv2.stereoCalibrateExtended(
[object_points], [image_points_left], [image_points_right],
camera_matrix_L, dist_coeffs, camera_matrix_R, dist_coeffs,
imageSize=(img.shape[1], img.shape[0]), # Correct image size as (width, height)
R=R_init, T=T_init,
criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-6),
flags=cv2.CALIB_USE_EXTRINSIC_GUESS
)
print("ret", ret)
if ret:
print("Stereo Calibration Successful")
print("Rotation Matrix between the cameras:")
print(R)
print("Translation Vector between the cameras:")
print(T)
print("dist_coeffs1", distCoeffs1)
print("dist_coeffs2", distCoeffs2)
print(rvec_L)
print(tvec_L)
else:
raise ValueError("stereoCalibrate failed to find a solution")
# Reproject object points to both cameras
reprojected_points_left, _ = cv2.projectPoints(object_points, rvec_L, tvec_L, camera_matrix_L, distCoeffs1)
reprojected_points_right, _ = cv2.projectPoints(object_points, R, T, camera_matrix_R, distCoeffs2)
return R, T, reprojected_points_left, reprojected_points_right
correspondences_left = np.array([
[671.0889955686854, 193.80354505169868, 2.4492935982947064e-16, -4.0, 11],
...
])
correspondences_right = np.array([
[436.2245592329106, 193.79399938137954, 2.4492935982947064e-16, -4.0, 11],
...
])
# Camera intrinsic parameters, replace with your actual camera matrix
camera_matrix_L = np.array([
[1018.9, 0, 601.447],
[0, 1018.9, 517.462],
[0, 0, 1]
], dtype=np.float32)
camera_matrix_R = np.array([
[1018.9, 0, 690.392],
[0, 1018.9, 517.462],
[0, 0, 1]
], dtype=np.float32)
# calling the function
R, T, reprojected_points_left, reprojected_points_right = stereo_calibrate(img_left, correspondences_left, correspondences_right, camera_matrix_L, camera_matrix_R)
This error is really puzzling me because I'm clearly passing in initial camera intrinsic matrices. Why is this error happening?
Figured it out lol. You need to specify an extra flag in the flags parameter of cv2.stereoCalibrateExtended(), specifically cv2.CALIB_USE_INTRINSIC_GUESS or cv2.CALIB_FIX_INTRINSIC_GUESS