function [output]=filter(input,t,f,h)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% 输入: 待平滑的图像
% t: 搜索窗口半径
% f: 相似性窗口半径
% h: 平滑参数
%
% nlmeans(ima,5,2,sigma);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 图像大小
[m n]=size(input);
% 输出
Output=zeros(m,n);
input2 = padarray(input,[f+t f+t],'symmetric');%边界作对称处理
% 高斯核
kernel = make_kernel(f);
kernel = kernel / sum(sum(kernel));
h=h*h;
beta=0.001;
dt=1/(2*1+4);
for i=1:m
for j=1:n
i1 = i+ f+t;%原始图像的像素位置 (中心像素)
j1 = j+ f+t;
W1= input2(i1-f:i1+f , j1-f:j1+f);%小窗口
wmax=0;
Rmax=0;Smax=0;
N=ones(1,5);
N(:,1)=input2(i1,j1-1); %四个邻域
N(:,2)=input2(i1,j1+1);
N(:,3)=input2(i1-1,j1);
N(:,4)=input2(i1+1,j1);
u=input2(i1,j1);
rmin=i1-t;
rmax=i1+t;
smin=j1-t;
smax=j1+t;
for r=rmin:1:rmax %大窗口
for s=smin:1:smax
if(r==i1 && s==j1) continue; end;
W2= input2(r-f:r+f , s-f:s+f); %大搜索窗口中的小相似性窗口
d = sum(sum(kernel.*(W1-W2).*(W1-W2)));
w=exp(-d/h); %权重
if w>wmax
wmax=w; %求最大权重
Rmax=r;
Smax=s;
end
end
end
N(:,5)=input2(Rmax,Smax);
num=(N-u)./(((N-u).^2 + beta).^(1/2)) ;
wei=weight(N,u,2);
output(i,j) = input2(i1,j1)+dt*sum(num.*wei);
end
end
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;
function [weight] = make_weight(ul,uk,h1) %权重函数
ex=abs(ul-uk)/h1
weight=exp(-ex.*ex);