I am trying to perform a stereo calibration of 2 USB cameras in order to perform depth map, but I fall on this error and I don't know how to solve. I would be really grateful to who would be able to help.
File "C:/Users/gaetano/stereoCalib.py", line 85, in <module>
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints,
gray.shape[::-1], None, None)
error: OpenCV(3.4.1) D:\Build\OpenCV\opencv-
3.4.1\modules\calib3d\src\calibration.cpp:3384: error: (-215) nimages > 0 in
function cv::calibrateCamera
(this error should have been solved using the following code)
#before here i have collect picture from both the camera, than
#grey conversion
i=0
while i < img_counter:
img = cv2.imread('colorRight_' + str(i) + '.jpg')
img2 = cv2.imread('colorLeft_' + str(i) + '.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
cv2.imwrite('greyRight_' + str(i) + '.jpg',gray)
cv2.imwrite('greyLeft_' + str(i) + '.jpg',gray2)
i += 1
nx = 9
ny = 6
chess_imagesL = glob.glob('greyLeft_*.jpg')
chess_imagesR = glob.glob('greyRight_*.jpg')
for i in range(len(chess_imagesL)):
# Read in the image
chess_board_imageL = mpimg.imread(chess_imagesL[i])
chess_board_imageR = mpimg.imread(chess_imagesR[i])
# Convert to grayscale
# gray = cv2.cvtColor(chess_board_image, cv2.COLOR_RGB2GRAY)
# Find the chessboard corners
ret, cornersL = cv2.findChessboardCorners(chess_board_imageL, (nx, ny),
None)
ret2, cornersR = cv2.findChessboardCorners(chess_board_imageR, (nx, ny),
None)
# If found, draw corners
if ret == True:
# Draw and display the corners
cv2.drawChessboardCorners(chess_board_imageL, (nx, ny), cornersL, ret)
cv2.drawChessboardCorners(chess_board_imageR, (nx, ny), cornersR, ret2)
result_nameL = 'boardL'+str(i)+'.png'
result_nameR = 'boardR'+str(i)+'.png'
cv2.imwrite(result_nameL, chess_board_imageL)
cv2.imwrite(result_nameR, chess_board_imageR)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.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((6*9,3), np.float32)
objp[:,:2] = np.mgrid[0:9,0:6].T.reshape(-1,2)
objpointsL=[]
objpointsR=[]
imgpointsL=[]
imgpointsR=[]
for i in range(len(chess_imagesL)):
# Read in the image
chess_board_imageL = mpimg.imread(chess_imagesL[i])
chess_board_imageR = mpimg.imread(chess_imagesR[i])
ret, cornersL = cv2.findChessboardCorners(chess_board_imageL, (nx, ny),
None)
ret2, cornersR = cv2.findChessboardCorners(chess_board_imageR, (nx, ny),
None)
# If found, draw corners
if ret == True:
objpointsL.append(objp)
objpointsR.append(objp)
corners2L = cv2.cornerSubPix(gray,cornersL,(11,11),(-1,-1),criteria)
corners2R = cv2.cornerSubPix(gray,cornersR,(11,11),(-1,-1),criteria)
imgpointsL.append(corners2L)
imgpointsR.append(corners2R)
cv2.drawChessboardCorners(chess_board_imageL, (nx, ny), corners2L, ret)
cv2.drawChessboardCorners(chess_board_imageR, (nx, ny), corners2R, ret2)
result_nameL = 'boardL'+str(i)+'.png'
result_nameR = 'boardR'+str(i)+'.png'
cv2.imwrite(result_nameL, chess_board_imageL)
cv2.imwrite(result_nameR, chess_board_imageR)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpointsL, imgpointsL,
gray.shape[::-1], None, None)
ret2, mtx2, dist2, rvecs2, tvecs2 = cv2.calibrateCamera(objpointsR,
imgpointsR, gray2.shape[::-1], None, None)
R = []
T = []
E = []
F = []
flags = cv2.CALIB_FIX_INTRINSIC
ret, mtx, dist, mtx2, dist2, R, T, E, F = cv2.stereoCalibrate(objpointsL,
imgpointsL ,imgpointsR, mtx, dist, mtx2, dist2, gray.shape[::-1], None,
None, None, None,flags = flags,
criteria = (cv2.TERM_CRITERIA_EPS, 30, 1e-6))
using the code you suggested, cameracalibration seems to work. but i have a problem on the next step, stereocameracalibration
File "C:/Users/gaetano/Desktop/sonido/CALIPROVA2.py", line 157, in ret, R, T = cv2.solvePnP(objpointsL,imgpointsL,mtx,dist,R,T,0,0)
TypeError: objectPoints is not a numpy array, neither a scalar
R = []
T = []
E = []
F = []
flags = cv2.CALIB_FIX_INTRINSIC
ret, mtx, dist, mtx2, dist2, R, T, E, F = cv2.stereoCalibrate(objpointsL,
imgpointsL ,imgpointsR, mtxL, distL, mtxR, distR,
grayL.shape[::-1], None, None, None, None,
flags = flags,
criteria = (cv2.TERM_CRITERIA_EPS, 30, 1e-6))
ret, R, T = cv2.solvePnP(objpointsL,imgpointsL,mtx,dist,R,T,0,0)
print(R)
print(T)
error in resizing
SystemError: new style getargs format but argument is not a tuple
print(roi1)
print(roi2)
# crop the image
x, y, w, h = roi1
dst = dst[y:y + h, x:x + w]
#
dst2 = dst2[y:y + h, x:x + w]
dst = cv2.resize(dst, 0, dst, 2, 2, interpolation = cv2.INTER_LINEAR)
So the error says:
error: OpenCV(3.4.1) D:\Build\OpenCV\opencv-3.4.1\modules\calib3d\src\calibration.cpp:3384: error: (-215) nimages > 0 in function cv::calibrateCamera
This means that you are passing empty list variables as the object points or as the image points.
In your code you have:
objpoints=[]
imgpoints=[]
which are then used only in the line:
#objpoints.append(objp)
and in the line:
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
This means that both are empty! nothing is inside those 2 lists that are then used in the function. In the next line:
ret2, mtx2, dist2, rvecs2, tvecs2 = cv2.calibrateCamera(objpoints, imgpoints2, gray2.shape[::-1], None, None)
Here you use imgpoints2
which exists and has point, but it has no objpoints (because it is commented out) and you will get a similar error.
Solution:
You have to make up your mind of what exactly you want to achieve here. If it is 2 calibrations, then maybe a function that takes a frame as input and does all the process will be better. This way you are sure that the variables are named correctly.
If a function is not good for you, then you can always do the same that you did for imgpoints2
to imgpoints
and the variable will be able to be use. Also, make sure that objpoints.append(objp)
is uncommented to get the function working again.
Just for sake of completeness, this is what i mean with the funciton:
def getObjPoints():
objp = np.zeros((6*7,3), np.float32)
objp[:,:2]=np.mgrid[0:7,0:6].T.reshape(-1,2)
return objp
def calibrateCamWithFrame( frame ):
objpoints=[getObjPoints]
imgpoints=[]
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray,(7,6),None)
# if no corners where found return None
if !ret:
return None
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
corners = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
imgpoints.append(corners)
frameWithCorners=cv2.drawChessboardCorners(frame,(7,6), corners, ret)
cv2.imshow('img',frameWithCorners)
cv2.waitKey(500)
return cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
Then from outside you will just call:
ret, mtx, dist, rvecs, tvecs = calibrateCamWithFrame(frame)
ret2, mtx2, dist2, rvecs2, tvecs2 = calibrateCamWithFrame(frame2)
UPDATE
Since you wanted is to calibrate 2 cameras, and did appropriate changes to the code to identify it, then the solution is to read image, find corners and appending data in the main loop. Something like:
nx = 9
ny = 6
imgpointsL = []
imgpointsR = []
objpointsL = []
objpointsR = []
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
for i in range(img_counter):
grayR = cv2.imread('colorRight_' + str(i) + '.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE )
grayL = cv2.imread('colorLeft_' + str(i) + '.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE )
retR, cornersR = cv2.findChessboardCorners(grayR, (nx, ny), None)
if retR:
cornersR = cv2.cornerSubPix(gray, cornersR, (11,11), (-1,-1), criteria)
imgpointsR.append(cornersR)
objpointsR.append(objp)
retL, cornersL = cv2.findChessboardCorners(grayL, (nx, ny), None)
if retL:
cornersL = cv2.cornerSubPix(gray, cornersL, (11,11), (-1,-1), criteria)
imgpointsL.append(cornersR)
objpointsL.append(objp)
And now you can calibrate each camera, note that I use imgpoints and objpoints for each camera... This way you are sure the sizes match, since not necessarily all the images in one camera will have the corners found correctly.
Then you can calibrate, making sure you have images:
if len(imgpointsL) >0:
retL, mtxL, distL, rvecsL, tvecsL = cv2.calibrateCamera(objpointsL, imgpointsL,grayL.shape[::-1], None, None)
if len(imgpointsL) >0:
retR, mtxR, distR, rvecsR, tvecsR = cv2.calibrateCamera(objpointsR, imgpointsR,grayR.shape[::-1], None, None)