function [dispMap]=StereoMatching(imL, imR, windowSize, dispMin, dispMax)
% Assume the image sizes are same between imgL and imgR
%注意:在畫圖程序中,查看視差值,在相同的點,如果左圖的點的X坐標的值大於右圖X坐標的值。
%即右圖X坐標較小,在代碼中,我們的想法是利用右圖加上某個視差才能和左圖坐標相當,進行匹配
%但是,MATLAB在存儲圖像時進行了行列坐標的轉換,即384*288的圖像在MATLAB中變成288*384的矩陣
%所以,此時應該是左圖加上某個視差值和右圖進行匹配。一定要注意這一點
[wL,hL] = size(imL);
%[wR,hR] = size(imgR);
win=(windowSize-1)/2;
%NCC
for(i=1+win:1:wL-win)%從中心元素開始遍歷行(從上開始往下遍歷)
for(j=1+win:1:hL-win-dispMax) %從中心元素開始遍歷列(從左開始往右遍歷)
preNCC = 0.0;
OptimalDisp = dispMin;
for(dispRange=dispMin:1:dispMax) %X坐標加上視差值,遍歷
sumUP=0.0; currL=0.0;currR = 0.0;meanL=0.0;meanR=0.0;
sumL=0.0; sumR=0.0;
Lwin = imL(i-win:i+win, j-win:j+win);%左圖窗口
Rwin = imR(i-win:i+win, j+dispRange-win:j+dispRange+win);%右圖中心沿着視差值的窗口
meanL = mean(Lwin(:));%左圖窗口取均值
meanR = mean(Rwin(:));%右圖窗口取均值
for x=-win:win
for y=-win:win
currL = imL(i+x,j+y)-meanL;%左圖窗口中的每一個像素點減去該窗口內的均值
currR = imR(i+x,j+y+dispRange)-meanR;%左圖窗口中的每一個像素點減去該窗口內的均值,並沿視差移動
sumUP = sumUP+ currL * currR;%窗口內每個像素點減去均值后對應相乘后再累加
sumL = sumL + currL * currL;%左圖窗口內每個像素平方后再累加
sumR = sumR + currR * currR;%右圖窗口內每個像素平方后再累加
end
end
cur = sumUP/sqrt(sumL*sumR);%按照公式求相關值
if (preNCC < cur) %找出沿着視差值移動的最大相關值
preNCC = cur;
OptimalDisp = dispRange; %並記錄該最大相關值的視差值
end
end %WTA方法且沒有進行亞像素優化
dispMap(i,j) = OptimalDisp; %生成視差圖
end
end
調用代碼
function start winSize = 7; fprintf(1,'Loading Images....\n'); imL = rgb2gray(imread('right.bmp'));%注意這里由於上面的代碼中紅色注釋部分原因,所以imL代表的是右圖 imL=double(imL); imR=rgb2gray(imread('left.bmp'));%注意這里由於上面的代碼中紅色注釋部分原因,所以imR代表的是左圖 imR=double(imR); fprintf(1,'Now Processing Stereo Matching....\n'); [dispMap]=discul(imL,imR,winSize,0,52); figure; imshow(dispMap,[0 52]); figure; imagesc(dispMap); end
左圖:left.bmp
右圖:right.bmp
結論:左圖的X坐標(245)大於右圖的(230),原本應該是右圖加上某個視差和左圖進行匹配,但是MATLAB存儲進行的裝置的原因,所以,應該對應的是左圖加上某個視差。
所以在調用時,進行了交換。
結果圖: