• (原+转)使用opencv的DFT计算卷积


    转载请注明出处:

    http://www.cnblogs.com/darkknightzh/p/5462665.html

    参考网址:

    http://blog.csdn.net/lichengyu/article/details/18848281

    貌似还有其他的,记不清了

    convolveDFT函数是从官方文档中抄录并做了修改,因为原来的程序有问题。一是输出Mat C应声明为引用;二是其中的mulSpectrums函数的第四个参数flag值没有指定,应指定为DFT_COMPLEX_OUTPUT或是DFT_REAL_OUTPUT.

    main函数中首先按灰度图读入图像,然后创造一个平滑核kernel,将输入图像转换成float类型(注意这步是必须的,因为dft只能处理浮点数),在调用convolveDFT求出卷积结果后,将卷积结果归一化方便显示观看。

    (180205:_XieLei 指出valid的时候结果不对,大家辩证的看待代码哈)

     1 #include <opencv2/opencv.hpp>
     2 #include <opencv2/highgui/highgui.hpp>
     3 #include <opencv2/imgproc/imgproc.hpp>
     4 using namespace cv;
     5 
     6 enum ConvolutionType                     // 函数 conv2 卷积时参数的类型
     7 {
     8     CONVOLUTION_FULL,                    // 卷积时的参数,和 matlab 的 full 一致
     9     CONVOLUTION_SAME,                    // 卷积时的参数,和 matlab 的 same 一致
    10     CONVOLUTION_VALID                    // 卷积时的参数,和 matlab 的 valid 一致
    11 };
    12 void Conv2DFT(Mat& convRes, const Mat& img, const Mat& kernel, ConvolutionType type, int ddepth)
    13 {
    14     int dft_M = getOptimalDFTSize(img.rows + kernel.rows - 1);   // 行数
    15     int dft_N = getOptimalDFTSize(img.cols + kernel.cols - 1);   // 列数
    16 
    17     Mat imagePad(dft_M, dft_N, CV_32FC1, Scalar(0));
    18     Mat imagePadROI = imagePad(Rect(0, 0, img.cols, img.rows));
    19     img.convertTo(imagePadROI, CV_32FC1, 1, 0);
    20 
    21     Mat kernelPad(dft_M, dft_N, CV_32FC1, Scalar(0));
    22     Mat kernelPadROI = kernelPad(Rect(0, 0, kernel.cols, kernel.rows));
    23     kernel.convertTo(kernelPadROI, CV_32FC1, 1, 0);
    24 
    25     dft(imagePad, imagePad, 0, imagePad.rows);
    26     dft(kernelPad, kernelPad, 0, kernelPad.rows);
    27 
    28     // set the last parameter to false to compute convolution instead of correlation
    29     mulSpectrums(imagePad, kernelPad, imagePad, DFT_COMPLEX_OUTPUT, false);  // false: A.*B;true:xf.*conj(yf)
    30     idft(imagePad, imagePad, cv::DFT_SCALE | cv::DFT_REAL_OUTPUT, imagePad.rows);
    31 
    32     Rect r;
    33     switch (type)
    34     {
    35     case CONVOLUTION_FULL:  // full
    36         r = Rect(0, 0, img.cols + kernel.cols - 1, img.rows + kernel.rows - 1);
    37         break;
    38     case CONVOLUTION_SAME:  // same
    39         r = Rect((kernel.cols + 0.5) / 2, (kernel.rows + 0.5) / 2, img.cols, img.rows);
    40         break;
    41     case CONVOLUTION_VALID:  // valid
    42         r = Rect((kernel.cols + 0.5) / 2, (kernel.rows + 0.5) / 2, img.cols - kernel.cols + 1, img.rows - kernel.rows + 1);
    43         break;
    44     default:  // same
    45         r = Rect((kernel.cols + 0.5) / 2, (kernel.rows + 0.5) / 2, img.cols, img.rows);
    46         break;
    47     }
    48 
    49     imagePad(r).convertTo(convRes, ddepth, 1, 0);
    50 }

    说明:

    不确定矩形框是否正确。

  • 相关阅读:
    饱和色
    Server.MapPath()相关
    Oracle修改表结构
    远程关机
    使用sqlplus创建表空间
    自写Js+CSS轮显效果
    右下角随机显示的CSS+JS图片广告
    JavaScript实现鼠标放上动画加载大图的代码
    CSS实现自适应的图片背景边框代码
    JavaScript弹性透明的图片放大代码
  • 原文地址:https://www.cnblogs.com/darkknightzh/p/5462665.html
Copyright © 2020-2023  润新知