1. 程式人生 > >影象濾波——高斯濾波原始碼

影象濾波——高斯濾波原始碼

要求

生成一個(2N+1)×(2N+1)大小的高斯模板H(標準為sigma),然後用此模板對影象進行濾波。不允許使用 fspecial 來產生高斯模板,不允許使用 imfilter、conv2 等函式。

原理及演算法

理解:高斯濾波就是對整幅影象進行加權平均的過程,每一個畫素點的值,都由其本身和鄰域內的其他畫素值經過加權平均後得到。高斯濾波的具體操作是:用一個模板(或稱卷積、掩模)掃描影象中的每一個畫素,用模板確定的鄰域內畫素的加權平均灰度值去替代模板中心畫素點的值

步驟:

1.    高斯模板公式,計算高斯模板,即實現fspecial 。

2.    實現相關運算元的imfilter;相關運算元方式 計算公式如下。W表示高斯運算元,a,b表示運算元大小。

舉例說明:

Imfilter的實現,對於非中心影象點,採用了兩種方案。方案一:直接不處理邊緣點。方案二:擴充原影象,形成一箇中間影象,根據N增加邊緣行和列,使得原影象中所有的點都可以處於運算元的中心點。

測試結果

測試結果如下:

當sigma=1.6,N=7時。

方案一的效果截圖見下圖。之前測試N=1和N=3時,效果還不錯,邊緣的噪點比較少,但是當變成N=7時,效果很差,可以很明顯地發現邊緣有很多噪點。

方案二的效果截圖見下圖。對比MATLAB自帶的imfilter預設的濾波函式,效果不錯。

思考反饋

測試的時候,使用的是彩色圖片,然後出現的測試結果見下圖。結果影象首先是灰度的,還是有三個的,所以思考良久,可能是grb通道原因,換成了灰度影象後,就可以了。/(ㄒoㄒ)/~~出問題的時候,居然一度懷疑自己演算法有問題/(ㄒoㄒ)/~~然後查看了十幾分鍾……

所以如果是彩色影象的話,是不是要分三個通道處理?還是說有其他比較好的方法。

 高斯濾波彩色影象出問題截圖
 

原始碼方案一:

clear all;

close all;

% 不處理邊緣的高斯濾波,對應文件的方案一

originimg=imread('lena.jpg');

originimg=rgb2gray(originimg);

[ori_row,ori_col]=size(originimg);


sigma = 1.6; %sigma賦值

N = 7; %大小是(2N+1)×(2N+1)

N_row = 2*N+1;


OriImage_noise = imnoise(originimg,'gaussian'); %加噪


gausFilter = fspecial('gaussian',[N_row N_row],sigma); %matlab 自帶高斯模板濾波

blur=imfilter(OriImage_noise,gausFilter,'conv');


H = []; %求高斯模板H

for i=1:N_row

for j=1:N_row

fenzi=double((i-N-1)^2+(j-N-1)^2);

H(i,j)=exp(-fenzi/(2*sigma*sigma))/(2*pi*sigma);

end

end

H=H/sum(H(:)); %歸一化


desimg=zeros(ori_row,ori_col); %濾波後圖像

for i=1:ori_row

for j=1:ori_col

desimg(i,j)=OriImage_noise(i,j);

end

end


temp=[];

for ai=N+1:ori_row-N-1

for aj=N+1:ori_col-N-1

temp=0;

for bi=1:N_row

for bj=1:N_row

temp= temp+(desimg(ai+bi-N,aj+bj-N)*H(bi,bj));

end

end

desimg(ai,aj)=temp;

end

end

desimg=uint8(desimg);



subplot(2,2,1);imshow(originimg);title('原圖');

subplot(2,2,2);imshow(OriImage_noise);title('噪聲圖');

subplot(2,2,3);imshow(desimg);title('myself高斯濾波');

subplot(2,2,4);imshow(blur);title('matlab高斯濾波');

原始碼方案二:

clear all;

close all;

% 擴充套件原影象的高斯濾波,對應文件的方案2

originimg=imread('lena.jpg');

originimg=rgb2gray(originimg);

[ori_row,ori_col]=size(originimg);


sigma = 1.6; %sigma賦值

N = 7; %大小是(2N+1)×(2N+1)

N_row = 2*N+1;


OriImage_noise = imnoise(originimg,'gaussian'); %加噪


gausFilter = fspecial('gaussian',[N_row N_row],sigma); %matlab 自帶高斯模板濾波

blur=imfilter(OriImage_noise,gausFilter,'conv');


H = []; %求高斯模板H

for i=1:N_row

for j=1:N_row

fenzi=double((i-N-1)^2+(j-N-1)^2);

H(i,j)=exp(-fenzi/(2*sigma*sigma))/(2*pi*sigma);

end

end

H=H/sum(H(:)); %歸一化


desimg=zeros(ori_row,ori_col); %濾波後圖像

midimg=zeros(ori_row+2*N,ori_col+2*N); %中間影象

for i=1:ori_row %原影象賦值給中間影象,四周邊緣設定為0

for j=1:ori_col

midimg(i+N,j+N)=OriImage_noise(i,j);

end

end

temp=[];

for ai=N+1:ori_row+N

for aj=N+1:ori_col+N

temp_row=ai-N;

temp_col=aj-N;

temp=0;

for bi=1:N_row

for bj=1:N_row

temp= temp+(midimg(temp_row+bi-1,temp_col+bj-1)*H(bi,bj));

end

end

desimg(temp_row,temp_col)=temp;

end

end

desimg=uint8(desimg);


subplot(2,2,1);imshow(originimg);title('原圖');

subplot(2,2,2);imshow(OriImage_noise);title('噪聲圖');

subplot(2,2,3);imshow(desimg);title('myself高斯濾波');

subplot(2,2,4);imshow(blur);title('matlab高斯濾波');