opencvstereoCalibrate 给出错误的未失真贴图

问题描述

我正在尝试校准来自 Waveshare IMX219-83 立体相机的图像。 未失真的图像不正确,我无法理解为什么它不起作用。 图像是 3280 × 2464,但我保存的 numpy 地图的长度都是 2464,这对我来说似乎很奇怪。

校准代码

import cv2
import numpy as np 
import glob
from tqdm import tqdm

chessboard_size = (6,9)

obj_points = [] 
img_points_l = [] 
img_points_r = []

objp = np.zeros((np.prod(chessboard_size),3),dtype=np.float32)
objp[:,:2] = np.mgrid[0:chessboard_size[0],0:chessboard_size[1]].T.reshape(-1,2)


calib_paths_left = sorted(glob.glob('./calib/left/*'))
calib_paths_right = sorted(glob.glob('./calib/right/*'))
print(calib_paths_left)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,30,0.001)

for i in tqdm(list(range(len(calib_paths_left)))[0::1]):
    image_l = cv2.imread(calib_paths_left[i])
    image_r = cv2.imread(calib_paths_right[i])

    gray_image_l = cv2.cvtColor(image_l,cv2.COLOR_BGR2GRAY)
    gray_image_r = cv2.cvtColor(image_r,cv2.COLOR_BGR2GRAY)

    
    print("Images loaded,Analizying...")
    ret_l,corners_l = cv2.findChessboardCorners(gray_image_l,chessboard_size,None)
    ret_r,corners_r = cv2.findChessboardCorners(gray_image_r,None)

    if ret_l and ret_r:
        print("Chessboard detected on both images!")
        print(calib_paths_left[i] + " and " + calib_paths_right[i])
        
        obj_points.append(objp)
        corners_fine_l = cv2.cornerSubPix(gray_image_l,corners_l,(11,11),(-1,-1),criteria)
        corners_fine_r = cv2.cornerSubPix(gray_image_r,corners_r,criteria)
        img_points_l.append(corners_fine_l)
        img_points_r.append(corners_fine_r)

        output_l = image_l.copy()
        output_r = image_r.copy()

        cv2.drawChessboardCorners(output_l,(6,9),corners_fine_l,ret_l)
        cv2.drawChessboardCorners(output_r,corners_fine_r,ret_r)
        cv2.imshow('corners_fine_l',output_l)
        cv2.imshow('corners_fine_r',output_r)
        cv2.waitKey(500)
        
cv2.destroyAllWindows()

# Calibrate cameras individually (undistort)
ret_l,mtx_l,dist_l,rvecs_l,tvecs_l = cv2.calibrateCamera(
    obj_points,img_points_l,gray_image_l.shape[::-1],None,None)
h_l,w_l= gray_image_l.shape[:2]
new_mtx_l,roi_l= cv2.getoptimalNewCameraMatrix(mtx_l,(w_l,h_l),1,h_l))

ret_r,mtx_r,dist_r,rvecs_r,tvecs_r = cv2.calibrateCamera(
    obj_points,img_points_r,gray_image_r.shape[::-1],None)
h_r,w_r= gray_image_l.shape[:2]
new_mtx_r,roi_r= cv2.getoptimalNewCameraMatrix(mtx_r,(w_r,h_r),h_r))


# Calibrate cameras as stereocamera
flags = 0
flags |= cv2.CALIB_FIX_INTRINSIC

criteria_stereo= (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,0.001)

retval_stereo,new_mtx_l,new_mtx_r,rot,trans,emat,fmat = cv2.stereoCalibrate(
    obj_points,criteria_stereo,flags)

rectify_scale= 1
rect_l,rect_r,proj_mat_l,proj_mat_r,Q,roi_l,roi_r= cv2.stereoRectify(
    new_mtx_l,rectify_scale,(0,0))


Left_Stereo_Map= cv2.initUndistortRectifyMap(new_mtx_l,rect_l,cv2.CV_16SC2)
Right_Stereo_Map= cv2.initUndistortRectifyMap(new_mtx_r,cv2.CV_16SC2)

print("Saving parameters ......")
np.save("camera_params/Left_Stereo_Map_x",Left_Stereo_Map[0])
np.save("camera_params/Left_Stereo_Map_y",Left_Stereo_Map[1])
np.save("camera_params/Right_Stereo_Map_x",Right_Stereo_Map[0])
np.save("camera_params/Right_Stereo_Map_y",Right_Stereo_Map[1])

重新映射图像,显示不良结果

import cv2
import numpy as np

Left_Stereo_Map_x = np.load("camera_params/Left_Stereo_Map_x.npy")
Left_Stereo_Map_y = np.load("camera_params/Left_Stereo_Map_y.npy")
Right_Stereo_Map_x = np.load("camera_params/Right_Stereo_Map_x.npy")
Right_Stereo_Map_y = np.load("camera_params/Right_Stereo_Map_y.npy")


image_l = cv2.imread("calib/left/frame_l_30.jpg")
image_r = cv2.imread("calib/right/frame_r_30.jpg")

gray_image_l = cv2.cvtColor(image_l,cv2.COLOR_BGR2GRAY)
gray_image_r = cv2.cvtColor(image_r,cv2.COLOR_BGR2GRAY)

cv2.imshow("Left image before rectification",gray_image_l)
cv2.imshow("Right image before rectification",gray_image_r)

image_l_undist = cv2.remap(image_l,Left_Stereo_Map_x,Left_Stereo_Map_y,cv2.INTER_lanczos4,cv2.BORDER_CONSTANT,0)
image_r_undist = cv2.remap(image_r,Right_Stereo_Map_x,Right_Stereo_Map_y,0)

cv2.imshow("Left image after rectification",image_l_undist)
cv2.imshow("Right image after rectification",image_r_undist)
cv2.waitKey(0)

这些是我校准的图像类型:

example left image for calibration

example right image for calibration

这是我得到的输出

output left

output right

我现在检查了很多次代码,但无法理解为什么它不起作用。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)