空域变换之图像增强以及Matlab实现(入门级学习,高手路过莫喷)
一、前述
本博客旨在对数字图像处理中的图像锐化、图像增强和边缘提取中用到的Laplace算子、Roberts算子、Prewitt算子和Sobel算子进行Matlab的直观实现,并带给读者不同的增强算子图像处理后的直观感受,理论和原理部分将会轻描淡写。
二、各空域算子原理以及Matlab实现
I.Laplace算子(拉普拉斯算子)
Laplace算子是一种二阶微分算子,其对细点细线等灰度陡峭变换的边缘特别敏感,因此在数字图像的Laplace算子卷积运算前需先对图像进行均值滤波去除高频噪声。Laplace算子的公式推导如下:
▽ 2 f = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 = f ( x + 1 , y ) + f ( x − 1 , y ) + f ( x , y + 1 ) + f ( x , y − 1 ) − 4 f ( x , y ) \bigtriangledown ^{2}f=\frac{\partial ^{2}f}{\partial x^{2}}+\frac{\partial ^{2}f}{\partial y^{2}}=f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)-4f(x,y) ▽2f=∂x2∂2f+∂y2∂2f=f(x+1,y)+f(x−1,y)+f(x,y+1)+f(x,y−1)−4f(x,y)
按照上述二阶微分算子各个空间像素的权重,得出Laplace4-领域的掩模为:
利用旋转不变性,将4-领域算子扩展为8-领域算子,则原像素的对角领域也参与到图像锐化之中,接着为了方便后续的图像增强叠加,将模板领域上各权重取反。于是Laplace8-领域掩模为:
Matlab实现过程:用Matlab2017a创建脚本编写拉普拉斯算子掩模运算流程,采用Laplace 4-领域算子和8-领域算子分别对图像进行锐化,最后与滤波后的原图叠加以达到图像增强的目的,代码部分如下:
%read RGB component
lenna=imread('C:\Users\Hasee\Desktop\timg.jpg');
figure(1);
imshow(lenna);title('origin image');
[m,n,l]=size(lenna);
sharpen_lenna = zeros(m,n,l);
sharpen_R = zeros(m,n);
sharpen_G = zeros(m,n);
sharpen_B = zeros(m,n);
laplace_lenna = zeros(m,n,l);
Laplace_R = zeros(m,n);
Laplace_G = zeros(m,n);
Laplace_B = zeros(m,n);
filter_lenna = zeros(m,n,l);
filter_R = zeros(m,n);
filter_G = zeros(m,n);
filter_B = zeros(m,n);
%RGB component normalization
R_normalize = mat2gray(lenna(:,:,1));
G_normalize = mat2gray(lenna(:,:,2));
B_normalize = mat2gray(lenna(:,:,3));
%RGB component filter
for j=2:m-1
for k=2:n-1
filter_R(j,k) = (4*R_normalize(j,k)+R_normalize(j-1,k-1)+2*R_normalize(j,k-1)+R_normalize(j+1,k-1)+2*R_normalize(j-1,k)+2*R_normalize(j+1,k)+R_normalize(j-1,k+1)+2*R_normalize(j,k+1)+R_normalize(j+1,k+1))/16;
filter_G(j,k) = (4*G_normalize(j,k)+G_normalize(j-1,k-1)+2*G_normalize(j,k-1)+G_normalize(j+1,k-1)+2*G_normalize(j-1,k)+2*G_normalize(j+1,k)+G_normalize(j-1,k+1)+2*G_normalize(j,k+1)+G_normalize(j+1,k+1))/16;
filter_B(j,k) = (4*B_normalize(j,k)+B_normalize(j-1,k-1)+2*B_normalize(j,k-1)+B_normalize(j+1,k-1)+2*B_normalize(j-1,k)+2*B_normalize(j+1,k)+B_normalize(j-1,k+1)+2*B_normalize(j,k+1)+B_normalize(j+1,k+1))/16;
end
end
filter_lenna = cat(3,filter_R,filter_G,filter_B);
figure(2);
imshow(filter_lenna);title('filter image');
% %Laplace 8-领域 算子
% for j=2:m-1
% for k=2:n-1
% Laplace_R(j,k) = (8*filter_R(j,k)-filter_R(j-1,k-1)-filter_R(j,k-1)-filter_R(j+1,k-1)-filter_R(j-1,k)-filter_R(j+1,k)-filter_R(j-1,k+1)-filter_R(j,k+1)-filter_R(j+1,k+1));
% Laplace_G(j,k) = (8*filter_G(j,k)-filter_G(j-1,k-1)-filter_G(j,k-1)-filter_G(j+1,k-1)-filter_G(j-1,k)-filter_G(j+1,k)-filter_G(j-1,k+1)-filter_G(j,k+1)-filter_G(j+1,k+1));
% Laplace_B(j,k) = (8*filter_B(j,k)-filter_B(j-1,k-1)-filter_B(j,k-1)-filter_B(j+1,k-1)-filter_B(j-1,k)-filter_B(j+1,k)-filter_B(j-1,k+1)-filter_B(j,k+1)-filter_B(j+1,k+1));
% end
% end
% laplace_lenna = cat(3,Laplace_R,Laplace_G,Laplace_B);
% figure(3);
% imshow(laplace_lenna);title('laplace 8-field image');
%Laplace 4-领域 算子
for j=2:m-1
for k=2:n-1
Laplace_R(j,k) = (4*filter_R(j,k)-filter_R(j,k-1)-filter_R(j-1,k)-filter_R(j+1,k)-filter_R(j,k+1));
Laplace_G(j,k) = (4*filter_G(j,k)-filter_G(j,k-1)-filter_G(j-1,k)-filter_G(j+1,k)-filter_G(j,k+1));
Laplace_B(j,k) = (4*filter_B(j,k)-filter_B(j,k-1)-filter_B(j-1,k)-filter_B(j+1,k)-filter_B(j,k+1));
end
end
laplace_lenna = cat(3,Laplace_R,Laplace_G,Laplace_B);
figure(3);
imshow(laplace_lenna);title('laplace 4-field image');
figure(4);
sharpen_lenna = laplace_lenna + filter_lenna;
imshow(sharpen_lenna);title('sharpen image');
运行脚本后,Laplace 4-领域算子 图像锐化和增强的结果如下:
采用Laplace 8-领域算子进行图像锐化和增强结果如下:
II.Roberts算子
Roberts交叉梯度算子,与下面将要讲到的Prewitt算子和Sobel算子都是一阶微分算子,利用一阶微分算子对于图像陡峭变化边缘以及阶梯性灰度变换边缘具有敏感性强的特点,对图像边缘进行提取。Roberts算子的推导过程如下:
M
(
x
,
y
)
=
g
x
2
+
g
y
2
M(x,y) = \sqrt{g_{x}^{2} + g_{y}^{2}}
M(x,y)=gx2+gy2,于是
M
(
x
,
y
)
≈
∣
g
x
∣
+
∣
g
y
∣
M(x,y) \approx |g_{x}| + |g_{y}|
M(x,y)≈∣gx∣+∣gy∣,因此Roberts算子的掩模为:
Matlab实现Roberts算子掩模运算代码如下:
lenna = imread('C:\Users\Hasee\Desktop\timg.jpg');
[m,n,l] = size(lenna);
Roberts_lenna = zeros(m,n,l);
r_bias = mat2gray(lenna(:,:,1));
g_bias = mat2gray(lenna(:,:,2));
b_bias = mat2gray(lenna(:,:,3));
Rob_rbias = zeros(m,n);
Rob_gbias = zeros(m,n);
Rob_bbias = zeros(m,n);
figure(1);
imshow(lenna);title('origin image');
for i=1:m-1
for j=1:n-1
Rob_rbias(i,j) = sqrt((r_bias(i+1,j+1)-r_bias(i,j))^2 + (r_bias(i,j+1)-r_bias(i+1,j))^2);
Rob_gbias(i,j) = sqrt((g_bias(i+1,j+1)-g_bias(i,j))^2 + (g_bias(i,j+1)-g_bias(i+1,j))^2);
Rob_bbias(i,j) = sqrt((b_bias(i+1,j+1)-b_bias(i,j))^2 + (b_bias(i,j+1)-b_bias(i+1,j))^2);
% Rob_rbias(i,j) = abs(r_bias(i+1,j+1)-r_bias(i,j))+abs(r_bias(i,j+1)-r_bias(i+1,j));
% Rob_gbias(i,j) = abs(g_bias(i+1,j+1)-g_bias(i,j))+abs(g_bias(i,j+1)-g_bias(i+1,j));
% Rob_bbias(i,j) = abs(b_bias(i+1,j+1)-b_bias(i,j))+abs(b_bias(i,j+1)-b_bias(i+1,j));
end
end
Roberts_lenna = cat(3,Rob_rbias,Rob_gbias,Rob_bbias);
figure(2);
imshow(Roberts_lenna);title('Roberts process');
其中,当掩模模板按照原像素位置的1范数求得时,由于线性操作,其对噪声敏感度稍强,当按照原像素位置的2范数求得时,其对噪声的敏感度相对低一些。按原像素2范数设置Roberts算子,运行结果如下所示:
按原像素1范数设置Roberts算子,运行结果如下所示:
III.Prewitt算子
由于Roberts算子是偶数维的一阶交叉梯度算子,实际操作上没有奇数维的模板好操作,而且其对噪声的敏感度比较强,因此在其基础上改进一下。Prewitt算子引入了像素的加法运算,采用3×3的模板运算,一定程度上降低的噪声敏感。Prewitt算子的推导过程如下:
M
(
x
,
y
)
=
g
x
2
+
g
y
2
M(x,y) = \sqrt{g_{x}^{2} + g_{y}^{2}}
M(x,y)=gx2+gy2,于是
M
(
x
,
y
)
≈
∣
g
x
∣
+
∣
g
y
∣
M(x,y) \approx |g_{x}| + |g_{y}|
M(x,y)≈∣gx∣+∣gy∣,因此Prewitt算子的掩模为:
Matlab实现Prewitt算子掩模运算代码如下:
lenna = imread('C:\Users\Hasee\Desktop\timg.jpg');
[m,n,l] = size(lenna);
Prewitt_lenna = zeros(m,n,l);
r_bias = mat2gray(lenna(:,:,1));
g_bias = mat2gray(lenna(:,:,2));
b_bias = mat2gray(lenna(:,:,3));
Prewi_rbias = zeros(m,n);
Prewi_gbias = zeros(m,n);
Prewi_bbias = zeros(m,n);
figure(1);
imshow(lenna);title('origin image');
for i=2:m-1
for j=2:n-1
Prewi_rbias(i,j) = sqrt((r_bias(i-1,j+1)+r_bias(i,j+1)+r_bias(i+1,j+1)-r_bias(i-1,j-1)-r_bias(i,j-1)-r_bias(i+1,j-1))^2 + (r_bias(i+1,j-1)+r_bias(i+1,j)+r_bias(i+1,j+1)-r_bias(i-1,j-1)-r_bias(i-1,j)-r_bias(i-1,j+1))^2);
Prewi_gbias(i,j) = sqrt((g_bias(i-1,j+1)+g_bias(i,j+1)+g_bias(i+1,j+1)-g_bias(i-1,j-1)-g_bias(i,j-1)-g_bias(i+1,j-1))^2 + (g_bias(i+1,j-1)+g_bias(i+1,j)+g_bias(i+1,j+1)-g_bias(i-1,j-1)-g_bias(i-1,j)-g_bias(i-1,j+1))^2);
Prewi_bbias(i,j) = sqrt((b_bias(i-1,j+1)+b_bias(i,j+1)+b_bias(i+1,j+1)-b_bias(i-1,j-1)-b_bias(i,j-1)-b_bias(i+1,j-1))^2 + (b_bias(i+1,j-1)+b_bias(i+1,j)+b_bias(i+1,j+1)-b_bias(i-1,j-1)-b_bias(i-1,j)-b_bias(i-1,j+1))^2);
% Prewi_rbias(i,j) = abs(r_bias(i-1,j+1)+r_bias(i,j+1)+r_bias(i+1,j+1)-r_bias(i-1,j-1)-r_bias(i,j-1)-r_bias(i+1,j-1)) + abs(r_bias(i+1,j-1)+r_bias(i+1,j)+r_bias(i+1,j+1)-r_bias(i-1,j-1)-r_bias(i-1,j)-r_bias(i-1,j+1));
% Prewi_gbias(i,j) = abs(g_bias(i-1,j+1)+g_bias(i,j+1)+g_bias(i+1,j+1)-g_bias(i-1,j-1)-g_bias(i,j-1)-g_bias(i+1,j-1)) + abs(g_bias(i+1,j-1)+g_bias(i+1,j)+g_bias(i+1,j+1)-g_bias(i-1,j-1)-g_bias(i-1,j)-g_bias(i-1,j+1));
% Prewi_bbias(i,j) = abs(b_bias(i-1,j+1)+b_bias(i,j+1)+b_bias(i+1,j+1)-b_bias(i-1,j-1)-b_bias(i,j-1)-b_bias(i+1,j-1)) + abs(b_bias(i+1,j-1)+b_bias(i+1,j)+b_bias(i+1,j+1)-b_bias(i-1,j-1)-b_bias(i-1,j)-b_bias(i-1,j+1));
end
end
Prewitt_lenna = cat(3,Prewi_rbias,Prewi_gbias,Prewi_gbias);
figure(2);
imshow(Prewitt_lenna);title('Prewitt process');
与Roberts算子一样,当掩模模板按照原像素位置的1范数求得时,由于线性操作,其对噪声敏感度稍强,当按照原像素位置的2范数求得时,其对噪声的敏感度相对低一些。按原像素2范数设置Prewitt算子,运行结果如下所示:
按原像素1范数设置Prewitt算子,运行结果如下所示:
IV.Sobel算子
通过Prewitt算子发现,我们也可以像加权平均滤波那样在Prewitt算子的基础上添加适当的权重,以达到进一步锐化图像的效果。Sobel算子的掩模为:
Matlab实现Sobel算子掩模运算代码如下:
lenna = imread('C:\Users\Hasee\Desktop\timg.jpg');
[m,n,l] = size(lenna);
Sobel_lenna = zeros(m,n,l);
r_bias = mat2gray(lenna(:,:,1));
g_bias = mat2gray(lenna(:,:,2));
b_bias = mat2gray(lenna(:,:,3));
Sobel_rbias = zeros(m,n);
Sobel_gbias = zeros(m,n);
Sobel_bbias = zeros(m,n);
figure(1);
imshow(lenna);title('origin image');
for i=2:m-1
for j=2:n-1
Sobel_rbias(i,j) = sqrt((r_bias(i-1,j+1)+2*r_bias(i,j+1)+r_bias(i+1,j+1)-r_bias(i-1,j-1)-2*r_bias(i,j-1)-r_bias(i+1,j-1))^2 + (r_bias(i+1,j-1)+2*r_bias(i+1,j)+r_bias(i+1,j+1)-r_bias(i-1,j-1)-2*r_bias(i-1,j)-r_bias(i-1,j+1))^2);
Sobel_gbias(i,j) = sqrt((g_bias(i-1,j+1)+2*g_bias(i,j+1)+g_bias(i+1,j+1)-g_bias(i-1,j-1)-2*g_bias(i,j-1)-g_bias(i+1,j-1))^2 + (g_bias(i+1,j-1)+2*g_bias(i+1,j)+g_bias(i+1,j+1)-g_bias(i-1,j-1)-2*g_bias(i-1,j)-g_bias(i-1,j+1))^2);
Sobel_bbias(i,j) = sqrt((b_bias(i-1,j+1)+2*b_bias(i,j+1)+b_bias(i+1,j+1)-b_bias(i-1,j-1)-2*b_bias(i,j-1)-b_bias(i+1,j-1))^2 + (b_bias(i+1,j-1)+2*b_bias(i+1,j)+b_bias(i+1,j+1)-b_bias(i-1,j-1)-2*b_bias(i-1,j)-b_bias(i-1,j+1))^2);
% Sobel_rbias(i,j) = abs(r_bias(i-1,j+1)+2*r_bias(i,j+1)+r_bias(i+1,j+1)-r_bias(i-1,j-1)-2*r_bias(i,j-1)-r_bias(i+1,j-1)) + abs(r_bias(i+1,j-1)+2*r_bias(i+1,j)+r_bias(i+1,j+1)-r_bias(i-1,j-1)-2*r_bias(i-1,j)-r_bias(i-1,j+1));
% Sobel_gbias(i,j) = abs(g_bias(i-1,j+1)+2*g_bias(i,j+1)+g_bias(i+1,j+1)-g_bias(i-1,j-1)-2*g_bias(i,j-1)-g_bias(i+1,j-1)) + abs(g_bias(i+1,j-1)+2*g_bias(i+1,j)+g_bias(i+1,j+1)-g_bias(i-1,j-1)-2*g_bias(i-1,j)-g_bias(i-1,j+1));
% Sobel_bbias(i,j) = abs(b_bias(i-1,j+1)+2*b_bias(i,j+1)+b_bias(i+1,j+1)-b_bias(i-1,j-1)-2*b_bias(i,j-1)-b_bias(i+1,j-1)) + abs(b_bias(i+1,j-1)+2*b_bias(i+1,j)+b_bias(i+1,j+1)-b_bias(i-1,j-1)-2*b_bias(i-1,j)-b_bias(i-1,j+1));
end
end
Sobel_lenna = cat(3,Sobel_rbias,Sobel_gbias,Sobel_bbias);
figure(2);
imshow(Sobel_lenna);title('Sobel process');
同样地,按原像素2范数设置Sobel算子,运行结果如下所示:
按原像素1范数设置Sobel算子,运行结果如下所示:
三、小结
通过实践不难发现,
(1)一阶梯度算子对图像边缘敏感度高且其响应时间比二阶梯度算子要宽,而二阶梯度算子对细点、细线或者线端点敏感度更高;据此特点,一阶梯度算子可以用来提取图像的边缘信息,二阶梯度算子可以增强图像的细节,达到图像锐化效果。
(2)Laplace算子由于其对细线和细点特别敏感,因此在进行Laplace算子运算之前必须要先对图像进行滤波。
(3)Roberts算子由于其算子的交叉梯度特性,其对图像中的斜线边缘会更敏感,但由于没有引入加法,Roberts算子对噪声有一定敏感度。
(4)Prewitt算子和Sobel算子中,由于Sobel算子添加了4-领域像素的权重,因此Sobel算子的效果会比Prewitt算子会更好一些,相比之下一般采用Sobel算子进行边缘提取会有更优效果。
本文地址:https://blog.csdn.net/weixin_42024702/article/details/109002733