引言:基于opencv3.0,对bm、sgbm和gc算法进行了对比测试研究。由于sgbm算法视差效果好速度快的特点,常常被广泛应用和改进,本文针对sgbm算法主要参数设置作了对比测试,以供大家参考。
bm:block matching ,采用sad方法计算匹配代价;
sgbm: 修改自heiko hirschmuller的《stereo processing by semi-global matching and mutual information》:http://www.openrs.org/photogrammetry/2015/sgm%202008%20pami%20-%20stereo%20processing%20by%20semiglobal%20matching%20and%20mutual%20informtion.pdf;长按以下二维码可直接打开
与原方法不同点:
没有实现原文中基于互信息的匹配代价计算,而是采用bt算法(depth discontinuities by pixel-to-pixel stereo() by s. birchfield and c. tomasi);
默认运行单通道dp算法,只用了5个方向,而fulldp使能时则使用8个方向(可能需要占用大量内存);
增加了一些bm算法中的预处理和后处理程序;
gc:opencv3.0中没有实现,可以在opencv以下版本中找到。该方法效果是最好的,但是速度太慢,不能达到实时的匹配效率;
1、sgbm
主要参数:mindisparity 、numdisparities、blocksize、p1、p2。其他参数设置参照http://blog.csdn.net/zhubaohua_bupt/article/details/51866567
代码:
#include stdafx.h
#include opencv2/opencv.hpp
using namespace std;
using namespace cv;
int _tmain(int argc, _tchar* argv[])
{
mat left = imread(imgl.jpg, imread_grayscale);
mat right = imread(imgr.jpg, imread_grayscale);
mat disp;
int mindisparity = 0;
int ndisparities = 64;
int sadwindowsize = 11;
//sgbm
cv::ptr sgbm = cv::stereosgbm::create(mindisparity, ndisparities, sadwindowsize);
int p1 = 8 * left.channels() * sadwindowsize* sadwindowsize;
int p2 = 32 * left.channels() * sadwindowsize* sadwindowsize;
sgbm->setp1(p1);
sgbm->setp2(p2);
sgbm->setprefiltercap(15);
sgbm->setuniquenessratio(10);
sgbm->setspecklerange(2);
sgbm->setspecklewindowsize(100);
sgbm->setdisp12maxdiff(1);
//sgbm->setmode(cv::stereosgbm::mode_hh);
sgbm->compute(left, right, disp);
disp.convertto(disp, cv_32f, 1.0 / 16); //除以16得到真实视差值
mat disp8u = mat(disp.rows, disp.cols, cv_8uc1); //显示
normalize(disp, disp8u, 0, 255, norm_minmax, cv_8uc1);
imwrite(results/sgbm.jpg, disp8u);
return 0;
}
mindisparity:最小视差,默认为0。此参数决定左图中的像素点在右图匹配搜索的起点,int 类型;
numdisparities:视差搜索范围长度,其值必须为16的整数倍。最大视差 maxdisparity = mindisparity + numdisparities -1;
blocksize:sad代价计算窗口大小,默认为5。窗口大小为奇数,一般在3*3 到21*21之间;
p1、p2:能量函数参数,p1是相邻像素点视差增/减 1 时的惩罚系数;p2是相邻像素点视差变化值大于1时的惩罚系数。p2必须大于p1。需要指出,在动态规划时,p1和p2都是常数。
一般建议:p1 = 8*cn*sgbm.sadwindowsize*sgbm.sadwindowsize;p2 = 32*cn*sgbm.sadwindowsize*sgbm.sadwindowsize;
总结:
1. blocksize(sadwindowsize) 越小,也就是匹配代价计算的窗口越小,视差图噪声越大;blocksize越大,视差图越平滑;太大的size容易导致过平滑,并且误匹配增多,体现在视差图中空洞增多;
2. 惩罚系数控制视差图的平滑度,p2>p1,p2越大则视差图越平滑;
3. 八方向动态规划较五方向改善效果不明显,主要在图像边缘能够找到正确的匹配;
2、bm
代码:
#include stdafx.h
#include opencv2/opencv.hpp
using namespace std;
using namespace cv;
int _tmain(int argc, _tchar* argv[])
{
mat left = imread(imgl.jpg, imread_grayscale);
mat right = imread(imgr.jpg, imread_grayscale);
mat disp;
int mindisparity = 0;
int ndisparities = 64;
int sadwindowsize = 11;
cv::ptr bm = cv::stereobm::create(ndisparities, sadwindowsize);
// setter
bm->setblocksize(sadwindowsize);
bm->setmindisparity(mindisparity);
bm->setnumdisparities(ndisparities);
bm->setprefiltersize(15);
bm->setprefiltercap(31);
bm->settexturethreshold(10);
bm->setuniquenessratio(10);
bm->setdisp12maxdiff(1);
copymakeborder(left, left, 0, 0, 80, 0, ipl_border_replicate); //防止黑边
copymakeborder(right, right, 0, 0, 80, 0, ipl_border_replicate);
bm->compute(left, right, disp);
disp.convertto(disp, cv_32f, 1.0 / 16); //除以16得到真实视差值
disp = disp.colrange(80, disp.cols);
mat disp8u = mat(disp.rows, disp.cols, cv_8uc1);
normalize(disp, disp8u, 0, 255, norm_minmax, cv_8uc1);
imwrite(results/bm.jpg, disp8u);
return 0;
}
虹科分享 | 专为创意专业人士设计的Thunderbolt适配器
Testbench的基本组成和设计规则
Linux应用开发-GPS电子围栏设计
将GaN用于射频应用的所有优势
物联网的发展真的有表面看上去这么光鲜吗?
基于OpenCV3.0的BM、SGBM和GC算法对比
微型水质监测站,多参数水质在线监测系统
游戏版号申报正式重启
PCB中的玻纤效应原理分析
AP Autosar在SOA开发中的应用方法论
手机红外技术的优缺点
基于义齿压力测量的微型电容式传感器研制工艺及封装测试
总结必买小米6的四大理由──雷军好人啊!
诺基亚推出ReefShark芯片组以及对此组合的详细分析
IGBT表面的“果冻”有什么作用?
OPPOR17雾光渐变色高清图集
直流伺服电机的速度和位置控制原理是什么?
多款移动固态硬盘对比谁最好
无线电子标签RFID介绍及其应用
人脸识别校园智能系统应用于学校师生生活之中