opencv-python 详解线性和非线性滤波、模糊、卷积原理

作者:RayChiu_Labloy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处


目录

关于滤波、模糊和卷积:

谈一下卷积基础:

再看一些滤波函数就容易理解了:

线性滤波分类和详解:

均值滤波

方框滤波

高斯滤波

非线性滤波分类和详解

中值滤波:

双边滤波:

关于空间距离和灰度距离:

 总结小技巧:


关于滤波、模糊和卷积

  • 滤波、模糊都属于卷积,不同滤波方法之间只是卷积核不同(对线性滤波而言)
  • 低通滤波器是模糊,高通滤波器是锐化

        低通滤波器就是允许低频信号通过,在图像中边缘和噪点都相当于高频部分,所以低通滤波器用于去除 噪点、平滑和模糊图像。高通滤波器则反之,用来增强图像边缘,进行锐化处理。

        常见噪声有椒盐噪声和高斯噪声,椒盐噪声可以理解为斑点,随机出现在图像中的黑点或白点;高斯噪声可以理解为拍摄图片时由于光照等原因造成的噪声。

谈一下卷积基础

 拿上边这张图来举例,左边原图、中间卷积核、右边卷积后的图,卷积操作就是卷积核在原图上一点一点滑动,每滑动一步进行一次卷积计算(就是卷积核和原图重叠区域进行相乘相加操作),计算的结果赋值到核心位置,如果原图不进行padding操作结果图大小会变小。

这里是padding、卷积实验代码:

# ex2tron's blog:
# http://ex2tron.wang

import cv2
import numpy as np

img = cv2.imread('6_by_6.bmp', 0)
print(img)
# 结果应该如下:
# [[213 166 237 240 196 243]
#  [166  81 213 181  34 197]
#  [237 217 247 240 196 243]
#  [245 200 241 241 199 240]
#  [200  38 190 189  35 197]
#  [241 185 237 240 189 241]]

# 固定值边框:zero padding
cons = cv2.copyMakeBorder(img, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=0)
print(cons)
# 结果应该如下:
# [[0   0   0   0   0   0   0   0]
#  [0 213 166 237 240 196 243   0]
#  [0 166  81 213 181  34 197   0]
#  [0 237 217 247 240 196 243   0]
#  [0 245 200 241 241 199 240   0]
#  [0 200  38 190 189  35 197   0]
#  [0 241 185 237 240 189 241   0]
#  [0   0   0   0   0   0   0   0]]

"""
默认边框类型
这个原理简单流程复杂,自行百度一下就理解了,这里不解释了
"""
default = cv2.copyMakeBorder(img, 1, 1, 1, 1, cv2.BORDER_DEFAULT)
print(default)
# 结果应该如下:
# [[ 81 166  81 213 181  34 197  34]
#  [166 213 166 237 240 196 243 196]
#  [ 81 166  81 213 181  34 197  34]
#  [217 237 217 247 240 196 243 196]
#  [200 245 200 241 241 199 240 199]
#  [ 38 200  38 190 189  35 197  35]
#  [185 241 185 237 240 189 241 189]
#  [ 38 200  38 190 189  35 197  35]]


img = cv2.imread('lena.jpg')

# 定义卷积核
kernel = np.ones((3, 3), np.float32) / 10
# 卷积操作,-1表示通道数与原图相同
dst = cv2.filter2D(img, -1, kernel)

hs = np.hstack((img, dst))
cv2.imshow('res', hs)
cv2.waitKey(0)

再看一些滤波函数就容易理解了:

线性滤波分类和详解:

        包含有均值、方框、高斯滤波(计算复杂慢一些)。线性滤波总体比非线性快一些。

均值滤波

        (均值模糊)blur = cv2.blur(img, (3, 3)) 就是卷积计算的时候相乘相加后再取均值

方框滤波

        (方框模糊)blur = cv2.boxFilter(img, -1, (3, 3), normalize=True) 如果normalize为true则就是均值滤波,false的时候就是相乘相加,计算结果超过255的就取255。

高斯滤波

        (高斯模糊)gaussian = cv2.GaussianBlur(img, (5, 5), 1) 重点说说。

        高斯模糊是一个削弱高频信号强度的低通滤波器

        适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域(卷积核覆盖区域)内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个卷积核模板(或称掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

高斯卷积核的生成:

概率论一维高斯函数正态分布函数

二维高斯函数:

 由上可知,二维高斯函数具有可分离性,所以OpenCV分两步计算二维高斯卷积,先水平再垂直,每个方向上都是一维的卷积。OpenCV中这个一维卷积的计算公式类似于上面的一维高斯函数:

 其中i=0…ksize-1,α是一个常数,也称为缩放因子,我们用cv2.getGaussianKernel(ksize,sigma) 来生成一维卷积核:

  • sigma<=0时, sigma=0.3*((ksize-1)*0.5 - 1) + 0.8
  • sigma>0时,sigma=sigma
print(cv2.getGaussianKernel(3, 0)) 
# 结果:[[0.25][0.5][0.25]]

生成之后,先进行三次的水平卷积:

 然后再进行垂直的三次卷积:

 这就是OpenCV中高斯卷积核的生成方式。其实,OpenCV源码中对小于7×7的核是直接计算好放在数组里面的,这样计算速度会快一点,上面矩阵也可以写成:

 线性滤波对于椒盐噪声的过滤并不是很好,由此我们本次将谈到OpenCV中的非线性滤波。

非线性滤波分类和详解

        包含分类有:中值滤波、双边滤波

中值滤波

        中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,其基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点,对于斑点噪声和椒盐噪声来说尤其有用,因为它不依赖于邻域内那些与典型值差别很大的值。中值滤波器在处理连续图像窗函数时与线性滤波器的工作方式类似,但滤波过程却不再是加权运算。
        中值滤波在一定的条件下可以克服常见线性滤波器如最小均方滤波、方框滤波器、均值滤波等带来的图像细节模糊,而且对滤除脉冲干扰及图像扫描噪声非常有效,也常用于保护边缘信息, 保存边缘的特性使它在不希望出现边缘模糊的场合也很有用,是非常经典的平滑噪声处理方法。

image.png

 说白了就是卷积核覆盖区域值排序取中位数赋值给像素点。24 75 78 104 113 121 154 204 235 那么中间值就是113了。一般采用奇数点的邻域来计算中值,但如果像素点数为偶数时,中值就取排序像素中间两点的平均值。 
        中值滤波对于去除椒盐噪声特别的有效,我们先来看一下椒盐噪声的定义:
椒盐噪声是由图像传感器,传输信道,解码处理等产生的黑白相间的亮暗点噪声。椒盐噪声是指两种噪声,一种是盐噪声(salt noise)盐=白色(255),另一种是胡椒噪声(pepper noise),椒=黑色(0)。前者是高灰度噪声,后者属于低灰度噪声。一般两种噪声同时出现,呈现在图像上就是黑白杂点。对于彩色图像,则表现为在单个像素BGR三个通道随机出现的255与0,而中值滤波的取值恰恰是中间值,所以会将这些极端值过滤掉

         中值滤波器与均值滤波器比较的优势:在均值滤波器中,由于噪声成分被放入平均计算中,所以输出受到了噪声的影响,但是在中值滤波器中,由于噪声成分很难选上,所以几乎不会影响到输出。因此同样用3x3区域进行处理,中值滤波消除的噪声能力更胜一筹。中值滤波无论是在消除噪声还是保存边缘方面都是一个不错的方法。 
        中值滤波器与均值滤波器比较的劣势:中值滤波花费的时间是均值滤波的5倍以上。

双边滤波

        双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。
        双边滤波器的好处是可以做边缘保存,一般过去用的高斯滤波去降噪,都会较明显地模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。

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

关于空间距离和灰度距离:

空间距离:指的是当前点与中心点的欧式距离。空间域高斯函数其数学形式为:

 其中(xi,yi)为当前点位置,(xc,yc)为中心点的位置,sigma为空间域标准差。

 灰度距离:指的是当前点灰度与中心点灰度的差的绝对值。值域高斯函数其数学形式为:

         其中gray(xi,yi)为当前点灰度值,gray(xc,yc)为中心点灰度值,sigma为值域标准差。对于高斯滤波,仅用空间距离的权值系数核与图像卷积后,确定中心点的灰度值。即认为离中心点越近的点,其权重系数越大。

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

         两者权重系数相乘,得到最终的卷积模板。由于双边滤波需要每个中心点邻域的灰度信息来确定其系数,所以其速度与比一般的滤波慢很多,而且计算量增长速度为核大小的平方。

 总结小技巧

  • 在不知道用什么滤波器好的时候,优先高斯滤波 cv2.GaussianBlur() ,然后均值滤cv2.blur() 
  • 斑点和椒盐噪声优先使用中值滤波 cv2.medianBlur() 。
  • 要去除噪点的同时尽可能保留更多的边缘信息,使用双边滤波 cv2.bilateralFilter() 。

 实现代码参考另一篇文章:opencv-python 实现均值、高斯、中值、双边滤波_RayChiu757374816的博客-CSDN博客_cv2 gaussianblur 【如果对您有帮助,交个朋友给个一键三连吧,您的肯定是我博客高质量维护的动力!!!】 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值