前言
开始第二天的学习!!冲 继续昨天的内容
一、使用导向滤波对传输率t进行进一步改进
1、概述
这部分是结合 这篇博客 感兴趣的可以直接点开这个学习 写的很好
引导过滤器根据局部线性模型原理,通过考虑引导图像的内容来计算过滤输出,引导图像可以是输入图像本身或另一个不同的图像。具有以下特点:
引导滤波器可以像流行的双边滤波器一样用作边缘保留平滑算子,但在边缘附近有更好的效果。
引导过滤器也是平滑之外的一个更通用的概念:它可以将引导图像的结构传输到过滤输出,从而实现新的过滤应用,例如去雾和引导羽化。
此外,无论核大小和强度范围如何,引导滤波器自然具有快速且非近似的线性时间算法。目前它是最快的边缘保留滤波器之一。
我们发现当假设局部传输率一致时,此时暗通道中会出现光晕体和块,这是由于局部内的传输率t并不一定是相同的。
本文使用导向滤波对传输率t进行进一步优化
2、原理
引导滤波的定义中,用到了局部线性模型,该模型认为,某函数上一点与其邻近部分的点成线性关系,一个复杂的函数就可以用很多局部的线性函数来表示,当需要求该函数上某一点的值时,只需计算所有包含该点的线性函数的值并做平均即可。我们可以将图像看成一个二维函数,因此,而且没法写出解析表达式,因此我们假设该引导滤波函数的输出与输入在一个二维窗口内满足线性关系,如下:
这里p是输入图像 ,I是引导图像 ,q是滤波输出图像, ak和bk是系数, ωk是窗口。
对上式两边取梯度,可以得到:
可以看出 当引导图I有梯度时,输出图q也有梯度,这里可以说明为什么该滤波有保持边缘的效果
接下来需要计算ak和bk,我们将输入图像p纳入考虑范围中,根据一般的加性噪声模型,我们很容易得到以下式子:
其中ni表示需要去除的噪声或纹理。
显然,我们现在要找到一个解能够最小化输出图q和输入图p的差别。定义代价函数如下:
这里,\varepsilon是正则化参数,我们对代价函数求最小值,
令偏导为0,计算得到:
其中pk和uk分别是P和I窗口内的均值
(看到在一个窗口的均值,均可以使用方框滤波(默认为均值)来实现)。 得到bk,我们再求ak
根据方差和协方差公式,
最终计算得到:
这里其实最后的代码实现过程 还是按照最初的到的那个ak的式子,使用方框滤波来实现,我也不知道为什么要提到方差这些,,可能是为了表示方便??
3、代码实现
def Guidedfilter(im,p,r,eps): #导向滤波 可以保留图像边缘的同时 给图像去噪 让图像变光滑
mean_I = cv2.boxFilter(im,-1,(r,r))
mean_p = cv2.boxFilter(p, -1,(r,r))
mean_Ip = cv2.boxFilter(im*p,-1,(r,r))
cov_Ip = mean_Ip - mean_I*mean_p
mean_II = cv2.boxFilter(im*im,-1,(r,r))
var_I = mean_II - mean_I*mean_I
a = cov_Ip/(var_I + eps)
b = mean_p - a*mean_I
mean_a = cv2.boxFilter(a,-1,(r,r))
mean_b = cv2.boxFilter(b,-1,(r,r))
q = mean_a*im + mean_b
return q
opencv中有直接实现方框滤波的API
OpenCV 在 ximgproc 模块提供了 cv.ximgproc.guidedFilter 函数实现导向滤波算法。
函数说明:
cv.ximgproc_guidedFilter.filter(guide, src, d[, eps[, dDepth]) → dst
1
参数说明:
src:输入图像,可以是灰度图像,也可以是多通道的彩色图像
guide:导向图像,大小和类型与 src 相同
dst:输出图像,大小和类型与 src 相同
d:滤波核的像素邻域直径
eps:规范化参数, eps 的平方类似于双边滤波中的 sigmaColor
dDepth:输出图片的数据深度
def transrefine(img