opencv-python 降噪

概念

噪声

定义

图像噪声是指存在于图像数据中的不必要的或多余的干扰信息。噪声的存在严重影响了图像的质量,因此在图像增强处理和分类处理之前,必须予以纠正。 图像中各种妨碍人们对其信息接受的因素即可称为图像噪声 。噪声在理论上可以定义为“不可预测,只能用概率统计方法来认识的随机误差。因此将图像噪声看成是多维随机过程是合适的,因而描述噪声的方法完全可以借用随机过程的描述,即用其概率分布函数和概率密度。

种类

常见的图像噪声有以下几种:

  1. 椒盐噪声(Salt and Pepper Noise):椒盐噪声是一种随机出现的噪声,它将图像中的一些像素值随机地变为最大值或最小值,使得图像出现黑白斑点。
  2. 高斯噪声(Gaussian Noise):高斯噪声是一种常见的噪声类型,它是由于传感器本身的零偏和随机噪声造成的。高斯噪声对图像的影响主要体现在图像中出现逐渐变化的全局性噪声。
  3. 泊松噪声(Poisson Noise):泊松噪声是一种采样噪声,它主要源于光子计数的随机性,对于灰度较高的区域噪声比较明显,而对于灰度较低的区域噪声较小。
  4. 水平条纹噪声(Horizontal Banding Noise):它是由于摄像头在图像采集过程中的电信号串扰产生的,会在图像中出现宽度相等的水平条纹。
  5. 偏移噪声(Offset Noise):偏移噪声是由于图像传感器的零点偏移而产生的,它会对图像的整体亮度和对比度产生影响。

不同类型的图像噪声在特征和影响方面存在差异,因此针对不同噪声类型选择相应的滤波算法会更加有效。

滤波方法

常见

常见的图像滤波方法主要有以下几种:

  1. 均值滤波(Mean Filter):均值滤波是一种线性滤波方法,它利用像素周围的邻域像素的灰度值进行平均来平滑图像,从而实现降噪和去除图像中的细节信息。
  2. 中值滤波(Median Filter):中值滤波是一种非线性滤波方法,它采用中值代替一组数据的平均值,能够有效消除椒盐噪声和斑点噪声,同时保留图像中的边缘信息。
  3. 高斯滤波(Gaussian Filter):高斯滤波是一种线性滤波方法,它通过利用高斯函数对图像进行加权平均来平滑图像,同时可以有效地去除高斯噪声。
  4. 双边滤波(Bilateral Filter):双边滤波是一种非线性滤波方法,它在进行像素平滑的过程中不仅考虑相邻像素之间的距离关系,还考虑像素之间的灰度值差异,从而能够在保留图像细节信息的同时,进行有效的降噪。
  5. K邻近滤波(K-Nearest Neighbors Filter):K邻近滤波是一种基于像素邻域的滤波方法,它利用一个像素周围的邻域像素的灰度值来更新该像素的值,从而实现图像的平滑化和去噪。
  6. 自适应滤波(Adaptive Filter):自适应滤波是一种基于局部图像结构的非线性滤波方法,它根据图像的局部结构特征来优化滤波器的权重,从而实现对复杂噪声的消除。

不同的图像滤波方法在滤波效果、处理时间、滤波器设计等方面存在差异,根据实际情况选择适合的滤波方法可以达到最佳的滤波效果。

分类方法

  1. 线性滤波与非线性滤波:线性滤波是根据邻域内像素的加权平均值计算出中心像素的滤波方法,例如均值滤波和高斯滤波等。在这些方法中,目标图像的每个像素值通过与其相邻区域内的其他像素值按一定权值进行加和而产生。因此,处理过程是线性的,同时也使得处理过程简单明了,可以被有效地采用。非线性滤波是根据像素邻域内的像素彼此各自的比较,然后根据这些像素值进行计算的处理。它在某些情况下具有优势,尤其是当噪声比较大或图像质量比较低时。例如,中值滤波和双边滤波等滤波方法就是一种非线性滤波方法,它们的处理过程是非线性的,即每个像素的输出值不仅仅取决于邻域内像素的加权平均值。非线性滤波通常能够更好地处理具有复杂和非线性特征的图像。

  2. 时域滤波和频域滤波:时域滤波是指对图像像素值进行直接处理的滤波方法,例如均值滤波和中值滤波等;而频域滤波则是对图像进行傅里叶变换,然后对傅里叶变换后的频域图像进行处理的滤波方法,例如高通滤波和低通滤波等。

  3. 平滑滤波和锐化滤波:平滑滤波主要用于去除图像中的噪声和平滑图像细节,例如均值滤波和高斯滤波等;而锐化滤波通常用于增强图像的边缘和细节,例如 Sobel 滤波和 LoG 滤波等。

  4. 线性时不变滤波和递归滤波:线性时不变滤波是指每个像素点的输出只依赖于同一像素点的输入和固定的滤波器系数,例如 Sobel 滤波和 Laplacian 滤波等;而递归滤波则是指每个像素点的输出依赖于前一个像素点的输出,例如高斯滤波和 Bilateral 滤波等。

  5. 参数滤波和非参数滤波:参数滤波是指获得滤波核中的参数,而非参数滤波是指滤波核中的参数是根据图像数据进行估计得到的,例如双边滤波和中值滤波等。

方法解释

均值滤波

原理

均值滤波是常用的一种图像滤波方法,其原理是在图像中对每个像素点周围的邻域内取平均值,然后将平均值作为该像素点的灰度值。这样的处理能够去除图像中的噪声,并使图像的细节更为平滑。均值滤波的具体步骤如下:

  1. 对于图像中的每一个像素点,选择一个固定大小的邻域(一般为 3x3 或 5x5 的矩阵)。
  2. 对邻域内的所有像素点进行求和,并计算平均值。
  3. 将计算出的平均值赋给像素点的灰度值。
  4. 重复上述步骤,直到所有像素点都被处理。

均值滤波存在的一个缺点是处理后的图像会变得模糊,这是因为使用平均值来代表像素点的灰度值可能会损失一些细节信息。为了解决这个问题,可以使用其他的滤波算法,比如中值滤波和高斯滤波等,这些算法能够更好地保持图像的细节信息。

cv.blur()

dst = cv.blur(src, ksize[, dst[, anchor[, borderType]]])

参数说明:

  • src: 输入图像,可以是8位、16位或32位的灰度图像或彩色图像。
  • ksize: 滤波内核的大小,用一个元组 (w, h) 表示,其中 wh 分别表示水平和竖直方向的大小。元组中的每个值必须是正奇数。
  • dst (可选): 输出图像,与输入图像大小、深度和通道数相同。
  • anchor (可选): 锚点,表示内核中心的位置。默认值为 (-1, -1),即为内核的中心。
  • borderType (可选): 描边类型。默认值为 cv.BORDER_DEFAULT

cv.blur() 函数可以对一个单通道或多通道的图像进行处理。处理后的图像是一个与输入图像尺寸和通道数相同的图像矩阵。在滤波前,需要指定一个固定大小的滤波内核来处理图像中的每一个像素点。函数内部使用一个矩阵内核将邻域内所有像素点的值加起来并取平均数,得到新的像素灰度值。这样就可以去除噪声,同时保留图像中的边缘和其他特征信息。

代码参考

import numpy as np
import cv2 as cv

picture_init = cv.imread('init.jpg')

picture_finished = cv.blur(picture_init, (5, 5))

merge_picture = cv.hconcat([picture_init,picture_finished])
cv.imshow("finished", merge_picture)
cv.waitKey()
cv.destroyAllWindows()

优缺点

均值滤波是一种基本的图像滤波方法,它通过求取邻域内像素的平均值,来对图像的噪声进行消除。

均值滤波的优点如下:

  1. 实现简单,易于理解。
  2. 对于椒盐噪声这种随机噪声的去除效果比其他滤波算法更加明显,而且去噪过程非常平滑,不会破坏图像的细节和纹理。

均值滤波的缺点如下:

  1. 均值滤波只能消除噪声,不能恢复图像本身的特征和细节,因此可能导致图像模糊。
  2. 当邻域大小增大时,均值滤波的去噪效果会提高,但是这也会导致图像的细节和边缘部分变得模糊。因此,选择合适的邻域大小是非常重要的。
  3. 均值滤波对于高斯噪声等其他特定噪声的去除效果不够理想

中值滤波

原理

中值滤波是一种常用的非线性滤波器,其主要原理是用像素邻域里的像素点的中值代替中心像素点的灰度值。具体的中值滤波过程如下:

  1. 对于每个像素,以它为中心,取一个大小为k×k的邻域矩阵,k的取值通常为奇数,在邻域中的像素值按大小排序。
  2. 将排序后的像素值取中值,然后用这个中值来代替中心像素点的灰度值。
  3. 重复对整个图像进行上述操作,直到应用滤波器完成。

中值滤波器的好处在于它能够有效地消除椒盐噪声和斑点噪声,使图像更加清晰,同时保留了图像的细节信息。但是,中值滤波器对于大尺度噪声的去除效果不是很好。

cv.medianBlur()

dst = cv2.medianBlur(src, ksize)

其中,src参数是输入图像,可以是灰度图像或彩色图像;ksize参数是滤波器的大小,通常为正奇数(例如3、5、7等),指定了滤波器的半径大小(即包括中心像素在内的邻域大小)。若不指定ksize,默认值为3。

优缺点

优点:

  1. 对于添加椒盐噪声的图像(即黑白图中的白加噪声或黑加噪声),中值滤波能够给出较为明显的效果。
  2. 相比其他滤波算法,如均值滤波,中值滤波能够有效地去除噪声并保留原始图像的边缘信息。
  3. 中值滤波的实现简单,计算速度较快,适用于实时处理。

缺点:

  1. 对于高斯噪声、泊松噪声等其他类型的噪声,中值滤波的效果并不理想。
  2. 中值滤波的滤波器大小的选择需要在噪声去除和边缘保留之间进行平衡,过大的滤波器会导致图像模糊,而过小的滤波器可能不足以消除噪声。
  3. 中值滤波的处理效率虽然较高,但对于大型图像和视频数据处理,其效率仍然有待优化。

中值滤波和均值滤波的区别

  1. 中值滤波和均值滤波在处理噪声时的效果不同。对于图像中的椒盐噪声或脉冲噪声,中值滤波能够较好地去除噪声,而均值滤波的效果较差。而对于高斯噪声等其他类型的噪声,均值滤波通常比中值滤波更有效。
  2. 中值滤波和均值滤波在处理后图像的质量方面也有很大的不同。中值滤波能够保留图像的边缘信息和细节,而均值滤波会平滑图像并模糊边缘和细节。
  3. 中值滤波和均值滤波的运算复杂度也不同。中值滤波的计算复杂度要大于均值滤波,因为它需要对窗口中的像素值进行排序,并求出其中位数

因此,中值滤波和均值滤波虽然处理方式相似,但在处理效果、处理后的图像质量以及运算复杂度等方面存在很大差异,需要根据具体应用场景选择合适的滤波方法。

高斯滤波

原理

高斯滤波将高斯核应用于图像的每个像素,将像素与其周围像素的加权平均值进行计算,从而平滑图像并降低噪声。

是一种对人眼视觉的模仿。

opencv-python 降噪_第1张图片

GaussianBlur()

cv2.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) -> dst

其中,函数参数的含义如下:

  • src:输入图像,可以是单通道或多通道图像,数据类型是uint8、float32、float64等。
  • ksize:高斯核的大小,它必须是正数和奇数。例如,可以使用(3,3)、(5,5)等等。如果使用(0,0),那么根据sigma的值,使用推断核大小。
  • sigmaX:高斯核沿x轴的标准差,如果sigmaX设为0,那么函数将根据ksize计算sigmaX的值。默认值为0。sigma越小,关注区域越小越集中

opencv-python 降噪_第2张图片

  • dst:输出图像,如果未提供,则创建一个大小和类型与输入图像相同的空数组,数据类型是与输入图像相同的类型。

  • sigmaY:同sigmaX,但是沿着y轴计算。

  • borderType:卷积边缘模式,它可以是以下四种模式之一:

    • cv2.BORDER_DEFAULT:默认值,在边界上根据图像类型决定公式。
    • cv2.BORDER_CONSTANT:添加一个常数值填充(i.e., 黑色或者白色)。
    • cv2.BORDER_REFLECT:和边界的成像象为镜像。
    • cv2.BORDER_REPLICATE:最后一行或者一列被复原填充,跟着你的边界。
    • cv2.BORDER_WRAP:用另一边的边缘来包装。

优缺点

优点:

  1. 去除高斯噪声:高斯滤波可以有效地去除高斯噪声,是图像去噪的常用方法之一。
  2. 平滑效果好:高斯滤波可以对图像进行平滑处理,从而去除孤立的噪声点并且保留图像的整体特征。
  3. 容易调整平滑程度:高斯滤波的平滑效果可以通过调整标准差sigma来实现,sigma越大,平滑效果越明显。

缺点:

  1. 无法处理椒盐噪声:高斯滤波的处理效果对于椒盐噪声不是很好,因为椒盐噪声噪声本质上是由黑白噪声点构成的,而高斯滤波对于随机噪声不是很有效。
  2. 无法区分边界和平滑:高斯滤波在平滑的同时,可能会模糊图像的边界,从而导致信息丢失。
  3. 计算复杂度高:高斯滤波的计算量与其核的大小有关,因此在处理大图像时会增加计算开销。

双边滤波

原理

双边滤波的原理是基于高斯滤波的思想,但在计算像素权重时,同时考虑了像素强度和空间距离两个因素。双边滤波的卷积核包括两部分:一个是像素值差异的高斯函数,一个是空间距离的高斯函数。

bilateralFilter()

cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

参数说明:

  • src:输入图像,可以是任意维度和任意通道数的灰度图像或彩色图像;
  • dst:输出图像,它的大小、类型和通道数与输入图像相同;
  • d:在过滤的过程中,表示每个像素的邻域大小,与其他滤波函数中的卷积核大小类似;如果 d 的值为 0,则通过 sigmaSpace计算邻域大小;
  • sigmaColor:控制像素值的相似性(色彩空间)的高斯函数标准差;数值越大,与非常相似的颜色也会进行比较,从而得到更深的颜色混合;
  • sigmaSpace:控制空间相似性的高斯函数标准差;数值越大,越远的像素将相互影响,从而使较大的区域的颜色相似;
  • borderType:确定图像边界的处理方式,同其他图像处理函数。

需要注意的是,sigmaColorsigmaSpace是双边滤波中最为重要的两个参数,您可以尝试不同的参数值来获得不同的滤波效果。一般情况下,sigmaColorsigmaSpace的取值范围为[1, 200],数值越大,滤波效果越强,但同时也越容易出现图像的模糊效果。

实例代码

import numpy as np
import cv2 as cv

picture_init = cv.imread('init.jpg')
# picture_finished = cv.medianBlur(picture_init, 5)
picture_finished = cv.bilateralFilter(picture_init, 0, 100, 100)
merge_picture = cv.hconcat([picture_init,picture_finished])
cv.imshow("finished", merge_picture)
cv.waitKey()
cv.destroyAllWindows()

优缺点

优点:

  • 保留了图像的边缘信息,因此边缘保持清晰,不会出现模糊情况。
  • 可以去除椒盐噪声(随机噪声)和高斯噪声(高斯白噪声)。
  • 对于不同的图像,可以根据其特性调整双边滤波的参数,从而获得滤波效果。

缺点:

  • 比较耗时,计算量大,速度较慢。
  • 对于大尺寸的图像,容易出现明显的边缘效应(边缘区域变亮或变暗),从而导致图像合成出现问题。
  • 在远离像素点的区域内仍然受到高斯权重的影响,容易导致低频信号的衰减。

K邻近滤波

K临近滤波,也称为K近邻滤波,是一种基于统计学高斯分布的非线性滤波算法。它的基本思想是,在对当前像素进行滤波处理时,找到K个邻域内最相似的像素值,并通过加权平均的方式对这K个像素值进行平滑操作,从而实现对噪声的抑制和图像平滑的目的。该算法可以用于去除高斯噪声、椒盐噪声、斑点噪声等。

具体实现流程如下:

  • 对于图像中的每一个像素,找到它的K近邻像素;
  • 计算这K个邻居像素值的平均值;
  • 将当前像素值替换为这个平均值。

K临近滤波算法的核心是邻域的选择和加权系数的计算。K的选择需要根据噪声的特点和图像的大小选择合适的值,一般选取3、5、7、9等奇数。加权系数的计算需要根据像素间的距离来计算,距离越远的像素,其权重越低。

需要注意的是,K临近滤波并不是一种线性滤波方法,因此在进行滤波处理时需要考虑其计算量和运行速度。同时,由于K近邻算法对图像中的每个像素都进行了K次搜索和计算,因此对于处理大图像而言,也容易受到其空间复杂度的限制。

实例代码

import numpy as np
import cv2 as cv

picture_init = cv.imread('init.jpg')
# picture_finished = cv.medianBlur(picture_init, 5)
picture_finished = cv.fastNlMeansDenoising(picture_init, None, 10, 7, 21)
merge_picture = cv.hconcat([picture_init,picture_finished])
cv.imshow("finished", merge_picture)
cv.waitKey()
cv.destroyAllWindows()

自适应滤波

原理

自适应滤波是一种基于局部像素灰度值的滤波方法,它可以根据像素之间的差异来确定滤波器的大小和强度。相比于传统的线性滤波方法,自适应滤波可以更好地处理图像中的边缘信息和细节,从而获得更好的滤波效果。

在自适应滤波中,滤波器的大小和强度是根据每个像素附近的像素灰度值自适应确定的。其中滤波器大小通常是由窗口大小或者集合大小决定的,而滤波强度则通常由像素协方差矩阵决定,例如高斯自适应滤波器便是一种如此实现的。

自适应滤波的基本流程如下:

  • 对于图像中的每一个像素点,动态调整滤波器大小和强度,选择一个最佳的滤波器大小和强度;
  • 根据选择的滤波器大小和强度,对当前像素点的邻域像素值进行滤波处理,得到新的像素值;
  • 将当前像素值替换为新的像素值,完成滤波处理。

自适应滤波的实现要点在于确定最佳滤波器大小和强度的方法。一般的方法则是按照像素间的差异来计算滤波器的大小和强度,常用的有:

  • 均值滤波:像素值的分布呈正态分布时,可用均值滤波器;
  • 高斯滤波:像素值的分布呈高斯分布时,可用高斯滤波器;
  • 中值滤波:像素值的分布呈峰值和裂谷分布时,可用中值滤波器。

自适应滤波的优点是可以保留图像中的细节信息,同时能够去除大部分噪声,因此在图像处理中应用很广泛。

cv2.adaptiveThreshold()

cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst])

  • src:输入图像,必须为8位单通道图像;
  • maxValue:二值化时预设的像素最大值;
  • adaptiveMethod:滤波器类型,可选值包括cv2.ADAPTIVE_THRESH_MEAN_Ccv2.ADAPTIVE_THRESH_GAUSSIAN_C,分别表示基于均值和基于高斯的滤波器;
  • thresholdType:阈值类型,常用的值包括cv2.THRESH_BINARYcv2.THRESH_BINARY_INV
  • blockSize:邻域大小,必须是奇数;
  • C:阈值参数的预设常数。

实例代码

import numpy as np
import cv2

# 加载图像并转换为HSV图像
image = cv2.imread("init.jpg")
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# 分离每个通道图像
H, S, V = cv2.split(hsv)

# 对每个通道图像进行自适应滤波
adap_H = cv2.adaptiveThreshold(H, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 15)
adap_S = cv2.adaptiveThreshold(S, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 15)
adap_V = cv2.adaptiveThreshold(V, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 15)

# 合并通道图像,形成彩色图像
result = cv2.merge([adap_H, adap_S, adap_V])

# 显示结果图像
cv2.imshow("Input", image)
cv2.imshow("Adaptive Thresholding", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

参考资料

图像噪声_百度百科 (baidu.com)

ChatGPT

图像预处理之高斯滤波、拉普拉斯滤波_哔哩哔哩_bilibili

你可能感兴趣的:(opencv,Python学习笔记,python,opencv,计算机视觉)