I've been trying to calibrate my camera for instrinsics with the following opencv code. I keep getting the error, error: (-215:Assertion failed) nimages > 0 in function 'cv::calibrateCameraRO'
.
I've checked if the images are being read by using the cv.imshow()
function and i'm able to view the image as the code loops. I do think that images are being fed and the address is correct. Any clues on what the problem may be?
import numpy as np
import cv2 as cv
import glob
import pickle
chessboardSize = (9,6)
frameSize = (1500,2000)
# termination criteria
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((chessboardSize[0] * chessboardSize[1], 3), np.float32)
objp[:,:2] = np.mgrid[0:chessboardSize[0],0:chessboardSize[1]].T.reshape(-1,2)
size_of_chessboard_squares_mm = 20
objp = objp * size_of_chessboard_squares_mm
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
images = glob.glob('\images\*.png')
# images = ['images\img0.png', 'images\img1.png', 'images\img10.png', 'images\img2.png', 'images\img3.png', 'images\img4.png', 'images\img5.png', 'images\img6.png', 'images\img7.png', 'images\img8.png', 'images\img9.png']
# images = ['images\img0.png', 'images\img1.png']
for image in images:
img = cv.imread(image)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv.findChessboardCorners(gray, chessboardSize, None)
# print(ret)
# print(corners)
# If found, add object points, image points (after refining them)
if ret == True:
objpoints.append(objp)
corners2 = cv.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
imgpoints.append(corners)
# Draw and display the corners
cv.drawChessboardCorners(img, chessboardSize, corners2, ret)
cv.imshow('img', img)
cv.waitKey(1000)
cv.destroyAllWindows()
############## CALIBRATION #######################################################
ret, cameraMatrix, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, frameSize, None, None)
Turns out I was making a pretty stupid error. One that should have been obvious but I didn't pay much attention.
The chessboard I was using for calibration had 9x6 chess-squares. This meant there were 8x5 vertices - the input most of my code above uses.
For my case of a 9x6 chessboard - simply changing chessboardSize = (9,6)
to chessboardSize = (8,5)
will do the trick. Similar to any other size. A good way to verify this is to verify that vertices have colored lines over them in the calibrated images during the following code snippet.
# Draw and display the corners
cv.drawChessboardCorners(img, chessboardSize, corners2, ret)
cv.imshow('img', img)