python 立体匹配_手写双目立体匹配 SGM 算法(下)
上节的内容主要对 SGM 算法的匹配代价体 (Cost Volume) 进行了详细介绍,发现如果只寻找逐个像素匹配代价的最优解会使得视差图对噪声特别敏感。因此在能量方程中考虑使用该点像素的邻域视差数据来构造惩罚函数以增加平滑性约束, 这个求解过程也称为代价聚合 (Cost Aggregation)的过程。
能量方程
SGM 算法建立了能量方程,并引入了视差约束条件,以对此进行优化:
等式右边第一项表示像素点 $p$ 在视差范围内所以匹配代价之和; 第二项和第三项是指当前像素 $p$ 和其邻域内所有像素 $q$ 之间的平滑性约束,增加了惩罚因子 $P1$ 和 $P2$: 若 $p$ 和 $q$ 的视差的差值等于 1,则惩罚因子 $P1$,若差值大于 1,则惩罚因子为 $P2$。
为了高效地求解它,SGM 提出一种路径代价聚合的思路,即将像素所有视差下的匹配代价进行像素周围所有路径上的一维聚合得到路径下的路径代价值,然后将所有路径代价值相加得到该像素聚合后的匹配代价值。
路径代价
设 $L_{r}$ 表示穿过 $r$ 方向的扫描路径代价,其计算方式如下所示:
等号右边第一项表示像素点 $p$ 的初始匹配代价;第二项表示 $p$ 的前一个像素点 $p − r$ 的最小匹配代价:若和 $p$ 的视差差值为 0,无需加任何惩罚因子,差值为 1,加惩罚因子 $P1$ ,若差值大于 1,则惩罚因子为 $P2$;第三项表示前一个像素点 $p − r$ 沿 $r$ 路径上的最小匹配代价,加入该项的目的是抑制 $L_{r}( p, d )$ 的数值过大,并不会影响视差空间。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29def (slice, offset):
"""
part of the aggregation step, finds the minimum costs in a D x M slice (where M = the number of pixels in the
given direction)
:param slice: M x D array from the cost volume.
:param offset: ignore the pixels on the border.
:return: M x D array of the minimum costs for a given slice in a given direction.
"""
P1 = 5
P2 = 70
slice_dim, disparity_dim = slice.shape
disparities = [d for d in range(disparity_dim)] * disparity_dim
disparities = np.array(disparities).reshape(disparity_dim, disparity_dim)
penalties = np.zeros(shape=(disparity_dim, disparity_dim), dtype=np.uint32)
penalties[np.abs(disparities - disparities.T) == 1] = P1
penalties[np.abs(disparities - disparities.T) > 1] = P2
minimum_cost_path = np.zeros(shape=(other_dim, disparity_dim), dtype=np.uint32)
minimum_cost_path[offset - 1, :] = slice[offset - 1, :]
for i in range(offset, other_dim):
previous_cost = minimum_cost_path[i - 1, :]
current_cost = slice[i, :]
costs = np.repeat(previous_cost, repeats=disparity_dim, axis=0).reshape(disparity_dim, disparity_dim)
costs = np.amin(costs + penalties, axis=0)
minimum_cost_path[i, :] = current_cost + costs - np.amin(previous_cost)
return minimum_cost_path
代价聚合
单路聚合
如果我们只考虑单路扫描会是什么样的结果呢?假设代价聚合路线为从上至下,即 south 方向(2 号路线)。如下图所示,那么
1
2
3
4
5
6
7
8main_aggregation = np.zeros(shape=(image_h, image_w, max_disparity), dtype=np.uint32)
aggregation_volume = np.zeros(shape=(image_h, image_w, max_disparity, 1), dtype=np.uint32)
for x in range(0, image_w):
south = cost_volume[0:image_h, x, :]
main_aggregation[:, x, :] = get_path_cost(south, 1)
aggregation_volume[:, :, :, 0] = main_aggregation
便得到了代价聚合体(aggregation_volume)进行视差计算,找到该路径下的聚合最小匹配代价值:
1
2
3
4
5
6
7
8
9def select_disparity(aggregation_volume):
"""
last step of the sgm algorithm, corresponding to equation 14 followed by winner-takes-all approach.
:param aggregation_volume: H x W x D x N array of matching cost for all defined directions.
:return: disparity image.
"""
volume = np.sum(aggregation_volume, axis=3)
disparity_map = np.argmin(volume, axis=2)
return disparity_map
最后通过最小化该路径在一维聚合下的匹配代价,得到了视差图如下图所示。
1
2
3disparity_map = select_disparity(aggregation_volume)
disparity_map = normalize(disparity_map)
cv2.imwrite("scan_south_disp.png", disparity_map)
多路聚合
从单路扫描的结果可以看出,一维扫描线优化仅仅只受一个方向约束,容易造成“条纹效应”,所以在 SGM 算法中,聚合了多个扫描路径上的匹配代价。
一共有八个方向:south 和 north,east 和 west,south_east 和 north_west, south_west 和 north_east。刚刚实现了 south 方向单路扫描聚合代价的最优求解,而其他路扫描聚合代价的过程和它是类似的。限于篇幅,在这里就不补充了,最后得到的视差图如下所示:
python 立体匹配_手写双目立体匹配 SGM 算法(下)相关推荐
- 多元线性回归算法python实现_手写算法-Python代码推广多元线性回归
1.梯度下降-矩阵形式 上篇文章介绍了一元线性回归,包括Python实现和sklearn实现的实例.对比,以及一些问题点,详情可以看这里: 链接: 手写算法-Python代码实现一元线性回归 里面封装 ...
- python识别手写文字_如何快速使用Python神经网络识别手写字符?(文末福利)
原标题:如何快速使用Python神经网络识别手写字符?(文末福利) 点击标题下[异步社区]可快速关注 在本文中,我们将进一步探讨一些使用Python神经网络识别手写字符非常有趣的想法.如果只是想了解神 ...
- python手写代码面试_常见Python面试题—手写代码系列
原标题:常见Python面试题-手写代码系列 1.如何反向迭代一个序列 #如果是一个list,最快的方法使用reverse tempList = [1,2,3,4] tempList.reverse( ...
- python手写代码面试_常见Python面试题 — 手写代码系列
原标题:常见Python面试题 - 手写代码系列 作者: Peace & Love 来自:https://blog.csdn.net/u013205877/article/details/77 ...
- 如何识别手写文字python_如何快速使用Python神经网络识别手写字符?(文末福利)...
点击标题下[异步社区]可快速关注 在本文中,我们将进一步探讨一些使用Python神经网络识别手写字符非常有趣的想法.如果只是想了解神经网络的基本知识,那不必阅读本文,可以先阅读<Python神 ...
- Python神经网络识别手写数字-MNIST数据集
Python神经网络识别手写数字-MNIST数据集 一.手写数字集-MNIST 二.数据预处理 输入数据处理 输出数据处理 三.神经网络的结构选择 四.训练网络 测试网络 测试正确率的函数 五.完整的 ...
- 利用Python对MNIST手写数据集进行数字识别(初学者入门级)
利用Python对MNIST手写数据集进行数字识别 一.编程环境Jupyter Notebook Jupyter Notebook,之前被称为IPython notebook,是一个交互式的Web应用 ...
- python svm实现手写数字识别——直接可用
python svm实现手写数字识别--直接可用 1.训练 1.1.训练数据集下载--已转化成csv文件 1.2 .训练源码 2.预测单张图片 2.1.待预测图像 2.2.预测源码 2.3.预测结果 ...
- 手写字体的fisher算法识别
代表了一些投影的方法 最佳W值的确定: 最佳w值的确定实际上就是对Fisher准则函数求取其达极大值时的. 对于这个问题可以采用拉格朗日乘子算法解决,保持分母为一非零常数c的条件下,求其分子项的极大值 ...
最新文章
- php controller 间调用,php – 在CodeIgniter中的另一个Controller中调用Controller函数
- SparkStreaming从Kafka读取数据两种方式
- java四子棋实验报告_Python 实现劳拉游戏的实例代码(四连环、重力四子棋)
- python绘制曲线图-python绘制多个曲线的折线图
- jQuery中$(document).ready()和window.onload的区别?
- iOS iOS9下实现app间的跳转
- 使用JUnit规则测试预期的异常
- [恢]hdu 2021
- python-字符串的切片操作
- 浅谈Java设计模式
- MooTool 1.0.0 发布,开发者常备桌面小工具
- iOS开发——高级篇——线程同步、线程依赖、线程组
- 算法中的最优化方法_学习目录
- EOS钱包及代码分析
- 学计算机穿格子衬衫的男人,教你成为穿格子衬衫的帅气理工男
- 2020年十大数字客户体验(CX)软件平台
- java程序员 thinkpad_JAVA程序员笔记本电脑推荐?
- 增加关键词密度不要堆积
- Windows 端口代理配置(Netsh)
- 双十一买什么充电宝好?实惠好用的充电宝推荐
热门文章
- Oracle 数据库维护知识
- 利用 Zabbix 监控数据库文件大小
- 在CentOS 8上安装与配置Apache虚拟主机
- Linux 的 复制命令 【 cp 】 (copy)及其 (常用参数 -fp)
- linux 查看 shell进程,Linux之shell 和进程
- unknown host www.baidu.com 解决方法
- Genymotion 启动app闪退解决方案
- Java框架之SpringMVC 05-拦截器-异常映射-Spring工作流程
- Unity 生成APK 出错的解决方法
- 【问题解决方案】anaconda-python在cmd-pip安装requests后依然提示No module named requests