您當前的位置:首頁 > 攝影

StereoVision--立體視覺(3)

作者:由 Zemo Freedom 發表于 攝影時間:2017-11-06

緊接著上次的文章,這次將詳細的說明一下立體匹配(這裡需要說明一樣,這裡所有的圖片都是存在對極約束的,也就是完成過校正,可以說對於左右兩幅影象上的匹配點,它們的y值相等,而x之間的差別就是視差d),並且會給出最近看的一些文章,以及對文章的一些理解。(PS:目前,立體匹配領域,主要有兩個評測網站,一個是KITTI(

http://www。

cvlibs。net/datasets/kit

ti/eval_stereo_flow。php?benchmark=stereo

),另一個是middlebury(

http://

vision。middlebury。edu/s

tereo/

),兩個網站上的演算法都交叉,但是又不完全一樣)

對於影象的匹配我們都知道,就是對兩幅圖片或者更多圖片,找到它們相似的地方。那麼對於立體匹配而言,就是基於同一場景得到的多張二維圖,透過找到相同點進一步還原場景的三維資訊,一般採用的影象是雙目影象,下面給出Middlebury上的一組標準圖,第一幅圖和第二幅圖分別是雙目相機得到的左圖和右圖,第三幅圖就是視差圖。可以很明顯的看出來越亮的地方表示視差越大,也就離相機越近,反之離相機也就越遠。

StereoVision--立體視覺(3)

StereoVision--立體視覺(3)

下面給出立體匹配的四個最基本的步驟:

匹配代價計算(Matching Cost Computation:CC)

代價聚合(Cost Aggregation:CA)

視差計算(Disparity Computation )

視差精化(Disparity Refinement ):對上一步得到的粗估計的視差圖進行精確計算,策略有很多,例如plane fitting,BP,動態規劃等。這裡不再熬述。

同樣的,立體匹配也分為全域性匹配和區域性匹配兩種,這兩種在匹配步驟上也有所差異。

全域性匹配

全域性立體匹配演算法一般來說會省略第二步,主要是採用了全域性的最佳化理論方法估計視差,建立全域性能量函式,透過最小化全域性能量函式得到最優視差值。其能量函式由資料項和平滑項構成。

E(d)=E_{data}(d)+E_{smooth}(d)

全域性匹配演算法得到的結果比較準確,但是其執行時間比較長,不適合實時執行。主要的演算法有圖割(graph cuts)、信念傳播(belief propagation)、動態規劃(Dynamic Programming )等演算法。

區域性匹配

基本原理是給定在一幅影象上的某一點,選取該畫素點鄰域內的一個子視窗,在另一幅影象中的一個區域內,根據某種相似性判斷依據,尋找與子視窗影象最為相似的子圖,而其匹配的子圖中對應的畫素點就為該畫素的匹配點。通常方法有SAD、SSD、NCC等等。

下面來詳細的一步一步的介紹立體匹配的每一個步驟,並且結合一個具體的例子來進行說明。

匹配代價計算

一般來說,匹配代價的計算是對左右兩幅影象的每一個畫素點而言的,可以認為定義了一個處理左右兩幅影象中匹配畫素點的函式

f(I_{L}(x,y),I_{R}(x+d,y))

,這裡的

d

是我們定義的視差範圍,也就是對於左圖中的一個畫素點

I_{L}(x,y)

,我們給它在右圖中定義一個尋找視差的範圍

d

舉個例子:假設我們對於匹配影象定義了視差的尋找範圍為0~16,也就是說

d\in(0,16)

d

是整數),對於左圖的一個畫素點

I_{L}(x,y)

在右圖中能夠計算匹配代價的區域就是

I_{R}(x+0,y)到I_{R}(x+16,y)

這之間。

我們是不是可以這樣想,對於每一個畫素點,在給定的視差範圍內,我們找到

min(f(I_{L}(x,y),I_{R}(x+d,y))),d\in(d_{min},d_{max})

,我們是不是就可以認為這個最小值就代表這是正確的匹配點,而這個最小值對應的

d

就是我們要找的視差(這一步運用的是Winner Take All: WTA策略)。如果對每一個畫素都這樣進行操作的話,我們是不是就可以得到最後的視差圖。顯然這是成立的,但是這樣做的最後的視差圖效果非常的差,在這裡可以給大家展示一下這樣簡單操作後的結果。

StereoVision--立體視覺(3)

StereoVision--立體視覺(3)

左圖(標準圖) 右圖(簡單處理後的視差圖)

代價聚合

我們從上圖中基於點之間的匹配很容易受噪聲的影響,所以我們需要在點的周圍建立一個window,讓畫素塊和畫素塊之間進行比較,這樣肯定靠譜些。代價聚合往往是區域性演算法或者半全域性演算法才會使用,全域性演算法拋棄了window,採用基於全圖資訊的方式建立能量函式。

或者說,我們換一種看法,可以看做是對匹配代價計算的結果進行濾波的一個過程。

舉個例子:假設我們有一個3*3的窗,在這個窗上進行代價聚合的函式為

g(x)

,首先看對原始左影象一個畫素點的聚合:

\sum_{(x_{L},y_{L})\in(W_{x_{L}},W_{y_{L}})}^{}{g(x_{L},y_{L})}

(結果是視窗的中心點的值),同理對於右邊的影象,需要在視差範圍內做聚合:

\sum_{(x_{R}+d,y_{R})\in(W_{x_{R}},W_{y_{R}})}^{}{g(x_{R}+d,y_{R})}

。然後,下一步就需要對處理之後的畫素計算匹配代價,並且找到它們的代價最小值:

min(f(I_{L}(x^{’},y^{’}),I_{R}((x+d)^{’},y^{’}))),d\in(d_{min},d_{max})

。我們可以看到,最後同一的公式是一個關於視差

d

的函式。

再看一看以濾波的方式來解釋,這裡我們直接對得到的視差圖進行代價聚合:

\sum_{(x_{D},y_{D})\in(W_{x_{D}},W_{y_{D}})}^{}{g(x_{D},y_{D})}

(x_{D},y_{D})

表示視差圖座標),這裡的

(x_{D},y_{D})

就是經過匹配代價計算後的畫素值。可以看到最後兩種方法的結果都是一樣的(可以使用最簡單的Box filter去驗證)。

視差計算

其實在上面兩個步驟的時候,就已經提及到了視差計算。視差計算最常用的策略就是WTA策略。這一步也可以分為區域性演算法與全域性演算法,區域性演算法直接最佳化代價聚合模型。而全域性演算法,要建立一個能量函式。輸出的是一個粗略的視差圖。

視差精化

這一步也就是對得到的視差進行最佳化的過程,通常方法都是“亞畫素求精+均值濾波”。但是不可否認的是,立體匹配最關鍵的步驟仍然是代價計算和代價聚合步驟。

下面以區域性匹配中的SAD做為例子來更好的理解立體匹配,其中著重考慮的是代價計算和代價聚合。

這裡簡單的介紹一下SAD,SAD就是Sum of Absolute differences,下面給出SAD計算公式:

C(x,y,d)=\sum_{x,y\in W}{|I_{L}(x,y),I_{R}(x+d,y)|}

下面給出實現的程式碼:

#include

#include

#include

using

namespace

std

using

namespace

cv

int

main

(){

int

hWin

=

3

//窗的大小為3*3

cout

<<

“hWin: ”

<<

hWin

<<

“; ”

<<

“compare length: ”

<<

compareLength

<<

endl

cout

<<

“SAD test”

<<

endl

Mat

left_image

=

imread

“disp2。png”

);

Mat

right_image

=

imread

“disp6。png”

);

int

imageWidth

=

left_image

cols

int

imageHeight

=

left_image

rows

//cout << left_image。size();

Mat

SAD_image

=

Mat

left_image

size

(),

CV_8UC1

1

);

Mat

MatchLevel_image

=

Mat

left_image

size

(),

CV_8UC1

1

);

//設定視差尋找範圍d為0~7

int

minDBounds

=

0

int

maxDBounds

=

7

namedWindow

“Left”

);

namedWindow

“Right”

);

namedWindow

“SAD”

);

namedWindow

“MatchLevel”

);

imshow

“Left”

left_image

);

imshow

“Right”

right_image

);

/*SAD Transform */

int

i

j

m

n

k

unsigned

char

centerPixel

=

0

unsigned

char

neighborPixel

=

0

int

bitCount

=

0

unsigned

int

bigger

=

0

int

sum

=

0

unsigned

int

*

match_level

=

new

unsigned

int

maxDBounds

-

minDBounds

+

1

];

int

temp_min

=

0

int

temp_index

=

0

unsigned

char

*

dst

unsigned

char

*

left_src

=

NULL

unsigned

char

*

right_src

=

NULL

unsigned

char

left_pixel

=

0

unsigned

char

right_pixel

=

0

unsigned

char

sub_pixel

=

0

for

i

=

0

i

<

imageHeight

i

++

{

for

j

=

0

j

<

imageWidth

j

++

{

//計算每一個畫素的SAD

for

k

=

minDBounds

k

<=

maxDBounds

k

++

{

sum

=

0

for

m

=

i

-

hWin

m

<=

i

+

hWin

m

++

{

for

n

=

j

-

hWin

n

<=

j

+

hWin

n

++

{

if

m

<

0

||

m

>=

imageHeight

||

n

<

0

||

n

>=

imageWidth

{

sub_pixel

=

0

}

else

if

n

+

k

>=

imageWidth

{

sub_pixel

=

0

}

else

{

left_src

=

unsigned

char

*

left_image

data

+

m

*

left_image

step

+

n

+

k

right_src

=

unsigned

char

*

right_image

data

+

m

*

right_image

step

+

n

left_pixel

=

*

left_src

right_pixel

=

*

right_src

if

left_pixel

>

right_pixel

{

sub_pixel

=

left_pixel

-

right_pixel

}

else

{

sub_pixel

=

right_pixel

-

left_pixel

}

}

sum

+=

sub_pixel

}

}

match_level

k

=

sum

//cout<<“SUM:”<

}

/*尋找最佳匹配點*/

temp_min

=

0

temp_index

=

0

for

m

=

1

m

<

maxDBounds

-

minDBounds

+

1

m

++

{

//cout<<“match_level[m]:”<

if

match_level

m

<

match_level

temp_index

])

{

temp_min

=

match_level

m

];

temp_index

=

m

}

}

dst

=

unsigned

char

*

SAD_image

data

+

i

*

SAD_image

step

+

j

*

dst

=

temp_index

*

8

dst

=

unsigned

char

*

MatchLevel_image

data

+

i

*

MatchLevel_image

step

+

j

*

dst

=

temp_min

}

}

imshow

“SAD”

SAD_image

);

imshow

“MatchLevel”

MatchLevel_image

);

imwrite

“MatchLevel。jpg”

MatchLevel_image

);

imwrite

“depth。jpg”

SAD_image

);

waitKey

0

);

return

0

}

下面是標準視差圖和SAD的結果圖

StereoVision--立體視覺(3)

StereoVision--立體視覺(3)

左圖(標準圖) 右圖(SAD的視差圖)

我們可以很明顯的看到,SAD的結果和最終的標準圖還是有很大的差別,圖中的有些特徵也沒有很好的還原出來。

後面將開始著重於對立體匹配文章的解讀,將一些文章的讀後感跟大家分享。

標簽: 視差  Image  SAD  Pixel  left