立体匹配-ZNCC
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存储进行的装置的原因,所以,应该对应的是左图加上某个视差。
所以在调用时,进行了交换。
结果图: