1.算法原理 SAD(Sum of absolute differences)是一种图像匹配算法。用公式表示为: SAD(u,v) = Sum{|Left(u,v) - Right(u,v)|} 选择最小值。基本思想:差的绝对值之和。此算法常用于图像块匹配,将每个像素对应数值之差的绝对值求和,据此评估两个图像块的相似度。该算法快速、但并不精确,通常用于多级处理的初步筛选。 2.基本流程 输入:两幅图像,一幅Left,一幅Right 对左图,依次扫描,选定一个锚点: (1)构造一个小窗口,类似于卷积核; (2)用窗口覆盖左边的图像,选择出窗口覆盖区域内的所有像素点; (3)同样用窗口覆盖右边的图像并选择出覆盖区域的像素点; (4)左边覆盖区域减去右边覆盖区域,并求出所有像素点灰度差的绝对值之和; (5)移动右边图像的窗口,重复(3)-(4)的处理(这里有个搜索范围,超过这个范围跳出); (6)找到这个范围内SAD值最小的窗口,即找到了左图锚点的最佳匹配的像素块。
下面我写一下对于这个算法的理解: 我们要构造一个窗口D分别用于覆盖左边图像和右边图像,窗口的size大小可以自己去定义,然后用D窗口圈出了AB两幅图像后,我们需要左右窗口内的选定的像素做差,然后求取其绝对值,并且对绝对值求和。在视差范围内移动窗口 ,并重复作差,求取绝对值,并求和。找到最小的匹配块,并且标记记录下来
3、参考代码
clear all clc left=double(rgb2gray(imread('left.jpg'))); right=double(rgb2gray(imread('right.jpg')));
[m n]=size(left);
w=9; %窗口半径 depth=20; %最大偏移距离,同样也是最大深度距离 imgn=zeros(m,n); for i=1+w:m-w for j=1+w+depth:n-w tmp=[]; lwin=left(i-w:i+w,j-w:j+w); for k=0:-1:-depth rwin=right(i-w:i+w,j-w+k:j+w+k); diff=lwin-rwin; tmp=[tmp sum(abs(diff(:)))]; end [junk imgn(i,j)]=min(tmp); %获得最小位置的索引 end end imshow(imgn,[]);

4、改进 (其实不难发现,算法中存在大量的冗余计算,主要体现在,你需要反复地计算出,已经计算过的差值,绝对值,求和,所以,能不能只计算一次插值呢,能不能先求取插值,比如生成一个插值图像(imgL-imgR),然后利用窗口D在插值图像上面滑动,计算和,然后在针对每个点进行匹配) (这份代码是在网上找到的,写代码还是一件费劲的事,自己还是很菜,有些地方还没看懂,慢慢努力吧…)
im1=double(rgb2gray(imread('left.jpg'))); im2=double(rgb2gray(imread('right.jpg')));
D=20; %最大视差 N=9; %窗口半径 [H,W]=size(im1);
%计算右图减去左图,相减产生D个矩阵放到imgDiff中 imgDiff=zeros(H,W,D); e=zeros(H,W); for i=1:D e(:,1:(W-i))=abs(im2(:,1:(W-i))- im1(:,(i+1):W)); e2=zeros(H,W);%计算窗口内的和 for y=(N+1):(H-N) for x=(N+1):(W-N) e2(y,x)=sum(sum(e((y-N):(y+N),(x-N):(x+N)))); end end imgDiff(:,:,i)=e2; end
%找到最小的视差,到dispMap dispMap=zeros(H,W); for x=1:W for y=1:H [val,id]=sort(imgDiff(y,x,:)); if abs(val(1)-val(2))>10 dispMap(y,x)=id(1); end end end %显示 imshow(dispMap,[]);
此程序提高了计算效率,程序运行时间大大减少。 --------------------- 作者:muzi李 来源:CSDN 原文:blog.csdn.net/laoliaixuex… 更多技术资讯可关注:itheimaGZ获取 |
|