立体匹配算法(Stereo correspondence)SGM

SGM(Semi-Global Matching)原理:

SGM的原理在wiki百科和matlab官网上有比较详细的解释:
wiki matlab
如果想完全了解原理还是建议看原论文 paper(我就不看了,懒癌犯了。)
优质论文解读和代码实现
一位大神自己用c++实现的SGM算法github
先介绍两个重要的参数:
注:这一部分参考的是matlab的解释,后面的部分是参考的opencv的实现,细节可能有些出入,大体上是一致的。
Disparity Levels and Number of Directions

Disparity Levels

Disparity Levels: Disparity levels is a parameter used to define the search space for matching. As shown in figure below, the algorithm searches for each pixel in the Left Image from among D pixels in the Right Image. The D values generated are D disparity levels for a pixel in Left Image. The first D columns of Left Image are unused because the corresponding pixels in Right Image are not available for comparison. In the figure, w represents the width of the image and h is the height of the image. For a given image resolution, increasing the disparity level reduces the minimum distance to detect depth. Increasing the disparity level also increases the computation load of the algorithm. At a given disparity level, increasing the image resolution increases the minimum distance to detect depth. Increasing the image resolution also increases the accuracy of depth estimation. The number of disparity levels are proportional to the input image resolution for detection of objects at the same depth. This example supports disparity levels from 8 to 128 (both values inclusive). The explanation of the algorithm refers to 64 disparity levels. The models provided in this example can accept input images of any resolution.——matlab

字太多,看不懂,让gpt解释了一下:

# gpt生成,仅供本人理解SSD原理
import numpy as npdef compute_disparity(left_img, right_img, block_size=5, num_disparities=64):# 图像尺寸height, width = left_img.shape# 初始化视差图disparity_map = np.zeros_like(left_img)# 遍历每个像素for y in range(height):for x in range(width):# 定义搜索范围min_x = max(0, x - num_disparities // 2)max_x = min(width, x + num_disparities // 2)# 提取左图像块left_block = left_img[y:y+block_size, x:x+block_size]# 初始化最小 SSD 和对应的视差min_ssd = float('inf')best_disparity = 0# 在搜索范围内寻找最佳视差for d in range(min_x, max_x):# 提取右图像块right_block = right_img[y:y+block_size, d:d+block_size]# 计算 SSDssd = np.sum((left_block - right_block)**2)# 更新最小 SSD 和对应的视差if ssd < min_ssd:min_ssd = ssdbest_disparity = abs(x - d)# 将最佳视差保存到视差图中disparity_map[y, x] = best_disparityreturn disparity_map# 示例用法
left_img = np.random.randint(0, 255, size=(100, 100), dtype=np.uint8)
right_img = np.roll(left_img, shift=5, axis=1)  # 创建右图,右移了5个像素disparity_map = compute_disparity(left_img, right_img, block_size=5, num_disparities=64)# 可视化结果(这里简化为将视差图缩放以便可视化)
import matplotlib.pyplot as plt
plt.imshow(disparity_map, cmap='gray')
plt.title('Disparity Map')
plt.show()

这样就明白了,Disparity Levels就是计算视差的范围(视差搜索范围)。

Number of Directions

Number of Directions:

Number of Directions: In the SGBM algorithm, to optimize the cost function, the input image is considered from multiple directions. In general, accuracy of disparity result improves with increase in number of directions. This example analyzes five directions: left-to-right (A1), top-left-to-bottom-right (A2), top-to-bottom (A3), top-right-to-bottom-left (A4), and right-to-left (A5).
在这里插入图片描述

按照单一路径匹配像素不够稳健,按照图像进行二维最优的全局匹配时间复杂度太高(NP完全问题),所以SGM的作者使用一维路径聚合的方式来近似二维最优。
在这里插入图片描述
pic 参考

SAD和SSD

用SAD 或者 SSD计算图像相似度,来做匹配。
公式:
> 这里是引用
公式和代码虽然是gpt生成的,但是公式看起来没错,代码可以帮助理解,仅供参考。
代码里面的 num_disparities 就是 Disparity Levels

SGBM in opencv

本人用opencv较多,这里仅关注代码在opencv的实现。

opencv StereoSGBM_create示例:

# gpt生成,仅作为参考,具体请查看opencv官方文档https://docs.opencv.org/4.x/d2/d85/classcv_1_1StereoSGBM.html
import cv2
import numpy as np# 读取左右视图
left_image = cv2.imread('left_image.png', cv2.IMREAD_GRAYSCALE)
right_image = cv2.imread('right_image.png', cv2.IMREAD_GRAYSCALE)# 创建SGBM对象
sgbm = cv2.StereoSGBM_create(minDisparity=0,numDisparities=16,  # 视差范围,一般为16的整数倍blockSize=5,        # 匹配块的大小,一般为奇数P1=8 * 3 * 5 ** 2,   # SGBM算法参数P2=32 * 3 * 5 ** 2,  # SGBM算法参数disp12MaxDiff=1,    # 左右视差图的最大差异uniquenessRatio=10,  # 匹配唯一性百分比speckleWindowSize=100,  # 过滤小连通区域的窗口大小speckleRange=32      # 连通区域内的差异阈值
)# 计算视差图
disparity_map = sgbm.compute(left_image, right_image)# 将视差图进行归一化处理
disparity_map = cv2.normalize(disparity_map, None, 0, 255, cv2.NORM_MINMAX)# 显示左图、右图和视差图
cv2.imshow('Left Image', left_image)
cv2.imshow('Right Image', right_image)
cv2.imshow('Disparity Map', disparity_map.astype(np.uint8))cv2.waitKey(0)
cv2.destroyAllWindows()

Difference between SGBM and SGM

what is the difference between opencv sgbm and sgm
opencv官方的解释:
The class implements the modified H. Hirschmuller algorithm [82] that differs from the original one as follows:

  1. By default, the algorithm is single-pass, which means that you consider only 5 directions instead of 8. Set mode=StereoSGBM::MODE_HH in createStereoSGBM to run the full variant of the algorithm but beware that it may consume a lot of memory.
  2. The algorithm matches blocks, not individual pixels. Though, setting blockSize=1 reduces the blocks to single pixels.
  3. Mutual information cost function is not implemented. Instead, a simpler Birchfield-Tomasi sub-pixel metric from [15] is used. Though, the color images are supported as well.
    Some pre- and post- processing steps from K. Konolige algorithm StereoBM are included, for example: pre-filtering (StereoBM::PREFILTER_XSOBEL type) and post-filtering (uniqueness check, quadratic interpolation and speckle filtering).

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/311504.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法】数论---约数

约数里面的一个重要性质&#xff1a;一个数的约数都是成对存在的(以sqrt(x)为分界线) 一、求一个数的所有约数---试除法 int x; cin>>x; int yue[10000]{0},idx0; for(int i1;i<x/i;i) {if(x%i0){yue[idx]i;cout<<i<<" ";} }for(int iidx-1;i&…

Java 8 中的 Stream 轻松遍历树形结构!

可能平常会遇到一些需求&#xff0c;比如构建菜单&#xff0c;构建树形结构&#xff0c;数据库一般就使用父id来表示&#xff0c;为了降低数据库的查询压力&#xff0c;我们可以使用Java8中的Stream流一次性把数据查出来&#xff0c;然后通过流式处理&#xff0c;我们一起来看看…

八个理由:从java8升级到Java17

目录 前言 1. 局部变量类型推断 2.switch表达式 3.文本块 4.Records 5.模式匹配instanceof 6. 密封类 7. HttpClient 8.性能和内存管理能力提高 前言 从Java 8 到 Java 20&#xff0c;Java 已经走过了漫长的道路&#xff0c;自 Java 8 以来&#xff0c;Java 生态系统…

基于JAVA的独居老人物资配送系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询社区4.2 新增物资4.3 查询物资4.4 查询物资配送4.5 新增物资配送 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的独居老人物资配送系统&#xff0c;包含了社区档案、…

GitHub的2FA验证问题解决工具

文章目录 前言认识2FA开源工具使用&#xff1a;AuthenticatorPro获取AuthenticatorPro的安卓APK如何使用 参考文章 前言 打开GitHub跳出来这个提示&#xff0c;需要进行验证&#xff1a; 如何解决呢&#xff1f;方案有很多&#xff0c;我们可以使用开源的一个工具&#xff1a;…

穿越时光的镜头:2023回顾与2024展望

前言 2023 年就像一本充满着惊喜和挑战的书籍&#xff0c;它的每一页都留下了我生活中不同的痕迹。回顾过去&#xff0c;我发现了许多意想不到的成长和启示&#xff0c;也体验了生活的起起伏伏。 这篇文章是对 2023 年的一个小小总结&#xff0c;也是对未来的一点期许。在这里…

大数据HCIE成神之路之数据预处理(5)——偏态数据处理

偏态数据处理 1.1 偏态数据三种处理方案1.1.1 实验背景1.1.2 实验目标1.1.3 实验数据解析1.1.4 实验思路1.1.5 实验操作步骤步骤1 导入相关模块和 Data_to_Transform.csv 数据集步骤2 平方根法步骤3 对数转换步骤4 Box-Cox转换 1.1 偏态数据三种处理方案 1.1.1 实验背景 许多…

Apollo自动驾驶:从概念到现实的里程碑

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 ChatGPT体验地址 文章目录 前言1. Apollo Client2. Apollo Server3. Apollo Federation4. Apollo Tracing5. Apollo Codegen6. Apollo Link7. 其他工具和框架结论 &#x1f680;&#x1f…

uni-app新建页面

新建页面 一、右键点击 pages 文件夹&#xff0c;点击新建页面。 二、输入页面名称、选择创建 vue 文件、勾选创建同名目录、选择默认模板、勾选在 pages.json 中注册、点击创建即可。 原创作者&#xff1a;吴小糖 创作时间&#xff1a;2023.12.28

【网络安全】有趣的基础知识

背景 逐条记录网络安全学习中有趣的内容和知识。 内容 CNNIC&#xff08;中国互联网络信息中心&#xff09;是中国国家域名.cn的管理组织。中国互联网络信息中心于1997年6月3日组建&#xff0c;现为工业和信息化部 直属事业单位 &#xff0c;行使国家互联网络信息中心职责。…

通过栈将中缀表达式转换为等价的后缀表达式

为什么要从中缀表达式转换为等价的后缀表达式&#xff1f; →使后缀表达式包含运算符优先级的信息&#xff0c;方便计算机能理解进行运算。 什么是中缀表达式&#xff1f; →中缀表达式虽然是人类看得懂的简单算术形式&#xff0c;但对计算机来说反而复杂难以理解 什么是后缀表…

[设计模式 Go实现] 创建型~抽象工厂模式

抽象工厂模式用于生成产品族的工厂&#xff0c;所生成的对象是有关联的。 如果抽象工厂退化成生成的对象无关联则成为工厂函数模式。 比如本例子中使用RDB和XML存储订单信息&#xff0c;抽象工厂分别能生成相关的主订单信息和订单详情信息。 如果业务逻辑中需要替换使用的时候…