System information (version)
- OpenCV => 4.5.5
- Python => 3.9
- Operating System / Platform => Windows 64 Bit
- Compiler => Visual Studio 2019
Detailed description
When trying to calibrate a wide FOV camera using opencv-contrib-python the omnidir.calibrate() results in Assertion error (-215):
"OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv_contrib\modules\ccalib\src\omnidir.cpp:854: error: (-215:Assertion failed) !objectPoints.empty() && objectPoints.type() == CV_64FC3 in function 'cv::omnidir::internal::computeJacobian'"
Additional description:
shape of objectpoints: (8, 1, 150, 3)
size of objectpoints: 3600
type of objectpoints: dtype=np.float64
Steps to reproduce
import cv2
assert cv2.__version__[0] >= '3', 'The fisheye module requires opencv version >= 3.0.0'
import numpy as np
import os
import glob
import matplotlib.pyplot as plt
# Globals
image_path = 'C:/Users/FJOHAN86/source/repos/Camera_calibration/Checkboard/'
#output_path = '../fisheye_images/output/'
image_extension = 'jpg'
image_size = (4032 , 3024)
checkerboard_size = (10,15)
subpixel_criteria = (cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 300, 0.1)
fisheye_calibration_flags = cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC+cv2.fisheye.CALIB_CHECK_COND+cv2.fisheye.CALIB_FIX_SKEW
omnidir_calibration_flags = cv2.omnidir.CALIB_USE_GUESS + cv2.omnidir.CALIB_FIX_SKEW + cv2.omnidir.CALIB_FIX_CENTER + cv2.omnidir.CALIB_FIX_XI
draw_chessboard_marked_images = False
def getObjectAndImagePoints(imagePath, imageExtension, checkerboardSize, subpixelCriteria, drawChessboardMarkedImages):
objp = np.zeros((1, checkerboardSize[0]*checkerboardSize[1], 3), np.float32)
objp[0,:,:2] = np.mgrid[0:checkerboardSize[0], 0:checkerboardSize[1], ].T.reshape(-1, 2)
_img_shape = None
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
images = glob.glob(imagePath + '*.' + imageExtension)
for fname in images:
img = cv2.imread(fname)
if _img_shape == None:
_img_shape = img.shape[:2]
else:
assert _img_shape == img.shape[:2], "All images must share the same size."
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, checkerboardSize, cv2.CALIB_CB_ADAPTIVE_THRESH+cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE)
print('Nr of corners ' + str(corners.shape))
# If found, add object points, image points (after refining them)
if ret == True:
corners = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), subpixelCriteria)
corners = corners.reshape((150,2)) # This is necessary only for omnidirectional calibration
imgpoints.append(corners)
objpoints.append(objp)
if drawChessboardMarkedImages:
gray2 = gray
cv2.drawChessboardCorners(gray2, checkerboardSize, corners, ret)
cv2.imwrite(os.path.splitext(fname)[0] + '_' + 'CHESSCORNERS.png', gray2)
return (objpoints, imgpoints)
def getOmnidirectionalCalibrationParams(objectpoints, imagepoints, calibration_flag, subpixel_criteria):
K = np.zeros((3,3))
D = np.zeros((1,4))
xi = np.array([])
idx = np.array([])
no_images = len(imagepoints)
no_points = len(imagepoints[0])
#objectpoints = np.reshape(objectpoints, (no_images, 1, no_points, 3))
objectpoints = np.array(objectpoints,dtype=np.float64).reshape(no_images, 1, no_points, 3)
#imagepoints = np.reshape(imagepoints, (no_images, 1, no_points, 2))
imagepoints = np.array(imagepoints,dtype=np.float64).reshape(no_images, 1, no_points, 2)
print('shape of objectpoints ' + str(objectpoints.shape))
print('shape of imagepoints ' + str(imagepoints.shape))
print("size of objectpoints " + str(objectpoints.size))
print("size of imagepoints " + str(imagepoints.size))
ret, K, xi, D, rvecs, tvecs, idx = cv2.omnidir.calibrate(objectpoints, imagepoints,image_size , K, xi, D, calibration_flag, subpixel_criteria)
return ret, K, xi, D, rvecs, tvecs, idx
# Find camera calibration parameters
objectpoints, imagepoints = getObjectAndImagePoints(image_path, image_extension, checkerboard_size, subpixel_criteria, draw_chessboard_marked_images)
ret, K, xi, D, rvecs, tvecs, idx = getOmnidirectionalCalibrationParams(objectpoints, imagepoints, omnidir_calibration_flags, subpixel_criteria)
print("Found " + str(len(imagepoints)) + " valid images for calibration")
print("K = np.array(" + str(K.tolist()) + ")")
print("D = np.array(" + str(D.tolist()) + ")")
print("xi = np.array(" + str(xi.tolist()) + ")")
Reproduce
input dump:
load inputs:
file = open('inputsDump.txt', 'rb')
objectpoints, imagepoints, image_size, K, xi, D, calibration_flag, subpixel_criteria = pickle.load(file)
ret, K, xi, D, rvecs, tvecs, idx = cv2.omnidir.calibrate(objectpoints, imagepoints,image_size , K, xi, D, calibration_flag, subpixel_criteria)