http://blog.csdn.net/kuweicai/article/details/78385871

1. 导向滤波简介

导向滤波是何凯明在学生时代提出的一个保边滤波(edge-preserving smoothing)算法。何凯明在cv圈应该算是名人了,学生时代关于图像去雾的研究就以第一作者的身份获得Best Paper Award(CVPR 2009),而且今年刚刚又斩获Marr Prize(ICCV 2017)。更多关于何凯明的最新研究动态可以点击以下链接何凯明。

导向滤波顾名思义,就是有选择(导向)性的滤波,其与我们经常提及的高斯滤波、双边滤波相比,它具有导向性,说具体点就是,它通过输入一副图像(矩阵)作为导向图,这样滤波器就知道什么地方是边缘,这样就可以更好的保护边缘,最终达到在滤波的同时,保持边缘细节。所以有个说法是导向滤波是各向异性的滤波器,而高斯滤波、双边滤波这些是各向同性滤波器,我觉得也是很贴切。

导向滤波作为一种保边滤波,可以运用在很多场合,比如美颜,去雾,三维重建等。

如果你仅仅只是需要运用这个算法,现在opencv 3.0和MATLAB 14都已经添加了guided filter的API,可以直接调用。

opencv中的API如下void cv::ximgproc::guidedFilter(),具体的可以参考opencv的帮助文档关于导向滤波的介绍guidedFilter。

但是需要提醒的是,opencv中guidedFilter()函数包含在ximgproc模块下,但是从官方下载的标准的opencv.exe程序中并不包含该模块,需要分别下载opencv的source文件和contrib模块的source文件,然后自己编译,具体可以参考opencv3.1.0+contrib模块编译总结。

2. 导向滤波的原理

查看了很多相关的资料,觉得白马负金羁的导向滤波(Guided Filter)的解析与实现一文将其原理解释的非常通俗易懂了,这里就不再赘述。仅给出最后的推导结果,其中fmean为一个窗口半径为r的均值滤波器(对应的窗口大小为2r+1),corr为相关,var为方差,cov为协方差。

3. opencv实现代码

这一部分主要参考了

OpenCV导向滤波(引导滤波)实现(Guided Filter)代码,以及使用颜色先验算法去雾中的代码,进行了修改和注释。GuidedFilter()调用opencv自带的boxFilter()函数来实现求取平均值。关于opencv自带的boxFilter()函数的相关介绍可以参考

boxFilter。

GuidedFilter()的代码,比较容易理解:

cv::Mat GuidedFilter(cv::Mat I,cv::Mat p,intr,doubleeps)

{

/*

% GUIDEDFILTER   O(N) time implementation of guided filter.

%

%   - guidance image: I (should be a gray-scale/single channel image)

%   - filtering input image: p (should be a gray-scale/single channel image)

%   - local window radius: r

%   - regularization parameter: eps

*/

cv::Mat _I;

I.convertTo(_I, CV_64FC1,1.0/255);

I = _I;

cv::Mat _p;

p.convertTo(_p, CV_64FC1,1.0/255);

p = _p;

//[hei, wid] = size(I);

inthei = I.rows;

intwid = I.cols;

r=2*r+1;//因为opencv自带的boxFilter()中的Size,比如9x9,我们说半径为4

//mean_I = boxfilter(I, r) ./ N;

cv::Mat mean_I;

cv::boxFilter(I, mean_I, CV_64FC1,cv::Size(r, r));

//mean_p = boxfilter(p, r) ./ N;

cv::Mat mean_p;

cv::boxFilter(p, mean_p, CV_64FC1,cv::Size(r, r));

//mean_Ip = boxfilter(I.*p, r) ./ N;

cv::Mat mean_Ip;

cv::boxFilter(I.mul(p), mean_Ip, CV_64FC1,cv::Size(r, r));

//cov_Ip = mean_Ip - mean_I .* mean_p; % this is the covariance of (I, p) in each local patch.

cv::Mat cov_Ip = mean_Ip - mean_I.mul(mean_p);

//mean_II = boxfilter(I.*I, r) ./ N;

cv::Mat mean_II;

cv::boxFilter(I.mul(I), mean_II, CV_64FC1,cv::Size(r, r));

//var_I = mean_II - mean_I .* mean_I;

cv::Mat var_I = mean_II - mean_I.mul(mean_I);

//a = cov_Ip ./ (var_I + eps); % Eqn. (5) in the paper;

cv::Mat a = cov_Ip / (var_I + eps);

//b = mean_p - a .* mean_I; % Eqn. (6) in the paper;

cv::Mat b = mean_p - a.mul(mean_I);

//mean_a = boxfilter(a, r) ./ N;

cv::Mat mean_a;

cv::boxFilter(a, mean_a, CV_64FC1,cv::Size(r, r));

//mean_b = boxfilter(b, r) ./ N;

cv::Mat mean_b;

cv::boxFilter(b, mean_b, CV_64FC1,cv::Size(r, r));

//q = mean_a .* I + mean_b; % Eqn. (8) in the paper;

cv::Mat q = mean_a.mul(I) + mean_b;

returnq;

}

需要注意的是,上面的函数只能对单一通道进行处理(如果是多通道,需要split后进行滤波,然后merge)。下面是调用GuidedFilter(),r=16, eps=0.01,对原图像进行滤波的结果。

4. 快速导向滤波

导向滤波的时间复杂度为O(N),其中N为像素点的个数。

何凯明在2015又发表了一篇《Fast Guided Filter》的文章,阐述了一种很实用的更快速的导向滤波流程。如下所示。其本质是通过下采样减少像素点,计算mean_a & mean_b后进行上采样回复到原有的尺寸大小。假设缩放比例为s,那么缩小后像素点的个数为N/s^2,那么时间复杂度变为O(N/s^2)(只是需要注意的是上采样和下采样本身也是有时间消化的)。

基于上面的理论,只需调用resize()函数来实现下采样和上采样,关于resize()函数的使用可以参考

resize()代码如下:

cv::Mat fastGuidedFilter(cv::Mat I_org,cv::Mat p_org,intr,doubleeps,ints)

{

/*

% GUIDEDFILTER   O(N) time implementation of guided filter.

%

%   - guidance image: I (should be a gray-scale/single channel image)

%   - filtering input image: p (should be a gray-scale/single channel image)

%   - local window radius: r

%   - regularization parameter: eps

*/

cv::Mat I,_I;

I_org.convertTo(_I, CV_64FC1,1.0/255);

resize(_I,I,Size(),1.0/s,1.0/s,1);

cv::Mat p,_p;

p_org.convertTo(_p, CV_64FC1,1.0/255);

//p = _p;

resize(_p, p, Size(),1.0/s,1.0/s,1);

//[hei, wid] = size(I);

inthei = I.rows;

intwid = I.cols;

r = (22* r +1)/s+1;//因为opencv自带的boxFilter()中的Size,比如9x9,我们说半径为4

//mean_I = boxfilter(I, r) ./ N;

cv::Mat mean_I;

cv::boxFilter(I, mean_I, CV_64FC1,cv::Size(r, r));

//mean_p = boxfilter(p, r) ./ N;

cv::Mat mean_p;

cv::boxFilter(p, mean_p, CV_64FC1,cv::Size(r, r));

//mean_Ip = boxfilter(I.*p, r) ./ N;

cv::Mat mean_Ip;

cv::boxFilter(I.mul(p), mean_Ip, CV_64FC1,cv::Size(r, r));

//cov_Ip = mean_Ip - mean_I .* mean_p; % this is the covariance of (I, p) in each local patch.

cv::Mat cov_Ip = mean_Ip - mean_I.mul(mean_p);

//mean_II = boxfilter(I.*I, r) ./ N;

cv::Mat mean_II;

cv::boxFilter(I.mul(I), mean_II, CV_64FC1,cv::Size(r, r));

//var_I = mean_II - mean_I .* mean_I;

cv::Mat var_I = mean_II - mean_I.mul(mean_I);

//a = cov_Ip ./ (var_I + eps); % Eqn. (5) in the paper;

cv::Mat a = cov_Ip / (var_I + eps);

//b = mean_p - a .* mean_I; % Eqn. (6) in the paper;

cv::Mat b = mean_p - a.mul(mean_I);

//mean_a = boxfilter(a, r) ./ N;

cv::Mat mean_a;

cv::boxFilter(a, mean_a, CV_64FC1,cv::Size(r, r));

Mat rmean_a;

resize(mean_a, rmean_a, Size(I_org.cols, I_org.rows),1);

//mean_b = boxfilter(b, r) ./ N;

cv::Mat mean_b;

cv::boxFilter(b, mean_b, CV_64FC1,cv::Size(r, r));

Mat rmean_b;

resize(mean_b, rmean_b, Size(I_org.cols, I_org.rows),1);

//q = mean_a .* I + mean_b; % Eqn. (8) in the paper;

cv::Mat q = rmean_a.mul(_I) + rmean_b;

returnq;

}

取s==8,计算结果和之前的guidedFilter()的计算结果如下所示:

而计算时间却从 338.808ms降到100.856ms,但是滤波结果从肉眼观察几乎没有降低。

快速导向滤波 matlab,导向滤波小结:从导向滤波(guided filter)到快速导向滤波(fast guide filter)的原理,应用及opencv实现代码...相关推荐

  1. 导向滤波小结:从导向滤波(guided filter)到快速导向滤波(fast guide filter)的原理,应用及opencv实现代码

    1. 导向滤波简介 导向滤波是何凯明在学生时代提出的一个保边滤波(edge-preserving smoothing)算法.何凯明在cv圈应该算是名人了,学生时代关于图像去雾的研究就以第一作者的身份获 ...

  2. 详解——导向滤波(Guided Filter)和快速导向滤波

    文章目录 导读 原理推导 导向滤波的应用 导向滤波的实现 快速导向滤波的实现 算法效果 代码 参考 导读 在图像滤波算法中,导向滤波.双边滤波.最小二乘滤波并称三大保边滤波器,他们是各向异性滤波器.相 ...

  3. 三种经典图像滤波方法介绍——双边滤波(Bilateral filter)、导向滤波(Guided Fliter)、滚动导向滤波(RollingGuidedFilter)

    文章目录 一.前言 二.双边滤波(Bilateral filter) 2.1 双边滤波的理论介绍及公式推导 2.2 双边滤波的matlab程序实现 三.导向滤波(Guided Fliter) 3.1 ...

  4. 频域滤波(matlab)

    频域滤波 频率域图像增强首先通过傅里叶变换将图像从空间域转变成频率域,然后在频率域内对图像进行处理,最后通过傅里叶反变换转换到空间域.频率域内的图像增强通常包括低通滤波.高通滤波.同态滤波等. 设f( ...

  5. 引导滤波matlab代码实现,引导图滤波(Guided Image Filtering)原理以及OpenCV实现

    引导图滤波器是一种自适应权重滤波器,能够在平滑图像的同时起到保持边界的作用,具体公式推导请查阅原文献<Guided Image Filtering>以及matlab源码:http://ka ...

  6. 频率域滤波matlab函数,频率域滤波(2) - osc_t0xmr011的个人空间 - OSCHINA - 中文开源技术交流社区...

    一.频率域滤波的基本步骤: 1)使用函数tofloat把输入图像转换为浮点图像(im2double函数也可以) [f,revertclass] = tofloat(f) 2)使用函数paddedsiz ...

  7. kalman滤波的matlab,kalman滤波matlab实现

    <kalman滤波matlab实现>由会员分享,可在线阅读,更多相关<kalman滤波matlab实现(8页珍藏版)>请在人人文库网上搜索. 1.function S = do ...

  8. 逆谐波滤波matlab,基于MATLAB仿真的SPWM逆变电路谐波分析及滤波器设计

    第 7 卷第 3 期 2010 年 9 月 长 沙 理 工 大 学 学 报 ( 自 然 科 学 版 ) Journal of Changsha University of Science and Te ...

  9. 中值滤波matlab

    摘  要 中值滤波技术是一种在去除噪声的同时能较好保护图像边缘细节的非线性技术,在图像增强和恢复等领域中得到了广泛的应用.文章阐述了中值滤波的原理和特点,并使用软件工具MATLAB实现了图像的中值滤波 ...

最新文章

  1. Nginx配置中文域名
  2. 如何使用myFocus插件制作焦点图效果
  3. git每次操作提示输入密码问题解决
  4. Python这门语言为什么适合初学者?88.7%的小白听了会感谢选择它
  5. 牛!Python 全栈必备的 150 个实战案例,一次性获得!
  6. java base64 显示不完整_如何解决CAD图纸显示不完整、图纸无效?一分钟教你,不允许错过...
  7. SpringSecurity 流程图
  8. linux修改私钥的密码,linux使用密钥+密码登录ssh(centos7)
  9. jquery 2.0.3代码结构
  10. 【优化覆盖】基于matlab虚拟力算法求解无线网络传感覆盖优化问题【含Matlab源码 1187期】
  11. Android架构 armeabi、armeabi-v7a、arm64-v8a、x86详解
  12. matlab2016 wavread,matlab 7.10里面的wavread函数不能打开.wav文件。我的wav文件是电脑自带的录音机录的...
  13. AUBO E系列教育科研型机器人QA--持续更新中
  14. iOS如何完成蓝牙打印机功能
  15. 数据分析基础篇16讲之07用户画像:标签化就是数据的抽象能力
  16. 外置USB供电与内置锂电池供电自动切换电路,便携电子设备常用,经典电路必须掌握...
  17. 如何修复网页被劫持、页面劫持的解决方法、详细
  18. struts2优点总结
  19. JAVA 11.11
  20. 水晶报表使用经验总结

热门文章

  1. p值 统计学意义_什么是统计意义? P值定义以及如何计算
  2. 阿里云天池学习赛-零基础入门数据分析-学术前沿趋势分析(task1)
  3. mac常见问题(五) Mac 无法开机
  4. R语言学习笔记:主成分分析及因子分析
  5. Arduino与Proteus仿真实例-LM75温度传感器驱动仿真
  6. 熊猫烧香.威金.落雪.SXS.ARP.网络执法管.AUTORUN.INF等高危病毒清除
  7. 并行传输VS串行传输
  8. chrome图片下载插件
  9. 1.SD卡初始化、写入、读取、数据比较
  10. uniapp中的分享功能实现(APP,小程序,公众号)