最近在做双目视差估计算法,在OpenCV里有一些算法,其中半全局块匹配(Semi-Global Block Matching,SGBM)算法具有视差效果好速度快的特点,因此常常被广泛应用。本文主要讨论的就是SGBM算法。OpenCV的SGBM算法主要参考了《Stereo Processing by Semiglobal Matching and Mutual Information》这篇论文。

1. 计算每个像素点的代价

原论文使用的方法是利用互信息熵,而OpenCV使用的是Birchfield和Tomasi的方法(参照《Depth Discontinuities by Pixel-to-Pixel Stereo》)。这里我们分别介绍一下。

1.1 利用互信息熵

所谓的熵,是用来表示随机变量的不确定性,熵的值越大,信息的不确定性也越大。熵H和互信息MI的定义分别如下:

熵H的定义

互信息MI(Mutual Information)的定义

其中,PI代表某个点i的概率分布,也就是灰度直方图为i的点出现的概率;对应地,PI1,I2就是两个图对应点i1和i2的联合概率分布,也就是:

Kim等人将上式做了一个改进:利用泰勒展开把HI1,I2的计算转化为求和问题(参见论文《Visual Correspondence Using Energy Minimization and Mutual Information》)。

其中圈中带叉表示卷积运算,g(i,k)为高斯卷积核。

相应地,边缘熵以及边缘概率的计算如下:

这样的话,互信息的定义为:

MI匹配代价CMI为:

其中q是点p在视差为d的情况下的对应校正点。

原作者使用分层互信息(HMI)进行计算,每一层尺寸减少一半。单次计算的时间复杂度是O(WHD),即width×height×disparity range,所以上次迭代将会是当前迭代速度的1/8。

这里1/163要乘3的原因是小尺寸的随机视差图不靠谱,需要迭代3次。我们可以看到,相比于后文的BT方法仅仅慢了14%

1.2 Birchfield和Tomasi的方法(简称BT方法)

对于一个匹配序列M,其代价函数γ(M)表示匹配结果不准确的程度,其值越小越好。

其中,κocc表示未匹配的惩罚项(constant occlusion penalty),κr表示匹配的奖励项,Nocc和Nr分别表示未匹配和匹配的点数。

2. 损失聚合

我们为视差设置一个能量函数E(D)

其中P1和P2分别表示视差差值为1和视差差值大于1的惩罚系数,一般P1

代价聚合公式(初始为C(p,d))

图片的代价聚合是各个像素点代价聚合之和

选取使代价聚合最小的视差值mindS[emb(q,d),d]即可。

3. OpenCV相关函数的使用

我们看一下stereoSGBM类的参数。

static Ptr cv::StereoSGBM::create (int minDisparity = 0,

int numDisparities = 16,

int blockSize = 3,

int P1 = 0,

int P2 = 0,

int disp12MaxDiff = 0,

int preFilterCap = 0,

int uniquenessRatio = 0,

int speckleWindowSize = 0,

int speckleRange = 0,

int mode = StereoSGBM::MODE_SGBM

)

minDisparity:最小的视差值。

numDisparity:视差范围,即最大视差值和最小视差值之差,必须是16的倍数。

blockSize:匹配块大小(SADWindowSize),必须是大于等于1的奇数,一般为3~11 。

P1,P2:惩罚系数,一般:P1=8*通道数*SADWindowSize*SADWindowSize,P2=4*P1

disp12MaxDiff :左右视差图的最大容许差异(超过将被清零),默认为 -1,即不执行左右视差检查。

preFilterCap:预滤波图像像素的截断值。该算法首先计算每个像素的x导数,并通过[-preFilterCap,preFilterCap]间隔剪切其值。结果值被传递给Birchfield-Tomasi像素成本函数。

uniquenessRatio:视差唯一性百分比, 视差窗口范围内最低代价是次低代价的(1 + uniquenessRatio/100)倍时,最低代价对应的视差值才是该像素点的视差,否则该像素点的视差为 0,通常为5~15.

speckleRange:视差变化阈值。

mode:模式

简单地试了一下:

#include "stdafx.h"

#include

#include

#include

#include

#include

using namespace cv;

int main(int argc, char** argv) {

//读入图像。

Mat left = cv::imread("left.png");

Mat right = cv::imread("right.png");

if (left.empty() || right.empty()) {

std::cout << "could not load image...\n";

return -1;

}

//图像转灰度

cv::cvtColor(left, left, CV_BGR2GRAY);

cv::cvtColor(right, right, CV_BGR2GRAY);

//设置参数

int numberOfDisparities = 48, SADWindowSize = 11;

int uniquenessRatio = 15, speckleWindowSize = 50, speckleRange = 32;

cv::Ptr<:stereosgbm> sgbm = cv::StereoSGBM::create(0, numberOfDisparities, SADWindowSize);

int cn = left.channels();

sgbm->setP1(8 * cn * SADWindowSize * SADWindowSize);

sgbm->setP2(32 * cn * SADWindowSize * SADWindowSize);

sgbm->setPreFilterCap(63);

sgbm->setUniquenessRatio(uniquenessRatio);

sgbm->setSpeckleWindowSize(speckleWindowSize);

sgbm->setSpeckleRange(speckleRange);

sgbm->setDisp12MaxDiff(1);

//计算并显示视差

Mat disp;

sgbm->compute(left, right, disp);

disp.convertTo(disp, CV_8U, 255 / (numberOfDisparities*16.)); //将16位符号整形的视差矩阵转换为8位无符号整形矩阵

cv::imshow("disparity", disp);

cv::waitKey();

return 0;

}

左视图

视差结果

参考资料

Heiko Hirschmuller “Stereo Processing by Semiglobal

Matching and Mutual Information ”[M].IEEE,2005

S. Birchfield and C. Tomasi, “Depth Discontinuities by Pixel-toPixel Stereo,” Proc. Sixth IEEE Int’l Conf. Computer Vision, pp. 1073-

1080, Jan. 1998.

php实现微信公众号半匹配,半全局块匹配(Semi-Global Block Matching)算法相关推荐

  1. 或许,这是最好的一款微信公众号编辑器!

    微信公众号这个当下最为热门和流行的内容平台,对于很多人都不陌生.越来越多的人开通微信公众号,然后把自己的知识.感想分享给大家. 开通微信公众号之后遇到第一个问题就是该如何寻找一款好用的微信排版工具. ...

  2. 如何排版 微信公众号「代码块」

    最近博主刚开通微信公众号「石佳劼的博客」,被微信公众平台的图文编辑器折腾的不轻,如果文章中包含「代码块」,怎么排版都显得杂乱无章.之前一直用 Markdown 写作,从来没有考虑过排版.样式问题,因为 ...

  3. 微信公众号python开发_Python微信公众号开发

    准备工作 首先,申请一个属于自己的微信公众号(必须保证全局管理员是自己的微信账户,否则会很麻烦),还要拥有自己的服务器(Ubuntu 系统)来部署代码,且服务器已经成功安装了网络相关的两个常用软件 u ...

  4. php实现微信公众号生成淘宝客推广海报(正则匹配淘宝联盟)

    现在很多人做淘宝客,包括我.做淘宝客一个月也可以赚个一两千零用钱,但是"淘宝联盟"APP生成的带二维码宣传图在微信是被屏蔽的,无法打开的! 例如: 所以很多做淘客的,开始开发自己的 ...

  5. php实现微信公众号生成淘宝客推广海报(正则匹配淘宝联盟) 1

    现在很多人做淘宝客,包括我.做淘宝客一个月也可以赚个一两千零用钱,但是"淘宝联盟"APP生成的带二维码宣传图在微信是被屏蔽的,无法打开的! 例如: 所以很多做淘客的,开始开发自己的 ...

  6. php 公众号验证回调方法_微信公众号关键词自动回复设置方法!

    什么是公众号关键词自动回复? 在微信公众号平台设置关键词自动回复,可以通过添加规则,关注/订阅的用户发送的消息内容如果是你设置的关键字,即可以实现自动回复预先设置好的内容. 关键字自动回复设置方法: ...

  7. 微信公众号基础功能搭建

    自动回复 在微信公众号后台首页左侧导航栏中找到功能.然后点击自动回复.自动回复包含被关注回复.收到消息回复和关键词回复三项内容. 被关注回复 用户关注公众号之后就会收到回复消息,消息形式包括文字.图片 ...

  8. 获取微信公众号文章封面图的技巧/网站

    直接使用访问:http://weixin.shareperform.com 以下主要是立项和事项的过程. 作为一个从Code转为营销策划的营销人,这周实力修一波操作. 一.需求 一个好的微信公众号推文 ...

  9. 微信公众号运营基础篇:排版、内容创作与引流篇

    微信公众号运营,其实就是通过多样的手段和技能在微信生态中可以更好的实现"用户获取"&"用户转化"以及"更好地实现已有客户的维系". ...

最新文章

  1. Caffe代码导读(5):对数据集进行Testing
  2. sift分类java_使用SIFT / SURF进行特征匹配是否可以用于类似对象的分类?
  3. python里的join方法_python中join()方法介绍
  4. python期末项目书怎么写_自己写了一部书怎么出版
  5. 哪些技能面试经常被问,但实际开发很少用上?
  6. 使用Hyper-V创建虚拟机
  7. 采用JAVASCRIPT实现全选的三种情况
  8. asp小偷转html,ASP “小偷”程序(抓取程序)
  9. 以一个通俗易懂的方式解释一下写程序为什么要声明接口和类,面向对象的编程思想,字数不多,主要通过代码理解
  10. Android ListView 获取Item的值和得到每一个Item的view对象以及得到他们所对应的控件值
  11. 再看《JavaScript高级程序设计》第8-9章
  12. SA8155 QNX 系统启动时序
  13. Vue入门学习总结一:Vue定义
  14. 四大列表控件之RadioButtonList控件(单选按钮)
  15. 116.【SpringBoot和Vue结合-图书馆管理系统】
  16. 车身控制器BCM系统功能规范
  17. vim编辑器如何退出
  18. springboot罗亚方舟考研资料库网站设计与实现毕业设计源码302302
  19. 服务器主板显示不了独立显卡,独立显卡故障——如何才知道显卡和主板不兼容...
  20. Doxygen简介及使用说明

热门文章

  1. Linux协议栈:基于ping流程窥探Linux网络子系统,及常用优化方法
  2. (4)Linux进程调度-组调度及带宽控制
  3. 【转】使用 OpenSSL API 进行安全编程 - 创建基本的安全连接和非安全连接
  4. C语言编写汇编的编译器,用c编写一个asm的编译器
  5. X Window Bitmaps And Pixmaps
  6. 免费制作微信小程序开发关于旅游_教大家怎么一步步免费自己做微信小程序
  7. MapReduce的API介绍
  8. linux c设置系统时间函数,Linux C 中获取local日期和时间 time()localtime()函数
  9. python面向对象代码_两百行代码搞定!使用Python面向对象做个小游戏
  10. Leecode刷题热题HOT100(13)——罗马数字转整数