Я калибрую пару стереокамер, чтобы получить матрицу вращения и трансляции между двумя камерами. Я использовал cv2.stereoCalibrate для калибровки, используя изображения, снятые с обеих камер одновременно. Проблема, с которой я сталкиваюсь, заключается в том, что я получаю очень высокое значение. Как уменьшить значения ret. если я использую только одну пару изображений, значение ret составляет около 0.11, но когда я использую более одной пары изображений, значение ret снимает до 48. В чем может быть проблема?
Я использовал разные пары изображений, но происходит одно и то же. Если номер пары изображений больше одного. Значения ret возвращаются к 48.
# Start calibration from the camera
import cv2
import numpy as np
# Termination criteria
criteria =(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
criteria_stereo= (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# Prepare object points
objp = np.zeros((9*7,3), np.float32)
objp[:,:2] = np.mgrid[0:9,0:7].T.reshape(-1,2)
objp = objp*2.1 #cm
# Arrays to store object points and image points from all images
objpoints= [] # 3d points in real world space
imgpointsR= [] # 2d points in image plane
imgpointsL= []
print('Starting calibration for the 2 cameras... ')
# Call all saved images
for i in range(1,3): # amount of pictures you have taken for the calibration inbetween range(0,?) wenn starting from the image number 0
t1= str(i)
#t2= str(i)
ChessImaR= cv2.imread('r'+t1+'.jpg',0) # Right side
ChessImaL= cv2.imread('l'+t1+'.jpg',0) # Left side
retR, cornersRf = cv2.findChessboardCorners(ChessImaR,(9,7),None) # Define the number of chees corners we are looking for
retL, cornersLf = cv2.findChessboardCorners(ChessImaL,(9,7),None) # Left side
if (True == retR) & (True == retL):
#print(t)
objpoints.append(objp)
cornersR = cv2.cornerSubPix(ChessImaR,cornersRf,(11,11),(-1,-1),criteria)
cornersL =cv2.cornerSubPix(ChessImaL,cornersLf,(11,11),(-1,-1),criteria)
ChessImaRd = cv2.drawChessboardCorners(ChessImaR, (9,7), cornersR,retR)
ChessImaLd = cv2.drawChessboardCorners(ChessImaL, (9,7), cornersL,retL)
cv2.imshow('imgR',ChessImaRd)
cv2.imshow('imgL',ChessImaLd)
cv2.waitKey(500)
cv2.destroyAllWindows()
imgpointsR.append(cornersR)
imgpointsL.append(cornersL)
# Determine the new values for different parameters
# Right Side
retR, mtxR, distR, rvecsR, tvecsR = cv2.calibrateCamera(objpoints,imgpointsR,ChessImaR.shape[::-1],None,None)
hR,wR= ChessImaR.shape[:2]
OmtxR, roiR= cv2.getOptimalNewCameraMatrix(mtxR,distR,(wR,hR),1,(wR,hR))
# Left Side
retL, mtxL, distL, rvecsL, tvecsL = cv2.calibrateCamera(objpoints,imgpointsL,ChessImaL.shape[::-1],None,None)
hL,wL= ChessImaL.shape[:2]
OmtxL, roiL= cv2.getOptimalNewCameraMatrix(mtxL,distL,(wL,hL),1,(wL,hL))
print('Done!')
# StereoCalibrate function
flags = 0
flags |= cv2.CALIB_FIX_INTRINSIC
#flags |= cv2.CALIB_FIX_PRINCIPAL_POINT
#flags |= cv2.CALIB_USE_INTRINSIC_GUESS
#flags |= cv2.CALIB_FIX_FOCAL_LENGTH
#flags |= cv2.CALIB_FIX_ASPECT_RATIO
#flags |= cv2.CALIB_ZERO_TANGENT_DIST
#flags |= cv2.CALIB_RATIONAL_MODEL
#flags |= cv2.CALIB_SAME_FOCAL_LENGTH
#flags |= cv2.CALIB_FIX_K3
#flags |= cv2.CALIB_FIX_K4
#flags |= cv2.CALIB_FIX_K5
retS,cameraMatrix1,distCoeffs1,cameraMatrix2,distCoeffs2,R,T,E,F= cv2.stereoCalibrate(objpoints,
imgpointsL,
imgpointsR,
mtxL,
distL,
mtxR,
distR,
ChessImaR.shape[::-1],
criteria_stereo,
flags)
print("\n")
print("Rotation Matrix")
print(R)
print("\n")
print("Translation Matrix")
print(T)
print("\n")
print("ret")
print(retS)
print("\n")
R1, R2, P1, P2, Q, roi1, roi2 = cv2.stereoRectify(cameraMatrix1,distCoeffs1,cameraMatrix2,distCoeffs2,(640, 480),R,T,alpha=-1)
#retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F
print("projection matrix 1")
print(P1)
print("\n")
print("projection matrix 2")
print(P2)
print("\n")
Это код, который я использовал для калибровки.
Образец калибровочных изображений