【OpenCV】双目相机计算深度图和点云

双目相机计算深度图的基本原理是通过两台相机从不同角度拍摄同一场景,然后利用视差来计算物体的距离。本文的Python实现示例,使用OpenCV库来处理图像和计算深度图。

1、数据集介绍

Mobile stereo datasets由Pan Guanghan、Sun Tiansheng、Toby Weed和Daniel Scharstein在2019-2021年期间创建的,使用了Roger Dai、Kyle Meredith、Tommaso Monaco、Nick Mosier和Daniel Scharstein在2017-2018年期间开发的结构化光采集系统。该系统采用安装在UR5机械臂上的移动设备(苹果iPod touch 6G);地基真差是使用[5]中描述的结构化照明管道的一个子集来计算的。这些数据集包括11个场景,在许多不同的照明条件和曝光(包括闪光灯和移动设备的“火炬”照明)下,从1-3个不同的观看方向拍摄。
在这里插入图片描述

数据集基本描述:

Dataset description
Each dataset consists of 2 views taken under several different illuminations and exposures. The files are organized as follows:
SCENE{1,2,3}/                  -- scene imaged from 1-3 viewing directions
  ambient/                     -- directory of all input views under ambient lighting
    {F,L,T}{0,1,...}/          -- different lighting conditions (F=flash, L=lighting, T=torch)
      im0e{0,1,2,...}.png      -- left view under different exposures
      im1e{0,1,2,...}.png      -- right view under different exposures
  calib.txt                    -- calibration information
  im{0,1}.png                  -- default left and right view (typically ambient/L0/im{0,1}e2.png)
  disp{0,1}.pfm                -- left and right GT disparities
Zip files containing the above files can be downloaded here. "all.zip" contains all 24 scenes (image pair, disparities, calibration file), but not the ambient subdirectories. The latter are available in separate zip files.

Calibration file format
Here is a sample calib.txt file:
cam0=[1758.23 0 953.34; 0 1758.23 552.29; 0 0 1]
cam1=[1758.23 0 953.34; 0 1758.23 552.29; 0 0 1]
doffs=0
baseline=111.53
width=1920
height=1080
ndisp=290
isint=0
vmin=75
vmax=262
Explanation:

cam0,1:        camera matrices for the rectified views, in the form [f 0 cx; 0 f cy; 0 0 1], where
  f:           focal length in pixels
  cx, cy:      principal point

doffs:         x-difference of principal points, doffs = cx1 - cx0 (here always == 0)

baseline:      camera baseline in mm

width, height: image size

ndisp:         a conservative bound on the number of disparity levels;
               the stereo algorithm MAY utilize this bound and search from d = 0 .. ndisp-1

vmin, vmax:    a tight bound on minimum and maximum disparities, used for color visualization;
               the stereo algorithm MAY NOT utilize this information
To convert from the floating-point disparity value d [pixels] in the .pfm file to depth Z [mm] the following equation can be used:
Z = baseline * f / (d + doffs)
Note that the image viewer "sv" and mesh viewer "plyv" provided by our software cvkit can read the calib.txt files and provide this conversion automatically when viewing .pfm disparity maps as 3D meshes.

  • 如果使用自己的双目相机,则需要知道相机两个摄像头的内参矩阵cam0,1、基线baseline

2、Python代码

代码使用的双目图像数据是chess2

import cv2
import numpy as np
import time
import matplotlib.pyplot as plt

def load_images(left_path, right_path):
    left_image = cv2.imread(left_path, 0)
    right_image = cv2.imread(right_path, 0)
    return left_image, right_image

#
def compute_disparity_map(left_image, right_image, cam0, cam1, doffs, ndisp, vmin, vmax, block_size=15):
    stereo = cv2.StereoSGBM_create(
        minDisparity=vmin,  # 视差从0开始
        numDisparities=ndisp,  # 视差范围数量,必须是16的倍数
        blockSize=block_size,  # 匹配块的大小,奇数
        P1=8 * 3 * block_size ** 2,  # 平滑惩罚项(第一级)
        P2=32 * 3 * block_size ** 2,  # 平滑惩罚项(第二级),通常是P1的4倍
        disp12MaxDiff=1,  # 左右视差检查的最大允许差异
        uniquenessRatio=10,  # 唯一性比率阈值
        speckleWindowSize=100,  # 斑点滤波器窗口大小
        speckleRange=32  # 斑点滤波器最大容许差异
    )
    disparity_map = stereo.compute(left_image, right_image).astype(np.float32) / 16.0
    return disparity_map

# 转成深度图
def convert_disparity_to_depth(disparity_map, focal_length_px, baseline_mm):
    # 避免除以零的情况
    depth_map = (focal_length_px * baseline_mm) / disparity_map
    depth_map[disparity_map == 0] = 0  # 设置无效区域的深度为0
    return depth_map

# 过滤最远平面
def filter_far_plane(depth_map, max_distance=1500):  
    depth_map[depth_map 
### Matlab 中双目相机校正后深度图花屏的原因分析 在 MATLAB 的双目视觉应用中,如果经过校正的双目相机生成的深度图出现花屏现象,可能由以下几个原因引起: #### 1. **标定精度不足** 如果标定时使用的棋盘格图案数量较少或者拍摄角度单一,则可能导致内外参数估计不准确。这种误差会直接影响立体匹配的结果,从而导致深度图中的噪声或错误像素点增多[^2]。 #### 2. **极线不对齐** 即使完成了相机标定,在实际处理过程中仍可能存在轻微的极线未完全对齐的情况。这通常是因为镜头畸变矫正不够理想或是标定过程引入的小范围偏差所致。当极线偏离理论位置时,视差计算会出现较大波动,最终反映到深度图上即表现为花屏效果。 #### 3. **光照条件变化影响特征提取** 特征检测算法(如SAD、NCC等)对于环境光线非常敏感。如果采集左眼与右眼图像时光照强度差异明显,那么两幅图片间对应关系难以建立良好连接,进而造成误配情况增加,使得生成出来的深度地图质量下降并呈现斑驳状分布[^1]. #### 解决方案 以下是针对上述问题提出的几种改进措施: - #### 提高标定数据集的质量 收集更多不同方向距离下的棋盘格样本用于重新执行标定程序可以有效提升模型准确性。确保每张照片都清晰可见整个网格结构,并覆盖尽可能广的工作区域。 - #### 应用额外的几何约束调整极线一致性 使用`stereoRectify()`函数来强制让一对摄像头获取的画面满足平行投影假设前提下再做进一步操作前先完成矩形化变换步骤能够显著改善这一状况: ```matlab [R1,R2,P1,P2,Q,validPixROI1,validPixROI2]= stereoRectify(cameraParams.IntrinsicMatrixL,cameraParams.DistortionCoefficientsL,... cameraParams.IntrinsicMatrixR,cameraParams.DistortionCoefficientsR,size(I),cameraParams.RotationMatrix,cameraParams.TranslationVector); ``` - #### 预处理输入影像增强对比度稳定性 对原始RGB帧实施直方图均衡化或其他形式的颜色空间转换有助于减少外界因素干扰带来的负面影响。例如通过Gamma校正方法可以使暗部细节更加突出而不会过度曝光亮区部分: ```matlab gammaValue = 0.4; adjustedImage = imadjust(originalImage,[],[],gammaValue); imshow(adjustedImage); title('Adjusted Image'); ``` 综上所述,通过对硬件配置优化以及软件层面采取适当策略相结合的方式可极大程度缓解甚至消除此类异常表现的发生概率。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值