雙邊濾波模板主要有兩個模板生成,第一個是高斯模板,第二個是以灰度級的差值作為函數系數生成的模板。然后這兩個模板點乘就得到了最終的雙邊濾波模板。
第一個模板是全局模板,所以只需要生成一次。第二個模板需要對每個像素都計算一次,所以需要放到循環的里面來生成,這很像表面模糊啊。哦,表面模糊就是用了一個截尾濾波器。
這里的公式我參考了這里,不過她給的第二個好像不是截尾均值濾波器,而是以灰度差值為自變量的高斯濾波器。截尾均值濾波器這里有一些理論和實現,
代碼如下:
clear all; close all; clc; img=imread('lena.jpg'); img=mat2gray(img); [m n]=size(img); imshow(img); r=10; %模板半徑 imgn=zeros(m+2*r+1,n+2*r+1); imgn(r+1:m+r,r+1:n+r)=img; imgn(1:r,r+1:n+r)=img(1:r,1:n); %擴展上邊界 imgn(1:m+r,n+r+1:n+2*r+1)=imgn(1:m+r,n:n+r); %擴展右邊界 imgn(m+r+1:m+2*r+1,r+1:n+2*r+1)=imgn(m:m+r,r+1:n+2*r+1); %擴展下邊界 imgn(1:m+2*r+1,1:r)=imgn(1:m+2*r+1,r+1:2*r); %擴展左邊界 sigma_d=2; sigma_r=0.1; [x,y] = meshgrid(-r:r,-r:r); w1=exp(-(x.^2+y.^2)/(2*sigma_d^2)); %以距離作為自變量高斯濾波器 h=waitbar(0,'wait...'); for i=r+1:m+r for j=r+1:n+r w2=exp(-(imgn(i-r:i+r,j-r:j+r)-imgn(i,j)).^2/(2*sigma_r^2)); %以周圍和當前像素灰度差值作為自變量的高斯濾波器 w=w1.*w2; s=imgn(i-r:i+r,j-r:j+r).*w; imgn(i,j)=sum(sum(s))/sum(sum(w)); end waitbar(i/m); end close(h) figure; imshow(mat2gray(imgn(r+1:m+r,r+1:n+r)));
效果:
原圖
雙邊濾波后