一、NLmeansfilter 函數
function [output]=NLmeansfilter(input,t,f,h)
% input: 處理的圖像
% t: 搜索窗的半徑
% f: 相似窗的半徑
% h: 濾波參數
[m,n]=size(input);%圖像的範圍
output=zeros(m,n);
input2=padarray(input,[f f],'symmetric');%便於後面控制邊界的處理
kernel=make_kernel(f);
kernel=kernel/sum(sum(kernel));%高斯濾波器
for i=1:m
for j=1:n
i1=i+f;
j1=j+f;
W1=input2(i1-f:i1+f,j1-f:j1+f);%使用2f+1區域
wmax=0;
average=0;
sweight=0;
rmin=max(i1-t,f+1);
rmax=min(i1+t,m+f);
smin=max(j1-t,f+1);%不斷變化搜索窗的大小
smax=min(j1+t,n+f);%之前始終沒懂這裏是幹什麼的,用於控制搜索窗口的移動
%遍歷搜索21*21的區域
for r=rmin:1:rmax
for s=smin:1:smax
if(r==i1&&s==j1)%遍歷搜索,若遇到的相同的像素跳過
%以r,s的像素爲中心計算高斯加權歐式距離
continue;
end
W2=input2(r-f:r+f,s-f:s+f);%相同大小的區域,2f+1的區域
d=sum(sum(kernel.*(W1-W2)^2));%兩個2f+1區域的高斯加權歐式距離計算
w=exp(-d/h^2);%像素點(r-f,s-f)的權值
if(w>wmax)
wmax=w;
end
sweight=sweight+w;%計算除像素點(i,j)之外的所有點的權值,便於後面計算平均值
average=average+w*input2(r,s);%所有權重的加權和的計算
end
end
average=average+wmax*input2(i1,j1);%search window的權值,中心的值賦給最大的權重
sweight=sweight+wmax;
if(sweight>0)
output(i,j)=average/sweight;%求加權後的平均
else
output(i,j)=input(i,j);%判斷權值是否爲0
end
end
end
1、之前看這個代碼,始終沒看懂搜索窗的移動的控制,用max,min 兩個函數控制起始的情況,之後的情況則始終大於f+1,關鍵在於起始條件的控制
2、對於高斯加權歐式距離計算的理解,實際上是高斯核卷積的過程,W1-W2計算出兩個領域的每個點的歐式距離,高斯核賦予不同的權重,其實從代碼中也可以看出,歐式距離越遠的點所佔的權重越小,中心點的賦予的權重最大
二、高斯核的函數
function [kernel]=make_kernel(f)%高斯濾波窗口函數
kernel=zeros(2*f+1,2*f+1);
for d=1:f
value=1/(2*d+1)^2;
for i=-d:d
for j=-d:d
kernel(f+1-i,f+1-j)=kernel(f+1-i,f+1-j)+value;
end
end
end
kernel=kernel./f;
1、注意高斯函數注意理解value的用處,用於歸一化的處理,d代表離中心點的距離,離中心點越遠,value 值越小
2、使用2f+1的原因是因爲相似窗的半徑爲f,所以高斯核以及領域計算時應該使用2f+1,注意細節
三、demo
clear
clc
clf
colormap(gray)
% create example image
ima=100*ones(100);
ima(50:100,:)=50;
ima(:,50:100)=2*ima(:,50:100);
fs=fspecial('average');
ima=imfilter(ima,fs,'symmetric');
% add some noise
sigma=10;
rima=ima+sigma*randn(size(ima));
% show it
imagesc(rima)
drawnow
% denoise it
fima=NLmeansfilter(ima,5,2,sigma);
% show results
clf
subplot(2,2,1),imagesc(ima),title('original');
subplot(2,2,2),imagesc(rima),title('noisy');
subplot(2,2,3),imagesc(fima),title('filtered');
subplot(2,2,4),imagesc(rima-fima),title('residuals');
demo通過創建一幅圖像後,先加上噪聲,之後再除噪聲
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
看了代碼進行復現後對於non-local的理解也更深了,關鍵思想在於非局部尋找相似的區域,而是在整幅圖像尋找相似的區域,並利用高斯加權歐式距離進行權重賦值,而實現過程中爲了避免重複的尋找,運用一個搜索窗與相似窗來計算
同時學到了高斯加權歐式距離的計算,高斯核的代碼實現,注意代碼相關的細節控制
該算法對於紋理區域以及週期性結構區域的去噪的效果較好,因爲在這類的圖像區域內,search window中能夠找到較多的相似的區域,更能發揮算法的特點
四、算法複雜度總結
關於算法複雜度,作者在論文中也有所提及,設搜索窗的大小爲21*21,相似窗的大小爲7*7,圖像的大小爲N^2,則算法複雜度爲49*441*N^2,因此設搜索窗爲M*M,相似窗爲L*L,圖像大小爲N*N,算法複雜度爲M^2*L^2*N^2