当前位置: 首页 > news >正文

【立体匹配】:双目立体匹配SGBM:(1)运行

:这是一个专题,我会一步步介绍SGBM的实现,按照我的使用和优化过程逐步改善算法,附带实现方法

                                    系列文章
  1. 【立体匹配】:双目立体匹配SGBM:(1)运行

【立体匹配】:双目立体匹配SGBM:(1)运行

  • 双目立体匹配SGBM概述
      • SGBM参数配置方法
      • 性能优化策略
      • 常见问题与解决方案
  • 具体使用
    • sgbm的python类接口

双目立体匹配SGBM概述

SGBM(Semi-Global Block Matching)是一种结合局部和全局优化的立体匹配算法,通过代价聚合和动态规划实现视差计算。其核心包括代价计算、代价聚合、视差计算和视差优化四个步骤。


SGBM参数配置方法

OpenCV中SGBM的关键参数如下:

import cv2  
sgbm = cv2.StereoSGBM_create(  minDisparity=0,        # 最小视差  numDisparities=64,     # 视差范围(需为16的倍数)  blockSize=3,           # 匹配块大小(奇数)  P1=8*3*3,             # 平滑性惩罚参数1  P2=32*3*3,            # 平滑性惩罚参数2  disp12MaxDiff=1,       # 左右视差检查阈值  preFilterCap=63,       # 预处理滤波截断值  uniquenessRatio=15,    # 唯一性匹配比率  speckleWindowSize=100, # 视差连通区域滤波窗口  speckleRange=32        # 视差连通性阈值  
)

性能优化策略

参数调优

  • 增大numDisparities可提升深度范围但会增加计算量,建议根据实际场景调整。
  • P1P2控制视差平滑性,通常设为P1=8*通道数*blockSize^2P2=4*P1

预处理增强

  • 使用直方图均衡化或CLAHE增强图像对比度:
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))  
left_img = clahe.apply(left_img)

后处理优化

  • 采用WLS(加权最小二乘)滤波消除噪声:
wls_filter = cv2.ximgproc.createDisparityWLSFilter(sgbm)  
filtered_disp = wls_filter.filter(disp, left_img)

常见问题与解决方案

边缘模糊

  • 原因:blockSize过大导致过度平滑。
  • 解决:减小blockSize或使用导向滤波优化视差图。

视差不连续

  • 原因:uniquenessRatio过低或噪声干扰。
  • 解决:增大uniquenessRatio至10-20,或启用speckleWindowSize滤波。

具体使用

sgbm的python类接口

import cv2
import numpy as np
import time
cv2.setNumThreads(4)  # 设置最大线程
cv2.setUseOptimized(True)
class SGBM:def __init__(self, use_blur=True):self.prev_disp = Noneself.alpha = 0.3  # 平滑系数 (0-1),越小越平滑self.use_blur = use_blurself.sgbm = self.create_sgbm()def create_sgbm(self):window_size = 5min_disp = 0num_disp = 64 - min_disp  # 必须是16的整数倍stereo = cv2.StereoSGBM_create(minDisparity=min_disp,numDisparities=num_disp,blockSize=window_size,P1=8 * 3 * window_size**2,  # 视差平滑参数P2=32 * 3 * window_size**2,disp12MaxDiff=1,uniquenessRatio=10,speckleWindowSize=100,speckleRange=32,mode=cv2.STEREO_SGBM_MODE_SGBM_3WAY# STEREO_SGBM_MODE_SGBM_3WAY ,STEREO_SGBM_MODE_HH, STEREO_SGBM_MODE_SGBM, STEREO_SGBM_MODE_HH4,STEREO_SGBM_MODE_HH4的速度最快,STEREO_SGBM_MODE_HH的精度最好)return stereodef create_bm_matcher(self):stereo = cv2.StereoBM_create(numDisparities=64,   # 视差范围(必须是16的倍数)blockSize=15         # 匹配块大小(奇数,建议5~25))return stereodef estimate_depth(self, left_image, right_image):"""进行深度估计推理,返回视差图(深度图)。"""# 转换为灰度图gray_left = cv2.cvtColor(left_image, cv2.COLOR_BGR2GRAY)gray_right = cv2.cvtColor(right_image, cv2.COLOR_BGR2GRAY)# clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))# gray_left = clahe.apply(gray_left)# gray_right = clahe.apply(gray_right)# gray_left = cv2.equalizeHist(gray_left)# gray_right = cv2.equalizeHist(gray_right)disp = self.sgbm.compute(gray_left, gray_right).astype(np.float32) / 16.0  # SGBM返回的视差需要除以16# # 应用选择的滤波器# if current_filter in ['guided', 'wls', 'fgs']:#     disp = apply_disparity_filter(#         disp, left_image, current_filter,#         lambda_=8000, sigma=1.5#     )# else:#     disp = apply_disparity_filter(disp, filter_type=current_filter)if self.prev_disp is not None:disp = self.alpha * disp + (1 - self.alpha) * self.prev_dispself.prev_disp = disp.copy()# disp = cv2.medianBlur(disp, 5)  # 中值滤波disp = cv2.morphologyEx(disp, cv2.MORPH_CLOSE, np.ones((5,5),np.uint8))  # 闭运算填充空洞return disp

在这个类里,默认调用sgbm方法,也可以切换bm算法,速度更快,但是视差图的空洞更多

import cv2
import numpy as npfrom stereomodel.OpencvSGBM.utils.SGBM import SGBM
from config import StereoSGBM_ins = SGBM(use_blur=True)
Stereo_ins = Stereo()
if __name__ == '__main__':left_img = cv2.imread('../../data/mid/im0.png')right_img = cv2.imread('../../data/mid/im1.png')disp = SGBM_ins.estimate_depth(left_img, right_img)Stereo_ins.show_depth_point(disp, left_img)

sgbm方法
在这里插入图片描述
bm方法
在这里插入图片描述

http://www.xdnf.cn/news/942355.html

相关文章:

  • 深入解析JavaScript构造函数与原型链
  • JavaScript 自定义对象详解
  • AI医生时代来临!o1模型在医疗诊断中超越人类医生
  • 查看进程线程的方法
  • 进制符号表示
  • 【阿里巴巴 x 浙江大学】信息与交互设计 - 信息设计漫谈
  • AIGC 基础篇 Python基础 02
  • MS8312A 车规 精密、低噪、CMOS、轨到轨输入输出运算放大器,用于传感器、条形扫描器
  • arxir网址自动转向国内镜像
  • 【DTOF传感器】光子飞行时间传感技术
  • 通信之光端机
  • 苏超 - 江苏省城市足球联赛
  • Angular中Webpack与ngx-build-plus 浅学
  • 【刷题模板】链表、堆栈
  • AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年6月8日第102弹
  • 06. C#入门系列【自定义类型】:从青铜到王者的进阶之路
  • 星耀8上市品鉴暨北京中和吉晟吉利银河用户中心开业媒体见面会
  • 免费批量去水印工具 - 针对文心一言生成图片
  • DDR供电设计中的VTT与VREF作用和区别
  • leetcode Top100 189.轮转数组
  • global security market 的知识点总结 SMA
  • 给跳绳设计一双卡扣
  • Hilt在android项目中使用的注解说明
  • 设置QDialog的setModal(true)对show()无法阻塞
  • Python 训练营打卡 Day 46
  • 力扣-131.分割回文串
  • 基于fpga的疲劳驾驶检测
  • 【Autosar COM】Marvell 88Q5050 以太网交换机驱动技术解析
  • JavaScript 的意义
  • 山东大学项目实训——基于DeepSeek的智能写作与训练平台(十二)