關於雙目測距中立體匹配演算法的研究 一

2021-09-13 16:21:12 字數 3698 閱讀 2958

2.2.2 上一節中的**的具體實現

目前常用的立體匹配演算法有bm(blocking match塊匹配),sgbm(semi-global bm),gc(graph cut圖割);傳統的立體匹配演算法中,全域性匹配演算法都無法滿足實時性的要求,因此此處只對bm和sgbm這種區域性匹配法進行分析和優化,gc是全域性匹配不做介紹。

bm演算法是一種基於sad窗的區域性匹配演算法,思想是以左目影象的源匹配點為中心,定義乙個視窗d,其大小為(2m+1x2n+1),統計其視窗的灰度值的和,然後在右目影象中逐步計算其左右視窗的灰度和的差值,最後搜尋到的差值最小的區域的中心畫素即為匹配點。基於sad視窗的bm演算法的處理速度很快,理論上一副320x240的灰度圖匹配時間為30ms。實驗使用640x480的鏡頭,測算出平均耗時約為90ms。但是這種演算法只能用於處理簡單場景,對於稍微複雜的場景會存在邊緣匹配關鍵點缺失的資訊丟失問題,嚴重影響測距效能。

#include

#include

#include

using namespace std;

using namespace cv;

mat imagel, imager;

ptr bm = stereobm:

:create(32

,15);

intmain()

下面依次給出視差圖和ll.jpg以及rr,jpg;可以看出效果一般,基本不實用。同時可以看到除了輪廓資訊丟失之外,左側有一條明顯的黑色部分:資訊完全丟失。這是乙個明顯的錯誤,接下來我們分析一下產生這個黑條的原因。

這裡給出opencv中stereobm演算法的原始碼的位置:d:\opencv\sources\modules\calib3d\src(依據個人安裝路徑查詢,**太多不便貼上展示)

bm演算法一共1278行,看起來蠻嚇人的,但是仔細一分析其實沒有多麼恐怖,演算法主要由以下部分組成:

定義結構體stereobmparams;

使用opencl和不適用opencl情況下prefilternorm函式的實現,這個函式的功能是對預處理;

使用opencl和不適用opencl情況下prefilterxsobel函式的實現,這個函式的功能是對預處理;

在cpu支援cv_sse2指令集優化的情況下,findstereocorrespondencebm_sse2的函式實現;

在cpu不支援cv_sse2指令集優化的情況下,findstereocorrespondencebm的函式實現;

構造迴圈體進行平行計算prefilterinvoker;

定義stereobm的子類stereobmimpl;

在子類stereobmimpl類裡實現所有需要呼叫的函式,如compute,setmindisparity,setprefiltercap等等。

首先建立乙個智慧型指標指向stereobm的bm物件,這裡呼叫了create函式,這個函式會呼叫下面的**:

ptr stereobm:

:create

(int _numdisparities,

int _sadwindowsize)

關於makeptr函式的定義(建立智慧型指標的基本原理和智慧型指標的優點不再贅述)

template

ptrmakeptr

(const a1& a1,

const a2& a2)

因此creat函式最後返回的結果為

ptrbm指向stereobmimpl的指標;stereobmimpl是stereobm的子類,因此bm是父類指標指向了子類物件。

2. 讀取設定引數;

3. 呼叫compute函式:bm->compute(imagel, imager, disp);

函式定義為:void compute( inputarray leftarr, inputarray rightarr, outputarray disparr ),輸入的形參為左圖,右圖和用來儲存輸出的視差圖。

void

compute

(inputarray leftarr, inputarray rightarr, outputarray disparr)

mat disp = disp0;

//定義disp

if(dtype == cv_32f)

//此處型別為cv_16s,如果是32f則在此處更改為16s

int wsz = params.sadwindowsize;

//sad視窗大小

int bufsize0 =

(int)(

(ndisp +2)

*sizeof

(int))

; bufsize0 +=(

int)

((height + wsz +2)

*ndisp *

sizeof

(int))

; bufsize0 +=(

int)

((height + wsz +2)

*sizeof

(int))

; bufsize0 +=(

int)

((height + wsz +2)

*ndisp*

(wsz +2)

*sizeof

(uchar)

+256);

int bufsize1 =

(int)(

(width + params.prefiltersize +2)

*sizeof

(int)+

256)

;int bufsize2 =0;

if(params.specklerange >=

0&& params.specklewindowsize >0)

bufsize2 = width*height*

(sizeof

(point_<

short

>)+

sizeof

(int)+

sizeof

(uchar));

//to be continued

這部分首先用getmat()函式將左右兩幅inputarray型別的影象轉化成mat型別;同時disp0也是cv_16s型別的mat圖,然後prefilteredimg0建立乙個和left0一樣大的cv_8u型別的影象矩陣的矩陣體,prefilteredimg1與之相同;cost則是和left0一樣大的cv_16s型別的影象矩陣的矩陣體。定義left和right影象,分別為

prefilteredimg0和prefilteredimg1;

width1用來表示最終生成的視差圖的有效寬度,因為左圖最左側的點在右圖中沒有對應點;故視差圖中沒有這一部分,這也解釋了之前我們的疑問,為什麼最終的視差圖左側有一條明顯的額黑色的資訊缺失;這是必然出現的,而且這一部分的寬度隨著視差視窗的大小變化,視差視窗越大,則黑帶越寬。

定義wsz為sad視窗大小;

雙目立體匹配演算法漫談

雙目立體匹配演算法是計算機視覺中比較經典的問題。有大量經典的雙目立體匹配演算法。本文簡要介紹一下雙目立體匹配的常用基本流程,也可以說是套路。第一次寫這麼長的博文,我想到 寫 更詳細內容的可見文章a taxonomy and evaluation of dense two frame stereo c...

halcon的雙目立體匹配及應用概述

對要求大測量範圍和較高測量精度的場合,採用基於雙攝像機的雙目立體視覺系統比較合適 對測量範圍要求比較小,對視覺系統體積和質量要求嚴格,需要高速度實時測量物件,基於光學成像的單攝像機雙目立體視覺系統便成為最佳選擇。基於雙攝像機的雙目立體視覺系統必須安裝在乙個穩定的平台上,在進行雙目視覺系統標定以及應用...

基於深度學習演算法和傳統立體匹配演算法的雙目立體視覺

人類通過眼睛感知世界 獲取資訊。人類獲取資訊的方式有很多種,可通過眼睛 耳朵 觸覺 嗅覺 味覺等,但我們接受到的絕大部分資訊都是通過視覺的方式獲取到的。由此可見,視覺系統在人類的生存 生產 發展中起到了極其重要的作用。隨著計算機技術 智慧型機械人等的廣泛研究與應用,不少科學家嘗試將人類視覺系統功能賦...