导向滤波原理浅析

17 篇文章 1 订阅
12 篇文章 8 订阅

前言

在图像处理上,导向滤波器(Guided Image Filter)是一种能使图像平滑化的非线性滤波器。与双边滤波器(Bilateral Filter)相同,这个滤波器同样能够在清楚保持图像边界的情况下,达到让图像平滑的效果。
在这里插入图片描述

但不同于双边滤波器,导向滤波器有两个优点:

  1. 首先,双边滤波器有非常大的计算复杂度(O(N^2)),但导向滤波器因为并未用到过于复杂的数学计算,有线性的计算复杂度。
  2. 双边滤波器因为数学模型的缘故,在某些时候会发生梯度反转(gradient reverse)的状况,出现图像有损;而导向滤波器因为在数学上以线性组合为基础出发,输出图片(Output Image)与引导图片(Guidance Image)的梯度方向一致,不会出现梯度反转的问题(大概率不出现,某些条件下必定不出现)。

可以说,导向滤波相比双边滤波的两大优势就是速度快和不会有梯度反转。

实际的应用场景除了去噪平滑外,还可以用于细节加强(detail smoothing/enhancement,如“羽化”)、HDR compression、image matting/feathering、haze removal(去雾)、joint upsampling、深度图修整等功能。
在这里插入图片描述

原理

为了达到图像平滑去噪效果,首先定义输出的结果图是输入图减去噪声后的结果。同时,为了让输出图保持引导图的边界,将输出图定为引导图的线性组合。

可以说,导向滤波核心原理是假设导向图I与滤波结果输出图q符合局部(以像素 k k k为中心的 w k w_k wk窗口内)线性模型:
在这里插入图片描述
局部线性模型(local linear model)保证了结果图与导向图的edge一致( ∇ q = a ∇ I ∇q = a∇I q=aI)。

为了得到线性系数,需要构建方程求解。论文采用的是最小化输出q与输入图p之间的差异,即最小化窗口内的代价函数:
在这里插入图片描述
其中 ϵ \epsilon ϵ 是防止 a k a_k ak 过大的正则化参数。

方程的解可以根据 linear regression 求得,细节见参考资料[7][18]中推导:
在这里插入图片描述
其中, μ k \mu_k μk σ k 2 \sigma^2_k σk2是导向图I在窗口 w k w_k wk内的均值和方差, ∣ w ∣ |w| w是窗口 w k w_k wk内的像素数目, p ‾ k = 1 ∣ w ∣ ∑ i ∈ w k p i \overline{p}_k=\frac{1}{|w|}\sum_{i\in w_k}{p_i} pk=w1iwkpi是窗口 w k w_k wk内的均值。

基本上,根据得到的 a k a_k ak b k b_k bk就可以计算得出窗口 w k w_k wk内的每一个 q i q_i qi。但是进一步考虑,由于每一个像素不一定只被一个窗口 w k w_k wk所包含,例如九宫格情况下中心像素点就被9个3x3的 w k w_k wk窗口包含。
在这里插入图片描述
所以最简单的方式则是对这9个 w k w_k wk窗口得到的 q i q_i qi做一个加权平均,得到的最终 q i q_i qi才是真正的结果值。
在这里插入图片描述
经过对所有 q i q_i qi的加权平均(实际上用的是均值滤波), ∇ q ∇q q不再是 ∇ I ∇I I线性关系。但是由于 ( a ‾ i , b ‾ i ) (\overline a_i, \overline b_i) (ai,bi)是经过均值滤波得到,在导向图的强边界处,输出图的梯度会比导向图小。这种情况下可以认为 ∇ q ≈ a ‾ ∇ I ∇q \approx \overline a∇I qaI,表示导向图I边界的强变化还能被输出图q维持。
在这里插入图片描述
算法伪码如下:
在这里插入图片描述
其中, f m e a n ( ⋅ , r ) f_{mean}(·, r) fmean(,r) 是半径为r的均值滤波器。

而方差和协方差定义如下:
在这里插入图片描述
在这里插入图片描述
对式子 (5) 进行变换,
在这里插入图片描述

则可以得到算法伪码中的:

在这里插入图片描述

特别说明:
通过参数 ϵ \epsilon ϵ 定义什么是“平坦区块(patch)”或“高变化区块”。若一个区块的方差远低于参数 ϵ \epsilon ϵ ,其通过滤波器后将被平滑;反之,方差远高于 ϵ \epsilon ϵ的区块将被视为边界而被保留。

双边滤波中的范围方差(range variance)参数 σ r 2 \sigma _{r}^{2} σr2的功能和导向滤波的 ϵ \epsilon ϵ相似。它们都定义了什么样的区块应该被平滑,而什么样的区块应该被保留。

实现

OpenCV中对导向滤波有CPU实现。
在这里插入图片描述

核心代码如下:

void GuidedFilterImpl::filter(InputArray src, OutputArray dst, int dDepth /*= -1*/)
{
    CV_Assert( !src.empty() && (src.depth() == CV_32F || src.depth() == CV_8U) );
    if (src.rows() != h || src.cols() != w)
    {
        CV_Error(Error::StsBadSize, "Size of filtering image must be equal to size of guide image");
        return;
    }

    if (dDepth == -1) dDepth = src.depth();
    int srcCnNum = src.channels();

    vector<Mat> srcCn(srcCnNum);
    vector<Mat>& srcCnMean = srcCn;
    split(src, srcCn);

    if (src.depth() != CV_32F)
    {
        parConvertToWorkType(srcCn, srcCn);
    }

    vector<vector<Mat> > covSrcGuide(srcCnNum);
    computeCovGuideAndSrc(srcCn, srcCnMean, covSrcGuide);

    vector<vector<Mat> > alpha(srcCnNum);
    for (int si = 0; si < srcCnNum; si++)
    {
        alpha[si].resize(gCnNum);
        for (int gi = 0; gi < gCnNum; gi++)
            alpha[si][gi].create(h, w, CV_32FC1);
    }
    runParBody(ComputeAlpha_ParBody(*this, alpha, covSrcGuide));
    covSrcGuide.clear();

    vector<Mat>& beta = srcCnMean;
    runParBody(ComputeBeta_ParBody(*this, alpha, srcCnMean, beta));

    parMeanFilter(beta, beta);
    parMeanFilter(alpha, alpha);

    runParBody(ApplyTransform_ParBody(*this, alpha, beta));
    if (dDepth != CV_32F)
    {
        for (int i = 0; i < srcCnNum; i++)
            beta[i].convertTo(beta[i], dDepth);
    }
    merge(beta, dst);
}

具体文件参考GitHub的OpenCV Contrib包实现

GPU版导向滤波实现参考GitHub - TracelessLe/pybind11_guidedfilter_cuda

cv::cuda::GpuMat GuidedFilterMono::filterSingleChannel(const cv::cuda::GpuMat &p, cv::cuda::Stream &stream) const {
  cv::cuda::GpuMat mean_p, mean_Ip, cov_Ip;
  box_filter->apply(p, mean_p, stream);
  cv::cuda::multiply(I, p, mean_Ip, 1, -1, stream);
  box_filter->apply(mean_Ip, mean_Ip, stream);
  cv::cuda::multiply(mean_I, mean_p, cov_Ip, 1, -1, stream);
  cv::cuda::subtract(mean_Ip,
                     cov_Ip,
                     cov_Ip,
                     cv::noArray(),
                     -1,
                     stream); // this is the covariance of (I, p) in each local patch.

  cv::cuda::GpuMat a, b;
  cv::cuda::add(var_I, cv::Scalar(eps), a, cv::noArray(), -1, stream);
  cv::cuda::divide(cov_Ip, a, a, 1, -1, stream); // Eqn. (5) in the paper;

  cv::cuda::multiply(a, mean_I, b, 1, -1, stream);
  cv::cuda::subtract(mean_p, b, b, cv::noArray(), -1, stream); // Eqn. (6) in the paper;

  box_filter->apply(a, a, stream);
  box_filter->apply(b, b, stream);

  cv::cuda::multiply(a, I, a, 1, -1, stream);
  cv::cuda::add(a, b, a, cv::noArray(), -1, stream);

  return a;
}

扩展讨论

(1)相比双边滤波,导向滤波有速度快和避免梯度反转等优势。
在这里插入图片描述
(2)基于原始的导向滤波算法引入resize得到的Fast导向滤波能够将时间复杂度从O(N)降到O(N / r^2),同时保证滤波结果图像质量损失不大。其中r是resize(或称之为scale)的倍数。
在这里插入图片描述

在这里插入图片描述

参考资料

[1] wikipedia - Edge-preserving smoothing
[2] 维基百科 - 引导影像滤波器
[3] Guided Image Filtering - Kaiming He
[4] GitHub - opencv_contrib/modules/ximgproc/src/guided_filter.cpp
[5] OpenCV Docs - GuidedFilter
[6] 知乎 - 导向滤波原理(Guided Filter)
[7] 知乎 - 引导滤波guideFilter原理推导与实验
[8] 维基百科 - 方差
[9] 维基百科 - 协方差
[10] 知网 - 引导滤波算法的CUDA加速实现
[11] 豆丁网 - 引导滤波算法的CUDA加速实现
[12] GitHub - acstacey/GLFCV/src/guidedfilter.cpp
[13] GitHub - xxxzhou/oeip/oeip-win-cuda/GuidedFilterLayer.cpp
[14] cnblogs - CUDA加opencv复现导向滤波算法
[15] GitHub - foowaa/3DVisionUnit/GuidedFitlerOptimzation_CUDA/GuidedFilter.cu
[16] GitHub - TracelessLe/pybind11_guidedfilter_cuda
[17] csdn - 双边滤波原理浅析
[18] 导向滤波 Guided Image Filtering

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
GIF导向图像滤波是一种基于导向滤波的图像处理方法。它主要通过引入一个导向场来帮助滤波过程。导向滤波是一种基于本地图像结构进行滤波的方法,通过在每个像素位置的局部邻域内的像素值来计算输出像素的值。 GIF导向图像滤波的原理是先计算出导向场。导向场是根据输入图像的某种特征来计算的,例如输入图像的梯度方向。这个导向场可以用于指导滤波过程中的像素值计算,使得滤波结果更加准确。 具体地说,对于每个像素,通过计算其邻域内像素的梯度方向来获得导向场的值。然后,在滤波过程中,不再仅仅考虑像素值的差异,而是同时考虑像素值的差异和导向场的差异。 在计算输出像素的值时,使用一个权重函数来结合像素值差异和导向场差异。这个权重函数可以根据具体的应用而定,常见的有高斯权重和双边滤波权重。根据权重函数,计算出邻域内像素的加权平均值,作为输出像素的值。 通过引入导向场,GIF导向图像滤波可以在保持图像细节的同时减少噪声和平滑图像。导向场能够帮助滤波器更好地理解图像的结构,从而得到更加精确的滤波结果。 总之,GIF导向图像滤波的原理是通过引入导向场来指导滤波过程,以达到更好的滤波效果。该方法在图像处理中具有广泛的应用,可以用于图像去噪、图像增强等方面。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

TracelessLe

❀点个赞加个关注再走吧❀

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

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

打赏作者

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

抵扣说明:

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

余额充值