Pyroz Pyroz - 2 months ago 26
Python Question

Calibrating Webcam using Python and OpenCV Error

Pretty new to all this and I'm trying to do the calibration for a Webcam following this guide and using the code below. I get the following error ..


OpenCV Error: Assertion failed (ni > 0 && ni == ni1) in collectCalibrationData, file /build/buildd/opencv-2.4.8+dfsg1/modules/calib3d/src/calibration.cpp, line 3193

cv2.error: /build/buildd/opencv-2.4.8+dfsg1/modules/calib3d/src/calibration.cpp:3193: error: (-215) ni > 0 && ni == ni1 in function collectCalibrationData


Can someone explain what this error is and how to fix it?

(Full error at the bottom)

import numpy as np
import cv2
import glob


criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world
imgpoints = [] # 2d points in image plane.
images = glob.glob('*.png')


objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
objp = objp * 22


for fname in images:

img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret = False
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, (6,9))
# If found, add object points, image points (after refining them)
if ret == True:
objpoints.append(objp)
cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)

imgpoints.append(corners)
# Draw and display the corners
cv2.drawChessboardCorners(img, (6,9), corners, ret)
cv2.imshow('img',img)
cv2.waitKey(0)

cv2.waitKey(0)
for i in range (1,5):
cv2.waitKey(1)
cv2.destroyAllWindows()
cv2.waitKey(1)


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



OpenCV Error: Assertion failed (ni > 0 && ni == ni1) in collectCalibrationData, file /build/buildd/opencv-2.4.8+dfsg1/modules/calib3d/src/calibration.cpp, line 3193
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 540, in runfile
execfile(filename, namespace)
File "/home/students/Test/test.py", line 49, in
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
cv2.error: /build/buildd/opencv-2.4.8+dfsg1/modules/calib3d/src/calibration.cpp:3193: error: (-215) ni > 0 && ni == ni1 in function collectCalibrationData

Answer

Digging into the source code:

for( i = 0; i < nimages; i++, j += ni )
{
    Mat objpt = objectPoints.getMat(i);
    Mat imgpt1 = imagePoints1.getMat(i);
    ni = objpt.checkVector(3, CV_32F);
    int ni1 = imgpt1.checkVector(2, CV_32F);
    CV_Assert( ni > 0 && ni == ni1 );
    ...

This: Assertion failed (ni > 0 && ni == ni1) means either that your object points array is of length zero, or that the object and image arrays are of different sizes.

To be clear: calibrateCamera() expects to be provided with not just an array of object points and another array of image points, but with an array of arrays of image and object points. If you only have one image (and therefore one pair of sets of image and object points) you can just wrap those arrays in a set of square brackets:

obj = [[x, y, z], [x1, y1, z1]] # wrong
img = [[x, y], [x1, y1]]        # wrong

obj = [[[x, y, z], [x1, y1, z1]]] # right
img = [[[x, y], [x1, y1]]]        # right

Thinking back to when I first followed this tutorial myself, it looks like the only thing you've changed is the file extension (from jpg to png) which suggests that you are using your own resources - and therefore that your problem could lie with the number of images you are using. I think it's possible that the image/images you are using just aren't having the checkerboard picked out successfully - and therefore your object point array never gets anything added to it. Try printing out the arrays before running calibrateCamera and maybe using the checkerboard images provided inside /samples/cpp