KITTI 2015立体数据集图像是否已校正?OpenCV校正实现方法
关于KITTI 2015立体数据集图像校正状态的明确说明
- 如果你从立体匹配基准页面下载的是官方打包的标准训练/测试集,图像分辨率为1242×375,这类图像已经完成了精确的立体校正,极线完全水平对齐,满足立体匹配算法的输入要求,不需要自行做校正操作,重复校正反而会引入插值误差,降低精度。
- 如果你提取的是KITTI raw原始数据中的对应场景图像,分辨率为1392×512,这类图像是未做畸变校正和立体校正的原始传感器输出,需要自行利用标定参数完成校正流程。
标定参数含义说明
你提供的标定文件是KITTI全量传感器标定结果,其中和双目校正相关的参数含义如下(以常用的彩色双目对为例,_02代表左彩色相机,_03代表右彩色相机;灰度双目对对应_00左、_01右):
K_xx:对应相机的3×3内参矩阵,参数按行顺序展开存储D_xx:对应相机的畸变系数,顺序为[k1, k2, p1, p2, k3],完全匹配OpenCV的畸变参数输入格式(k1/k2/k3为径向畸变系数,p1/p2为切向畸变系数)R_rect_xx:官方预计算的校正旋转矩阵,作用是将原始相机坐标系下的点转换到极线共面、水平对齐的校正后坐标系P_rect_xx:校正后的3×4投影矩阵,校正后左右相机的内参完全一致,右相机投影矩阵第0行第3列的数值除以负的fx值,就是双目基线长度S_xx:原始未校正图像的分辨率,格式为[宽, 高]S_rect_xx:校正后输出图像的标准分辨率,格式为[宽, 高]
注意:不需要自己通过两个相机的
R_xx、T_xx参数计算相对位姿再调用stereoRectify生成校正矩阵,官方已经提供了最优的R_rect_xx和P_rect_xx,直接使用即可保证校正结果和官方基准对齐。
OpenCV校正实现流程
针对1392×512分辨率的原始未校正图像,校正步骤如下:
- 解析标定文件,将对应左右相机的参数转换为numpy数组,形状匹配OpenCV接口要求
- 对左右相机分别调用
cv2.initUndistortRectifyMap生成像素重映射表 - 对原始左右图像分别调用
cv2.remap完成重映射,得到校正后的立体对
参考实现代码:
import cv2 import numpy as np def parse_kitti_calib(calib_path): calib = {} with open(calib_path, 'r') as f: for line in f.readlines(): line = line.strip() if not line or ':' not in line: continue key, val = line.split(':', 1) calib[key] = np.array([float(x) for x in val.split()]) return calib def rectify_images(left_raw, right_raw, calib, cam_left='02', cam_right='03'): # 解析左相机参数 K_left = calib[f'K_{cam_left}'].reshape(3,3) D_left = calib[f'D_{cam_left}'] R_rect_left = calib[f'R_rect_{cam_left}'].reshape(3,3) P_left = calib[f'P_rect_{cam_left}'].reshape(3,4) size_rect_left = tuple(calib[f'S_rect_{cam_left}'].astype(np.int32)) # 解析右相机参数 K_right = calib[f'K_{cam_right}'].reshape(3,3) D_right = calib[f'D_{cam_right}'] R_rect_right = calib[f'R_rect_{cam_right}'].reshape(3,3) P_right = calib[f'P_rect_{cam_right}'].reshape(3,4) size_rect_right = tuple(calib[f'S_rect_{cam_right}'].astype(np.int32)) # 生成重映射表 map_left_x, map_left_y = cv2.initUndistortRectifyMap( K_left, D_left, R_rect_left, P_left, size_rect_left, cv2.CV_32FC1 ) map_right_x, map_right_y = cv2.initUndistortRectifyMap( K_right, D_right, R_rect_right, P_right, size_rect_right, cv2.CV_32FC1 ) # 执行重映射 left_rect = cv2.remap(left_raw, map_left_x, map_left_y, cv2.INTER_LINEAR) right_rect = cv2.remap(right_raw, map_right_x, map_right_y, cv2.INTER_LINEAR) return left_rect, right_rect # 调用示例 if __name__ == '__main__': calib = parse_kitti_calib('calib.txt') left_raw = cv2.imread('raw_left.png') right_raw = cv2.imread('raw_right.png') left_rect, right_rect = rectify_images(left_raw, right_raw, calib) cv2.imwrite('left_rect.png', left_rect) cv2.imwrite('right_rect.png', right_rect)
校正完成后可以做简单验证:在左右图上找几对明显的同名点,检查两点的y坐标差,正常应该在1像素以内,满足立体匹配的输入要求。
内容的提问来源于stack exchange,提问作者Taki Eddine
相关产品推荐
相关产品推荐

