引言:基于OpenCV3.0,對BM、SGBM和GC算法進(jìn)行了對比測試研究。由于SGBM算法視差效果好速度快的特點(diǎn),常常被廣泛應(yīng)用和改進(jìn),本文針對SGBM算法主要參數(shù)設(shè)置作了對比測試,以供大家參考。
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;長按以下二維碼可直接打開
與原方法不同點(diǎn):
沒有實(shí)現(xiàn)原文中基于互信息的匹配代價計算,而是采用BT算法("Depth Discontinuities by Pixel-to-Pixel Stereo()" by S. Birchfield and C. Tomasi);
默認(rèn)運(yùn)行單通道DP算法,只用了5個方向,而fullDP使能時則使用8個方向(可能需要占用大量內(nèi)存);
增加了一些BM算法中的預(yù)處理和后處理程序;
GC:OpenCV3.0中沒有實(shí)現(xiàn),可以在OpenCV以下版本中找到。該方法效果是最好的,但是速度太慢,不能達(dá)到實(shí)時的匹配效率;
1、SGBM
主要參數(shù):minDisparity 、numDisparities、blockSize、P1、P2。其他參數(shù)設(shè)置參照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
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得到真實(shí)視差值
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:最小視差,默認(rèn)為0。此參數(shù)決定左圖中的像素點(diǎn)在右圖匹配搜索的起點(diǎn),int 類型;
numDisparities:視差搜索范圍長度,其值必須為16的整數(shù)倍。最大視差 maxDisparity = minDisparity + numDisparities -1;
blockSize:SAD代價計算窗口大小,默認(rèn)為5。窗口大小為奇數(shù),一般在3*3 到21*21之間;
P1、P2:能量函數(shù)參數(shù),P1是相鄰像素點(diǎn)視差增/減 1 時的懲罰系數(shù);P2是相鄰像素點(diǎn)視差變化值大于1時的懲罰系數(shù)。P2必須大于P1。需要指出,在動態(tài)規(guī)劃時,P1和P2都是常數(shù)。
一般建議:P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
總結(jié):
1. blockSize(SADWindowSize) 越小,也就是匹配代價計算的窗口越小,視差圖噪聲越大;blockSize越大,視差圖越平滑;太大的size容易導(dǎo)致過平滑,并且誤匹配增多,體現(xiàn)在視差圖中空洞增多;
2. 懲罰系數(shù)控制視差圖的平滑度,P2>P1,P2越大則視差圖越平滑;
3. 八方向動態(tài)規(guī)劃較五方向改善效果不明顯,主要在圖像邊緣能夠找到正確的匹配;
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
// 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得到真實(shí)視差值
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;
}
-
機(jī)器視覺
+關(guān)注
關(guān)注
161文章
4320瀏覽量
119995 -
OpenCV
+關(guān)注
關(guān)注
29文章
624瀏覽量
41214
原文標(biāo)題:立體匹配算法對比研究
文章出處:【微信號:www_51qudong_com,微信公眾號:機(jī)器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論