第三章-OpenCV基础-6-滤波处理

前置内容

在尽量保留图片原有信息的情况下,过滤掉图像内部的噪声的过程成为对图像的平滑处理(又称滤波处理),所得到的图像成为平滑图像(把图像中的噪点过滤掉,生成一个相对平滑的图像)。

举个栗子:

一个图像有个噪点,加载发现有个点的像素值和周边像素值差异太大格格不入,使用周边像素点平均生成一个新的值,重新显示,噪点不见,页面平滑。

图像平滑处理的基本原理是将噪声所在像素点的像素值根据一定方式处理为周边临近像素点的近似值,书中介绍均值滤波、高斯滤波、中值滤波等方法。

另外,图像平滑处理通常伴随图像的模糊操作,所以平滑处理有时也称为图像模糊处理。

均值滤波

基本原理: 均值滤波是指用当前像素点周边N*N个像素值的均值代替当前像素值。需要遍历处理图像内的每一个像素点。

以像素点为中心时,可以计算3x3范围内9个像素点的平均数,也可以计算5x5范围内的25个像素点的平均数。对图像的边界点,可以只取图像内存在的周围领域点的像素平均值。

对于5x5的范围,计算如下图:

也就是每个像素点的滤波都是视为与一个内部值均为1/25的5x5的矩阵相乘得到均值滤波的计算结果。

简化后可以变成如下所示结果:

在OpenCV中,将上图右侧的矩阵称为卷积核(这个卷积核太重要了,只要一个个图分析下来)。一般形式如下:

其中,M和N分别对应矩阵的高度和宽度,一般情况下,M和N相等。M和N的值越大,参与运算的像素点越多,当前像素点的计算结果受到越多的周围的点影响。

函数语法: dst = cv2.blur( src , ksize , anchor , borderType )

  • dst : 进行均值滤波后得到的处理结果
  • src : 原始图片
  • ksize : 滤波核的大小,也就是上面所说的M和N的值
  • anchor : 锚点,默认值为(-1,-1),表示当前计算均值的像素点位于滤波核的中心位置,默认即可。
  • borderType : 边界样式,决定以何种方式处理边界,根据填充值的不同边界样式也不同,填充值可以为0/255/边缘值/特定值,直接采用默认即可。

所以均值滤波函数可以简化为 dst = cv2.blur( src ,ksize )

举栗说明:

import cv2 as cv

lena_noise = cv.imread("lenaNoise.png")
lena_3x3 = cv.blur(lena_noise, (3, 3))  # 滤波核越小,图像噪点越清晰,但图片越清晰
lena_7x7 = cv.blur(lena_noise, (17, 17))  # 滤波核越大,图像越模糊
cv.imshow("lena noise", lena_noise)
cv.imshow("lena 3x3", lena_3x3)
cv.imshow("lena 7x7", lena_7x7)

cv.waitKey()
cv.destroyAllWindows()

效果如下(依次为原图、3x3、7x7):

高斯滤波

原理:在均值滤波中,计算矩阵中的每个像素的权重都是相等的,在高斯滤波中,会将临近的像素点的权重加大,远离中心位置的像素点的权重减少。

根据滤波核的大小一般有3x3、5x5、7x7,权重分布如下:

这里以3x3的卷积核为例。

实际计算为:

矩阵范围内的各个点乘以各个点的权重比例之和就是高斯滤波后的新值。

另外,大小一样的滤波核内部相同位置的比重可以不一样,无论滤波核的权重数为整数或者小数,体现的都是比重。

函数语法: dst = cv2.GaussianBlur( src , ksize , sigmaX , sigmaY , borderType )

  • dst和src分别是输出图像和原始输入图像
  • ksize : 滤波核大小,宽高必须是奇数
  • sigmaX : 滤波核在水平方向上的标准差,控制的是权重比,此参数为必选项
  • sigmaY : 滤波核在垂直方向上的标准差,若该值为0,则只采用sigmaX。
  • borderType : 边界样式,以何种方式处理边界,默认值即可

sigma越大,权重值分布越平缓。邻域点对输出值的影响越大,图像越模糊。sigma越小,权重值分布越突变。邻域点对输出值的影响越小,图像变化就更小。

官方文档建议显示指定ksize、sigmaX、sigmaY,可以指定sigmaX和sigmaY为默认值0,所以常用形式为:

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

举栗说明:

import cv2 as cv

lena_noise = cv.imread("lenaNoise.png")
ksize = 3 #滤波核长宽
lena_0 = cv.GaussianBlur(lena_noise, (ksize, ksize), 0, 0)  # sigmaY=sigmaY=0
lena_05 = cv.GaussianBlur(lena_noise, (ksize, ksize), 0.5, 0.5)  # sigmaY=sigmaY=0.5
lena_1 = cv.GaussianBlur(lena_noise, (ksize, ksize), 1, 1)  # sigmaY=sigmaY=1
cv.imshow("lena noise", lena_noise)
cv.imshow("lena_0", lena_0)
cv.imshow("lena_05", lena_05)
cv.imshow("lena_1", lena_1)

cv.waitKey()
cv.destroyAllWindows()

中值滤波

基本原理:中值滤波取当前像素点及周边像素点的像素值,并做排序处理,然后取中间值作为像素点的像素值。

像素点及周边像素点排序后为[ 66 , 78 , 90 , 91 , 93 , 94 , 95 , 97 , 101],取中间值93替换为当前像素点的78。

函数语法: dst = cv2.medianBlur( src , ksize)

ksize:滤波核的宽高必须是比1大的基数

举栗说明:

import cv2 as cv

lena_noise = cv.imread("lenaNoise.png")
lena_0 = cv.medianBlur(lena_noise, 3)  # 滤波核的长宽为3
cv.imshow("lena noise", lena_noise)
cv.imshow("lena_medianBlur", lena_0)

cv.waitKey()
cv.destroyAllWindows()

小结:综合多种平滑操作的计算算法和实际效果,还是中值滤波的效果比较好,但涉及排序运算上会多一些。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mr_Sun_01

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

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

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

打赏作者

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

抵扣说明:

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

余额充值