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

news2025/7/27 17:15:49

:这是一个专题,我会一步步介绍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 = None
        self.alpha = 0.3  # 平滑系数 (0-1),越小越平滑
        self.use_blur = use_blur
        self.sgbm = self.create_sgbm()
    def create_sgbm(self):
        window_size = 5
        min_disp = 0
        num_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 stereo
    def create_bm_matcher(self):
        stereo = cv2.StereoBM_create(
            numDisparities=64,   # 视差范围(必须是16的倍数)
            blockSize=15         # 匹配块大小(奇数,建议5~25)
        )
        return stereo
   
    def 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_disp
        self.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 np

from stereomodel.OpencvSGBM.utils.SGBM import SGBM
from config import Stereo

SGBM_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.coloradmin.cn/o/2406064.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

< 自用文 OS有关 新的JD云主机> 国内 京东云主机 2C4G 60G 5Mb 498/36月 Ubuntu22

攒了这么久,废话一些: 前几周很多事儿,打算回北京,开个清真的德克萨斯烤肉店,写了一篇 : < 自用文 Texas style Smoker > 美式德克萨斯烟熏炉 从设计到实现 (第一部分&…

《架构即未来》笔记

思维导图 第一部分:可扩展性组织的人员配置 第二部分:构建可扩展的过程 第三部分:可扩展的架构方案 第四部分:其他的问题和挑战 资料 问软件工程研究所: https://www.sei.cmu.edu/ AKF公司博客: http://www.akfpart…

ubuntu2404 gpu 没接显示器,如何保证远程显示的分辨率

1. 使用 xserver-xorg-video-dummy 创建虚拟显示器 如果系统在无物理显示器连接时无法识别显示输出,可以使用 xserver-xorg-video-dummy 驱动程序创建虚拟显示器。以下是设置步骤: 安装虚拟显示器驱动程序: sudo apt install xserver-xorg-v…

【基于阿里云搭建数据仓库(离线)】使用UDTF时出现报错“FlatEventUDTF cannot be resolved”

目录 问题: 可能的原因有: 解决方法: 问题: 已经将包含第三方依赖的jar包上传到dataworks,并且成功注册函数,但是还是报错:“FlatEventUDTF cannot be resolved”,如下&#xff1a…

Pycharm的终端无法使用Anaconda命令行问题详细解决教程

很多初学者在Windows系统上安装了Anaconda后,在PyCharm终端中运行Conda命令时,会遇到以下错误: conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。 请检查名称的拼写,如果包括路径,请确保…

SAP学习笔记 - 开发24 - 前端Fiori开发 Filtering(过滤器),Sorting and Grouping(排序和分组)

上一章讲了SAP Fiori开发的表达式绑定,自定义格式化等内容。 SAP学习笔记 - 开发23 - 前端Fiori开发 Expression Binding(表达式绑定),Custom Formatters(自定义格式化)-CSDN博客 本章继续讲SAP Fiori开发…

自建 dnslog 回显平台:渗透测试场景下的隐蔽回显利器

🔍 背景介绍 在渗透测试与红队评估过程中,DNS 外带(DNS Exfiltration) 是一种常见且隐蔽的通信通道。由于多数目标环境默认具备外网 DNS 解析能力,即便在 无回显、无文件上传权限 的条件下,仍可通过 DNS 请…

Digital IC Design Flow

Flow介绍 1.设计规格 架构师根据市场需求制作算法模型(Algorithm emulation)及芯片架构(Chip architecture),确定芯片设计规格书(Chip design specification) 原型验证 原型验证(Prototype Validation)通常位于产品开发流程的前期阶段,主要是在设计和开发的初步阶…

设备健康管理的范式革命:中讯烛龙全链路智能守护系统

当工业设备的“亚健康”状态导致隐性产能损失高达23%时,中讯烛龙推出 ​​“感知-诊断-决策-闭环”四位一体解决方案,让设备全生命周期健康管理成为企业增长的隐形引擎。 一、行业痛点:传统运维的三大断层 1. 健康感知盲区 某风电场因无法捕…

循环神经网络(RNN):从理论到翻译

循环神经网络(RNN)是一种专为处理序列数据设计的神经网络,如时间序列、自然语言或语音。与传统的全连接神经网络不同,RNN具有"记忆"功能,通过循环传递信息,使其特别适合需要考虑上下文或顺序的任…

Redis:常用数据结构 单线程模型

🌈 个人主页:Zfox_ 🔥 系列专栏:Redis 🔥 常用数据结构 🐳 Redis 当中常用的数据结构如下所示: Redis 在底层实现上述数据结构的过程中,会在源码的角度上对于上述的内容进行特定的…

夏普比率(Sharpe ratio)​

具有投资常识的人都明白,投资光看收益是不够的,还要看承受的风险,也就是收益风险比。 夏普比率描述的正是这个概念,即每承受一单位的总风险,会产生多少超额的报酬。 用数学公式描述就是: 其中&#xff1…

【优选算法】模拟 问题算法

​一&#xff1a;替换所有的问号 class Solution { public:string modifyString(string s) {int n s.size();for(int i 0; i < n; i){if(s[i] ?){for(char ch a; ch < z; ch){if((i0 && ch !s[i1]) || (in-1 && ch ! s[i-1]) || ( i>0 &&…

Flask+LayUI开发手记(八):通用封面缩略图上传实现

前一节做了头像上传的程序&#xff0c;应该说&#xff0c;这个程序编写和操作都相当繁琐&#xff0c;实际上&#xff0c;头像这种缩略图在很多功能中都会用到&#xff0c;屏幕界面有限&#xff0c;绝不会给那么大空间摆开那么大一个界面&#xff0c;更可能的处理&#xff0c;就…

低代码采购系统搭建:鲸采云+能源行业订单管理自动化案例

在能源行业数字化转型浪潮下&#xff0c;某大型能源集团通过鲸采云低代码平台&#xff0c;仅用3周时间就完成了采购订单管理系统的定制化搭建。本文将揭秘这一成功案例的实施路径与关键成效。 项目背景与挑战 该企业面临&#xff1a; 供应商分散&#xff1a;200供应商使用不同…

android关于pthread的使用过程

文章目录 简介代码流程pthread使用hello_test.cppAndroid.bp 编译过程报错处理验证过程 简介 android开发经常需要使用pthread来编写代码实现相关的业务需求 代码流程 pthread使用 需要查询某个linux函数的方法使用&#xff0c;可以使用man 函数名 // $ man pthread_crea…

如何用 HTML 展示计算机代码

原文&#xff1a;如何用 HTML 展示计算机代码 | w3cschool笔记 &#xff08;请勿将文章标记为付费&#xff01;&#xff01;&#xff01;&#xff01;&#xff09; 在编程学习和文档编写过程中&#xff0c;清晰地展示代码是一项关键技能。HTML 作为网页开发的基础语言&#x…

2025年ESWA SCI1区TOP,自适应学习粒子群算法AEPSO+动态周期调节灰色模型,深度解析+性能实测

目录 1.摘要2.粒子群算法PSO原理3.改进策略4.结果展示5.参考文献6.代码获取7.算法辅导应用定制读者交流 1.摘要 能源数据的科学预测对于能源行业决策和国家经济发展具有重要意义&#xff0c;尤其是短期能源预测&#xff0c;其精度直接影响经济运行效率。为了更好地提高预测模型…

LeetCode - 53. 最大子数组和

目录 题目 Kadane 算法核心思想 Kadane 算法的步骤分析 读者可能的错误写法 正确的写法 题目 53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; Kadane 算法核心思想 定义状态变量: currentSum: 表示以当前元素为结束的子数组的最大和。 maxSum: 记录全局最大…

【读代码】从预训练到后训练:解锁语言模型推理潜能——Xiaomi MiMo项目深度解析

项目开源地址:https://github.com/XiaomiMiMo/MiMo 一、基本介绍 Xiaomi MiMo是小米公司开源的7B参数规模语言模型系列,专为复杂推理任务设计。项目包含基础模型(MiMo-7B-Base)、监督微调模型(MiMo-7B-SFT)和强化学习模型(MiMo-7B-RL)等多个版本。其核心创新在于通过…