数字图像处理——第3章 灰度变换与空间滤波
写在前面
图像在成像、采集、传输、处理等过程中不可避免的会造成某些降质。说白了就是图像可能会不清晰,采集中未突出所需部分,例如有噪音、散斑、运动模糊等等。所以我们要进行图像增强,达到我们想要的,最清晰的效果。图像增强是指对图像的某些特征如边缘、轮廓、对比度等进行强调。今天所学的灰度变换和空间滤波正是图像增强的两种方法。
同时,灰度变换和空间滤波都是在空间域进行的,也就是说直接在图像的像素上进行操作。
3.1 灰度变换
灰度变换主要针对独立的像素点进行处理,通过改变原始图像数据所占据的灰度范围而使图像在视觉上得到良好的改变。所以他属于点处理。
3.1.1 基本的灰度变换函数
r表示原图的像素值,s表示处理后的像素值。下述的实验均采用简单的opencv函数即可实现。
图像反转
使用图像反转,可得到灰度级范围为[0,L-1]的一幅图像的反转图像,该反转图像由下式给出:
s = L − 1 − r s=L-1-r s=L−1−r
其中,L表示原图中最大的像素值,使用这种变换可以反转一幅图像的灰度级,从而去突出图像暗色区域中的白色或灰色细节,特别是当黑色面积在尺寸上占主导地位时。如下图所示
对数变换
对数变换公式如下所示
s = c×log ( 1 + r ) s=\operatorname{c×log}(1+r) s=c×log(1+r)
其中c是常数,并且假设r大于等于0。此处1的作用是防止log指数大于0。对数变换可以将输入中范围较窄的低灰度值映射为输出中范围较宽的灰度值,或将输入中范围较宽的灰度值映射为输出中范围较窄的灰度值。我们使用对数变换可以用来扩展图像中的暗像素值,同时压缩更高灰度的值。反对数函数作用刚好相反。
伽玛变换
伽玛变换幂律变换,公式如下:
s = c r γ — — 其 中 γ 和 c 为 正 常 数 s=c r^{\gamma}——其中 \gamma和c为正常数 s=crγ——其中γ和c为正常数
当γ>1,且越来越大时会拉伸图像中灰度级较高的区域,压缩灰度级较低的部分,有图可知,γ越大,灰度就越密集,图中眼睛眉毛等区域可看出拉伸的效果。
分段线性变换函数–三种
(1)对比度拉伸。图像对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,即指一幅图像灰度反差的大小。一般来说对比度越大,图像越清晰醒目,色彩也越鲜明艳丽;而对比度小,则会让整个画面都灰蒙蒙的。采用这里分析特殊情况,就是g(x,y) = 255 / (B - A) ×[f(x,y) - A],其中,A = min[f(x,y)],最小灰度级;B = max[f(x,y)],最大灰度级;f(x,y)为输入图像,g(x,y)为输出图像,如果当灰度图像中最小值A=0,最大值B=255,则图像没有什么改变:
(2)灰度级分层。灰度级分层主要突出图像中特定灰度范围的亮度,这类方法中大多数是两种基本方法的变形。
①将感兴趣范围内的所有灰度值显示为一个值(如白),其他值显示为其他值(如黑)——即二值映射
②第二种方法是使感兴趣范围的灰度变亮(或变暗),而保持其他灰度级不变——即区域映射
(3)比特分割。在灰度图中,像素值的范围为[0, 255],即共有256级灰度。在计算机中,我们使用8比特数来表示每一个像素值。因此可以提取出不同比特层面的灰度图。比特层面分层可用于图片压缩。如使用高四位比特层表示原有的八层比特平面。
3.1.2 直方图处理
图像直方图反映了图像像素分布的统计特性,是图像处理中简单有效的工具。在直方图中,暗图像集中分布在灰度级的低端;亮图像集中分布在灰度级的高端。低对比度图像具有较窄的直方图,且集中于灰度级的中部;高对比度图像的直方图分量则覆盖了很宽的灰度级范围。一般灰度图才进行直方图的展示。
直方图均衡化(Histogram Equalization)
均衡化的基本原理:是把原始图的直方图变换为均匀分布的形式,这样就增加了像素灰度值的动态范围从而可达到增强图像整体对比度的效果。
均衡化步骤:
- 统计图像中每个灰度级出现的次数,计算图像中每个灰度级出现的概率;
- 根据变换公式得到直方图均衡化的变换函数;
- 根据变换函数映射到每个像素点;
- 输出映射后的图像;
'''
直方图的均衡化。可实现上述效果
'''
import cv2
from matplotlib import pyplot as plt
import numpy as np
image = cv2.imread(" ");# 读取图片,填入图片地址
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)# 将图片转成灰度图
plt.hist(gray.ravel(), 256, [0, 256])# 画出灰度图的直方图
plt.show()
equ = cv2.equalizeHist(gray)# 均衡化
plt.hist(equ.ravel(), 256, [0, 256])# 画出均衡化后的直方图
plt.show()
cv2.imshow('equalization', np.hstack((gray, equ))) # 并排显示原灰度图和均衡化后的灰度图
cv2.waitKey(0)
直方图规定化(Histogram Specification)
直方图规定化,也叫做直方图匹配。其原理为有目的的增强某个灰度区间的图像,即能够人为地修正直方图的形状,使之与期望的图像相匹配。基本步骤如下:
- 计算原图像的累积直方图
- 计算规定直方图的累积直方图
- 计算两累积直方图的差值的绝对值
- 根据累积直方图差值建立灰度级的映射
直方图规定化原理是对两个直方图都做均衡化,变成相同的归一化的均匀直方图。以此均匀直方图起到媒介作用,再对参考图像做均衡化的逆运算即可。直方图均衡化是直方图规定化的桥梁。如下图实验所示,代码参照这篇博客。
局部直方图处理
在某种意义上,像素被基于整幅图像的灰度分布的变换函数修改。虽然这种全局方法适用于整个图像的增强,但存在这样的情况,增强图像中小区域的细节也是需要的。这些区域中,一些像素的影响在全局变换的计算中可能被忽略了,因为全局变换没有必要保证期望的局部增强。解决方法是以图像中每个像素的邻域中的灰度分布为基础设计变换函数。
3.2空间滤波
空间滤波就是直接在灰度值上,做一些滤波操作。滤波是图像处理中常用的技术,可以锐化图像、模糊图像、去除噪声、增强图像等等。简单来说,就是用一个n×n的矩阵扣在图像上,用模板中每一个元素对扣住的范围中对应的像素进行数学操作,将产生的数值赋给模板中心点所对应。下图直观感受下:
3.2.1 平滑空间滤波器
平滑滤波用于模糊处理和降低噪声。模糊处理常用于预处理任务中,如在目标提取之前去除图像中的一些琐碎细节,也就是得到感兴趣的区域的粗略表示,将次要的的元素与背景融合,使得主要的元素变得易于检测。通过线性或非线性平滑滤波也可降低噪声。
均值滤波器是较简单的平滑滤波器,它使用滤波器模板确定的邻域内像素的平均值来代替图像中每个像素的值,这种处理降低了图像中尖锐的变换同时可以消除典型的随机噪声引起的剧烈变化,对于下图的3×3平滑滤波器,从它的代入式我们就可以清晰的看出他的作用:
R = 1 9 ∑ i = 1 9 z i R=\frac{1}{9} \sum_{i=1}^{9} z_{i} R=91i=1∑9zi
R是由模板定义的3×3邻域内像素灰度的平均值。下图片则可更加直观的看出上述公式:其中前面的分数分母代表着9个像素值之和。
上述说到平滑空间滤波器能够模糊处理降低噪声,那就试验下,首先给图片加上噪声,然后再用5×5的滤波器进行处理,得到的结果如下:
代码如下,毕竟一键运行的东西谁都喜欢
"""
均值滤波
"""
import numpy as np
import cv2
# 定义函数,生成噪声
def salt_pepperNoise(src):
dst = src.copy()
num = 1000 # 噪声点个数
ndim = np.ndim(src)
row, col = np.shape(src)[0:2]
for i in range(num):
x = np.random.randint(0, row) # 随机生成噪声点位置
y = np.random.randint(0, col)
indicator = np.random.randint(0, 2) # 生成随机数0和1,决定是椒噪声还是盐噪声
# 灰度图像
if ndim == 2:
if indicator == 0:
dst[x, y] = 0
else:
dst[x, y] = 255
# 彩色图像
elif ndim == 3:
if indicator == 0:
dst[x, y, :] = 0
else:
dst[x, y, :] = 255
return dst
if __name__ == '__main__':
img = cv2.imread(' ')# 填写自己图片路径
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 生成椒盐图
saltPimg = salt_pepperNoise(gray)
cv2.imshow('saltPepper', saltPimg)
# 均值滤波,使用cv2.medianBlur函数
MeanFimg = cv2.medianBlur(saltPimg, 5)
cv2.imshow('MeanFilter', MeanFimg)
cv2.waitKey(0)
同样,上述操作使用cv2.medianBlur函数完成,也可以完成高斯滤波、双边滤波,使用的函数分别为cv2.GaussianBlur()、cv2.bilateralFilter()。
3.2.2 锐化空间滤波器
平滑空间滤波器是用来平滑图像和抑制噪声的;而锐化空间滤波器恰恰相反,主要用来增强图像的突变信息,图像的细节和边缘信息。平滑滤波器主要是使用邻域的均值(或者中值)来代替模板中心的像素,消弱和邻域间的差别,以达到平滑图像和抑制噪声的目的;相反,锐化滤波器则使用邻域的微分作为算子,增大邻域间像素的差值,使图像的突变部分变的更加明显。
使用一阶微分进行图像锐化——梯度
一维函数f(x)的一阶微分的基本定义是差值:
∂ f ∂ x = f ( x + 1 ) − f ( x ) \frac{\partial f}{\partial x}=f(x+1)-f(x) ∂x∂f=f(x+1)−f(x)
图像处理中的一阶微分是用梯度幅值来实现的,梯度也就是(x,y)处f的最大变换率的方向,向量▽f的幅值表示为M(x,y),即
M ( x , y ) = mag ( ∇ f ) = g x 2 + g y 2 M(x, y)=\operatorname{mag}(\nabla f)=\sqrt{g_{x}^{2}+g_{y}^{2}} M(x,y)=mag(∇f)=gx2+gy2
通常我们在实现中,使用绝对值来近似平方和平方根操作更适合于计算:
M ( x , y ) ≈ ∣ g x ∣ + ∣ g y ∣ M(x, y) \approx\left|g_{x}\right|+\left|g_{y}\right| M(x,y)≈∣gx∣+∣gy∣
使用sobel算子对图片进行边缘检测,突出边缘和细节信息。sobel算子从不同方向上去检测梯度的变化,因此sobel算子在边缘检测上起着重要的作用,如下图所示:
使用二阶微分进行图像锐化——拉普拉斯算子
首先一个二维图像函数 f(x,y) 的拉普拉斯算子定义为:
∇ 2 f = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 \nabla^{2} f=\frac{\partial^{2} f}{\partial x^{2}}+\frac{\partial^{2} f}{\partial y^{2}} ∇2f=∂x2∂2f+∂y2∂2f
二阶微分定义为如下差分:
∂ 2 f ∂ x 2 = f ( x + 1 ) + f ( x − 1 ) − 2 f ( x ) ∂ 2 f ∂ y 2 = f ( y + 1 ) + f ( y − 1 ) − 2 f ( y ) \frac{\partial^{2} f}{\partial x^{2}}=f(x+1)+f(x-1)-2 f(x)\\ \frac{\partial^{2} f}{\partial y^{2}}=f(y+1)+f(y-1)-2 f(y) ∂x2∂2f=f(x+1)+f(x−1)−2f(x)∂y2∂2f=f(y+1)+f(y−1)−2f(y)
结合上述三个公式,可以得出离散拉普拉斯算子是:
∇ 2 f ( x , y ) = f ( x + 1 , y ) + f ( x − 1 , y ) + f ( x , y + 1 ) + f ( x , y − 1 ) − 4 f ( x , y ) \nabla^{2} \mathrm{f}(\mathrm{x}, \mathrm{y})=\mathrm{f}(\mathrm{x}+1, \mathrm{y})+\mathrm{f}(\mathrm{x}-1, \mathrm{y})+\mathrm{f}(\mathrm{x}, \mathrm{y}+1)+\mathrm{f}(\mathrm{x}, \mathrm{y}-1)-4 \mathrm{f}(\mathrm{x}, \mathrm{y}) ∇2f(x,y)=f(x+1,y)+f(x−1,y)+f(x,y+1)+f(x,y−1)−4f(x,y)
所以说拉普拉斯算子可以用来对图片进行边缘检测,也可以由下图直观感受,使用cv2.Laplacian函数:
总结
本章学习的灰度变换和空间滤波都是图像增强的一种手段,且都是在空间域中操作的。空间域处理主要分为灰度变换与空间滤波两类,灰度变换在图像的单个像素上操作,主要以对比度和阈值处理为目的。空间滤波涉及改善性能的操作,如通过图像中每一个像素的领域处理来锐化图像。
转载:https://blog.csdn.net/LLyj_/article/details/115796281