半全局塊匹配(Semi-Global Block Matching)算法

最近在做雙目視差估計(jì)算法,在OpenCV里有一些算法鹦聪,其中半全局塊匹配(Semi-Global Block Matching澡匪,SGBM)算法具有視差效果好速度快的特點(diǎn),因此常常被廣泛應(yīng)用拆融。本文主要討論的就是SGBM算法蠢琳。OpenCV的SGBM算法主要參考了《Stereo Processing by Semiglobal Matching and Mutual Information》這篇論文。

1. 計(jì)算每個(gè)像素點(diǎn)的代價(jià)

原論文使用的方法是利用互信息熵镜豹,而OpenCV使用的是Birchfield和Tomasi的方法(參照《Depth Discontinuities by Pixel-to-Pixel Stereo》)傲须。這里我們分別介紹一下。

1.1 利用互信息熵

所謂的熵趟脂,是用來(lái)表示隨機(jī)變量的不確定性泰讽,熵的值越大,信息的不確定性也越大昔期。熵H和互信息MI的定義分別如下:

熵H的定義
互信息MI(Mutual Information)的定義

其中已卸,PI代表某個(gè)點(diǎn)i的概率分布,也就是灰度直方圖為i的點(diǎn)出現(xiàn)的概率硼一;對(duì)應(yīng)地累澡,PI1,I2就是兩個(gè)圖對(duì)應(yīng)點(diǎn)i1和i2的聯(lián)合概率分布,也就是:

Kim等人將上式做了一個(gè)改進(jìn):利用泰勒展開(kāi)把HI1,I2的計(jì)算轉(zhuǎn)化為求和問(wèn)題(參見(jiàn)論文《Visual Correspondence Using Energy Minimization and Mutual Information》)欠动。

其中圈中帶叉表示卷積運(yùn)算永乌,g(i,k)為高斯卷積核。

相應(yīng)地具伍,邊緣熵以及邊緣概率的計(jì)算如下:

這樣的話,互信息的定義為:

MI匹配代價(jià)CMI為:

其中q是點(diǎn)p在視差為d的情況下的對(duì)應(yīng)校正點(diǎn)圈驼。

原作者使用分層互信息(HMI)進(jìn)行計(jì)算人芽,每一層尺寸減少一半。單次計(jì)算的時(shí)間復(fù)雜度是O(WHD)绩脆,即width×height×disparity range萤厅,所以上次迭代將會(huì)是當(dāng)前迭代速度的1/8橄抹。

這里1/163要乘3的原因是小尺寸的隨機(jī)視差圖不靠譜,需要迭代3次惕味。我們可以看到楼誓,相比于后文的BT方法僅僅慢了14%

1.2 Birchfield和Tomasi的方法(簡(jiǎn)稱BT方法)

對(duì)于一個(gè)匹配序列M,其代價(jià)函數(shù)γ(M)表示匹配結(jié)果準(zhǔn)確的程度名挥,其值越小越好疟羹。

其中,κocc表示未匹配的懲罰項(xiàng)(constant occlusion penalty)禀倔,κr表示匹配的獎(jiǎng)勵(lì)項(xiàng)榄融,Nocc和Nr分別表示未匹配和匹配的點(diǎn)數(shù)。

2. 損失聚合

我們?yōu)橐暡钤O(shè)置一個(gè)能量函數(shù)E(D)

其中P1和P2分別表示視差差值為1和視差差值大于1的懲罰系數(shù)救湖,一般P1<P2愧杯。添加兩個(gè)正則化項(xiàng)一是為了保持視差圖平滑,二是為了保持邊緣鞋既。我們要做的是找到D使得能量函數(shù)E(D)最小力九,但是不幸的是,在二維圖像的這個(gè)問(wèn)題是一個(gè)NP-完全問(wèn)題邑闺。為了解決這個(gè)問(wèn)題畏邢,原文選擇沿著一圈8個(gè)或者16個(gè)方向進(jìn)行優(yōu)化。

代價(jià)聚合公式(初始為C(p,d))
圖片的代價(jià)聚合是各個(gè)像素點(diǎn)代價(jià)聚合之和

選取使代價(jià)聚合最小的視差值mindS[emb(q,d),d]即可检吆。

3. OpenCV相關(guān)函數(shù)的使用

我們看一下stereoSGBM類的參數(shù)舒萎。


static Ptr<StereoSGBM> 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的倍數(shù)
  • blockSize:匹配塊大刑稹(SADWindowSize)咆贬,必須是大于等于1的奇數(shù),一般為3~11 帚呼。
  • P1掏缎,P2:懲罰系數(shù),一般:P1=8*通道數(shù)*SADWindowSize*SADWindowSize煤杀,P2=4*P1
  • disp12MaxDiff :左右視差圖的最大容許差異(超過(guò)將被清零)眷蜈,默認(rèn)為 -1,即不執(zhí)行左右視差檢查沈自。
  • preFilterCap:預(yù)濾波圖像像素的截?cái)嘀底萌濉T撍惴ㄊ紫扔?jì)算每個(gè)像素的x導(dǎo)數(shù),并通過(guò)[-preFilterCap枯途,preFilterCap]間隔剪切其值忌怎。結(jié)果值被傳遞給Birchfield-Tomasi像素成本函數(shù)籍滴。
  • uniquenessRatio:視差唯一性百分比, 視差窗口范圍內(nèi)最低代價(jià)是次低代價(jià)的(1 + uniquenessRatio/100)倍時(shí)榴啸,最低代價(jià)對(duì)應(yīng)的視差值才是該像素點(diǎn)的視差孽惰,否則該像素點(diǎn)的視差為 0,通常為5~15.
  • speckleRange:視差變化閾值鸥印。
  • mode:模式

簡(jiǎn)單地試了一下:

#include "stdafx.h"

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\calib3d\calib3d.hpp>
#include <iostream>

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;
    }

    //圖像轉(zhuǎn)灰度
    cv::cvtColor(left, left, CV_BGR2GRAY);
    cv::cvtColor(right, right, CV_BGR2GRAY);

    //設(shè)置參數(shù)
    int numberOfDisparities = 48, SADWindowSize = 11;
    int uniquenessRatio = 15, speckleWindowSize = 50, speckleRange = 32;
    cv::Ptr<cv::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);

    //計(jì)算并顯示視差
    Mat disp;
    sgbm->compute(left, right, disp);
    disp.convertTo(disp, CV_8U, 255 / (numberOfDisparities*16.));   //將16位符號(hào)整形的視差矩陣轉(zhuǎn)換為8位無(wú)符號(hào)整形矩陣
    cv::imshow("disparity", disp);
    cv::waitKey();

    return 0;
}
左視圖
視差結(jié)果

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辅甥,一起剝皮案震驚了整個(gè)濱河市酝润,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌璃弄,老刑警劉巖要销,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異夏块,居然都是意外死亡疏咐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門脐供,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)浑塞,“玉大人,你說(shuō)我怎么就攤上這事政己∽煤荆” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵歇由,是天一觀的道長(zhǎng)卵牍。 經(jīng)常有香客問(wèn)我,道長(zhǎng)沦泌,這世上最難降的妖魔是什么糊昙? 我笑而不...
    開(kāi)封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮谢谦,結(jié)果婚禮上释牺,老公的妹妹穿的比我還像新娘。我一直安慰自己回挽,他們只是感情好没咙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著厅各,像睡著了一般镜撩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上队塘,一...
    開(kāi)封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天袁梗,我揣著相機(jī)與錄音,去河邊找鬼憔古。 笑死遮怜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鸿市。 我是一名探鬼主播锯梁,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼焰情!你這毒婦竟也來(lái)了陌凳?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤内舟,失蹤者是張志新(化名)和其女友劉穎合敦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體验游,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡充岛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了耕蝉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崔梗。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖垒在,靈堂內(nèi)的尸體忽然破棺而出蒜魄,到底是詐尸還是另有隱情,我是刑警寧澤场躯,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布谈为,位于F島的核電站,受9級(jí)特大地震影響推盛,放射性物質(zhì)發(fā)生泄漏峦阁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一耘成、第九天 我趴在偏房一處隱蔽的房頂上張望榔昔。 院中可真熱鬧,春花似錦瘪菌、人聲如沸撒会。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)诵肛。三九已至,卻和暖如春默穴,著一層夾襖步出監(jiān)牢的瞬間怔檩,已是汗流浹背褪秀。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留薛训,地道東北人媒吗。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像乙埃,于是被迫代替她去往敵國(guó)和親闸英。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容