图像处理(去噪)----滤波

引言:

        图像去噪,主要用于去除图像的一些噪点,从而减少乃至消除噪点对边缘检测的影响。

        图像降噪常见的有均值滤波,高斯滤波,中值滤波,双边滤波,引导滤波等。

1、 均值滤波:

        实质就是在一个n*n的卷积核中,中心点取卷积核的均值,是一个简单粗暴的滤波方式,但无论离中心点远还是进权重值都是相同的(也就是影响系数相同)。

        常用来解决一些噪声分布均匀或是没有明显边缘和细节的图像。

2:高斯滤波:

2.1 数学原理:

        高斯滤波考虑到了空间距离的影响。(ps:这并不表明高斯滤波在任意情况下都优于均值滤波,在一些噪声均匀分布或是没有明显边缘核细节的图像的时候,均值滤波会比高斯的效果更好些,当然高斯具有更佳的泛用性)

      高斯滤波其实就是使用高斯分布(正态分布)来计算权重矩阵,由于考虑到了距离的影响因素,这也就使得它能够在去噪的同时,更好的保留图像的特征。好了下面来从数学的角度说明一下:

        这是高斯分布(正态分布)的概率函数:

        当我们在处理一个n*n的卷积核的时候,只考虑图像位置的时候,均值自然取0,然后我们将其扩展到二维的时候,便能获取一个二维高斯分布函数(具体细节纯数学了,这里就不花篇章解释了,有需要可以bing一下)

       我们这里取标准差为1.5举个例子,0.0454 = (-1,-1)带入上述二维公式,最后进行归一化(9个数值相加=1),当然这只是一个3*3,根据需求可以更换成其他大小。

        最后将3*3卷积核的原始数值与归一化后的矩阵相乘,然后矩阵元素求和,也就是最后(0,0)位置的数值了。

        高斯滤波在去噪的同时,更好的保留了图像的特征,这也就使得它图像处理中比均值滤波更为常用

2.2 opencv使用:

cv2.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) → dst

参数解释:

src: 输入图像,可以是任何数量的信道,但深度应为CV_8U,CV_16U,CV_16S,CV_32F或CV_64F
(ps:图像深度:也就是图像的像素能用多少位来表示,譬如CV_16S:每个像素就会以 16 位有符号整数的形式存储)

dst: 输出图像,和输入图像大小一致

ksize: 高斯核大小,类似(n*m),注意n,m可以不相同,但是必须是正奇数

sigmX: X方向上的高斯核标准偏差

sigmY: Y方向上的高斯核标准偏差,如果值为0,则与sigmX相同,若两者均为0,则自动计算

borderType: 边界填充方法

 2.3 一些疑惑

       不知道你们在看到这些参数的时候是否会思考,为什么会有XY两个方向上的标准差,明明我们在原理中,只使用了一个标准差,而且是如何自动计算标准差的,为了了解这一过程,需要我们来翻一下源代码/官方文档

        cv2.GaussianBlur调用了getGaussianKernel()接口,那么我们来看一下getGaussianKernel()接口:getGaussianKernel

        首先:我们可以看到sigma的计算公式:sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8,如果传入了sigmaX与Y,那么会返回两个一维高斯核传递给sepFilter2D函数,让我们来看下这个函数:

        我们可以看到cv2.sepFilter2D这个函数会传入两个1维的卷积核(kernel),然后对每一行用kernelX进行卷积,获得一个中间结果(也就是kernelX中的每个元素和该行的每个元素相乘然后相加),同理用kernelY对中间结果进行卷积,然后将结果平移delta个像素后存入dst,最后归一化后得到新的图像。       

举个例子:

import cv2
# 读取图像
image = cv2.imread('input.jpg')
# 高斯滤波
blurred_image = cv2.GaussianBlur(image, (5, 5), 0)
#(5, 5)是核大小,0是标准差

3、双边滤波:

        双边滤波在高斯滤波的基础上,还将值域纳入了考虑范围,请看下图,对于P点,它左边的q点产生了断崖式的值域变化,而右边的部分则几乎没有变化,那么两者对于P的影响实际上肯定是有比较大的差距的。如果仍然使用高斯滤波的话,那么边缘就会被一定程度的模糊。(ps:双边对于椒盐噪声的效果比高斯弱不少)

        所以,相对于高斯滤波,双边滤波对于边缘的处理效果会更加好(但是相较于高斯,双边滤波的时间复杂度会更加高一些,ps:优化思路:查表法 : 先把空间阈的对应的权重数值计算出来,同理值域也可以如此操作,在需要用到的时候,取出数值即可,也就是空间换时间)

        数学公式如下:(i,j)表示中心点((0,0))(k,l)表示邻接点

opencv使用:

dst = cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

#d空间距离参数一般取5/9,sigmaColor是颜色空间的标准差,sigmaSpace是坐标空间的标准差,borderType边界填充(可选)

参数详解:

        src:源 8 位或浮点、1 通道或 3 通道图像。
        dst:与 src 大小和类型相同的目标图像。
        d:过滤期间使用的每个像素邻域的直径。 如果它是非正数,则从sigmaSpace 计算。
        sigmaColor:在颜色空间中过滤 sigma。 较大的参数值意味着像素邻域内更远的颜色将混合在一起,从而产生更大的半等色区域。
        sigmaSpace:在坐标空间中过滤 sigma。 较大的参数值意味着更远的像素将相互影响,。 当 d>0 时,它指定邻域大小,而不考虑 sigmaSpace。 否则,d 与 sigmaSpace 成正比。
        borderType:用于推断图像外部像素的边框模式(可选)

4、引导滤波

        引导滤波:保边算法,效果比双边更好些,也是常用的工程算法:

        引导滤波基于一个假设:输出图像是引导图像的局部线性变换(梯度基本一致)。接下来看我手写的一些推导过程吧,有些公式输入实在是麻烦

        当处于低频区域,效果基本等同于均值滤波,当处于高频区域时,低频成分依旧来自于原始图像的均值滤波结果,但通过引导图像与目标图像间的结构相似度来影响协方差 Cov(Ik,Gk) 的大小,进而影响系数 ak 的大小,最终实现结构迁移幅度的控制。

import cv2
import numpy as np
image = cv2.imread('input_image.jpg')
#创建引导滤波器
guided_filter = cv2.ximgproc.createGuidedFilter(radius=5, eps=0.01)
# radius是滤波器半径,eps是归一化系数
#应用引导滤波:
filtered_image = guided_filter.filter(image)

用到了会继续补充细节问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

渊兮旷兮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值