python - opencv stereoCalibrate 给出错误的不失真图
问题描述
我正在尝试校准 Waveshare IMX219-83 Stereo-Camera 的图像。未失真的图像不正确,我无法理解为什么它不起作用。这些图像是 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, chessboard_size, 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,(11,11),(-1,-1),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,(6,9),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,dist_l,(w_l,h_l),1,(w_l,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, None)
h_r,w_r= gray_image_l.shape[:2]
new_mtx_r, roi_r= cv2.getOptimalNewCameraMatrix(mtx_r,dist_r,(w_r,h_r),1,(w_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, 30, 0.001)
retval_stereo, new_mtx_l, dist_l, new_mtx_r, dist_r, rot, trans, emat, fmat = cv2.stereoCalibrate(
obj_points, img_points_l, img_points_r, new_mtx_l, dist_l, new_mtx_r, dist_r, gray_image_l.shape[::-1], 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, dist_l, new_mtx_r, dist_r, gray_image_l.shape[::-1], rot, trans, rectify_scale,(0,0))
Left_Stereo_Map= cv2.initUndistortRectifyMap(new_mtx_l, dist_l, rect_l, proj_mat_l,
gray_image_l.shape[::-1], cv2.CV_16SC2)
Right_Stereo_Map= cv2.initUndistortRectifyMap(new_mtx_r, dist_r, rect_r, proj_mat_r,
gray_image_r.shape[::-1], 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, cv2.INTER_LANCZOS4, cv2.BORDER_CONSTANT, 0)
cv2.imshow("Left image after rectification", image_l_undist)
cv2.imshow("Right image after rectification", image_r_undist)
cv2.waitKey(0)
这些是我校准的图像类型:
这是我得到的输出:
我现在检查了很多次代码,但无法理解为什么它不起作用。
解决方案
推荐阅读
- android - Android导航组件从homefragment关闭应用程序
- ms-access - 在交叉表查询中按地名 ID 对列和行进行排序
- python - Python对列表中的值进行子集化
- jestjs - 开玩笑地嘲笑 axios 不是嘲笑
- rabbitmq - 重新排队过期消息的 Rabbitmq 问题
- angular - 包含 cordova.js 时,Angular Cordova 应用程序变为空白
- linux - Python3:无法在 Stratodesk/Notouch OS 上安装 evdev --> 无法执行“arm-linux-gnueabihf-gcc”:没有这样的文件或目录
- python - 从端点获取数据并将其存储在 csv 中
- java - org.gradle.tooling.BuildException: 处理资源失败,详见上面的 aapt 输出
- c++ - 我们如何将字符串转换为数字并可逆?