non-local 論文及代碼復現總結

一、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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章