Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)

1.常用低通滤波器介绍

1.1低通滤波器与高通滤波器的区别:

1.低通滤波主要用于噪点的消除或者是用于图像的降噪
2.高通滤波器主要于图像边缘的寻找

1.2 方盒滤波

  • boxFilter(src, ddepth, ksize[, dst[, anchor[, normalize[, borderType]]]]) 方盒滤波.
    • 方盒滤波的卷积核的形式如下:
      Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第1张图片

    • normalize = True时, a = 1 / (W * H) 滤波器的宽高

    • normalize = False是. a = 1

    • 一般情况我们都使用 normalize = True的情况. 这时 方盒滤波 等价于 均值滤波

代码实现

import numpy as np 
import cv2
#方盒滤波
img=cv2.imread('./dog.jpeg')

#不需要手动创建卷积核 需要告诉方盒滤波器 卷积核的大小是多少  结果会造成模糊
dst=cv2.boxFilter(img,-1,(3,3),normalize=True) 
dst2=cv2.boxFilter(img,-1,(3,3),normalize=False)
cv2.imshow('img',np.hstack((img,dst,dst2)))  
cv2.waitKey(0)
cv2.destroyAllWindows()
效果如图所示

Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第2张图片

1.3均值滤波

  • 当方盒滤波中 参数 normalize = True. 这时 方盒滤波 等价于 均值滤波
  • blur(src, ksize[, dst[, anchor[, borderType]]]) 均值滤波.
    Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第3张图片

1.4 高斯滤波器

高斯滤波的核心思想是让临近的像素具有更高的重要度. 对周围像素计算加权平均值, 较近的像素具有较大的权重值.

要理解高斯滤波首先要知道什么是高斯函数.高斯函数在是符合高斯分布(也叫正态分布)的数据的概率密度函数.画出来长这样子:

Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第4张图片
高斯函数的特点是以x轴某一点(这一点称为均值)为对称轴, 越靠近中心数据发生的概率越高, 最终形成一个两边平缓, 中间陡峭的钟型(有的地方也叫帽子)图形.

高斯函数的一般形式为:

Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第5张图片
高斯滤波就是使用符合高斯分布的卷积核对图片进行卷积操作. 所以高斯滤波的重点就是如何计算符合高斯分布的卷积核, 即高斯模板.

假定中心点的坐标是(0,0),那么取距离它最近的8个点坐标,为了计算,需要设定σ的值。假定σ=1.5,则模糊半径为1的高斯模板就算如下:

Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第6张图片
我们可以观察到越靠近中心, 数值越大, 越边缘的数值越小.符合高斯分布的特点.

通过高斯函数计算出来的是概率密度函数, 所以我们还要确保这九个点加起来为1,这9个点的权重总和等于0.4787147,因此上面9个值还要分别除以0.4787147,得到最终的高斯模板。

注: 有些整数高斯模板是在归一化后的高斯模板的基础上每个数除上左上角的值, 然后取整.
Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第7张图片

有了卷积核, 计算高斯滤波就简单了.假设现有9个像素点,灰度值(0-255)的高斯滤波计算如下:

Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第8张图片
将这9个值加起来,就是中心点的高斯滤波的值。对所有点重复这个过程,就得到了高斯模糊后的图像。

Opencv中的函数

  • GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])

    • kernel 高斯核的大小.
    • sigmaX, X轴的标准差
    • sigmaY, Y轴的标准差, 默认为0, 这时sigmaY = sigmaX
    • 如果没有指定sigma值, 会分别从ksize的宽度和高度中计算sigma.
  • 选择不同的sigma值会得到不同的平滑效果, sigma越大, 平滑效果越明显.
    Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第9张图片

  • 没有指定sigma时, ksize越大, 平滑效果越明显
    Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第10张图片

# 高斯滤波
import cv2
import numpy as np

#导入图片
img=cv2.imread('./lvboqi/code/lena.png')

dst=cv2.GaussianBlur(img,(5,5),sigmaX=10)

#不指定 sigmaX,会使用ksize 计算出 sigmaX
dst1=cv2.GaussianBlur(img,(5,5),sigmaX=0)

cv2.imshow('img',np.hstack((img,dst,dst1)))  

cv2.waitKey(0)
cv2.destroyAllWindows()
效果如图 分别是 原图,指定sigmaX的结果,不指定sigmaX的结果.

截图有些小 可能不是很明显,建议实操一下 可以明显看出差别.

使用高斯滤波器降噪

import cv2
import numpy as np
# 使用高斯滤波器降噪
img=cv2.imread('./lvboqi/code/gaussian.png')
dst=cv2.GaussianBlur(img,(5,5),sigmaX=0.5)

#不指定 sigmaX,会使用ksize 计算出 sigmaX
# dst=cv2.GaussianBlur(img,(5,5),sigmaX=0)

cv2.imshow('img',np.hstack((img,dst)))  
cv2.waitKey(0)
cv2.destroyAllWindows()

Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第11张图片

1.5 中值滤波器

中值滤波原理非常简单, 假设有一个数组[1556789], 取其中的中间值(即中位数)作为卷积后的结果值即可.中值滤波对胡椒噪音(也叫椒盐噪音)效果明显.

import cv2
import numpy as np
# 使用中值滤波器降噪
img=cv2.imread('./lvboqi/code/papper.png')
# 注意这里的ksize就是一个数字
dst = cv2.medianBlur(img, 5)

cv2.imshow('img', np.hstack((img, dst)))


cv2.waitKey(0)
cv2.destroyAllWindows()

Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第12张图片

双边滤波器

双边滤波对于图像的边缘信息能过更好的保存。其原理为一个与空间距离相关的高斯函数与一个灰度距离相关的高斯函数相乘。

Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第13张图片
双边滤波本质上是高斯滤波, 双边滤波和高斯滤波不同的就是:双边滤波既利用了位置信息又利用了像素信息来定义滤波窗口的权重。而高斯滤波只用了位置信息.

对于高斯滤波,仅用空间距离的权值系数核与图像卷积后,确定中心点的灰度值。即认为离中心点越近的点,其权重系数越大。

双边滤波中加入了对灰度信息的权重,即在邻域内,灰度值越接近中心点灰度值的点的权重更大,灰度值相差大的点权重越小。此权重大小,则由值域高斯函数确定。

两者权重系数相乘,得到最终的卷积模板。由于双边滤波需要每个中心点邻域的灰度信息来确定其系数,所以其速度与比一般的滤波慢很多,而且计算量增长速度为核大小的平方。
Python机器视觉--OpenCV进阶(核心)--常用低通滤波器(方盒滤波器,均值滤波器,高斯滤波器,中值滤波器,双边滤波器)_第14张图片
双边滤波可以保留边缘, 同时可以对边缘内的区域进行平滑处理.

双边滤波的作用就相当于做了美颜.

  • bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])
    • sigmaColor是计算像素信息使用的sigma
    • sigmaSpace是计算空间信息使用的sigma

基于OpenCV实现

# 双边滤波
import cv2
import numpy as np


#导入图片
img = cv2.imread('./lena.png')

dst = cv2.bilateralFilter(img, 7, 20, 50)

cv2.imshow('img', np.hstack((img, dst)))


cv2.waitKey(0)
cv2.destroyAllWindows()

效果如图

你可能感兴趣的:(Python,机器视觉基础与进阶(含项目),opencv,python,计算机视觉)