介绍几种常见的图像去噪方法的代码实现
给出matlab的实现,可以自己移植各种语言,嵌入到项目里。
图像拉普拉斯锐化
function Image=laplacesharper(I)
I=double(I);
x=size(I,1);
y=size(I,2);
IR=I(:,:,1);
IG=I(:,:,2);
IB=I(:,:,3);
k=1;
for i=2:x-1
for j=2:y-1
IR2(i-1,j-1)=5*IR(i,j)-IR(i-1,j)-IR(i+1,j)-IR(i,j-1)-IR(i,j+1);
IG2(i-1,j-1)=5*IG(i,j)-IG(i-1,j)-IG(i+1,j)-IG(i,j-1)-IG(i,j+1);
IB2(i-1,j-1)=5*IB(i,j)-IB(i-1,j)-IB(i+1,j)-IB(i,j-1)-IB(i,j+1);
end
end
Image(:,:,1)=k*IR2;
Image(:,:,2)=k*IG2;
Image(:,:,3)=k*IB2;
Image=uint8(Image);
中值滤波
function Image=mediansmooth(I)
I=double(I);
x=size(I,1);
y=size(I,2);
IR=I(:,:,1);
IG=I(:,:,2);
IB=I(:,:,3);
k=1;
for i=2:x-1
for j=2:y-1
IR2(i-1,j-1)=median([IR(i-1,j-1),IR(i,j-1),IR(i+1,j-1),IR(i-1,j),IR(i,j),IR(i+1,j),IR(i-1,j+1),IR(i,j+1),IR(i+1,j+1)]);
IG2(i-1,j-1)=median([IG(i-1,j-1),IG(i,j-1),IG(i+1,j-1),IG(i-1,j),IG(i,j),IG(i+1,j),IG(i-1,j+1),IG(i,j+1),IG(i+1,j+1)]);
IB2(i-1,j-1)=median([IB(i-1,j-1),IB(i,j-1),IB(i+1,j-1),IB(i-1,j),IB(i,j),IB(i+1,j),IB(i-1,j+1),IB(i,j+1),IB(i+1,j+1)]);
end
end
Image(:,:,1)=k*IR2;
Image(:,:,2)=k*IG2;
Image(:,:,3)=k*IB2;
Image=uint8(Image);
非局部均值
function I_new=nonlmean(I,r,f,sigma,h)
%r:search window, so the size of window search=2*r+1
%f:similar window
I=double(I);
IR=I(:,:,1);
IG=I(:,:,2);
IB=I(:,:,3);
% h=0.55*sigma;
x=size(I,1);
y=size(I,2);
for i=1:x
for j=1:y
heightmax=min(x,i+r);
heightmin=max(1,i-r);
widthmax =min(y,j+r);
widthmin =max(1,j-r);
weight=zeros(heightmax-heightmin+1,widthmax-widthmin+1); % 一个窗的大小
for i1=heightmin:heightmax
for j1=widthmin:widthmax
d2 = 0;
count = 0;
for i2=-f:f
for j2=-f:f
if (i+i2>0 && i+i2<=x && j+j2>0 && j+j2<=y && i1+i2>0 && i1+i2<=x && j1+j2>0 && j1+j2<=y )
d2=d2+(IR(i+i2,j+j2)-IR(i1+i2,j1+j2))^2+(IG(i+i2,j+j2)-IG(i1+i2,j1+j2))^2+(IB(i+i2,j+j2)-IB(i1+i2,j1+j2))^2;
count=count+1;
end
end
end
ndist=-(max(d2-2*sigma*sigma,0)/(count*3));
weight(i1-heightmin+1,j1-widthmin+1)=exp(ndist/(h*h));
end
end
Sum_weight=sum(sum(weight));
weight=weight./Sum_weight;% 归一化
I_new(i,j,1)=sum(sum(IR(heightmin:heightmax,widthmin:widthmax).*weight));
I_new(i,j,2)=sum(sum(IG(heightmin:heightmax,widthmin:widthmax).*weight));
I_new(i,j,3)=sum(sum(IB(heightmin:heightmax,widthmin:widthmax).*weight));
end
end
测试接口
close all
clear all
clc
r=3;
f=1;
sigma=5;
h=10;
tic;
I=imread('test.jpg');
I=double(I);
Image=nonlmean(I,r,f,sigma,h);
imview(uint8(Image));
toc
其中, 非局部均值的方法是对每个点进行卷积,然后再对卷积的结果卷积,根据图像尺寸变大,计算量增加很厉害。所以推荐使用cuda, opencl, opengl shader进行计算,否则不便使用。
其他方法我接下来分享。