目录
一、图像滤波
卷积核
卷积核大小,一般为奇数,如
-
3*3
-
5*5
-
7*7
为什么卷积核大小是奇数?
原因:保证锚点在中间,防止位置发生偏移
卷积核大小的影响
在深度学习中,卷积核越大,看到的信息越多,提取的特征越好,同时计算量越大
二、图像平滑处理
图像噪声的定义和性质
图像噪声是指存在于图像数据中的不必要的或多余的干扰信息。它妨碍了人们通过视觉器官对接收信息的理解。噪声在理论上可以定义为“不可预测,只能用概率统计方法来认识的随机误差”。因此,将图像噪声看成是多维随机过程是合适的,描述噪声的方法可以借用随机过程的描述,即用其概率分布函数和概率密度分布函数。
图像噪声的分类
图像噪声可以根据其来源和性质进行分类。主要分为外部噪声和内部噪声。外部噪声是由外部环境因素引起的,如光线变化、电磁干扰等。内部噪声则是由设备本身的因素引起的,如传感器噪声、电路噪声等。
图像噪声的产生原因
图像噪声的产生原因多种多样,主要包括以下几个方面:
-
传感器和电路产生的噪声:扫描仪或数码相机的传感器和电路可能会产生电子噪声,导致图像中出现噪点。
-
长时间曝光:在拍摄夜景时,由于CCD无法处理较慢的快门速度所带来的巨大工作量,导致一些特定的像素失去控制,产生噪点。
-
格式压缩:使用JPEG格式对图像进行压缩时,由于图像数据的处理方式,可能会在边缘位置产生不自然的结合,形成噪点。
-
感光元件特性:感光元件的热稳定性等特性也可能导致噪点的产生。
图像噪声的影响和解决方法
图像噪声的存在严重影响了图像的质量,使得图像中的信息变得模糊和不清晰。为了减少图像中的噪声,可以采取一些专业的图像处理技术,如图像降噪(Image Denoising),通过减少数字图像中的噪声来提高图像的质量。
图像平滑处理的一个例子是减少图像中的噪声。比如,在拍摄夜间照片时,由于光线不足,图像可能出现许多随机噪点。通过应用平滑处理(如高斯模糊),可以降低这些噪点的影响,从而使图像看起来更清晰,细节更突出。这有助于后续的图像分析或特征提取,提升最终结果的准确性
常见的图像平滑处理方法包括高斯滤波、中值滤波和双边滤波。
1、高斯滤波
高斯滤波是图像处理中常用的一种平滑滤波方法,其主要作用是去除图像中的噪声,并减少图像细节,以实现图像的平滑处理。
高斯滤波的原理是利用高斯函数对图像进行加权平均。在滤波过程中,每个像素的值都会被其周围像素的加权平均值所取代,而这些权重则由高斯分布函数计算得出。通过这种方式,高斯滤波可以有效地减少图像中的噪声,并保留图像的整体特征。
高斯滤波的使用场景包括但不限于:
-
去除高斯噪声: 高斯滤波可以有效地去除高斯噪声,因为该滤波器在计算像素值时会对周围像素进行加权平均,从而抑制噪声的影响。
-
模糊处理: 由于高斯滤波会平均周围像素的值,因此它也可用于实现图像的模糊处理,例如在某些需求下需要模糊化处理的图像或区域。
-
提取大致轮廓: 由于高斯滤波会平滑图像细节,因此在一定程度上可以帮助提取图像的大致轮廓和结构特征。
import cv2
img = cv2.imread('../images/renwu01.jpeg')
"""
高斯滤波
主要作用是去除图像中的噪声,并减少图像细节,以实现图像的平滑处理
1. 去除高斯噪声:高斯滤波可以有效地去除高斯噪声,因为该滤波器在计算像素值时会对周围像素进行加权平均,从而抑制噪声的影响。
2. 模糊处理:由于高斯滤波会平均周围像素的值,因此它也可用于实现图像的模糊处理,例如在某些需求下需要模糊化处理的图像或区域。
3. 提取大致轮廓:由于高斯滤波会平滑图像细节,因此在一定程度上可以帮助提取图像的大致轮廓和结构特征。
"""
# 定义滤波参数
# 高斯核 必须是奇数
k = (11, 11)
# 标准差
d = 1
# 高斯去噪
gauss_img = cv2.GaussianBlur(img, k, d)
# 显示
cv2.imshow('old', img)
cv2.imshow('gauss_img', gauss_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2、双边滤波
双边滤波是图像处理中常用的一种平滑滤波方法,它可以同时平滑图像并保留边缘信息。
传统的线性滤波方法如均值滤波或高斯滤波在平滑图像的同时,可能会模糊或模糊边缘。而双边滤波通过考虑像素点的空间距离和灰度差异,实现了对图像进行平滑的同时,尽量保留图像的边缘细节。
双边滤波的原理是在滤波过程中,不仅考虑像素点与周围像素点之间的空间距离权重,还考虑像素点与周围像素点的灰度差异权重。这样,像素点的最终值将由它的邻域像素根据这两个权重的组合来计算得出,从而平滑图像的同时保留边缘信息。
双边滤波适用于各种类型的图像,特别适合于那些需要平滑处理但仍保留边缘细节的图像,例如人脸识别、图像增强和图像去噪等领域。
import cv2
img = cv2.imread('../images/renwu01.jpeg')
"""
双边滤波
图像处理中常用的一种平滑滤波方法,它可以同时平滑图像并保留边缘信息
适用于各种类型的图像,特别适合于那些需要平滑处理但仍保留边缘细节的图像,例如人脸识别、图像增强和图像去噪等领域
"""
# 定义双边滤波参数
"""
滤波器的直径
指定在每个像素周围考虑的像素邻域大小
"""
c = 30
"""
颜色权重 颜色空间的标准差
大color值:滤波器会在更大范围内进行平滑处理,导致图像细节的丢失较多
小color值:滤波器主要在颜色相似的区域内进行平滑处理,这样可以更好地保留边缘和细节
"""
color = 100
"""
事件权重 坐标空间的标准差
大space值:滤波器会在更大的空间范围内进行平滑处理,导致图像的局部细节被进一步平滑
小space值:主要在局部范围内进行平滑处理,这样可以更好地保留局部细节和边缘信息
"""
space = 150
# 双边滤波
bilateral_img = cv2.bilateralFilter(img, c, color, space)
# 显示图片
cv2.imshow('old', img)
cv2.imshow('bilateral', bilateral_img)
cv2.waitKey()
cv2.destroyAllWindows()
3、中值滤波
中值滤波是图像处理中常用的一种平滑滤波方法,其主要作用是去除图像中的胡椒噪声或其他类型的脉冲噪声。
中值滤波的原理是将每个像素点周围的邻域像素按照灰度值大小进行排序,然后取中间值作为该像素点的输出值。因为椒盐噪声或脉冲噪声的灰度值通常远远偏离周围像素的灰度值,通过中值滤波可以有效地将这些异常值去除,从而使图像变得更加平滑。
中值滤波适用于各种类型的图像,特别适合于那些受到椒盐噪声干扰的图像,例如传感器捕获的图像或者在传输过程中受到干扰的图像。
import cv2
"""
中值滤波
去除图像中的胡椒噪声或其他类型的脉冲噪声
"""
img = cv2.imread('../images/hujiao.png')
# img = cv2.imread('../images/renwu02.png')
# 定义中值滤波 滤波的孔径 必须是大于1的奇数
c = 5
# 中值滤波
blurred_img = cv2.medianBlur(img, c)
cv2.imshow('old', img)
cv2.imshow('blurred_img', blurred_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
三、图像边缘检测
使用OpenCV进行图像边缘检测的原因有以下几点:
-
图像边缘是物体与背景、物体与物体之间的边界,因此边缘检测对于图像分割、特征提取等任务非常重要。
-
图像边缘蕴含了丰富的信息,如形状、方向、纹理等,这些信息对于后续的图像处理和分析非常重要。
-
通过边缘检测,可以大幅减少数据量,并且剔除可以认为不相关的信息,保留了图像重要的结构属性。
-
边缘检测是图像处理和计算机视觉中的一个基本问题,它可以帮助我们标识数字图像中亮度变化明显的点,用于确定图片中物体的边界(边缘)或者区域。
Canny边缘检测
Canny 边缘检测广泛应用于图像处理、计算机视觉和机器学习中的物体识别、图像分割等任务。
import cv2
"""
一般和高斯滤波一起使用
edges = cv2.Canny(image, threshold1, threshold2)
image: 输入的灰度图像。
threshold1: 第一个阈值,用于边缘检测的低阈值。
threshold2: 第二个阈值,用于边缘检测的高阈值。
"""
img = cv2.imread('../images/car.png')
# 转成灰度图像
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 定义阈值
"""
lower 用于边缘检测的低阈值
低阈值用来识别可能的边缘像素
如果一个像素的梯度值大于低阈值,那么这个像素可能会被认为是边缘的一部分
单独依靠低阈值来识别边缘是不够的,因为它可能会导致很多虚假的边缘被识别出来,特别是那些由于噪声引起的边缘。
"""
lower = 80
"""
height 用于边缘检测的高阈值
如果一个像素的梯度值大于高阈值,那么这个像素几乎可以肯定是边缘的一部分
高阈值的存在可以有效地减少由于噪声引起的虚假边缘
"""
height = 100
# 获取图片的边缘信息 边缘部分为白色,其他部分为黑色
"""
返回值
edges:返回检测到的边缘图像,边缘部分为白色,其他部分为黑色
"""
edges = cv2.Canny(img, lower, height)
# 显示结果
cv2.imshow('old', img)
cv2.imshow('canny', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
四、图像形态学操作
在OpenCV中,形态学操作是一类基于形状的图像处理技术,主要用于提取图像中的有用特征,如边界检测、噪声去除等。常见的形态学操作包括腐蚀、膨胀、开运算、闭运算、梯度、顶帽和黑帽等。
1、腐蚀
腐蚀操作会减少图像中白色区域的大小,常用于消除小的白色噪声点。腐蚀的基本思想是,如果一个结构元素完全包含在前景物体内部,则该结构元素对应的输出图像位置的值为1,否则为0。
import cv2
import numpy as np
"""
图像形态学操作-腐蚀操作
eroded = cv2.erode(src, kernel, dst,iterations=1)
腐蚀操作会减少图像中白色区域的大小,常用于消除小的白色噪声点
基本思想
如果一个结构元素完全包含在前景物体内部,则该结构元素对应的输出图像位置的值为1,否则为0
参数
src: 输入图像。
kernel: 结构元素,用于定义腐蚀操作的方式。是一个矩阵结构数据
dst (可选): 输出图像。如果未提供,则会自动创建一个新的图像。
iterations (可选): 腐蚀操作的迭代次数,默认为1
iterations 参数控制腐蚀操作的迭代次数。
增加迭代次数会使腐蚀效果更加明显,但也会导致前景物体变得更小
"""
img = cv2.imread('../images/ceshi02.jpg')
# 定义结构元素
kernel = np.ones((3, 3), np.uint8)
# 腐蚀操作
eroded_img = cv2.erode(img, kernel, iterations=2)
# 显示结果
cv2.imshow('old', img)
cv2.imshow('eroded_img', eroded_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2、膨胀
膨胀操作与腐蚀相反,它会增加图像中白色区域的大小,常用于填补前景物体中的小洞或扩大前景物体的边界。
import cv2
import numpy as np
"""
图像形态学操作-膨胀操作
dilated = cv2.dilate(src, kernel, iterations=1)
和腐蚀操作相反,膨胀操作会增加图像中白色区域的大小,
常用于填补前景物体中的小洞或扩大前景物体的边界
参数
src: 输入图像。
kernel: 结构元素,用于定义膨胀操作的方式。是一个矩阵结构数据
dst (可选): 输出图像。如果未提供,则会自动创建一个新的图像。
iterations (可选): 膨胀操作的迭代次数,默认为1
"""
img = cv2.imread('../images/ceshi01.jpeg')
# 定义结构元素
kernel = np.ones((3, 3), np.uint8)
# 膨胀操作
dilated_img = cv2.dilate(img, kernel, iterations=3)
# 显示结果
cv2.imshow('old', img)
cv2.imshow('dilated_img', dilated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
3、开运算
开运算是先腐蚀后膨胀的过程,常用于去除小的物体、平滑较大的物体边界以及填充细长的突出部分。
import cv2
import numpy as np
"""
opened = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)
开运算是先腐蚀后膨胀的过程, ("先缩小后增大")
常用于去除小的物体、平滑较大的物体边界以及填充细长的突出部分
(去除外围,保留内部)
参数
- src: 输入图像。
- op: 形态学操作的类型,可以是以下几种之一:
- cv2.MORPH_OPEN:开运算
- cv2.MORPH_CLOSE:闭运算
- cv2.MORPH_GRADIENT:形态学梯度
- cv2.MORPH_TOPHAT:顶帽
- cv2.MORPH_BLACKHAT:黑帽
- kernel: 结构元素,用于定义形态学操作的方式。可以通过 cv2.getStructuringElement 函数获得
"""
img = cv2.imread('../images/kai.jpg')
# 定义结构元素
kernel = np.ones((7, 7), np.uint8)
# 腐蚀操作
eroded_img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
# 显示
cv2.imshow('old', img)
cv2.imshow('eroded_img', eroded_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
4、闭运算
闭运算是先膨胀后腐蚀的过程,常用于填充前景物体中的小洞,平滑较大物体的边界以及连接邻近的物体。
# 2024-11-04 吕国彰
import cv2
import numpy as np
"""
closed = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)
闭运算是先膨胀后腐蚀的过程,
常用于填充前景物体中的小洞,平滑较大物体的边界以及连接邻近的物体
(去除内部)
参数
- src: 输入图像。
- op: 形态学操作的类型,可以是以下几种之一:
- cv2.MORPH_OPEN:开运算
- cv2.MORPH_CLOSE:闭运算
- cv2.MORPH_GRADIENT:形态学梯度
- cv2.MORPH_TOPHAT:顶帽
- cv2.MORPH_BLACKHAT:黑帽
- kernel: 结构元素,用于定义形态学操作的方式。可以通过 cv2.getStructuringElement 函数获得
"""
img = cv2.imread('../images/bi01.jpeg')
# 定义结构元素
kernel = np.ones((7, 7), np.uint8)
# 腐蚀操作
eroded_img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
# 显示
cv2.imshow('old', img)
cv2.imshow('eroded_img', eroded_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
5、形态学梯度
形态学梯度是通过计算膨胀后的图像与腐蚀后的图像之间的差值来得到的,可以突出物体的边缘。
形态学梯度= 原图-腐蚀的图
import cv2
import numpy as np
"""
gradient = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel)
形态学梯度是通过计算膨胀后的图像与腐蚀后的图像之间的差值来得到的,
可以突出物体的边缘。
形态学梯度= 原图-腐蚀的图
"""
img = cv2.imread('../images/xtx.gif')
# 定义结构元素 越大边缘越宽
kernel = np.ones((3, 3), np.uint8)
# 腐蚀操作
eroded_img = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
# 显示
cv2.imshow('old', img)
cv2.imshow('eroded_img', eroded_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
6、顶帽
顶帽变换是原图像与开运算结果的差值,用于获取图像中的亮细节。
顶帽: 原图减去开运算,得到大图形外的小图形。
import cv2
import numpy as np
"""
tophat = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)
顶帽变换是原图像与开运算结果的差值,用于获取图像中的亮细节
原图减去开运算,得到大图形外的小图形
"""
# 读取图像
img = cv2.imread("../images/kai.jpg")
# 定义顶帽的卷积核
kernel = np.ones((7, 7), np.uint8)
# 执行腐蚀操作
eroded = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
# 显示结果
cv2.imshow('Original_Image', img)
cv2.imshow('Eroded_Image', eroded)
cv2.waitKey(0)
cv2.destroyAllWindows()
7、黑帽
黑帽变换是闭运算结果与原图像的差值,用于获取图像中的暗细节。
黑帽:原图减去闭运算,得到大图形内的小图形。
import cv2
import numpy as np
"""
blackhat = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)
黑帽变换是闭运算结果与原图像的差值,用于获取图像中的暗细节
原图减去闭运算,得到大图形内的小图形
"""
# 读取图像
img = cv2.imread("../images/kai.jpg")
# 定义顶帽的卷积核
kernel = np.ones((7, 7), np.uint8)
# 执行腐蚀操作
eroded = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
# 显示结果
cv2.imshow('Original_Image', img)
cv2.imshow('Eroded_Image', eroded)
cv2.waitKey(0)
cv2.destroyAllWindows()