图像处理的简单总结

  • 图像平滑:是通过降低图像中像素之间的变化来减少图像中的噪声和细节,使图像变得更加均匀和模糊。这在一些情况下很有用,如去除图像中的噪声、减少细节以改善压缩率或进行预处理以准备进行后续分析

  • 图像锐化:增强图像的高频信息,增强图像的边缘和细节,使图像看起来更清晰和有深度。

  • 图像腐蚀和膨胀:图像的膨胀和腐蚀是形态学的基本运算

    • 图像腐蚀:腐蚀就是通过卷积核,将边界部分向内部靠近,逐步腐蚀掉。其目的是缩小图像中的对象,去除对象的小细节,以及分离靠得很近的对象。腐蚀操作也使用结构元素,但与对象像素相邻的条件下,输出图像中的相应位置只有在结构元素的中心与对象像素都相邻的情况下才设置为对象像素。

      腐蚀操作会使对象变得更小,边界更加锐利,去除小的物体或细节。

    • 图像膨胀:膨胀就是通过卷积核,将边界部分向外部靠近,逐步变粗。实际上膨胀就是腐蚀的逆过程。其目的是增加图像中对象的大小,填充对象的空隙,以及连接相邻的对象。它的工作原理是用一个称为结构元素的小矩形或圆形核对原始图像进行滑动运算。如果结构元素的中心与对象像素相邻,那么在输出图像中的相应位置就会设置为对象像素。

      膨胀操作会使对象变得更大,边界更加平滑,而且可以用于连接断开的对象。

    • 开运算:是先腐蚀后膨胀,用于去除小的噪声,去除毛刺,分离紧密相邻的对象。

    • 闭运算:是先膨胀后腐蚀,用于填充对象的空隙,连接相邻的对象。

图像滤波简介

图像滤波,就是在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后面图像处理和分析的有效性和可靠性。

图像滤波按照图像域可分为两种类型:

  • 领域滤波:其本质就是数字窗口上的数学运算。一般用于图像平滑、图像锐化、特征提取(如纹理测量、边缘检测)等,邻域滤波使用邻域算子,利用给定像素周围像素值以决定此像素最终输出的一种算子。邻域滤波方式又分为线性滤波和非线性滤波,其中线性滤波包括均值滤波、方框滤波和高斯滤波等,非线性滤波包括中值滤波和双边滤波等。

  • 频域滤波:其本质是对像素频率的修改。一般用于降噪、重采样、图像压缩等。按图像频率滤除效果主要分为两种类型:低通滤波(滤除原图像的高频成分,即模糊图像边缘与细节)和高通滤波(滤除原图像的低频成分,即图像锐化,图像细节增强)。

    高频:变化剧烈的灰度分量,例如边界;低频:变化缓慢的灰度,例如一片大海

均值滤波
  • 均值滤波采用多次测量取平均的思想,用每一个像素周围的像素的平均值代替自身。均值滤波是方框滤波归一化后的特殊情况。

  • 取卷积核(kernel)区域下的所有像素的平均值来替换中心元素。

  • 优点:能够将受到噪声影响的像素使用该噪声周围的像素值进行修复,对椒盐噪声的滤除比较好。

  • 缺点:不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊。

方框滤波
  • 与均值滤波不同的是,方框滤波不会计算像素的均值。在均值滤波中,滤波结果的像素值是任意一个点的邻域平均值,等于各邻域像素值之和除以邻域面积。在方框滤波中,可以自由选择是否对均值滤波的结果进行归一化,即可以自由选择滤波结果是邻域像素值之和的平均值,还是邻域像素值之和。

  • 当normalize=True时,与均值滤波结果相同;

  • 当normalize=False时,表示对加和后的结果不进行平均操作,大于255的使用255表示。

高斯滤波
  • 高斯滤波(Gauss Filter)基于二维高斯核函数。用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。高斯滤波主要用来去除高斯噪声
  • 高斯滤波具有在保持细节的条件下进行噪声滤波的能力,因此广泛应用于图像降噪中,但其效率比均值滤波低。
中值滤波
  • 中值滤波将待处理的像素与其周围像素(包括自身)从小到大排序,取中值代替该像素。

  • 优点:去除脉冲噪声、椒盐噪声的同时又能保留图像边缘细节。

  • 缺点:当卷积核较大时,仍然使得图像变得模糊,而且计算量很大。
双边滤波
  • 因为高斯滤波把距离设为权重,设计滤波模板作为滤波系数,并且只考虑像素之间的空间位置关系,所以滤波结果丢失了边缘信息。

  • 双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。

低通滤波
  • 规则为低频信息能正常通过,而超过设定临界值的高频信息则被阻隔、减弱。但是阻隔、减弱的幅度则会依据不同的频率以及不同的滤波程序(目的)而改变。

  • 低通滤波,通过了低频信息,保留了图像背景和基本内容,图像边缘被阻挡,图像变模糊。

高通滤波
  • 规则为高频信息能正常通过,而低于设定临界值的低频信息则被阻隔、减弱。但是阻隔、减弱的幅度则会依据不同的频率以及不同的滤波程序(目的)而改变。

  • 高通滤波,通过了高频信息,提取了图像边缘和噪声。

opencv-python中各种滤波方法的应用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from PIL import Image
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np

img = cv.imread('lenna.jpg')

# 均值滤波
img_blur = cv.blur(img, (3,3)) # (3,3)代表卷积核尺寸,随着尺寸变大,图像会越来越模糊
img_blur = cv.cvtColor(img_blur, cv.COLOR_BGR2RGB) # BGR转化为RGB格式

# 方框滤波
img_boxFilter1 = cv.boxFilter(img, -1, (3,3), normalize=True) # 当 normalize=True 时,与均值滤波结果相同
img_boxFilter1 = cv.cvtColor(img_boxFilter1, cv.COLOR_BGR2RGB) # BGR转化为RGB格式

img_boxFilter2 = cv.boxFilter(img, -1, (3,3), normalize=False)
img_boxFilter2 = cv.cvtColor(img_boxFilter2, cv.COLOR_BGR2RGB) # BGR转化为RGB格式

# 高斯滤波
img_GaussianBlur= cv.GaussianBlur(img, (3,3), 0, 0) # 参数说明:(源图像,核大小,x方向的标准差,y方向的标准差)
img_GaussianBlur = cv.cvtColor(img_GaussianBlur, cv.COLOR_BGR2RGB) # BGR转化为RGB格式

# 中值滤波
img_medianBlur = cv.medianBlur(img, 3)
img_medianBlur = cv.cvtColor(img_medianBlur, cv.COLOR_BGR2RGB) # BGR转化为RGB格式

# 双边滤波
# 参数说明:(源图像,核大小,sigmaColor,sigmaSpace)
img_bilateralFilter=cv.bilateralFilter(img, 50, 100, 100)
img_bilateralFilter = cv.cvtColor(img_bilateralFilter, cv.COLOR_BGR2RGB) # BGR转化为RGB格式

titles = ['img_blur', 'img_boxFilter1', 'img_boxFilter2',
'img_GaussianBlur', 'img_medianBlur', 'img_bilateralFilter']
images = [img_blur, img_boxFilter1, img_boxFilter2, img_GaussianBlur, img_medianBlur, img_bilateralFilter]

# 低通滤波
def Low_Pass_Filter(srcImg_path):
#img = cv.imread('srcImg_path', 0)
img = np.array(Image.open(srcImg_path))
img = cv.cvtColor(img,cv.COLOR_BGR2GRAY)

# 傅里叶变换
dft = cv.dft(np.float32(img), flags = cv.DFT_COMPLEX_OUTPUT)
fshift = np.fft.fftshift(dft)

# 设置低通滤波器
rows, cols = img.shape
crow, ccol = int(rows/2), int(cols/2) # 中心位置
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1

# 掩膜图像和频谱图像乘积
f = fshift * mask

# 傅里叶逆变换
ishift = np.fft.ifftshift(f)
iimg = cv.idft(ishift)
res = cv.magnitude(iimg[:,:,0], iimg[:,:,1])

return res

# 高通滤波
def High_Pass_Filter(srcImg_path):
#img = cv.imread(srcImg_path, 0)
img = np.array(Image.open(srcImg_path))
img = cv.cvtColor(img,cv.COLOR_BGR2GRAY)

# 傅里叶变换
dft = cv.dft(np.float32(img), flags = cv.DFT_COMPLEX_OUTPUT)
fshift = np.fft.fftshift(dft)

# 设置高通滤波器
rows, cols = img.shape
crow, ccol = int(rows/2), int(cols/2) # 中心位置
mask = np.ones((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 0

# 掩膜图像和频谱图像乘积
f = fshift * mask

# 傅里叶逆变换
ishift = np.fft.ifftshift(f)
iimg = cv.idft(ishift)
res = cv.magnitude(iimg[:,:,0], iimg[:,:,1])
return res

边缘检测

图像边缘是图像最基本的特征,所谓边缘(Edge) 是指图像局部特性的不连续性。灰度或结构等信息的突变处称之为边缘。例如,灰度级的突变、颜色的突变,、纹理结构的突变等。边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像。

边缘通常可以通过一阶导数二阶导数检测得到。一阶导数是以最大值作为对应的边缘的位置,而二阶导数则以过零点作为对应边缘的位置。

  • 一阶导数的边缘算法:通过模板作为核与图像的每个像素点做卷积和运算,然后选取合适的阈值来提取图像的边缘。

    常见的有Roberts算子、Sobel算子和Prewitt算子。

  • 二阶导数的边缘算法:依据于二阶导数过零点,常见的有拉普拉斯 (Laplacian) 算子,此类算子对噪声敏感。

  • Canny算子:其是在满足一定约束条件下推导出来的边缘检测最优化算子。

图像梯度

图像梯度是边缘检测的基础知识,因此在讲边缘算子之前先复习下图像梯度的知识。

一幅图像 $f$ 在位置 $(x,y)$ 处的梯度定义如下:

因为图像是一种离散分布,因此求导其实就是做差分,$g_x$ 和 $g_y$ 定义如下:

其实上面的这两个公式可以使用下图的一维模板对图像 $f(x,y)$ 进行滤波得到。

梯度 $\nabla f$ 表示的是图像 $f$ 在位置 $(x,y)$ 处的梯度向量。梯度的方向以及梯度的大小表示如下:

梯度方向:

梯度大小:

用于计算梯度偏导数的滤波器模板,通常称之为梯度算子边缘算子边缘检测子等。

Roberts算子 (一阶)
Prewitt算子 (一阶)
Sobel算子 (一阶)
拉普拉斯算子 Laplacian (二阶)
Canny算子

Canny提出了一个对于边缘检测算法的评价标准,包括:

1) 以低的错误率检测边缘,也即意味着需要尽可能准确的捕获图像中尽可能多的边缘。
2) 检测到的边缘应精确定位在真实边缘的中心。
3) 图像中给定的边缘应只被标记一次,并且在可能的情况下,图像的噪声不应产生假的边缘。

简单来说就是,检测算法要做到:边缘要全,位置要准,抵抗噪声的能力要强。

该算子求边缘点的具体算法步骤如下:

  • (1)图像降噪,用高斯滤波器平滑图像:边缘检测算子受噪声的影响都很大。那么,我们第一步就是想到要先去除噪声,因为噪声就是灰度变化很大的地方,所以容易被识别为伪边缘。
  • (2)用一阶偏导有限差分计算梯度幅值和方向,例如 Sobel
  • (3)对梯度幅值进行非极大值抑制:sobel算子检测出来的边缘太粗了,我们需要抑制那些梯度不够大的像素点,只保留最大的梯度,从而达到瘦边的目的。通常灰度变化的地方都比较集中,将局部范围内的梯度方向上,灰度变化最大的保留下来,其它的不保留,这样可以剔除掉一大部分的点。将有多个像素宽的边缘变成一个单像素宽的边缘。即“胖边缘”变成“瘦边缘”。
  • (4)用双阈值算法检测和连接边缘:通过非极大值抑制后,仍然有很多的可能边缘点,进一步的设置一个双阈值,即低阈值(low),高阈值(high)。灰度变化大于high的,设置为强边缘像素,低于low的,剔除。在low和high之间的设置为弱边缘。对每一个弱边缘进一步判断,如果其领域内有强边缘像素,保留,如果没有,剔除。

直方图均衡化

直方图均衡化(Histogram Equalization)是一种增强图像对比度(Image Contrast)的方法,其主要思想是将一副图像的直方图分布变成近似均匀分布,从而增强图像的对比度。

直方图均衡化是将原图像通过某种变换,得到一幅灰度直方图为均匀分布的新图像的方法。

直方图均衡化方法的基本思想是对在图像中像素个数多的灰度级进行展宽,而对像素个数少的灰度级进行缩减。从而达到清晰图像的目的。

计算步骤:

  • (1)确定图像的灰度级别,彩色图像,需要将其转换为灰度图像,其中的灰度级一般是0-255
  • (2)计算图像归一化后的灰度直方图:统计每个灰度在原始图像上的像素所占总体的比例
  • (3)计算每个灰度值对应的累计概率密度,也就是计算累计直方图 $S(i)$
  • (4)根据公式求取像素映射关系:$SS(i) = 255 \times S(i)(需要取整),其中255就是灰度级$
  • (5)将原始灰度值带入公式就得到了他对应的新的灰度值。可以看出数量比较少的灰度值就会映射到同一个灰度,而且灰度直方图也会被拉开,对比度提高。