from:http://blog.csdn.net/wds555/article/details/23176313

何凯明去雾算法中的导向滤波实现,原文地址导向滤波。

导向图像I,滤波输入图像p以及输出图像q。像素点 i 处的滤波结果是被表达成一个加权平均:


假设导向滤波器在导向图像I和滤波输出q之间是一个局部线性模型:



最小化下面的窗口Wk的代价函数:


用来确定a,b的值

其中

论文所给算法如下:

matlab代码如下:

[plain] view plaincopy
  1. function q = guidedfilter(I, p, r, eps)
  2. %   GUIDEDFILTER   O(1) time implementation of guided filter.
  3. %
  4. %   - guidance image: I (should be a gray-scale/single channel image)
  5. %   - filtering input image: p (should be a gray-scale/single channel image)
  6. %   - local window radius: r
  7. %   - regularization parameter: eps
  8. [hei, wid] = size(I);
  9. N = boxfilter(ones(hei, wid), r); % the size of each local patch; N=(2r+1)^2 except for boundary pixels.
  10. mean_I = boxfilter(I, r) ./ N;
  11. mean_p = boxfilter(p, r) ./ N;
  12. mean_Ip = boxfilter(I.*p, r) ./ N;
  13. cov_Ip = mean_Ip - mean_I .* mean_p; % this is the covariance of (I, p) in each local patch.
  14. mean_II = boxfilter(I.*I, r) ./ N;
  15. var_I = mean_II - mean_I .* mean_I;
  16. a = cov_Ip ./ (var_I + eps); % Eqn. (5) in the paper;
  17. b = mean_p - a .* mean_I; % Eqn. (6) in the paper;
  18. mean_a = boxfilter(a, r) ./ N;
  19. mean_b = boxfilter(b, r) ./ N;
  20. q = mean_a .* I + mean_b; % Eqn. (8) in the paper;
  21. end
[plain] view plaincopy
  1. function imDst = boxfilter(imSrc, r)
  2. %   BOXFILTER   O(1) time box filtering using cumulative sum
  3. %
  4. %   - Definition imDst(x, y)=sum(sum(imSrc(x-r:x+r,y-r:y+r)));
  5. %   - Running time independent of r;
  6. %   - Equivalent to the function: colfilt(imSrc, [2*r+1, 2*r+1], 'sliding', @sum);
  7. %   - But much faster.
  8. [hei, wid] = size(imSrc);
  9. imDst = zeros(size(imSrc));
  10. %cumulative sum over Y axis
  11. imCum = cumsum(imSrc, 1);
  12. %difference over Y axis
  13. imDst(1:r+1, :) = imCum(1+r:2*r+1, :);
  14. imDst(r+2:hei-r, :) = imCum(2*r+2:hei, :) - imCum(1:hei-2*r-1, :);
  15. imDst(hei-r+1:hei, :) = repmat(imCum(hei, :), [r, 1]) - imCum(hei-2*r:hei-r-1, :);
  16. %cumulative sum over X axis
  17. imCum = cumsum(imDst, 2);
  18. %difference over Y axis
  19. imDst(:, 1:r+1) = imCum(:, 1+r:2*r+1);
  20. imDst(:, r+2:wid-r) = imCum(:, 2*r+2:wid) - imCum(:, 1:wid-2*r-1);
  21. imDst(:, wid-r+1:wid) = repmat(imCum(:, wid), [1, r]) - imCum(:, wid-2*r:wid-r-1);
  22. end

以下为单通道图像导向滤波opencv实现:

[cpp] view plaincopy
  1. #include "myGuidedFilter_Mat.h"
  2. CvMat * cumsum(CvMat *src,int rc)
  3. {
  4. CvMat *Imdst = cvCreateMat(src->rows,src->cols,CV_64FC1);
  5. Imdst=cvCloneMat(src);
  6. if (rc==1)
  7. {
  8. for(int y=1;y<src->height;y++)
  9. {
  10. double *ptr0=(double *)(Imdst->data.ptr+(y-1)*Imdst->step);
  11. double *ptr=(double *)(Imdst->data.ptr+y*Imdst->step);
  12. for(int x=0;x<src->width;x++)
  13. {
  14. ptr[x]=ptr0[x]+ptr[x];
  15. //cvSetReal2D(Imdst,y,x,cvGetReal2D(Imdst,y-1,x)+cvGetReal2D(Imdst,y,x));
  16. }
  17. }
  18. }
  19. else if (rc==2)
  20. {
  21. for(int y=0;y<src->height;y++)
  22. {
  23. double *ptr=(double *)(Imdst->data.ptr+y*Imdst->step);
  24. for(int x=1;x<src->width;x++)
  25. {
  26. ptr[x]=ptr[x-1]+ptr[x];
  27. //cvSetReal2D(Imdst,y,x,cvGetReal2D(Imdst,y,x-1)+cvGetReal2D(Imdst,y,x));
  28. }
  29. }
  30. }
  31. return Imdst;
  32. }
  33. CvMat * boxFilter(CvMat *src,int r)
  34. {
  35. CvMat *Imdst = cvCreateMat(src->rows,src->cols,CV_64FC1);
  36. Imdst=cvCloneMat(src);
  37. CvMat *subImage;
  38. //imCum = cumsum(imSrc, 1);
  39. CvMat *imCum = cumsum(Imdst,1);
  40. //imDst(1:r+1, :) = imCum(1+r:2*r+1, :);
  41. for (int y = 0;y<r;y++)
  42. {
  43. //double *ptrDst=(double *)Imdst->data.ptr+y*Imdst->step;
  44. //double *ptrCum=(double *)imCum->data.ptr+(y+r)*imCum->step;
  45. for(int x = 0;x<Imdst->width;x++)
  46. {
  47. //ptrDst[x]=ptrCum[x];
  48. cvSetReal2D(Imdst,y,x,cvGetReal2D(imCum,y+r,x));
  49. }
  50. }
  51. //imDst(r+2:hei-r, :) = imCum(2*r+2:hei, :) - imCum(1:hei-2*r-1, :);
  52. for (int y = r+1;y<Imdst->height-r-1;y++)
  53. {
  54. for(int x = 0;x<Imdst->width;x++)
  55. {
  56. cvSetReal2D(Imdst,y,x,(cvGetReal2D(imCum,y+r,x)-cvGetReal2D(imCum,y-r-1,x)));
  57. }
  58. }
  59. //imDst(hei-r+1:hei, :) = repmat(imCum(hei, :), [r, 1]) - imCum(hei-2*r:hei-r-1, :);
  60. subImage = cvCreateMat(r,Imdst->width,CV_64FC1);
  61. CvMat *tem=cvCreateMat(1,Imdst->width,CV_64FC1);
  62. cvGetRow(imCum,tem,imCum->height-1);
  63. cvRepeat(tem,subImage);
  64. /*for(int y=0;y<r;y++)
  65. {
  66. for(int x=0;x<Imdst->width;x++)
  67. {
  68. cvSetReal2D(subImage,y,x,cvGetReal2D(imCum,Imdst->height-1,x));
  69. }
  70. }*/
  71. for (int y = Imdst->height-r;y<Imdst->height;y++)
  72. {
  73. for(int x = 0;x<Imdst->width;x++)
  74. {
  75. cvSetReal2D(Imdst,y,x,cvGetReal2D(subImage,y-Imdst->height+r,x)-cvGetReal2D(imCum,y-r-1,x));
  76. }
  77. }
  78. cvReleaseMat(&subImage);
  79. cvReleaseMat(&tem);
  80. imCum = cumsum(Imdst, 2);
  81. //imDst(:, 1:r+1) = imCum(:, 1+r:2*r+1);
  82. for (int y = 0;y<Imdst->height;y++)
  83. {
  84. for(int x = 0;x<r;x++)
  85. {
  86. cvSetReal2D(Imdst,y,x,cvGetReal2D(imCum,y,x+r));
  87. }
  88. }
  89. //imDst(:, r+2:wid-r) = imCum(:, 2*r+2:wid) - imCum(:, 1:wid-2*r-1);
  90. for (int y = 0;y<Imdst->height;y++)
  91. {
  92. for(int x = r+1;x<Imdst->width-r-1;x++)
  93. {
  94. cvSetReal2D(Imdst,y,x,(cvGetReal2D(imCum,y,x+r)-cvGetReal2D(imCum,y,x-r-1)));
  95. }
  96. }
  97. //imDst(:, wid-r+1:wid) = repmat(imCum(:, wid), [1, r]) - imCum(:, wid-2*r:wid-r-1);
  98. subImage = cvCreateMat(Imdst->height,r,CV_64FC1);
  99. tem=cvCreateMat(Imdst->height,1,CV_64FC1);
  100. cvGetCol(imCum,tem,imCum->width-1);
  101. cvRepeat(tem,subImage);
  102. /*for(int y=0;y<Imdst->height;y++)
  103. {
  104. for(int x=0;x<r;x++)
  105. {
  106. cvSetReal2D(subImage,y,x,cvGetReal2D(imCum,y,Imdst->width-1));
  107. }
  108. }*/
  109. for (int y = 0;y<Imdst->height;y++)
  110. {
  111. for(int x = Imdst->width-r;x<Imdst->width;x++)
  112. {
  113. cvSetReal2D(Imdst,y,x,cvGetReal2D(subImage,y,x-Imdst->width+r)-cvGetReal2D(imCum,y,x-r-1));
  114. }
  115. }
  116. cvReleaseMat(&subImage);
  117. return Imdst;
  118. }
  119. CvMat * myGuidedFilter_Mat(CvMat * I,CvMat *img_pp,int r, double eps)
  120. {
  121. int height = img_pp->height;
  122. int width = img_pp->width;
  123. int type = CV_64FC1;
  124. CvMat *ones = cvCreateMat(height,width,type);
  125. cvSet(ones,cvRealScalar(1));
  126. CvMat * N = boxFilter(ones,r);
  127. //求I的均值
  128. CvMat * mean_I = cvCreateMat(height,width,type);
  129. cvDiv(boxFilter(I,r),N,mean_I);
  130. //求P的均值
  131. CvMat * mean_p = cvCreateMat(height,width,type);
  132. cvDiv(boxFilter(img_pp,r),N,mean_p);
  133. //求I*P的均值
  134. CvMat * pr = cvCreateMat(height,width,type);
  135. cvMul(I,img_pp,pr);
  136. CvMat * mean_Ip = cvCreateMat(height,width,type);
  137. cvDiv(boxFilter(pr,r),N,mean_Ip);
  138. //求I与p协方差
  139. cvMul(mean_I,mean_p,pr);
  140. CvMat * cov_Ip = cvCreateMat(height,width,type);
  141. cvSub(mean_Ip,pr,cov_Ip);
  142. //求I的方差
  143. CvMat * var_I  = cvCreateMat(height,width,type);
  144. cvMul(I,I,pr);
  145. cvDiv(boxFilter(pr,r),N,var_I);
  146. cvMul(mean_I,mean_I,pr);
  147. cvSub(var_I,pr,var_I);
  148. //求a
  149. CvMat * a = cvCreateMat(height,width,type);
  150. cvAddS(var_I,cvScalar(eps),var_I);
  151. cvDiv(cov_Ip,var_I,a);
  152. //求b
  153. CvMat * b = cvCreateMat(height,width,type);
  154. cvMul(a,mean_I,pr);
  155. cvSub(mean_p,pr,b);
  156. //求a的均值
  157. CvMat * mean_a = cvCreateMat(height,width,type);
  158. cvDiv(boxFilter(a,r),N,mean_a);
  159. //求b的均值
  160. CvMat * mean_b = cvCreateMat(height,width,type);
  161. cvDiv(boxFilter(b,r),N,mean_b);
  162. //求Q
  163. CvMat * q = cvCreateMat(height,width,type);
  164. cvMul(mean_a,I,a);
  165. cvAdd(a,mean_b,q);
  166. cvReleaseMat(&ones);
  167. cvReleaseMat(&mean_I);
  168. cvReleaseMat(&mean_p);
  169. cvReleaseMat(&pr);
  170. cvReleaseMat(&mean_Ip);
  171. cvReleaseMat(&cov_Ip);
  172. cvReleaseMat(&var_I);
  173. cvReleaseMat(&a);
  174. cvReleaseMat(&b);
  175. cvReleaseMat(&mean_a);
  176. cvReleaseMat(&mean_b);
  177. return q;
  178. }

opencv 实现导向滤波相关推荐

  1. OpenCV中导向滤波介绍与应用

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 导向滤波介绍 导向滤波是使用导向图像作为滤波内容图像,在导向图像上 ...

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

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

  3. 【OpenCV 例程200篇】61. 导向滤波(Guided filter)

    [OpenCV 例程200篇]61. 导向滤波(Guided filter) 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续 ...

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

    http://blog.csdn.net/kuweicai/article/details/78385871 1. 导向滤波简介 导向滤波是何凯明在学生时代提出的一个保边滤波(edge-preserv ...

  5. 【OpenCV图像处理】十七、图像的导向滤波

    http://blog.csdn.net/qq_34784753/article/details/70229009?locationNum=12&fps=1 导向图滤波是一种图像滤波技术,通过 ...

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

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

  7. 在OpenCV里实现导向滤波

    前面学习了双边滤波和联合滤波,都可以保边滤波,计算方式比较类似,都是使用相似性权重模板,下面来介绍一种不依赖于权重模板的保边滤波的另外一种方法-导向滤波.导向滤波比前面两种滤波优点有计算速度快,并且细 ...

  8. Opencv-Python-导向滤波快速导向滤波

    版本:Python:2.7.15  OpenCV:2.4.13 导向滤波算法原理 原理可以看博主:白马负金羁 的文章导向滤波(Guided Filter)的解析与实现,对原理解释十分通俗易懂. 导向滤 ...

  9. 导向滤波快速导向滤波及引导图的选择

    引导图的选择 我主要说的导向滤波其中的引导图选择问题. 百度百科的定义 : 导向图滤波是一种图像滤波技术 ,通过一张引导图G(导向图),对目标图像P(输入图像)进行滤波处理,使得最后的输出图像大体上与 ...

最新文章

  1. [Swift]LeetCode218. 天际线问题 | The Skyline Problem
  2. 困扰数学家25年的“切苹果”难题,被一位华人统计学博士解决了
  3. 老男孩教育每日一题-第108天-php-fpm优化关闭危险参数有哪些?
  4. Nuxt如何发起跨域资源请求?
  5. C#下的Web应用程序设计过程
  6. 一定质量的封闭气体被压缩后_多晶硅氯氢化装置补充氢隔膜压缩机十字头铜套磨损原因分析与改善探讨...
  7. python+ seleniumAPPium自动化 page Object 设计模式
  8. (转载)java中super的两种用法
  9. opencvpython图像代码_PythonOpenCV各种图像库的图像读写 增强 方式的简单介绍(附代码)...
  10. xtrabackup 2.4.3 BUG
  11. SegNet 论文解析
  12. [笔记分享] [Camera] 相机的flash led功能小结
  13. apache设置开机启动启动
  14. Windows 使用学习
  15. lunix 下编译draco遇到的问题及解决办法
  16. c语言邻接表的普里姆算法,图的遍历和生成树求解实现(邻接矩阵、邻接表 —图的深度广度遍历算法的实现和最小生成树PRIM和KRU...
  17. 性能测试LoadRunner
  18. homebrew php 扩展,Mac homebrew-1.5以后安装php扩展的方法
  19. MySQL数据库下载与安装
  20. 【Python金融量化 9- 100 】九、预测股票收益方法总结

热门文章

  1. win10语言栏不见了_慧投电脑投影仪win10语言栏不见了怎么办?!
  2. 购物网站Laravel版
  3. 利用决策树算法对sklearn中红酒数据集进行可视化分类
  4. 百度贴吧下载图片 【可搜索】
  5. python基于词语情感色彩进行数据分析(jieba库)
  6. 单片机应用系统设计技术——单片机体育比赛电子计时器
  7. Junction 详细使用方法
  8. cad2016中选择全图字体怎么操作_没有下载安装CAD软件怎么打印CAD图纸?快看这里...
  9. 北斗三号频点_北斗第三代RNSS多频点接收模块的制造方法
  10. 最好用的API调试接口 在线接口测试工具