Matlab|数字图像处理03|图像增强(直方图均衡化处理和定制处理)和图片复原(椒盐噪声、不同滤波器、自适应中值滤波)

一.直方图均衡化处理

1.自己编写代码实验直方图的均衡化。

在这里插入图片描述
代码:

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
2.调用 matlab 中的 imadjust/imhisteq 实验对原图、对比度低的图以及对比度大的图分别进行直方图均衡化。

在这里插入图片描述
可运行代码:

% 使用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

二、直方图定制处理

读懂 HistCust_demo.m 里面的代码,然后通过灰度变换,使得一副图像与给定图像的灰度直方图近似。即:将某一图像的直方图定制为给定图像的直方图。

在这里插入图片描述

在这里插入图片描述
可运行代码:

%拓展:通过灰度变换,使得一副图像与给定图像的灰度直方图近似。即:将某一图像的直方图定制为给定图像的直方图。
%直方图规定化
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

三、图片复原

1、椒盐噪声:代码第4行(img =double(imnoise(img,‘salt & %%pepper’,0.1)))中参数0.1如果调大后去噪结果有什么变化?如果效果不好,有什么可以解决的方法吗?请尝试解决。

当参数为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('最小值滤波结果');

2、对比窗口N的取值大小对最后结果的影响

在这里插入图片描述
从上图可以看出,
(1)中值滤波比均值滤波效果更好。最大值滤波和最小值滤波效果较差,在窗口较小时几乎无法显示图像。
(2)窗口尺寸越小,细节保留的更多,但是一部分椒盐噪声还没有滤除。
(3)当窗口尺寸大时,虽然把绝大多数的噪声都滤除了,但是图像细节丢失严重。

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('自适应中值滤波去噪');

猜你喜欢

转载自blog.csdn.net/ariarko/article/details/128541323