图像立体校正是两幅图像分别进行一次平面投影变化,使两幅图像的对应极线在同一条水平线上,而对极点被映射到无穷远处,这样可以使两幅图像只存在水平上的视差,将立体匹配问题从二维降至一维,提高匹配速度。
很多原理之类的csdn里有很多,我主要是为了发一下我写的代码,方便大家。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取摄像机参数
camera_matrix_matlab_left = np.array([[1.0523e+03, 0, 0],
[0, 1.0531e+03, 0],
[957.1695, 531.0523, 1]])
camera_matrix_left = camera_matrix_matlab_left.T
dist_coeffs_left = np.array([0.0077, -0.0081, 0, 0, 0])
camera_matrix_matlab_right = np.array([[1.0503e+03, 0, 0],
[0, 1.0505e+03, 0],
[954.3480, 534.2524, 1]])
camera_matrix_right = camera_matrix_matlab_right.T
dist_coeffs_right = np.array([-0.0022, 7.0971e-04, 0, 0, 0])
rotation_of_camera2_matlab = np.array([[1, 7.0557e-05, -0.0010],
[-6.8326e-05, 1, 0.0021],
[0.0010, -0.0021, 1]])
R = rotation_of_camera2_matlab.T
translation_of_camera2 = [-149.8199, -0.0849, -1.5292]
T = np.array([[translation_of_camera2[0]],
[translation_of_camera2[1]],
[translation_of_camera2[2]]])
# 图像大小
image_size = (1920, 1080)
# 计算立体校正映射
R1, R2, P1, P2, Q, _, _ = cv2.stereoRectify(camera_matrix_left, dist_coeffs_left,
camera_matrix_right, dist_coeffs_right,
image_size, R, T)
# 计算映射表
map_left_x, map_left_y = cv2.initUndistortRectifyMap(camera_matrix_left, dist_coeffs_left, R1, P1, image_size, cv2.CV_32FC1)
map_right_x, map_right_y = cv2.initUndistortRectifyMap(camera_matrix_right, dist_coeffs_right, R2, P2, image_size, cv2.CV_32FC1)
# 原始双目图像路径
image_path_left = "D:\\graduate\\research_topic\\data\\cal\\cal0613\\origin_left\\L72.jpg"
image_path_right = "D:\\graduate\\research_topic\\data\\cal\\cal0613\\origin_right\\R72.jpg"
# 加载图像
I1 = cv2.imread(image_path_left)
I2 = cv2.imread(image_path_right)
# 检查图像是否正确加载
if I1 is None:
raise ValueError(f"Failed to load image at {image_path_left}")
if I2 is None:
raise ValueError(f"Failed to load image at {image_path_right}")
# 应用立体校正映射
rectified_left = cv2.remap(I1, map_left_x, map_left_y, cv2.INTER_LINEAR)
rectified_right = cv2.remap(I2, map_right_x, map_right_y, cv2.INTER_LINEAR)
# 保存矫正后的图像
cv2.imwrite("D:\\graduate\\research_topic\\data\\cal\\cal0613\\o_r\\LL72.jpg", rectified_left)
cv2.imwrite("D:\\graduate\\research_topic\\data\\cal\\cal0613\\o_r\\RR72.jpg", rectified_right)
# 读取校正后的图像
J1 = cv2.imread("D:\\graduate\\research_topic\\data\\cal\\cal0613\\o_r\\LL72.jpg")
J2 = cv2.imread("D:\\graduate\\research_topic\\data\\cal\\cal0613\\o_r\\RR72.jpg")
# 堆叠图像
stacked_img1 = np.hstack((I1, I2))
stacked_img2 = np.hstack((J1, J2))
height, width = stacked_img1.shape[:2]
# 水平方向绘制线条
num_lines = 25
line_color = (0, 255, 0) # 绿色线条
# 计算线间距
line_spacing = height // (num_lines + 1)
# 绘制水平线, 在堆叠的图像上绘制
for i in range(1, num_lines + 1):
y_position = i * line_spacing
cv2.line(stacked_img1, (0, y_position), (width, y_position), line_color, 2)
cv2.line(stacked_img2, (0, y_position), (width, y_position), line_color, 2)
# 使用 matplotlib 显示图像
fig, axes = plt.subplots(2, 1, figsize=(20, 10))
axes[0].imshow(cv2.cvtColor(stacked_img1, cv2.COLOR_BGR2RGB))
axes[0].axis('off')
axes[0].set_title('Original Images')
axes[1].imshow(cv2.cvtColor(stacked_img2, cv2.COLOR_BGR2RGB))
axes[1].axis('off')
axes[1].set_title('Rectified Images')
plt.show()