轉載請注明出處:
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 }
說明:
不確定矩形框是否正確。
