立体匹配算法(Stereo correspondence)SGM

news/2024/11/8 22:41:14/

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.ppmy.cn/news/1287149.html

相关文章

基于自定义权重的支持向量机,基于自定义权重的SVM

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 完整代码和数据下载链接: 基于自定义权重的支持向量机,基于自定义权重的SVM资源-CSDN文库 https://download.csdn.net/download/abc991835105/88637048 SVM应用实例, 基于支…

【Python_PySide2学习笔记(二十一)】输入对话框QInputDialog类的基本用法

输入对话框QInputDialog类的基本用法 输入对话框QInputDialog类的基本用法前言正文1、整数输入框 QInputDialog.getInt()2、浮点数输入框 QInputDialog.getDouble()3、单行文本输入框 QInputDialog.getText()4、多行文本输入框 QInputDialog.getMultiLineText()5、下拉列表输入…

「Kafka」生产者篇

「Kafka」生产者篇 生产者发送消息流程 在消息发送的过程中&#xff0c;涉及到了 两个线程 ——main 线程和Sender 线程。 在 main 线程中创建了 一个 双端队列 RecordAccumulator。 main线程将消息发送给RecordAccumulator&#xff0c;Sender线程不断从 RecordAccumulator…

spring ioc源码-refresh();

主要作用是刷新应用上下文 Override public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 启动刷新的性能跟踪步骤StartupStep contextRefresh this.applicationStartup.start("spring.context.refre…

“图解C语言:一维数组的声明、创建与初始化艺术“

各位少年&#xff1a; 标题&#xff1a;《C语言一维数组的探索之旅&#xff1a;从声明到初始化&#xff0c;及如何避免常见误区》 引言 在编程世界中&#xff0c;数组无疑是最基础且重要的数据结构之一&#xff0c;尤其在C语言中&#xff0c;它以其简洁明了的特性为各类数据处…

过滤器、拦截器、切面

过滤器、拦截器、切面作用范围 原理不同范围不同具体参考[过滤器、拦截器、切面异同](https://juejin.cn/post/7110104873265758222) 执行顺序&#xff1a;过滤器>拦截器>切面 过滤器、拦截器属于请求层面的拦截&#xff1b;切面属于方法层面的拦截 原理不同 过滤器和拦…

编程笔记 html5cssjs 009 HTML链接

编程笔记 html5&css&js 009 HTML链接 一、HTML 链接二、文本链接三、图片链接四、HTML 链接- id 属性五、锚点链接六、HTML 链接 - target 属性小结 网页有了链接&#xff0c;就可根据需要进行跳转。纸质读物只能根据指示的页码翻页&#xff0c;而网页则可以通过链接直…

Vue Router的介绍与引入

在这里是记录我引入Vue Router的全过程&#xff0c;引入方面也最好先看官方文档 一.介绍 Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成&#xff0c;让用 Vue.js 构建单页应用变得轻而易举。功能包括&#xff1a; 嵌套路由映射动态路由选择模块化、基于组件的…