You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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分辨率的原始未校正图像,校正步骤如下:

  1. 解析标定文件,将对应左右相机的参数转换为numpy数组,形状匹配OpenCV接口要求
  2. 对左右相机分别调用cv2.initUndistortRectifyMap生成像素重映射表
  3. 对原始左右图像分别调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:31:09