非局部均值(NL-means)是近年來提出的一項新型的去噪技術。該方法充分利用了圖像中的冗餘信息,在去噪的同時能最大程度地保持圖像的細節特徵。基本思想是:當前像素的估計值由圖像中與它具有相似鄰域結構的像素加權平均得到。
理論上,該算法需要在整個圖像範圍內判斷像素間的相似度,也就是說,每處理一個像素點時,都要計算它與圖像中所有像素點間的相似度。但是考慮到效率問題,實現的時候,會設定兩個固定大小的窗口:搜索窗口和鄰域窗口。鄰域窗口在搜索窗口中滑動,根據鄰域間的相似性確定像素的權值。
下圖是NL-means算法執行過程,大窗口是以目標像素爲中心的搜索窗口,兩個灰色小窗口分別是以、爲中心的鄰域窗口。其中以爲中心的鄰域窗口在搜索窗口中滑動,通過計算兩個鄰域窗口間的相似程度爲賦以權值 。
NL-means執行過程
設含噪聲圖像爲,去噪後的圖像爲。中像素點處的灰度值通過如下方式得到:
其中權值表示像素點和間的相似度,它的值由以、爲中心的矩形鄰域、間的距離決定:
其中
爲歸一化係數,爲平滑參數,控制高斯函數的衰減程度。越大高斯函數變化越平緩,去噪水平越高,但同時也會導致圖像越模糊。越小,邊緣細節成分保持得越多,但會殘留過多的噪聲點。的具體取值應當以圖像中的噪聲水平爲依據。
程序:
close all;
clear all;
clc
I=double(imread('lena.tif'));
I=I+10*randn(size(I));
tic
O1=NLmeans(I,2,5,10);
toc
imshow([I,O1],[]);
function DenoisedImg=NLmeans(I,ds,Ds,h)
%I:含噪聲圖像
%ds:鄰域窗口半徑
%Ds:搜索窗口半徑
%h:高斯函數平滑參數
%DenoisedImg:去噪圖像
I=double(I);
[m,n]=size(I);
DenoisedImg=zeros(m,n);
PaddedImg = padarray(I,[ds,ds],'symmetric','both');
kernel=ones(2*ds+1,2*ds+1);
kernel=kernel./((2*ds+1)*(2*ds+1));
h2=h*h;
for i=1:m
for j=1:n
i1=i+ds;
j1=j+ds;
W1=PaddedImg(i1-ds:i1+ds,j1-ds:j1+ds);%鄰域窗口1
wmax=0;
average=0;
sweight=0;
%%搜索窗口
rmin = max(i1-Ds,ds+1);
rmax = min(i1+Ds,m+ds);
smin = max(j1-Ds,ds+1);
smax = min(j1+Ds,n+ds);
for r=rmin:rmax
for s=smin:smax
if(r==i1&&s==j1)
continue;
end
W2=PaddedImg(r-ds:r+ds,s-ds:s+ds);%鄰域窗口2
Dist2=sum(sum(kernel.*(W1-W2).*(W1-W2)));%鄰域間距離
w=exp(-Dist2/h2);
if(w>wmax)
wmax=w;
end
sweight=sweight+w;
average=average+w*PaddedImg(r,s);
end
end
average=average+wmax*PaddedImg(i1,j1);%自身取最大權值
sweight=sweight+wmax;
DenoisedImg(i,j)=average/sweight;
end
end
結果:
鑑於多位讀者向本人索取博客文檔,在此處給出下載鏈接。