双目立体视觉Bouguet矫正算法详解

本文详细解析了双目视觉系统的标定过程,包括双目摄像机需要标定的各项参数及其与单目摄像机标定的区别,重点介绍了旋转矩阵R和平移矩阵T的求解方法。同时,阐述了立体校正的重要性,解释了如何通过校正实现非共面行对准的图像平面校正成共面行对准,从而提高测距精度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                    版权声明:本文为博主原创文章,欢迎转载,请注明出处                        https://blog.youkuaiyun.com/u011574296/article/details/73826420                    </div>
                                                <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-3019150162.css">
                                    <div id="content_views" class="markdown_views prism-atom-one-dark">
                <!-- flowchart 箭头图标 勿删 -->
                <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
                    <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
                </svg>
                                        <p>人类可以看到3维立体的世界,是因为人的两只眼睛,从不同的方向看世界,两只眼睛中的图像的视差,让我们可以看到3维立体的世界。类似的,想要让计算机“看到”3维世界,就需要使用两个摄像头构成双目立体视觉系统。</p>

想要让双目视觉系统知道视差,首先应该知道双目视觉系统中两个摄像头之间的相对位置关系。。任意两个坐标系之间的相对位置关系,都可以通过两个矩阵来描述:旋转矩阵R和平移矩阵T。

我们可以同时对两个摄像头进行标定,分别得到二者相对同一坐标系的旋转矩阵和平移矩阵,然后就可以获得两个摄像头之间的相对位置关系,这就是双目标定!

一、双目立体标定

双目摄像机需要标定的参数:摄像机内参数矩阵,畸变系数矩阵,本征矩阵,基础矩阵,旋转矩阵以及平移矩阵(其中摄像机内参数矩阵和畸变系数矩阵可以通过单目标定的方法标定出来)

双目摄像机标定和单目摄像机标定最主要的区别就是双目摄像机需要标定出左右摄像机坐标系之间的相对关系

我们用旋转矩阵R和平移矩阵T来描述左右两个摄像机坐标系的相对关系,具体为:将左摄像机下的坐标转换到右摄像机下的坐标。

假设空间中有一点P,其在世界坐标系下的坐标为PWPW,其在左右摄像机坐标系下的坐标可以表示为:

Pl=RlPW+TlPl=RlPW+Tl

注:双目摄像机分析中往往以左摄像机为主坐标系,但是R和T却是左相机向右相机转换,所以Tx为负数

综合上式,可以推得:

R=RrRTlR=RrRlT

RlRl,带入上式就可以求出左右相机之间的旋转矩阵R和平移T。

求得的R和T就是立体标定要得到的结果。

单目摄像机需要标定的参数,双目都需要标定,双目摄像机比单目摄像机多标定的参数:R和T,主要是描述两个摄像机相对位置关系的参数,这些参数在立体校正和对极几何中用处很大

那么得到了立体标定的结果,下一步我们该做什么呢?
答案是:立体校正。

二、立体校正

在介绍立体校正的具体方法之前,让我们来看一下,为什么要进行立体校正?

双目摄像机系统主要的任务就是测距,而视差求距离公式是在双目系统处于理想情况下推导的,但是在现实的双目立体视觉系统中,是不存在完全的共面行对准的两个摄像机图像平面的。所以我们要进行立体校正。立体校正的目的就是,把实际中非共面行对准的两幅图像,校正成共面行对准。(共面行对准:两摄像机图像平面在同一平面上,且同一点投影到两个摄像机图像平面时,应该在两个像素坐标系的同一行),将实际的双目系统校正为理想的双目系统。

理想双目系统:两摄像机图像平面平行,光轴和图像平面垂直,极点处于无线远处,此时点(x0,y0)对应的级线就是y=y0

立体校正前:

这里写图片描述

立体校正后:

这里写图片描述

Bouguet校正原理

校正过程中两个图像平面均旋转一半的R,这样可以使重投影畸变最小,此时两个摄像机图像平面共面(畸变校正后光轴也平行),但是行不对准
极点是两个相机坐标系原点的连线和图像平面的交点,要想使得极点处于无穷远处(即行对准),就必须两个摄像机的图像平面和两个相机坐标系原点的连线平行
可以计算RrectRrect左乘到R分解后作用于左右相机坐标系的矩阵,即可得到最终的立体校正矩阵。

参考:

机器视觉学习笔记(6)——双目摄像机标定参数说明
机器视觉学习笔记(8)——基于OpenCV的Bouguet立体校正
双摄像头立体成像(三)-畸变矫正与立体校正

### 双目立体视觉深度估计算法实现原理 双目立体视觉的核心目标是从两幅或多幅图像中恢复场景的三维信息,其中深度估计是最基础也是最重要的部分之一。以下是关于双目立体视觉深度估计算法的具体实现原理及相关代码。 #### 1. 立体视觉的基础理论 立体视觉依赖于两个摄像头获取同一场景的不同视角图像,并通过比较这些图像中的像素位置差异(称为视差)来推断物体的距离。视差 \(d\) 和深度 \(Z\) 的关系可以通过以下公式描述[^2]: \[ Z = \frac{fB}{d} \] 其中: - \(f\) 是焦距, - \(B\) 是基线距离(即两个摄像头之间的水平间距), - \(d\) 是视差值。 该公式的前提是假设成像平面是平行的,这简化了许多实际操作中的复杂性[^4]。 #### 2. 深度估计的关键步骤 为了完成深度估计,通常需要以下几个关键步骤: ##### (1) 图像校正 由于实际拍摄过程中可能存在镜头畸变或其他误差,因此需先对输入的左、右图像进行校正。OpenCV 提供了 `stereoRectify` 函数用于生成矫正变换矩阵[^1]。 ```python import cv2 import numpy as np # 加载相机参数 cameraMatrixL, distCoeffsL, cameraMatrixR, distCoeffsR, R, T, E, F = load_camera_params() # 获取校正映射 RL, RR, PL, PR, Q, validPixROI1, validPixROI2 = \ cv2.stereoRectify(cameraMatrixL, distCoeffsL, cameraMatrixR, distCoeffsR, img_shape, R, T) mapL_x, mapL_y = cv2.initUndistortRectifyMap(cameraMatrixL, distCoeffsL, RL, PL, img_shape, cv2.CV_32FC1) mapR_x, mapR_y = cv2.initUndistortRectifyMap(cameraMatrixR, distCoeffsR, RR, PR, img_shape, cv2.CV_32FC1) # 应用校正 imgL_rectified = cv2.remap(imgL, mapL_x, mapL_y, cv2.INTER_LINEAR) imgR_rectified = cv2.remap(imgR, mapR_x, mapR_y, cv2.INTER_LINEAR) ``` ##### (2) 特征匹配与视差图生成 特征匹配的目标是在左右图像之间找到对应的点对。常用的方法有基于块匹配(Block Matching)和半全局匹配(Semi-Global Block Matching, SGBM)。下面是一个使用 OpenCV 中 SGBM 方法的例子: ```python def compute_disparity_map(imgL, imgR): window_size = 3 min_disp = 0 num_disp = 16 * 8 stereo = cv2.StereoSGBM_create( minDisparity=min_disp, numDisparities=num_disp, blockSize=window_size, uniquenessRatio=10, speckleWindowSize=100, speckleRange=32, disp12MaxDiff=1, P1=8 * 3 * window_size ** 2, P2=32 * 3 * window_size ** 2 ) disparity = stereo.compute(imgL, imgR).astype(np.float32) / 16.0 return disparity ``` ##### (3) 深度图转换 一旦获得了视差图,就可以利用前述公式将其转化为深度图。具体过程如下所示: ```python def convert_disparity_to_depth(disparity_map, focal_length, baseline): depth_map = (focal_length * baseline) / (disparity_map + 1e-7) # 防止除零错误 return depth_map ``` #### 3. 完整流程示例 综合上述各步,完整的双目深度估计算法可按以下方式实现: ```python if __name__ == "__main__": # 步骤 1: 载入并校正图像 imgL = cv2.imread('left_image.png', 0) imgR = cv2.imread('right_image.png', 0) imgL_rectified, imgR_rectified = rectify_images(imgL, imgR) # 步骤 2: 计算视差图 disparity_map = compute_disparity_map(imgL_rectified, imgR_rectified) # 步骤 3: 将视差图转为深度图 focal_length = 500 # 单位:像素 baseline = 0.1 # 单位:米 depth_map = convert_disparity_to_depth(disparity_map, focal_length, baseline) # 显示结果 plt.figure(figsize=(10, 5)) plt.subplot(1, 2, 1), plt.imshow(disparity_map, cmap='gray'), plt.title("Disparity Map") plt.subplot(1, 2, 2), plt.imshow(depth_map, cmap='jet'), plt.title("Depth Map") plt.show() ``` --- ###
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值