【OpenCV学习】图像平滑处理:均值滤波、方框滤波、高斯滤波、中值滤波、双边滤波、2D卷积(自定义滤波)

图像中的噪声

在一副图像上,某些像素点的像素值与周围像素点的值存在大小上的明显差异,反映在图像上时,该点会与周围有明显的色彩差异。这种与整体格格不入的像素点被称为噪声。如下图中的白点:
含有噪声的图片

图像平滑处理

在保留图像原有信息的基础上,过滤并去除掉图像中的噪声,这一过程就是图像的平滑处理,所得图像被称为平滑图像。
平滑处理的基本原理是:将噪声点的像素值处理为其周围临近像素点像素值的临近值。取近似值的方法很多,主要有如下的几种方法:

  • 均值滤波
  • 方框滤波
  • 高斯滤波
  • 中值滤波
  • 双边滤波
  • 2D卷积

图像平滑处理通常伴随着模糊操作,因此也被称为图像模糊处理。

均值滤波

均值滤波是指用当前像素点周围N*N个像素值的均值来代替当前像素值。使用该方法遍历图像中每一个像素点,即可完成整幅图像的均值滤波。函数语法如下:

dst = cv2.blur(src, ksize, anchor, borderType)
  • dst是返回值。
  • src是原始图像。
  • ksize是滤波核的大小。滤波核的大小决定了在均值处理的过程中,目标像素点所需计算邻域的大小,例如(5,5)。
  • anchor是锚点,默认是(-1,-1),表示当前计算均值的点位于和的中心点位置。该值通常采取默认的形式,特殊情况可指定不同的点作为锚点。
  • borderType是边界样式,该值决定了以何种方式处理边界,同样采取默认值即可。

因此,函数cv2.blur()的一般形式为:

dst = cv2.blur(src, ksize)

程序示例如下:

import cv2
img=cv2.imread("zstx.jpg")
r = cv2.blur(img,(5,5))
cv2.imshow("original",img)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:
cv2.blur()操作后的结果
从结果可以发现,噪声点明显消失,平滑后的图像较原始图像模糊。

当使用不同大小的卷积核进行均值滤波时会有什么不一样呢?
在源代码的基础上修改卷积核的大小:

import cv2
img=cv2.imread("zstx.jpg")
r = cv2.blur(img,(30,30))
cv2.imshow("original",img)
cv2.imshow("result",r)
cv2.waitKey()
cv2.destroyAllWindows()

将卷积核改为(30,30)后的结果如下:
卷积核为(30,30)的均值滤波
可以发现平滑处理后的图像更加模糊了,这说明了在均值滤波时,卷积核越大对图像的模糊效果越强,图像的失真越明显。卷积核越大意味着参与到均值运算中的像素就会越多,因此,卷积核越大,去噪效果越好。在实际处理当中,要在失真和去噪效果之间去个平衡,选取合适大小的卷积核。

方框滤波

方框滤波与均值滤波的不同点在于,可以自由选择是否对均值滤波的结果进行归一化,既可以自由选择滤波结果是邻域像素值之和的平均值,还是邻域像素值之和。函数语法如下:

dst = cv2.boxFilter(src, ddepth, ksize, anchor, normalize, borderType)
  • dst是返回值。
  • src为原始图像。
  • ddpeth是结果图像的图像深度,一般使用-1表示与原始图像使用相同的图像深度。
  • ksize是滤波核的大小。
  • anchor是锚点,默认值是(-1,-1),表示当前计算均值的点位于核的中心点位置。
  • normalize表示在滤波时是否进行归一化(是指将计算结果规范化为当前像素值范围内的值),该参数为逻辑值,值为1时表示真,值为0时表示假。
    normalize = 1,表示进行归一化处理,要用邻域像素值的和除以面积作为目标像素点的值。
    normalize = 0,表示不进行归一化处理,直接使用邻域像素值的和作为目标像素点的值。
  • borderType是边界样式,该值决定了以何种方式处理边界。

通常情况下,使用方框滤波函数时,参数anchor、normalize、borderType采取默认值即可,因此,cv2.boxFilter()函数的一般形式为:

dst = cv2.boxFilter(src, ddepth, ksize)

分别使用cv2.boxFilter()方法的归一化和不归一化对图像进行平滑处理,实例代码如下:

import cv2
img = cv2.imread("zstx.jpg")
r1 = cv2.boxFilter(img,-1,(5,5),normalize=1)
r2 = cv2.boxFilter(img,-1,(5,5),normalize=0)
cv2.imshow('original', img)
cv2.imshow('r1', r1)
cv2.imshow('r2',r2)
cv2.waitKey()
cv2.destroyAllWindows()

方框滤波的结果如下:
normalize = 1时
方框滤波处理,进行归一化处理时的结果
可以看出其结果与均值滤波相同,这是由于当进行归一化处理时,其卷积核的值与均值处理时的计算方法相同,因此目标像素点的值相同。

normalize = 0时
方框滤波结果,不进行归一化处理
可以发现处理后的图片接近纯白色,部分点出有颜色。这是由于,目标像素点的值是卷积核范围内像素点像素值的和,本例中则是目标像素点5*5邻域的像素值之和,因此,处理后的像素点像素值基本都会超过当前像素值的最大值255。部分点有颜色是因为这些点周围邻域的像素值均较小,邻域像素值在相加后仍然小于255。

高斯滤波

在进行均值滤波核方框滤波时,其邻域内每个像素的权重是相等的。在高斯滤波时,卷积核中心点的权重会加大,远离中心点的权重值减小,卷积核内的元素值呈现一种高斯分布。高斯滤波使用的是不同大小的卷积核,核的宽度和高度可以不相同,但是他们都必须是奇数。每一种尺寸的卷积核也可以有多种权重比例。特别说明,实际使用时卷积核往往需要进行归一化处理,使用没有进行归一化处理的卷积核滤波,得到的结果往往是错误的。

高斯滤波的函数语法如下:

dst = cv2.GaussianBlur(src, ksize, sigmaX, sigmaY, borderType)
  • dst是返回值。
  • src是原始图像。
  • ksize是滤波核的大小,滤波核必须是奇数。
  • sigmaX是卷积核在水平方向上(X轴方向)的标准差,其控制的是权重比例。
  • sigmaY是卷积核在垂直方向上(Y轴方向)的标准差,如果该值设为0,则只采用sigmaX的值。
  • borderType是边界样式,该值决定了以何种方式处理边界。该值在一般情况下默认即可。

在此函数中,参数sigmaY和borderType是可选参数,sigmaX是必选参数,但是可以将该参数设置为0,让函数自己去算sigmaX的具体值。在实际处理时,显示指定sigmaX和sigmaY为默认值为0,可以避免函数修改所造成的语法错误。函数的一般形式可以表示成:

dst = cv2.GaussianBlur(src, ksize, 0, 0)

实例程序:

import cv2
img = cv2.imread("zstx.jpg")
r = cv2.GaussianBlur(img,(5,5),0,0)
cv2.imshow('img',img)
cv2.imshow('r',r)
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:
高斯滤波结果
由结果可以发现,高斯滤波后的图像噪声点消失,图像依旧存在失真,其效果与均值滤波相当。但是高斯滤波的特点在于卷积核的形式与均值滤波核方框滤波的不同。

中值滤波

中值滤波与前面的滤波方式不同,不再采用加权求平均的方式计算目标像素值,而是用邻域内所有像素点的中间值来替代当前像素点的像素值。中值滤波会取当前像素点及周围临近像素点(一共奇数个像素点)的像素值,将这些像素值排序,然后将位于中间位置的像素值作为当前像素点的像素值。函数语法如下:

dst = cv2.medianBlur(src, ksize)
  • dst是返回值。
  • src是原图像。
  • ksize是滤波核的大小,此处的滤波核大小是指在滤波处理过程中其邻域图像的高度和宽度,核的大小必须是比1大的奇数。

示例程序:

import cv2
img = cv2.imread('zstx.jpg')
r1 = cv2.medianBlur(img,5)
cv2.imshow('img',img)
cv2.imshow('r1',r1)
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:
中值滤波的结果
从结果可以看出,中值滤波的效果较好,噪声去除明显,相较于均值处理,中值滤波不存在均值滤波等滤波方式带来的细节模糊(失真)问题。这是由于在中值滤波处理时,噪声成分很难被选上,因此可以在几乎不影响原有图片的情况下去除全部噪声。但由于涉及到排序等操作,中值滤波需要的运算量较大。

双边滤波

双边滤波综合考虑了空间信息和色彩信息等因素,在滤波过程中能够有效的保护图像内的边缘信息。在均值滤波、方框滤波、高斯滤波中,都会计算边缘上各个像素点的加权平均值,只考虑了空间的权重信息。双边滤波综合考虑距离和色彩的权重结果,既能够有效地去除噪声,又能够较好地保护边缘信息。
在双边滤波中,当处在边缘时,与当前点色彩相近的像素点(颜色距离很近)会被给予较大的权重值;而与当前色彩差别较大的像素点(颜色距离很远)会被给予较小的权重值(极端情况下权重可能为0,直接忽略该点),这样就保护了边缘信息。语法函数如下:

dst = cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, borderType)
  • dst是返回值。
  • src是原始图像。
  • d是在滤波时选取的空间距离参数,这里表示以当前像素点为中心点的直径。在实际应用中,推荐d=5,对于噪声较大的离线滤波,可以选择d=9。
  • sigmaColor是滤波处理时选取的颜色差值范围,该值决定了周围哪些像素点可以参与到滤波中来。该值为0时,滤波失去意义。该值为255时,指定范围内的所有点都能够参与运算。
  • borderType是边界样式,一般情况下直接采取默认。

为了简便起见,可以将sigmaColor和sigmaSpace值设置为相同值,如果这两个值较小(例如10),滤波效果将不太明显;如果这两个值较大(例如大于150),则滤波效果会比较明显,会产生卡通效果。参数borderType是可选参数,其余参数全部为必选参数。

示例程序:

import cv2
img = cv2.imread('zstx.jpg')
r = cv2.bilateralFilter(img,5,200,200)
cv2.imshow('img',img)
cv2.imshow('r',r)
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:
双边滤波结果
由图可知,双边滤波的去噪效果并不明显,很多噪声并没与去除,但是双边滤波的优势在于边缘信息的处理上。

2D卷积

Opencv提供了多种滤波方式来实现平滑图像的效果,大多数滤波方式使用的卷积核都具有一定的灵活性,能够方便地设置卷积核的大小和数值。但是,有时还需要使用特定的卷积核实现卷积操作。自定义卷积核的卷积操作的函数如下:

dst = cv2.filter2D(src, ddepth, kernal, anchor, delta, borderType)
  • dst是返回值。
  • src是原始图像。
  • ddepth是处理结果图像的图像深度,使用-1表示与原始图像相同。
  • kernal是卷积核,一个单通道数组。彩色图像则需将图像分解,每个通道使用不同的核(彩色图像有三个通道)。
  • anchor是锚点,默认值是(-1,-1),表示当前点位于核的中心点位置。特殊情况可指定不同的点作为锚点。
  • delta是修正值,是可选项。
  • borderType是边界样式,使用默认值即可。

通常情况下,使用cv2.filter2D()进行滤波时,参数锚点anchor、修正值delta、边界样式borderType直接采用默认值即可,因此语法的一般形式是:

dst = cv2. filter2D(src, ddepth, kernal)

示例程序:

import cv2
import numpy as np
img = cv2.imread('zstx.jpg')
kernel = np.ones((9,9),np.float32)/81
r = cv2.filter2D(img,-1,kernel)
cv2.imshow('img',img)
cv2.imshow('r',r)
cv2.waitKey()
cv2.destroyAllWindows()

在示例中,使用np.ones()函数自定义了一个9*9大小的卷积核,并让卷积核内的所有权重值相等。
结果如下:
自定义卷积核滤波后的结果
这里使用的卷积核比较简单,该滤波操作与直接使用均值滤波语句r=cv2.blur(img,(5,5))的效果一样。在实际使用中,可以定义更复杂的卷积核实现自定义滤波操作。

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值