OpenCV-Python——第12章:滤波器与图像平滑(图像模糊)

目录

2D卷积    平均模糊    高斯模糊    中值模糊    双边滤波    例子


1 2D卷积

与以为信号一样,我们也可以对 2D 图像实施低通滤波(LPF),高通滤波(HPF)等。LPF 帮助我们去除噪音,模糊图像。HPF 帮助我们找到图像的边缘

OpenCV 提供的函数 cv.filter2D() 可以让我们对一幅图像进行卷积操作。

filter2D(src, ddepth, kernel, dst, anchor, delta, borderType)

  • src:输入图像
  • ddepth:输出图像深度,-1使用原图像深度
  • kernel:卷积核
  • dst:输出图像
  • anchor:核的基准点,默认为(-1, -1), 说明位于核的中心位置,基准点即kernel中与进行处理的像素点重合的点。
  • delta:在储存目标图像前可选的添加到像素的值,默认值为0
  • borderType:边界类型,可查看https://blog.csdn.net/yukinoai/article/details/86423937

2 平均模糊

blur(src, ksize, dst, anchor, borderType)

  • src:输入图像
  • ksize:平均卷积核的尺寸,元组(x,y)
  • dst:输出图像
  • anchor:核的基准点
  • borderType:边界类型

这是由一个归一化卷积框完成的。他只是用卷积框覆盖区域所有像素的平均值来代替中心元素。可以使用函数 cv2.blur() 和cv2.boxFilter() 来完 这个任务。可以同看查看文档了解更多卷积框的细节。我们需要设定卷积框的 宽和高。下面是一个 归一化卷积框,又称平均滤波器核:

K = \dfrac{1}{K_{width} \cdot K_{height}} \begin{bmatrix}    1 & 1 & 1 & ... & 1 \\    1 & 1 & 1 & ... & 1 \\    . & . & . & ... & 1 \\    . & . & . & ... & 1 \\    1 & 1 & 1 & ... & 1   \end{bmatrix}

使用上述内核进行过滤会导致执行以下操作:对于每个像素,一个核大小窗口以此像素为中心,将落在此窗口内的所有像素相加,然后将结果除以核行乘核列,这等同于计算平均值该窗口内的像素值。 对图像中的所有像素执行此操作以产生输出滤波图像。

如果你不想使用归一化卷积框,你应该使用 cv2.boxFilter(),这时要传入参数 normalize=False。

3 高斯模糊

GaussianBlur(src, ksize, sigmaX, dst, sigmaY, borderType)

  • src:输入图像
  • ksize:平均卷积核的尺寸,元组(x,y)
  • sigmaX:高斯核在x方向的标准差
  • dst:输出图像
  • sigmaY:高斯核在y方向的标准差(sigmaY=0时,其值自动由sigmaX确定(sigmaY=sigmaX);sigmaY=sigmaX=0时,它们的值将由ksize.width和ksize.height自动确定)
  • borderType:边界类型

2维高斯函数可以表达为 :

G_{0}(x, y) = A  e^{ \dfrac{ -(x - \mu_{x})^{2} }{ 2\sigma^{2}_{x} } +  \dfrac{ -(y - \mu_{y})^{2} }{ 2\sigma^{2}_{y} } }

现在把卷积核换成高斯核(简单来说,方框不变,将原来每个方框的值是相等的,现在里面的值是符合高斯分布的,方框中心的值最大,其余方框根据 距离中心元素的距离递减,构成一个高斯小山包。原来的求平均数现在变成求 加权平均数,全就是方框里的值)。实现的函数是 cv2.GaussianBlur()。我 们需要指定高斯核的宽和高(必须是奇数)。以及高斯函数沿 X,Y 方向的标准 差。如果我们只指定了 X 方向的的标准差,Y 方向也会取相同值。如果两个标 准差都是 0,那么函数会根据核函数的大小自己计算。高斯滤波可以有效的从 图像中去除高斯噪音。

4 中值模糊

medianBlur(src, ksize, dst)

  • src:输入图像
  • ksize:平均卷积核的尺寸,元组(x,y)
  • dst:输出图像

顾名思义就是用与卷积框对应像素的中值来替代中心像素的值。这个滤波器经常用来去除椒盐噪声。前面的滤波器都是用计算得到的一个新值来取代中 心像素的值,而中值滤波是用中心像素周围(也可以使他本身)的值来取代他。 他能有效的去除噪声。卷积核的大小也应该是一个奇数。

5 双边滤波

bilateralFilter(src, d, sigmaColor, sigmaSpace, dst, borderType)

  • src:输入图像
  • d:邻域直径
  • sigmaColor:色空间过滤器的sigma值,这个参数的值大,表明该像素邻域内有宽广的颜色会被混合到一起,产生较大的半相等颜色区域。 
  • sigmaSpace:坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace. 
  • dst:输出图像
  • borderType:边界类型

函数 cv2.bilateralFilter() 能在保持边界清晰的情况下有效的去除噪音。但是这种操作与其他滤波器相比会比较慢。我们已经知道高斯滤波器是求 中心点邻近区域像素的高斯加权平均值。这种高斯滤波器只考虑像素之间的空 间关系,而不会考虑像素值之间的关系(像素的相似度)。所以这种方法不会考 虑一个像素是否位于边界。因此边界也会别模糊掉,而这正不是我们想要。

双边滤波在同时使用空间高斯权重和灰度值相似性高斯权重。空间高斯函数确保只有邻近区域的像素对中心点有影响,灰度值相似性高斯函数确保只有 与中心像素灰度值相近的才会被用来做模糊运算。所以这种方法会确保边界不 会被模糊掉,因为边界处的灰度值变化比较大。

6 例子

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('test15.jpg')  # 注意图片尺寸必须是卷积核的整倍,否则出错

# 2D卷积滤波
kernel = np.ones((5, 5), np.float32)/25  # 创建一个5x5的平均滤波器核
dst = cv2.filter2D(img, -1, kernel)

# 平均模糊
blur = cv2.blur(img, (5, 5))

# 高斯滤波
gauss = cv2.GaussianBlur(img, (5, 5), 0)

# 中值滤波
median = cv2.medianBlur(img, 5)

# 双边滤波
bila = cv2.bilateralFilter(img, 10, 200, 200)

plt.subplot(231), plt.imshow(img), plt.title('Original')
plt.subplot(232), plt.imshow(dst), plt.title('Filter2D')
plt.subplot(233), plt.imshow(blur), plt.title('Averaging')
plt.subplot(234), plt.imshow(gauss), plt.title('GuassianBlur')
plt.subplot(235), plt.imshow(median), plt.title('MedianBlur')
plt.subplot(236), plt.imshow(bila), plt.title('BilateralFilter')

plt.show()

结果如下 

 

你可能感兴趣的:(—OpenCV,opencv,滤波器,平滑,模糊)