OpenCV中导向滤波介绍与应用

Posted OpenCV学堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV中导向滤波介绍与应用相关的知识,希望对你有一定的参考价值。

OpenCV中导向滤波介绍与应用

导向滤波介绍

导向滤波是使用导向图像作为滤波内容图像,在导向图像上实现局部线性函数表达,实现各种不同的线性变换,输出变形之后的导向滤波图像。根据需要,导向图像可以跟输入图像不同或者一致。假设I是导向图像、p是输入图像、q是导向滤波输出图像,导向滤波是作为局部线性模型描述导向图像I与输出图像q之间的关系。

OpenCV中导向滤波介绍与应用

导向滤波算法实现的一般步骤为:

  1. 读取导向图像I与输入图像P

  2. 输入参数 与 其中 表示窗口半径大小,单位是像素, 表示模糊程度

  3. 积分图计算I的均值与方差、输入图像的均值以及I与P的乘积IP

  4. 计算线性相关因子a与b

    • a=(IP-meanImeanP)/(Var_I+ )

    • b=meanP-ameanI

  5. 计算a与b的均值

  6. 使用均值得到导向滤波结果Q=meana*I+meanb

导向滤波最常用四个功能是:

  • 边缘保留滤波

  • 图像去噪声

  • 图像边缘羽化

  • 图像增强(对比度)

OpenCV中导向滤波函数

由于导向滤波计算均值与方差可以通过积分图查找快速得到,因此导向滤波的速度会很快,作为边缘保留滤波它比双线性滤波有明显的速度优势,OpenCV中在扩展模块ximgproc中实现了图像的导向滤波函数,相关API函数与参数解释如下:

 
   
   
 
  1. void cv::ximgproc::guidedFilter    (  

  2.    InputArray guide,// 导向图像

  3.    InputArray src,// 输入下

  4.    OutputArray dst,//导向滤波输出

  5.    int radius,//窗口半径大小

  6.    double eps,// 模糊程度

  7.    int dDepth = -1// 输出图像深度

  8. )

eps值越大图像模糊程度越大、半径radius值越大图像模糊程度越高。

代码演示

通过代码演示了导向滤波根据输入的导向图像不一样分别实现了图像滤波的边缘保留、去噪声、羽化、对比度提升功能。完整的演示代码如下:

 
   
   
 
  1. #include <opencv2/opencv.hpp>

  2. #include <opencv2/ximgproc.hpp>

  3. #include <iostream>

  4. using namespace cv;

  5. using namespace cv::ximgproc;

  6. using namespace std;

  7. void guide_demo(Mat &guide, Mat &input, int r, double e);

  8. void enhance_demo(Mat &guide, Mat &input, int r, double e);

  9. int main(int argc, char** argv) {

  10.    Mat src = imread("D:/vcprojects/images/guide.png");

  11.    if (src.empty()) {

  12.        printf("could not load image...\n");

  13.        return -1;

  14.    }

  15.    namedWindow("input", CV_WINDOW_AUTOSIZE);

  16.    imshow("input", src);

  17.    namedWindow("output", CV_WINDOW_AUTOSIZE);

  18.    int r = 2;

  19.    double eps = 0.1;

  20.    int type = 0;

  21.    while (true) {

  22.        char c = waitKey(50);

  23.        printf("input digit : %d\n", c);

  24.        if (c == 49) { // 边缘保留

  25.            type = 1;

  26.        }

  27.        else if (c == 50) {

  28.            type = 2;

  29.        }

  30.        else if (c == 51) {

  31.            type = 3;

  32.        }

  33.        else if (c == 52) { // 去噪

  34.            type = 4;

  35.        }

  36.        else if (c == 53) { // 羽化

  37.            type = 5;

  38.        }

  39.        else if (c == 54) { // 提升

  40.            type = 6;

  41.        }

  42.        else if (c == 27) {

  43.            break;

  44.        }

  45.        if (type == 0 || type == 1 || type == 2 || type == 3) {

  46.            guide_demo(src, src, pow(r, type), eps*eps * pow(r, type));

  47.        }

  48.        else if(type == 4){

  49.            Mat guide = imread("D:/vcprojects/images/gf_guide.png");

  50.            Mat input = imread("D:/vcprojects/images/gf_noise.png");

  51.            imshow("input", input);

  52.            guide_demo(guide, input, 8, 0.02*0.02);

  53.        }

  54.        else if (type == 5) {

  55.            Mat guide = imread("D:/vcprojects/images/twocat.png");

  56.            Mat input = imread("D:/vcprojects/images/twocat_mask.png", IMREAD_GRAYSCALE);

  57.            imshow("input", input);

  58.            guide_demo(guide, input, 60, 10e-6);

  59.        }

  60.        else {

  61.            Mat input = cv::imread("D:/vcprojects/images/demo.png");

  62.            input.convertTo(input, CV_32F, 1.0 / 255.0);

  63.            imshow("input", input);

  64.            int r = 16;

  65.            double eps = 0.1 * 0.1;

  66.            enhance_demo(input, input, r, eps);

  67.        }

  68.    }

  69.    waitKey(0);

  70.    return 0;

  71. }

  72. void guide_demo(Mat &guide, Mat &input, int r, double e) {

  73.    double eps = e * 255 * 255;

  74.    Mat dst;

  75.    guidedFilter(guide, input, dst, r, eps, -1);

  76.    imshow("output", dst);

  77. }

  78. void enhance_demo(Mat &guide, Mat &input, int r, double e) {

  79.    Mat dst;

  80.    guidedFilter(guide, input, dst, r, e, -1);

  81.    Mat result = (guide - dst) * 5 + dst;

  82.    imshow("output", result);

  83. }

运行截图如下:

边缘保留

OpenCV中导向滤波介绍与应用

去噪声

OpenCV中导向滤波介绍与应用

边缘羽化

OpenCV中导向滤波介绍与应用

对比度提升


金舟不能凌阳侯之波,

玉马不任骋千里之迹。


关注【OpenCV学堂】

长按或者扫码下面二维码即可关注

+OpenCV学习群 376281510

进群暗号:guidedfilter


以上是关于OpenCV中导向滤波介绍与应用的主要内容,如果未能解决你的问题,请参考以下文章

CUDA加opencv复现导向滤波算法

OpenCV Gabor滤波器实现纹理提取与缺陷分析

OpenCV中积分图介绍与应用

《学习OpenCV3》第10章 滤波与卷积

opencv第三课,图像滤波

超高速导向滤波实现过程纪要(欢迎挑战)