【OpenCV】图像滤波

背景

图像的实质是一种二维信号,滤波是信号处理中的一个重要概念。在图像处理中,滤波是一种非常常见的技术,它们的原理非常简单。滤波是一个邻域操作算子,利用给定像素周围的像素的值决定此像素的最终的输出值。而领域算子是利用给定像素周围的像素值决定此像素的最终输出值的一种算子。

图像滤波原理

在这里插入图片描述

上图蓝色点可以解释为:

6.5 + 9.8 + 12.3 + 6.5 + 19.2 + 11.5 + 6.3 + 9.1 + 10.7 = 91.9 ≈ 92 6.5 + 9.8 + 12.3 + 6.5 + 19.2 + 11.5 + 6.3 + 9.1 + 10.7=91.9 \approx 92 6.5+9.8+12.3+6.5+19.2+11.5+6.3+9.1+10.7=91.992

线性滤波处理的输出像素值 g ( i , j ) g(i,j) g(i,j)是输入像素值 f ( i + k , j + l ) f(i+k,j+l) f(i+k,j+l)的加权和 :

g ( i , j ) = ∑ k , l f ( i + k , j + l ) h ( k , l ) g(i, j)=\sum_{k,l}f(i+k, j+l)h(k, l) g(i,j)=k,lf(i+k,j+l)h(k,l)

其中的加权和为 ,我们称其为“核”,滤波器的加权系数,即滤波器的“滤波系数”。
上面的式子可以简单写作:

g = f ⊗ h g=f\otimes h g=fh

其中 f f f表示输入像素值, h h h表示加权系数“核“, g g g表示输出像素值

线性滤波

方框滤波

在这里插入图片描述

normalize = true 与均值滤波相同
normalize = false 很容易发生溢出
normalize = false时,像素与核相乘后灰度值很容易大于255,出现高亮情况。

cv2.boxFilter(src,depth,ksize,normalize)

参数说明
src: 需要被处理的图像,即原始图像。
depth: 处理后结果图像的深度,一般使用-1表示与原始图像使用相同的图像深度。
ksize: 滤波核的大小,通常为奇数。
normalize: 是否归一化。

import cv2
img = cv2.imread('girl.png',cv2.IMREAD_UNCHANGED)
r = cv2.boxFilter(img, -1 , (7,7) , normalize = 1)

cv2.namedWindow('original',cv2.WINDOW_AUTOSIZE)
cv2.namedWindow('r',cv2.WINDOW_AUTOSIZE)

cv2.imshow('original',img)
cv2.imshow('r',r)

cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

均值滤波

均值滤波方法是:对待处理的当前像素,选择一个模板,该模板为其邻近的若干个像素组成,用模板的均值(方框滤波归一化)来替代原像素的值。公式表示为:

g(x,y)为该邻域的中心像素,n跟系数模版大小有关,一般3*3邻域的模板,n取为9,如:

( 1 9 1 9 1 9 1 9 1 9 1 9 1 9 1 9 1 9 ) \left(\begin{matrix} \frac{1}{9} & \frac{1}{9} & \frac{1}{9} \\ \frac{1}{9} & \frac{1}{9} & \frac{1}{9} \\ \frac{1}{9} & \frac{1}{9} & \frac{1}{9} \end{matrix}\right) 919191919191919191

当然,模板是可变的,一般取奇数,如5 * 5 , 7 * 7等等。

  • 均值滤波的应用场合
    根据冈萨雷斯书中的描述,均值模糊可以模糊图像以便得到感兴趣物体的粗略描述,也就是说,去除图像中的不相关细节,其中“不相关”是指与滤波器模板尺寸相比较小的像素区域,从而对图像有一个整体的认知。即为了对感兴趣的物体得到一个大致的整体的描述而模糊一幅图像,忽略细小的细节。

  • 均值滤波的缺陷
    均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点,特别是椒盐噪声。

cv2.blur(src, ksize)
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('opencv.png')
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
blur = cv2.blur(img,(7,7 ))
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.subplot(1,2,2),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

高斯滤波

应用: 高斯滤波是一种线性平滑滤波器,对于服从正态分布的噪声有很好的抑制作用。在实际场景中,我们通常会假定图像包含的噪声为高斯白噪声,所以在许多实际应用的预处理部分,都会采用高斯滤波抑制噪声,如传统车牌识别等。

高斯滤波和均值滤波一样,都是利用一个掩膜和图像进行卷积求解。不同之处在于:均值滤波器的模板系数都是相同的,而高斯滤波器的模板系数,中间像素点权重最高,越远离中心的像素权重越小(服从二维高斯分布)。所以,高斯滤波器相比于均值滤波器对图像个模糊程度较小,更能够保持图像的整体细节。

二维高斯分布

其中不必纠结于系数,因为它只是一个常数!并不会影响互相之间的比例关系,并且最终都要进行归一化,所以在实际计算时我们是忽略它而只计算后半部分:

其中(x,y)为掩膜内任一点的坐标,(ux,uy)为掩膜内中心点的坐标,在图像处理中可认为是整数;σ是标准差。

例如:要产生一个3×3的高斯滤波器模板,以模板的中心位置为坐标原点进行取样。模板在各个位置的坐标,如下所示(x轴水平向右,y轴竖直向下)。

这样,将各个位置的坐标带入到高斯函数中,得到的值就是模板的系数。

生成高斯掩膜(小数形式)
知道了高斯分布原理,实现起来也就不困难了。

首先我们要确定我们生产掩模的尺寸wsize,然后设定高斯分布的标准差。生成的过程,我们首先根据模板的大小,找到模板的中心位置center。 然后就是遍历,根据高斯分布的函数,计算模板中每个系数的值。

最后模板的每个系数要除以所有系数的和。这样就得到了小数形式的模板。由于中心点为(0, 0)点,故公式变为:

f ( x , y ) = e − x 2 + y 2 2 σ 2 f(x, y) = e^{-\frac{x^2 + y^2}{2\sigma ^2}} f(x,y)=e2σ2x2+y2

3×3,σ=0.8的小数型模板:

σ的意义及选取
高斯滤波器模板的生成最重要的参数就是高斯分布的标准差σ。标准差代表着数据的离散程度,如果σ较小,那么生成的模板的中心系数较大,而周围的系数较小,这样对图像的平滑效果就不是很明显;反之,σ较大,则生成的模板的各个系数相差就不是很大,比较类似均值模板,对图像的平滑效果比较明显。

来看下一维高斯分布的概率分布密度图:

于是我们有如下结论:σ越小分布越瘦高,σ越大分布越矮胖。

  • σ越大,分布越分散,各部分比重差别不大,于是生成的模板各元素值差别不大,类似于平均模板;
  • σ越小,分布越集中,中间部分所占比重远远高于其他部分,反映到高斯模板上就是中心元素值远远大于其他元素值,于是自然而然就相当于中间值得点运算。
cv2.Guassianblur(src, ksize, std)

src: 原始图像
ksize: 核大小
std: 标准差

import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('median.png')
img = cv.cvtColor(img,cv.COLOR_BGR2RGB)
blur = cv.GaussianBlur(img,(7,7),7)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(1,2,2),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述
可以看到部分高斯滤波可以处理部分的噪声

非线性滤波

中值滤波

中值滤波是一种典型的非线性滤波,是基于排序统计理论的一种能够有效抑制噪声的非线性信号处理技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,让周围的像素值接近真实的值从而消除孤立的噪声点。该方法在取出脉冲噪声、椒盐噪声的同时能保留图像的边缘细节。这些优良特性是线性滤波所不具备的。

中值滤波首先也得生成一个滤波模板,将该模板内的各像素值进行排序,生成单调上升或单调下降的二维数据序列,二维中值滤波输出为

cv2.medianBlur(img,ksize)
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('median.png')
median = cv.medianBlur(img,3)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(1,2,2),plt.imshow(median),plt.title('median')
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

双边滤波

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

cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace)

参数说明:
src: 输入原图
d: 像素的邻域直径
sigmaColor: 灰度值相似性高斯函数标准差
sigmaSpace: 空间高斯函数标准

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白哒哒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值