(原+轉)使用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 }

說明:

不確定矩形框是否正確。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM