淡定的CrazyDog的第一篇博客 雙目立體匹配SAD算法


  今天早上,我收拾好裝備,准備去實驗室了,結果拎包的時候不小心弄撒了紅酒,碎了滿地,我當時心里一萬頭草泥馬呼嘯而過!!!!!WTF,沒辦法,只能去找拖把,找了半天,在寢室找到一個斷了的拖把,沒辦法,只能去別的寢室借,可是我拿着別人寢室的拖把拖了沒幾下,拖把又TM斷了,而且還是同一個位置斷的!!!!!WTF!!!!我悄悄把別人寢室的拖把放回原處,裝作不知道怎么斷的樣子。回去拿着自己寢室斷掉的拖把,拖地,然后趴在地上(我要清理床下的碎屑),一點點清理碎屑和紅酒,開窗通風,撒上洗衣粉。在沒有暖氣的保護下,在飢寒交迫中支撐了1個半小時,三個字(凍成狗!!)終於沒有氣味了。阿西巴!!一上午沒有了,然后Lee給我雙目視覺論文我都沒看(其實我看不懂),回頭我上了CSDN去給自己普及一下雙目的知識,不過,這符合我crazydog的一貫風格,在本應該傷心的時候哈哈大笑,我是覺得這件事情本身很好笑

   話題扯的太遠了,我來寫一下今天的收獲和心得吧雙目匹配中最基礎的算法SAD算法。

 

 SAD 算法:SAD算法是一種最簡單的匹配算法,用公式表示為:

SAD(u,v) = Sum{|Left(u,v) - Right(u,v)|}  選擇最小值

此 種方法就是以左目圖像的源匹配點為中心,定義一個窗口D,其大小為(2m+1) (2n+1),統計其窗口的灰度值的和,然后在右目圖像中逐步計算其左右窗口的灰度和的差值,最后搜索到的差值最小的區域的中心像素即為匹配點。

基本流程:

1.構造一個小窗口,類似與卷積核。

2.用窗口覆蓋左邊的圖像,選擇出窗口覆蓋區域內的所有像素點。 

3.同樣用窗口覆蓋右邊的圖像並選擇出覆蓋區域的像素點。

4.左邊覆蓋區域減去右邊覆蓋區域,並求出所有像素點差的絕對值的和。

5.移動右邊圖像的窗口,重復3,4的動作。(這里有個搜索范圍,超過這個范圍跳出) 

6.找到這個范圍內SAD值最小的窗口,即找到了左邊圖像的最佳匹配的像素塊。

 

 

算法的流程如上面(抄襲自某CSDN博客):

上面的算法流程其實已經說的很明白了,下面我把這個算法翻譯的更加直白一點

第一步:設定一個窗口D對圖像進行鄰域求和,然后遍歷整個圖像,這樣,我們就得到了兩個計算了鄰域值的兩個矩陣,里面保存了矩陣的灰度值求和

(輸入:兩個m*n的灰度圖像

   輸出:兩個m*n的灰度矩陣,這兩個矩陣分別保存了兩個圖像在D鄰域下的灰度和

   算法: 用D窗口實現對每一個像素的滾動操作,最終生成矩陣L1和R1

 

%%滑動窗口計算
[m,n]=size(imgL1);
Dsize=8;  %滑動窗口D的size
S=30 ;    %最大的視差

dis=0;
N=Dsize/2;  %窗口大小的一半
sumL1=zeros(m,n);
sumR1=zeros(m,n);
for i=N+1:m-N
    for j=N+1:n-N
      
           sumL1(i,j)= sum(sum(imgL1((i-N):(i+N),(j-N):(j+N))));  %對D窗口內的數值進行求和
           sumR1(i,j)= sum(sum(imgR1((i-N):(i+N),(j-N):(j+N))));  
    end
end

  

 

 

第二步:搜索和匹配,在用L1的矩陣值剪掉R1的矩陣值,並求取絕對值,在視差偏移量最大的范圍內通過比較矩陣L1某個值與范圍內R1的值,並記錄下最小絕對值與偏移量

這里最小的便宜量對應了偏移量就是對應了視差圖的灰度值,這樣生成視差圖矩陣S1

(輸入:L1矩陣,R1矩陣

   輸出:S1矩陣

   算法:在視差偏移量允許范圍內,找到最佳匹配點,可以等效於求取最小代價函數scale,找到最小的數值點便確定了偏移量

 

disparity=zeros(m,n);

for i=N+1:m-N
    for j=N+1:n-N-S;
        SADsum=6666666;  scale=0.0; dis=0; 
        for k=0:1:S
            scale=abs(sumL1(i,j)-sumR1(i,j+k));
            if(scale<SADsum)
                SADsum=scale;   %尋找最小的匹配代價函數
               dis=k;         %記錄最小能量的位置
            end
        end
        disparity(i,j)=dis;   %保存
    end
end

第三步:后期處理和顯示

disparity=disparity*200/S;

dispMap=uint8(disparity);

imshow(dispMap)

  實驗結果如下:

 

 

 效果並不是很好嘛,誤差這么大的原因分析:(去看了看別人的代碼)因為兩個圖如果直接求和會造成兩個圖的數值過分大,數值太大一方面會影響運算的速度,另外一方面影響求和的精度,所以建議先實現圖像的相減操作,然后再求和,同時保存記錄好偏移量,這樣數值就不會很大了(下一篇博客,我會寫好改進的算法),同時介紹一下這一思想衍生的其他算法

 (咳咳,是我理解錯了博客的意思,我的鍋,我在第二篇博客里面會改正這個錯誤的,人都會犯錯的,求大神輕噴)

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM