PS=imread('C:/Users/。。。/Ch05/lenna_rgb.tif');
figure;
subplot(2,2,1);
imshow(PS)
title('输入的彩色JPG图像')
imwrite(rgb2gray(PS),'C:/Users/ark/Desktop/newwork/DIP/Ch05/lenna_gray.bmp'); %将图像灰度化并保存
PS=rgb2gray(PS); %灰度化后的数据存入数组
myHistogramEqaulization(PS)
%改写m文件
% myHistogramEqaulization.m,要求输出均衡化后的图像和变换函数
function [op]=myHistogramEqaulization(PS)
[m,n]=size(PS); %测量图像尺寸参数
GP=zeros(1,256); %预创建存放灰度出现概率的向量
for k=0:255
GP(k+1)=length(find(PS==k))/(m*n); %计算每级灰度出现的概率,将其存入GP中相应位置
end
subplot(2,2,2);
bar(0:255,GP,'g') %绘制直方图
title('原图像直方图')
xlabel('灰度值')
ylabel('出现概率')
S1=zeros(1,256);
for i=1:256
for j=1:i
S1(i)=GP(j)+S1(i); %计算Si
end
end
S2=round((S1*256)+0.5); %将Sk归到相近级的灰度(注意概率转化成灰度)
for i=1:256
GPeq(i)=sum(GP(find(S2==i))); %计算现有每个灰度级出现的概率
end
subplot(2,2,3);
bar(0:255,GPeq,'b') %显示均衡化后的直方图
title('均衡化后的直方图')
xlabel('灰度值')
ylabel('出现概率')
PA=PS;
for i=0:255
PA(find(PS==i))=S2(i+1); %将各个像素归一化后的灰度值赋给这个像素
end
subplot(2,2,4);
imshow(PA) %显示均衡化后的图像
title('均衡化后图像');
end
% 使用cell数组改写代码,使得代码更为精简
clear all; close all;clc;
I=imread('C:/Users/ark/。。。/lenna_rgb.tif'); %读入原图像
I=im2double(I); %将图象数组转换成double精度类型
%对于对比度变大的图像
I1=2*I-55/255;
%对于对比度变小的图像
I2=0.5*I+55/255;
%对于线性增加亮度的图像
I3=I+55/255;
%对于线性减小亮度的图像
I4=I-55/255;
Icell={I1,I2,I3,I4};
% A = cellfun(@mean,C)
for i=0:3
subplot(4,4,i*4+1);
imshow(Icell{i+1}),title('对比度大的原图');
subplot(4,4,i*4+2);
a=cell2mat(Icell(i+1));
imhist(a);
subplot(4,4,i*4+3),title('均衡化的图像');
% Ih=cell2mat(Icell(i+1));
imshow(histeq(Icell{i+1}));
subplot(4,4,i*4+4);
imhist(histeq(Icell{i+1})),title('均衡化后的直方图');
end
%拓展:通过灰度变换,使得一副图像与给定图像的灰度直方图近似。即:将某一图像的直方图定制为给定图像的直方图。
%直方图规定化
clear all;close all;clc;
%0. 读图像
I=imread('lenna_rgb.tif');
I=rgb2gray(I);
% figure,imshow(I),title('原图');
figure;
subplot(2,2,1);
imshow(I),title('原图');
I=double(I);
N=32;
Hist_image=hist(I(:),N);
Hist_image=Hist_image/sum(Hist_image);
Hist_image_cumulation=cumsum(Hist_image);
subplot(2,2,2);
stem([0:N-1],Hist_image),title('原图的直方图');
%1. 设计目标直方图 Index=0:N-1;
Index=0:7;
%正态分布直方图
Hist{1}=exp(-(Index-4).^2/8);
Hist{1}=Hist{1}/sum(Hist{1});
Hist_cumulation{1}=cumsum(Hist{1});
% figure;
subplot(2,2,3);
stem([0:7],Hist{1}),title('正态分布目标直方图');
%倒三角形状直方图
Hist{2}=abs(15-2*Index);
Hist{2}=Hist{2}/sum(Hist{2});
Hist_cumulation{2}=cumsum(Hist{2});
subplot(2,2,4);
stem([0:7],Hist{2}),title('倒三角形状目标直方图');
%2. 规定化处理
figure;
for m=1:2
Image=I;
%2.1 SML 处理
for k=1:N
Temp=abs(Hist_image_cumulation(k)-Hist_cumulation{m});
[Temp1,Project{m}(k)]=min(Temp);
end
%2.2 变换后直方图
for k=1:N
Temp=find(Project{m}==k);
if isempty(Temp)
Hist_result{m}(k)=0;
else
Hist_result{m}(k)=sum(Hist_image(Temp));
end
end
subplot(2,2,(m-1)*2+1),hold on;
stem([0:N-1],Hist_result{m}),title(m);
%2.3 结果图
subplot(2,2,(m-1)*2+2);
imshow(Image,[]),title(m);
end
当参数为0.1时,中值滤波基本能完全去除椒盐噪声,图像细节信息有所损失。均值滤波效果次之,最大值和最小值均值滤波的效果不好。当参数增大时,去噪效果均变差。解决办法有:可以采用基于噪声点检测的椒盐噪声去除方法[1-2]。先检测图像中的噪声点, 只对噪声点进行中值滤波, 而对非噪声点不作处理, 保留了图像信息。
[1]杨明,李晶.一种新的椒盐噪声去除方法[J].科技视界,2014(25):111.DOI:10.19694/j.cnki.issn2095-2457.2014.25.082.
[2]陈静,徐丹.一种去除灰度及彩色图像椒盐噪声的新方法[J].云南大学学报(自然科学版),2008,(06):564-568+574.
代码:
% clear all; close all;clc;
% %1. 生成含噪图像
% img = imread('lenna_gray.bmp'); figure; subplot(2,3,1),imshow(img),title('原图');
% img =double(imnoise(img,'salt & pepper',0.1));subplot(2,3,2),imshow(img,[]),title('椒盐噪声图');
%
% %2. 采用均值滤波
% N=5; %滤波模板大小
% h=fspecial('average',N); I=filter2(h,img);
% subplot(2,3,3),imshow(I,[]),title('均值滤波结果');
%
% %3. 中值滤波
% I=medfilt2(img,[N N]);
% subplot(2,3,4),imshow(I,[]),title('中值滤波结果');
%
%
% %4. 最大值滤波
% I=ordfilt2(img,N*N,true(N));
% subplot(2,3,5),imshow(I,[]),title('最大值滤波结果');
%
%
% %5.最小值滤波
% I=ordfilt2(img,1,true(N));
% subplot(2,3,6),imshow(I,[]),title('最小值滤波结果');
从上图可以看出,
(1)中值滤波比均值滤波效果更好。最大值滤波和最小值滤波效果较差,在窗口较小时几乎无法显示图像。
(2)窗口尺寸越小,细节保留的更多,但是一部分椒盐噪声还没有滤除。
(3)当窗口尺寸大时,虽然把绝大多数的噪声都滤除了,但是图像细节丢失严重。
%自编程实现中值滤波
% clear;
% n=5; %模板大小
% % image = imread('lenna_gray.bmp');
% % I=rgb2gray(image);
% I = imread('lenna_gray.bmp');
% J=imnoise(I,'salt',0.1);
% [height, width] = size(J); %获取图像尺寸
% FilterMid = J;
% for row = (n+1)/2:height-(n-1)/2
% for col = (n+1)/2:width-(n-1)/2
% temp = double(J(row-((n-1)/2):row+((n-1)/2),...
% col-((n-1)/2):col+((n-1)/2))); %获取模板区域
% %中值滤波
% template2 = sort(temp(:)); %对模板区域内像素值进行排序
% FilterMid(row, col) = template2((n*n+1)/2); %更新模板中心像素值
% end
% end
% figure ,subplot(1,3,1),imshow(I),title('原图像');
% subplot(1,3,2),imshow(J),title('加入椒盐噪声后的图像');
% subplot(1,3,3),imshow(FilterMid),title('中值滤波后的结果');
clear all;
close all;
clc;
img=imread('lenna_gray.bmp');
figure;
subplot(1,3,1);
imshow(img),title('原图像');
[m n]=size(img);
img=imnoise(img,'salt & pepper',0.1); %加入椒盐噪声
subplot(1,3,2);
imshow(img,[]),title('加入椒盐噪声后的图像');
Nmax=10; %确定最大的滤波半径
%下面是边界扩展,图像上下左右各增加Nmax像素。
imgn=zeros(m+2*Nmax+1,n+2*Nmax+1);
imgn(Nmax+1:m+Nmax,Nmax+1:n+Nmax)=img;
imgn(1:Nmax,Nmax+1:n+Nmax)=img(1:Nmax,1:n); %扩展上边界
imgn(1:m+Nmax,n+Nmax+1:n+2*Nmax+1)=imgn(1:m+Nmax,n:n+Nmax); %扩展右边界
imgn(m+Nmax+1:m+2*Nmax+1,Nmax+1:n+2*Nmax+1)=imgn(m:m+Nmax,Nmax+1:n+2*Nmax+1); %扩展下边界
imgn(1:m+2*Nmax+1,1:Nmax)=imgn(1:m+2*Nmax+1,Nmax+1:2*Nmax); %扩展左边界
re=imgn;
for i=Nmax+1:m+Nmax
for j=Nmax+1:n+Nmax
r=1; %初始滤波半径
while r~=Nmax
W=imgn(i-r:i+r,j-r:j+r);
W=sort(W);
Imin=min(W(:));
Imax=max(W(:));
Imed=W(uint8((2*r+1)^2/2));
if Imin<Imed && Imed<Imax %如果当前邻域中值不是噪声点,那么就用此次的邻域
break;
else
r=r+1; %否则扩大窗口,继续判断
end
end
if Imin<imgn(i,j) && imgn(i,j)<Imax %如果当前这个像素不是噪声,原值输出
re(i,j)=imgn(i,j);
else %否则输出邻域中值
re(i,j)=Imed;
end
end
end
subplot(1,3,3);
imshow(re(Nmax+1:m+Nmax,Nmax+1:n+Nmax),[]),title('自适应中值滤波去噪');