精华内容
下载资源
问答
  • 这里主要是main代码。实现的cpp在我资源里可以下载。// day11.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <iostream>...

    这里主要是main代码。
    实现的cpp在我资源里可以下载。

    // day11.cpp : Defines the entry point for the console application.
    //
    #include "stdafx.h"
    #include <iostream>;
    #include "opencv2/core/core.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "guidedfilter.h"
    #define ATV at<Vec3d>
    #define ATD at<double>
    #define ATU at<int>
    #define win_size 5
    #define omegar 0.95
    #define gfR 15
    #define gfE 0.001
    using namespace cv;
    using namespace std;
    Mat pick_patch(Mat& mat, int r, int c, int patch_size)
    {
     return mat(Range(r, r + patch_size), Range(c, c + patch_size));
    }
    double min3(double a, double b, double c)
    {
     if (a > b)
     {
      if (b > c)
      {
       return c;
      }
      else
      {
       return b;
      }
     }
     else
     {
      if (a < c)
      {
       return a;
      }
      else
      {
       return c;
      }
     }
    }
    double calMin(Mat &img)
    {
     double result;
     vector<Mat> temp;
     split(img, temp);
     Point minPoint;
     double minVal1 = 0;
     minMaxLoc(temp[0], &minVal1, NULL, &minPoint, NULL);
     double minVal2 = 0;
     minMaxLoc(temp[1], &minVal2, NULL, &minPoint, NULL);
     double minVal3 = 0;
     minMaxLoc(temp[2], &minVal3, NULL, &minPoint, NULL);
     result = min3(minVal1, minVal2, minVal3);
     return result;
    }
    Mat getDarkChannel(Mat &image, int winSize)
    {
     int nRows = image.rows;
     int nCols = image.cols;
     Mat result = Mat::zeros(nRows, nCols, CV_64FC1);
     /*
     Rect roi(winSize / 2, winSize / 2, nCols, nRows);
     Mat tempI = Mat::ones(nRows + (winSize / 2) * 2, nCols + (winSize / 2) * 2, CV_64FC3);
     image.copyTo(tempI(roi));
     */
     Mat tempI;
     copyMakeBorder(image, tempI, winSize / 2, winSize / 2, winSize / 2, winSize / 2, BORDER_REPLICATE);
     double temp = 0.0;
     Mat patch;
     for (int i = 0; i < nRows; ++i)
     {
      for (int j = 0; j < nCols; ++j)
      {
       patch = pick_patch(tempI, i, j, winSize);
       temp = calMin(patch);
       result.ATD(i, j) = temp;
      }
     }
     return result;
    }
    vector<double> getAtmosphere(Mat &img, Mat &darkChannel)
    {
     int m = img.rows;
     int n = img.cols;
     vector<double> result(3);
     int nPixels = m*n;
     int nSearchPixels = nPixels*0.01;
     Mat darkVect = darkChannel.reshape(0, nPixels);
     Mat imgVect = img.reshape(0, nPixels);
     Mat indices;
     sortIdx(darkVect, indices, SORT_EVERY_COLUMN + SORT_DESCENDING);
     vector<double> accumulator(3);
     accumulator[0] = 0.0;
     accumulator[1] = 0.0;
     accumulator[2] = 0.0;
     for (int i = 0; i < nSearchPixels; ++i)
     {
      accumulator[0] += imgVect.ATD(indices.ATU(i, 0), 0);
      accumulator[1] += imgVect.ATD(indices.ATU(i, 0), 1);
      accumulator[2] += imgVect.ATD(indices.ATU(i, 0), 2);
     }
     result[0] = accumulator[0] / nSearchPixels;
     result[1] = accumulator[1] / nSearchPixels;
     result[2] = accumulator[2] / nSearchPixels;
     return result;
    }
    Mat getTransmissionEstimate(Mat &img, vector<double> &atmosphere, double omega, int winSize)
    {
     Mat result;
     int m = img.rows;
     int n = img.cols;
     Mat tempAtm(1, 1, CV_64FC3);
     tempAtm.ATV(0, 0)[0] = atmosphere[0];
     tempAtm.ATV(0, 0)[1] = atmosphere[1];
     tempAtm.ATV(0, 0)[2] = atmosphere[2];
     Mat repAtmosphere = repeat(tempAtm, m, n);
     Mat tempDiv;
     divide(img, repAtmosphere, tempDiv);
     result = 1.0 - omega * getDarkChannel(tempDiv, win_size);
     return result;
    }
    Mat guidedfilter(Mat& source, Mat& guidedImage, int radius, double epsilon)
    {
     Mat result;
     Mat IP, I2;
     multiply(guidedImage, source, IP);
     multiply(guidedImage, guidedImage, I2);
     Mat meanI, meanP, meanIP, meanI2;
     Size wSize(2 * radius + 1, 2 * radius + 1);
     boxFilter(source, meanP, CV_64FC1, wSize);
     boxFilter(guidedImage, meanI, CV_64FC1, wSize);
     boxFilter(IP, meanIP, CV_64FC1, wSize);
     boxFilter(I2, meanI2, CV_64FC1, wSize);
     Mat varI = meanI2 - meanI.mul(meanI);
     Mat covIP = meanIP - meanI.mul(meanP);
     varI += epsilon;
     Mat a, b;
     divide(covIP, varI, a);
     b = meanP - a.mul(meanI);
     Mat meanA, meanB;
     boxFilter(a, meanA, CV_64FC1, wSize);
     boxFilter(b, meanB, CV_64FC1, wSize);
     result = meanA.mul(guidedImage) + meanB;
     return result;
    }
    Mat getRadiance(Mat &img, Mat &transmission, vector<double> &atmosphere)
    {
     Mat result;
     int m = img.rows;
     int n = img.cols;
     Mat tempAtm(1, 1, CV_64FC3);
     tempAtm.ATV(0, 0)[0] = atmosphere[0];
     tempAtm.ATV(0, 0)[1] = atmosphere[1];
     tempAtm.ATV(0, 0)[2] = atmosphere[2];
     Mat repAtmosphere = repeat(tempAtm, m, n);
     Mat maxTransmission(m, n, CV_64FC3);
     for (int i = 0; i < m; ++i)
     {
      for (int j = 0; j < n; ++j)
      {
       if (transmission.ATD(i, j) <= 0.1)
       {
        transmission.ATD(i, j) == 0.1;
       }
       maxTransmission.ATV(i, j)[0] = transmission.ATD(i, j);
       maxTransmission.ATV(i, j)[1] = transmission.ATD(i, j);
       maxTransmission.ATV(i, j)[2] = transmission.ATD(i, j);
      }
     }
     Mat tempDiv = img - repAtmosphere;
     divide(tempDiv, maxTransmission, result);
     result = result + repAtmosphere;
     for (int i = 0; i < m; ++i)
     {
      for (int j = 0; j < n; ++j)
      {
       if (result.ATV(i, j)[0] < 0.0)
       {
        result.ATV(i, j)[0] = 0.0;
       }
       if (result.ATV(i, j)[0] > 1.0)
       {
        result.ATV(i, j)[0] = 1.0;
       }
       if (result.ATV(i, j)[1] < 0.0)
       {
        result.ATV(i, j)[1] = 0.0;
       }
       if (result.ATV(i, j)[1] > 1.0)
       {
        result.ATV(i, j)[1] = 1.0;
       }
       if (result.ATV(i, j)[2] < 0.0)
       {
        result.ATV(i, j)[2] = 0.0;
       }
       if (result.ATV(i, j)[2] > 1.0)
       {
        result.ATV(i, j)[2] = 1.0;
       }
      }
     }
     return result;
    }
    int main()
    {
     Mat src = imread("009.bmp");// IMG_8766.jpg train.bmp tiananmen.png pumpkins.jpg IMG_8766.jpg
     int ratio = 1.0;
     resize(src, src, cv::Size(src.cols / ratio, src.rows / ratio));
     Mat tempImg;
     cvtColor(src, tempImg, CV_RGB2GRAY);
     int m = src.rows;
     int n = src.cols;
     src.convertTo(src, CV_64FC3, 1.0 / 255.0, 0);
     tempImg.convertTo(tempImg, CV_64FC1, 1.0 / 255.0, 0);
     Mat darkChannel;
     darkChannel = getDarkChannel(src, win_size);
     Mat temp;
     darkChannel.convertTo(temp, CV_8UC3, 255.0, 0);
    // imshow("temp", temp);
     vector<double> atmosphere(3);
     atmosphere = getAtmosphere(src, darkChannel);
     cout << atmosphere[0] << " " << atmosphere[1] << " " << atmosphere[2] << endl;
     Mat transEst = getTransmissionEstimate(src, atmosphere, omegar, win_size);
     Mat x = guidedFilter(tempImg, transEst, gfR, gfE);
    // imshow("x ", x);
     Mat result;
     result = getRadiance(src, x, atmosphere);
     result.convertTo(result, CV_8UC3, 255.0, 0);
     imwrite("myresult.jpg", result);
     imshow("result", result);
     waitKey();
     return 0;
    }

    展开全文
  • 导向滤波是处理速度较快的一种保边滤波器,适用范围也很广泛,去噪,细节增强以及HDR等地方都可以得到较好的结果,先从原理公式上进行推到,详细如下: 我在学习导向滤波的时候参考了下面这个网页,讲得挺详细的,...

    导向滤波是处理速度较快的一种保边滤波器,适用范围也很广泛,去噪,细节增强以及HDR等地方都可以得到较好的结果,先从原理公式上进行推到,详细如下:

    我在学习导向滤波物理意义的时候参考了下面这个网页:
    引导滤波/导向滤波(Guided Filter)
    我在学习导向滤波公式推导的时候参考了下面这个网页,讲得挺详细的,大家可以参考学习:
    导向滤波(Guided Filter)公式详解

    为了给自己留个纪念,我推导的过程如下:

    展开全文
  • 导向滤波原理浅析

    2021-01-19 21:00:08
    在图像处理上,导向滤波器(Guided Image Filter)是一种能使图像平滑化的非线性滤波器。与双边滤波器(Bilateral Filter)相同,这个滤波器同样能够在清楚保持图像边界的情况下,达到让图像平滑的效果。 但不同于...

    前言

    在图像处理上,导向滤波器(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符合局部(以像素kk为中心的wkw_k窗口内)线性模型:
    在这里插入图片描述
    局部线性模型(local linear model)保证了结果图与导向图的edge一致(q=aI∇q = a∇I)。

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

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

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

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

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

    在这里插入图片描述

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

    双边滤波中的范围方差(range variance)参数σr2\sigma _{r}^{2}的功能和导向滤波的ϵ\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

    展开全文
  • 最近两天看了何凯明大神的导向滤波器(Guided Image Filtering),刚刚才顿悟整篇文章的核心。本文只针对于 的情况,即对图像 进行滤波处理。个人认为导向滤波器其实就是对均值滤波器的改进。由于均值滤波器会使图像...

            最近两天看了何凯明大神的导向滤波器(Guided Image Filtering),刚刚才顿悟整篇文章的核心。本文只针对于I=pI=p的情况,即对图像II进行滤波处理。个人认为导向滤波器其实就是对均值滤波器的改进。由于均值滤波器会使图像模糊,尤其是对图像的边缘影响较大。然而,对图像进行处理时,图像的主要信息都隐藏在边缘处。所以为了保护图像的边缘信息,又能具有良好的滤波效果,是不是有一种滤波器在图像平滑的地方进行均值滤波,而在图像边缘的地方不进行滤波,或者进行轻微的滤波,那么图像的边缘信息不就保留下来了么,而且平滑的地方还有很好的均值滤波效果。
            那么问题来了,如何才能知道到底是不是图像的边缘呢?这里何凯明大神选取的指标是方差。方差是表示被统计信息变化特征的量。方差越大,表示图片在这里变化越大,也就表示此处是图像里某一物体的边缘,此处的信息需要进行保护。方差越小,表示图片在这里变化较小,该处所含信息量较少,可以进行滤波平滑处理。
            边缘参数找到了,如何将边缘参数的信息反映到对图像的滤波处理上呢?何凯明大神此处选取的是对图片每一像素值的线性处理,方程为:
    qi=aiIi+bi(1) \begin{aligned} q_i=a_iI_i+b_i &amp;&amp; (1) \end{aligned}
            这里qiq_i是处理后的像素值,IiI_i是待处理的像素值。 aia_ibib_i是对像素值 进行线性处理的参数。且
    ai=σi2σi2+ϵ(2) \begin{aligned} a_i=\frac{\sigma_i^2}{\sigma_i^2+\epsilon} &amp;&amp; (2) \end{aligned}
    bi=μiaiμi(3) \begin{aligned} b_i=\mu_i-a_i\mu_i &amp;&amp; (3) \end{aligned}
            将(3)代入(1)得
    qi=ai(Iiμi)+μi(4) \begin{aligned} q_i=a_i(I_i-\mu_i)+\mu_i &amp;&amp; (4) \end{aligned}

            这里μi\mu_i为该点及附近点的均值(即:该点经过均值滤波器处理后的值), σi2\sigma_i^2为该点及附近点的方差。 ϵ\epsilon为一设置参数,用来表示图片此处平坦还是边缘的方差阈值。由式(2)可知,aia_i的范围为(0,1)。当σϵ\sigma \ll \epsilon时,表示图片此处平坦,则ai0a_i \approx 0qiμiq_i \approx \mu_i 。此处的滤波效果为经过均值滤波器的效果。当σiϵ\sigma_i \gg \epsilon时,表示图片此处变化较为剧烈,为边缘,则ai1a_i \approx 1, qiIiq_i \approx I_i结果为图片未经过任何处理。
    细读论文会发现,滤波的最终公式为:
    qi=aˉiIi+bˉi(5) \begin{aligned} q_i = \bar a_iI_i+\bar b_i &amp;&amp; (5) \end{aligned}
            分别对参数aia_ibib_i进行了一次均值滤波处理。这里我没太想明白。可能是作者嫌处理后的图像不够平滑,又做了一次平滑处理吧。近似相当于对式(1)得到的结果进行了一次均值滤波处理,但是作者可能又觉得对式(1)得到的结果进行均值滤波处理边缘信息丢失的比较严重,所以作者只对参数aia_ibib_i分别进行均值滤波处理。这样得到的图片会更加光滑一些,且边缘信息丢失的也不严重吧。

    展开全文
  • 导向滤波

    千次阅读 2014-07-21 11:35:42
    假设导向滤波器在导向图像I和滤波输出q之间是一个局部线性模型: 最小化下面的窗口Wk的代价函数: 用来确定a,b的值 其中 论文所给算法如下: matlab代码如下: [pla
  • 中值滤波器 ( Median Filter ) C++ 实现  http://blog.csdn.net/hhygcy/article/details/4325462 非线性滤波专场:中值滤波、双边滤波 http://blog.csdn.net/poem_qianmo/article/details/23184547 Fast Median ...
  • 图像导向滤波操作

    2016-11-18 21:02:11
    #include #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" using namespace std; using namespace cv;...// 导向滤波器 cv::Mat
  • opencv 实现导向滤波

    千次阅读 2015-10-27 19:05:12
    何凯明去雾算法中的导向滤波实现,原文地址导向滤波。 导向图像I,滤波输入图像p以及输出图像q。...假设导向滤波器在导向图像I和滤波输出q之间是一个局部线性模型: 最小化下面的窗口Wk的代价函数:
  • 目前视频分辨率已达1080p HD,而且小屏幕移动设备现在也开始以视频为导向。因此相关设计必须涉及到更低的供电电压(如3V)和更低功耗要求。同时,每个产品往往还带有多个视频通道。视频的不断发展前景意味着设计团队...
  • 以下内容均假设两幅图像已经对齐。...假设导向滤波器在导向图像I和滤波输出q之间是一个局部线性模型: 最小化下面的窗口Wk的代价函数: 用来确定a,b的值 其中, Guided Filter的输入和...
  • 转载自:pplong的博客 前面介绍了双边滤波器(bilateral filter,LBF),然而BF的权值是不稳定的,因此在...两者之间的差别就是JBF用了一个导向图作为值域权重的计算依据。下面我们通过数学公式展示二者的不同: 先看B
  • 该专利设计了一种快速保边滤波器,可以达到双边滤波的效果,而时间复杂度为O(l),实际上该算法也是基于局部均值方差信息,来进行边缘保留的。个人觉得算法介于局部均值滤波和导向滤波之间,有类似之处,大家可以对比...
  • 原文地址:联合双边滤波器(jointbilateralfilter)作者:pplong前面介绍了双边滤波器(bilateral filter,LBF),然而BF的权值是不稳定的,因此在边缘附近会出现一些翻转。...两者之间的差别就是LBF用了一个导向图作...
  • 双指数边缘平滑滤波器用于磨皮算法的尝试。  说起为什么会看到这个东西,那还真的绕一圈。首先在写《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果及其他。 ...
  • 美颜-磨皮算法

    2020-05-06 11:06:54
    先看一下磨皮算法的一般流程: 磨皮算法主要的模块有两个:滤波模块和肤色区域检测模块;...②导向滤波器 ③Surface Blur表面模糊滤波器 ④局部均值滤波器 ⑤加权小二乘滤波器(WLS滤波器) ⑥Smart...
  • 说起为什么会看到这个东西,那还真的绕一圈。首先在写《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理...一文时里面提到了导向滤波,然后看何凯明的《Guided Image Filtering》一...
  • Guided Image Filtering.pdf

    2019-12-20 16:36:28
    在本文中,我们提出了一种新颖的显式图像滤波器,称为导向滤波器。导引滤波器从局部线性模型派生而来,它通过考虑导引图像的内容来计算滤波输出,该图像可以是输入图像本身,也可以是其他图像。像流行的双边滤波器[1...
  • 导向滤波DEMO

    2018-06-22 14:35:34
    针对本人博客保边滤波器集锦文章,给出对应的导向滤波DEMO,算法与代码实现请参看博文。
  • 在图像滤波算法中,导向滤波、双边滤波、最小二乘滤波并称三大保边滤波器,他们是各向异性滤波器。相对于常见的均值滤波、高斯滤波等各向同性滤波器,他们最大的特点是在去除噪声的同时,能最大限度保持边缘不被平滑...
  • 导向滤波学习

    2019-12-03 22:03:31
    目录前言原理直观理解应用——边缘保持平滑滤波器 前言     今天的数字图像处理课讲到了导向滤波,就拿过来论文学习了一下,下面两篇博客对我帮助很大:  导向滤波算法分析公式推导很详细;  导向滤波详解代码...
  • 代码下载:http://openasic.org/category/1/运行依赖:(具体版本为当前的运行环境中的版本,并不需要完全一样)tensorflow-gpu 1.12.0 (用于模型搭建)numpy 1.16.2 (用于四叉树分解、导向滤波器等矩阵运算)matplotlib...
  • 利用边缘保持的图像平滑算法,构建了多尺度图像分解框架,将图像分解为不同尺度的基础层图像和若干细节层图像,同时结合导向滤波器,在每个分解图层实施显著性区域提取。通过加权重建进行融合信息的视觉增强,得到...

空空如也

空空如也

1 2 3 4
收藏数 74
精华内容 29
关键字:

导向滤波器