数字图像处理:直方图均衡化、空域滤波、锐化——matlab实现

一、图像直方图均衡化

1.题目解析

灰度级范围为[0,L-1]的数字图像直方图是离散函数h(rk)=nk,其中rk是第k级灰度值,nk是图像中灰度为rk的像素个数。归一化直方图就是用图像像素个数除每个分量得到。直方图操作可以用于图像增强。
直方图均衡化处理就是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。实质上是对图像进行非线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一个较平的分段直方图。

2.实现思路

(1)首先得到图像的直方图:即遍历元素,统计每一灰度级(本题图像灰度级为256)的像素个数,用向量ori存储;也可以用内置函数imhist实现;
(2)再归一化:把上步得到的原始直方图除以图像像素总数,得到向量fre;
(3)然后求累积直方图:把每一灰度级之前的所有概率加和得到向量sump,可以用循环实现,也可以使用内置函数cumsum;
(4)再将上步得到的sump使用下式进行转化计算变换后的灰度值sump:
在这里插入图片描述

(5)循环将原图像的灰度值转换后赋值给新图像;
(6)最后进行规定化处理。

3.结果

在这里插入图片描述

4.代码
%% 请大家完成直方图均衡化函数 myHisteq.m,然后将本主程序中的变量 
%% filename设置‘bridge’,运行main_histeq.m,即可得到直方图均衡化后的结果
%%
clc; 
clear;
close all;

%% 读取图片
filename = 'bridge'; %测试图像1
im = imread([filename, '.jpg']);
n_1 = 2;
n_2 = 64;
n_3 = 256;

%% 将图像进行直方图均衡化
im_histeq_1 = myHisteq(im, n_1);
im_histeq_2 = myHisteq(im, n_2);
im_histeq_3 = myHisteq(im, n_3);

%% 将结果保存到当前目录下的result文件夹下
imwrite(im_histeq_1, sprintf('result/_%s_eq_%.d.jpg', filename, n_1));
imwrite(im_histeq_2, sprintf('result/_%s_eq_%.d.jpg', filename, n_2));
imwrite(im_histeq_3, sprintf('result/_%s_eq_%.d.jpg', filename, n_3));

%% 显示结果
figure(1); 
subplot(221); imshow(im); title('原图'); axis on
subplot(222); imshow(im_histeq_1); title('直方图均衡化, n=2'); axis on
subplot(223); imshow(im_histeq_2); title('直方图均衡化, n=64'); axis on
subplot(224); imshow(im_histeq_3); title('直方图均衡化, n=256'); axis on

myHisteq.m

function [img_2] = myHisteq(img_1, n) 
%直方图均衡化
size_1 = size(img_1);
h = size_1(1);
w = size_1(2);
img_2 = uint8(zeros(h, w));

ori=zeros(1,256);
for i=1:h
    for j=1:w
        k=img_1(i,j);
        ori(k+1)=ori(k+1)+1;
    end
end
fre=zeros(1,256);
for i=1:256
    fre(i)=ori(i)/(h*w);
end

sump=cumsum(fre);
sump=round(255.*sump+0.5);
for i=1:h
    for j=1:w
        img_2(i,j)=sump(img_1(i,j)+1);
    end
end
%灰度转换
kd=256./(n-1);
de = 256/n;
for i=1:h  
     for j=1:w 
         img_2(i,j) = floor(img_2(i,j)/de)*kd;               
     end  
end  
%imshow(img_2);
end

二、图像空域滤波

1.均值滤波
1.题目解析

平滑滤波器可用于模糊处理和降低噪声,去除或衰减图像中噪声或假轮廓。均值滤波器是输出包含再滤波器模板领域内像素的简单平均值,属于低通滤波。它使用滤波器模板确定的领域内像素的平均灰度值代替图像中每个像素的值,降低了图像灰度的尖锐变化,所以可以用于降低噪声,但是由于图像边缘也是由图像灰度尖锐变化带来的特性,所以均值滤波处理有边缘模糊的缺点。

2.实现思路

(1)首先确定滤波模板,这里采用3*3大小且值全为1的模板,如下图一;
在这里插入图片描述

(2)然后进行滑动,这里我分成处理边缘两种情况:
不处理边缘:
直接从第二行第二列开始计算,以该像素点为中心,求上下左右的平均值:用im矩阵存储以此为中心的3*3像素指,然后用两次sum求和(因为模板前有1/9系数,此时的和就是平均值),赋值给存储新图像的矩阵(初值为原始图像像素值),到倒数第二行和倒数第二列为止。
在这里插入图片描述

处理边缘:
首先将img_2初始化为输入图像大小的矩阵,再扩充原图像img_1,增加两行两列(直接用第一行/列和最后一行/列的值增加即可);然后从img_2大小的第一行第一列开始进行计算:求以该像素为中心的3*3矩阵值的均值,(因为img_1已扩充,所以直接其前也有值),直至img_2的所有像素值更新。
在这里插入图片描述

3.结果

在这里插入图片描述

4.代码
%% 请大家完成两个空域滤波算法函数 myAverage.m、myMedian.m,然后将本主程序中的变量 
%% filename设置为'circuit',运行main_filter.m,即可得到结果
%%
clc; 
clear;
close all;

%% 读取图像
filename = 'circuit'; % 受到椒盐噪声污染的电路板X射线图像
im = imread([filename, '.jpg']);

%% 将图像进行均值滤波
im_a = myAverage(im);

%% 将图像进行中值滤波
im_m = myMedian(im);

%% 将结果保存到当前目录下的result文件夹下
imwrite(im_a, sprintf('result/_%s_a.jpg', filename));
imwrite(im_m, sprintf('result/_%s_m.jpg', filename));

%% 显示结果
figure(1); 
subplot(131); imshow(im); title('原图'); axis on
subplot(132); imshow(im_a); title('均值滤波'); axis on
subplot(133); imshow(im_m); title('中值滤波'); axis on

myAverage.m

function [img_2] = myAverage(img_1)  
%均值滤波
size_1 = size(img_1);
h = size_1(1);
w = size_1(2);

%3X3的均值模板
L = 1/9*[1 1 1;1 1 1;1 1 1];

% %边缘不处理
% img_2=double(img_1);
% img_1=double(img_1);
% for i=2:h-1
%     for j=2:w-1
%         im=[img_1(i-1,j-1) img_1(i-1,j) img_1(i-1,j+1);
%             img_1(i,j-1) img_1(i,j) img_1(i,j+1);
%             img_1(i+1,j-1) img_1(i+1,j) img_1(i+1,j+1)];
%         img_2(i,j)=round(sum(sum(L.*im)));
%     end
% end
% img_2=uint8(img_2);


%边缘处理
img_2 = uint8(zeros(h, w));
%边缘增加两行两列
a = img_1(1,:);%取第一行
b = img_1(h,:);%取第h行
img_1 = double([a;img_1;b]);%增加
c = img_1(:,1);%第一列
d = img_1(:,w);
img_1 = double([c,img_1,d]);
for i= 1:h
    for j = 1:w
        im = [img_1(i,j) img_1(i,j+1) img_1(i,j+2);
            img_1(i+1,j) img_1(i+1,j+1) img_1(i+1,j+2);
            img_1(i+2,j) img_1(i+2,j+1) img_1(i+2,j+2)];
        img_2(i,j) = round(sum(sum(L.*im)));
    end
end

end

2.中值滤波
1.题目解析

中值滤波其是非线性空间滤波器,这种滤波器的响应以滤波器包围的图像区域中所包含的像素的排序为基础,使用中值代替中心像素的值。对椒盐噪声较为有效。

2.实现思路

实现思路与均值滤波相同,只不过将滤波器模板换成了排序中值,可以用内置函数median来实现。

3.结果

在这里插入图片描述

4.代码

myMedian.m

function [img_2] = myMedian(img_1)
%中值滤波
size_1 = size(img_1);
h = size_1(1);
w = size_1(2); 
img_2 = uint8(zeros(h, w));

% %不处理图片边缘
% for i=2:h-1
%     for j=2:w-1
%         img_2(i,j) = median([img_1(i-1,j-1) img_1(i-1,j) img_1(i-1,j+1)...
%             img_1(i,j-1) img_1(i,j) img_1(i,j+1)...
%             img_1(i+1,j-1) img_1(i+1,j) img_1(i+1,j+1)]);
%     end
% end

%处理图片边缘
a = img_1(1,:);
b = img_1(h,:);
img_1 = [a;img_1;b];
c = img_1(:,1);
d = img_1(:,w);
img_1 = [c,img_1,d];
for i= 1:h
    for j = 1:w
        img_2(i,j) = median([img_1(i,j) img_1(i,j+1) img_1(i,j+2) img_1(i+1,j) img_1(i+1,j+1) img_1(i+1,j+2) img_1(i+2,j) img_1(i+2,j+1) img_1(i+2,j+2)]);
    end
end

end



3.图像锐化
1.题目解析

锐化处理的主要目的是突出灰度的过渡部分,可以使用数字微分和实现锐化算子的各种方法来增强图像边缘和其他突变,削弱灰度变化缓慢的区域。
本题使用二阶微分进行图像锐化——拉普拉斯算子。定义一个二阶微分的离散公式,然后构造一个基于该公式的滤波器模板。
拉普拉斯算子是线性算子,可以被表示为:
在这里插入图片描述

在离散值上可被定义为:
在这里插入图片描述

模板为:
在这里插入图片描述

2.实现思路

(1)首先确定要选用的算子:我采用上图第四个;
(2)进行滑动,我分为处理边缘与不处理两种情况:
不处理边缘:从第二行第二列开始,到h-1行w-1列结束;
处理边缘:先按照上面方法进行矩阵扩充,然后再进行计算。
计算方式:
锐化图像 g(m,n) = 原图像 f(m,n)+ 加重的边缘(α*微分)
所以没一次滑动得到的像素值为原图像+计算的值。

3.结果

在这里插入图片描述

4.代码
%% 请大家完成图像锐化函数 mySharpen.m,然后将本主程序中的变量
%% filename设置‘moon’,运行main_sharpen.m,即可得到图像锐化后的结果
%%
clc; 
clear;
close all;

%% 读取图片
filename = 'moon'; %测试图像1
im = imread([filename, '.jpg']);

%% 将图像进行锐化
im_s = mySharpen(im);

%% 将结果保存到当前目录下的result文件夹下
imwrite(im_s, sprintf('result/_%s_s.jpg', filename)); 

%% 显示结果
figure(1); 
subplot(121); imshow(im); title('原图'); axis on
subplot(122); imshow(im_s); title('图像锐化'); axis on

mySharpen.m

function [img_2] = mySharpen(img_1) 

size_1 = size(img_1);
h = size_1(1);
w = size_1(2);
img_2 = zeros(h, w);

%拉普拉斯算子
L = [-1 -1 -1;-1 8 -1;-1 -1 -1];%高通滤波
%L=[0,-1,0;-1,4,-1;0,-1,0];%四方面滤波

% %不处理边缘
% img_1=double(img_1);
% for i=2:h-1
%     for j=2:w-1
%         im=[img_1(i-1,j-1) img_1(i-1,j) img_1(i-1,j+1);
%             img_1(i,j-1) img_1(i,j) img_1(i,j+1);
%             img_1(i+1,j-1) img_1(i+1,j) img_1(i+1,j+1)];
%         img_2(i,j) = round(sum(sum(L.*im)));
%         img_2(i,j) = img_2(i,j) + img_1(i,j);
%     end
% end
% img_2=uint8(img_2);

%处理边缘
h1 = img_1(1,:);%第一行
hh = img_1(h,:);%第h行
img_1 = [h1;img_1;hh];%拓宽
r1 = img_1(:,1);%第一列
rw = img_1(:,w);%第w列
img_1 = double([r1,img_1,rw]);
for i= 1:h
    for j = 1:w
        im = [img_1(i,j) img_1(i,j+1) img_1(i,j+2);
            img_1(i+1,j) img_1(i+1,j+1) img_1(i+1,j+2);
            img_1(i+2,j) img_1(i+2,j+1) img_1(i+2,j+2)];
        img_2(i,j) = round(sum(sum(L.*im)));
        img_2(i,j) = img_2(i,j) + img_1(i+1,j+1);
    end
end
img_2=uint8(img_2);
end

三、matlab自带函数实现

clc; 
clear;
close all;
%% 内置函数实现

%% 均值化
%img_1 = imread('bridge.jpg');
% J = histeq(img_1,2);
% figure(1);
% subplot(121); imshow(img_1);  title('原始灰度图像');
% subplot(122);imshow(J); title('直方图均衡化图像');
%figure(2);
%subplot(121); imhist(I);  title('原始灰度图像直方图');
%subplot(122);imhist(J); title('直方图均衡化图像直方图');
%% 均值滤波
% I = imread('circuit.jpg');
% figure(1);
% subplot(121);imshow(I);title('原始灰度图像');
% H = fspecial('average',3);
% blurred = imfilter(I,H,'replicate'); 
% subplot(122);imshow(blurred);title('均值滤波处理图像');
%% 中值滤波
% I = imread('circuit.jpg');
% figure(1);
% subplot(121);imshow(I);title('原始灰度图像');
% H = medfilt2(I,[3 3]);
% subplot(122);imshow(H);title('中值滤波处理图像');

%% 锐化
im=imread('moon.jpg');
im_a = imsharpen(im);
subplot(121);imshow(im);title('原始图像');
subplot(122);imshow(im_a);title('锐化后图像');

四、图片

lenna.jpg:
在这里插入图片描述
circuit.jpg:
请添加图片描述

bridge.jpg:请添加图片描述

上述公式图来自冈萨雷斯的《数字图像处理第三版》。

  • 14
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值