我正在尝试使用 see3cam 40 相机创建视差图,该相机是 131 度鱼眼镜头的 RAW RGB-IR USB3 相机。我已使用此教程 链接作为参考成功校准了我的相机。这是代码:
CHESSBOARD_SIZE = (9,6)
img_dir_left = "/home/dir_left"
img_dir_right = "/home/dir_right"
criteria = (cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 0.1)
calib_flags = cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC+cv2.fisheye.CALIB_CHECK_COND+cv2.fisheye.CALIB_FIX_SKEW
objp = np.zeros((1, CHESSBOARD_SIZE[0]*CHESSBOARD_SIZE[1], 3), np.float32)
objp[0,:,:2] = np.mgrid[0:CHESSBOARD_SIZE[0], 0:CHESSBOARD_SIZE[1]].T.reshape(-1, 2)
def calculate(imgDir):
imgPath = glob.glob(imgDir+'/*jpg')
img_size = None
objpoints = []
imgpoints = []
for image in sorted(imgPath):
img = cv2.imread(image)
if img_size == None:
img_size = img.shape[:2]
else:
assert img_size == img.shape[:2], "All images must share the same size."
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, CHESSBOARD_SIZE, cv2.CALIB_CB_ADAPTIVE_THRESH+cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE)
if ret:
objpoints.append(objp)
cornersM = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(cornersM)
cv2.drawChessboardCorners(img, CHESSBOARD_SIZE, cornersM, ret)
cv2.imshow(imgDir, img)
cv2.waitKey(1)
return objpoints, imgpoints, img_size, gray
def calibrate(objpoints, imgpoints, img_size, gray):
img_number = len(objpoints) #number of the pictures
K = np.zeros((3, 3))
D = np.zeros((4, 1))
rvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(img_number)]
tvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(img_number)]
print("rvecs", rvecs)
rms, _, _, _, _ = cv2.fisheye.calibrate(objpoints,imgpoints,gray.shape[::-1],K,D,rvecs,tvecs,calib_flags,
(cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-6))
print("RMS", rms)
print("Found " + str(img_number) + " valid images for calibration")
print("DIM=" + str(img_size[::-1]))
print("K=np.array(" + str(K.tolist()) + ")", )
print("D=np.array(" + str(D.tolist()) + ")\n", )
dimension = img_size[::-1]
k = K.tolist()
d = D.tolist()
return dimension , k , d
我同时拍摄了 13 张对等相机的图像。图像从原始 10 位状态转换为 8 位。相机安装在同一条线上,基线为 7 厘米。我的 RMS_left 是 0.509 和 RMS_right 0.341。
这是我用来使相机的帧不失真的功能。
def undistorted(frame, data):
data_in = data
img = frame
K, D, DIM = data_in['K'], data_in['D'], data_in['DIM']
K = np.array(K)
D = np.array(D)
map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), K, DIM, cv2.CV_16SC2)#cv2.CV_16SC2
undistorted_frame = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_TRANSPARENT, borderValue=29)
return undistorted_frame
当我尝试进行鱼眼立体校准时,我得到了这个 github链接中描述的相同错误。但是有一个解决所有错误的方法。
K_left = np.zeros((3, 3))
D_left = np.zeros((4, 1))
K_right = np.zeros((3, 3))
D_right = np.zeros((4, 1))
R = np.zeros((1, 1, 3), dtype=np.float64)
T = np.zeros((1, 1, 3), dtype=np.float64)
N_OK = len(imgpoints_left)
objp = np.zeros( (CHECKERBOARD[0]*CHECKERBOARD[1], 1, 3) , np.float64)
objp[:,0, :2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
objpoints = np.array([objp]*len(imgpoints_left),dtype=np.float64)
imgpoints_left = np.asarray(imgpoints_left, dtype=np.float64)
imgpoints_right = np.asarray(imgpoints_right, dtype=np.float64)
objpoints = np.reshape(objpoints, (N_OK, 1, CHECKERBOARD[0]*CHECKERBOARD[1], 3))
imgpoints_left = np.reshape(imgpoints_left, (N_OK, 1, CHECKERBOARD[0]*CHECKERBOARD[1], 2))
imgpoints_right = np.reshape(imgpoints_right, (N_OK, 1, CHECKERBOARD[0]*CHECKERBOARD[1], 2))
(rms, K_left, D_left, K_right, D_right, R, T) = \
cv2.fisheye.stereoCalibrate(
objpoints,
imgpoints_left,
imgpoints_right,
K_left,
D_left,
K_right,
D_right,
img_size,
R,
T,
calibration_flags
)
有人可以帮我澄清这个解决方法吗,我是 OpenCV 的新手,完全理解它。