2010-06-05 104 views
1

我刚刚学习使用OpenCV,并在使用DFT时遇到问题。我已经完成了一个使用MatLab的信号处理类,所以我正在尝试通过我们在该类中做的一些练习。我试图获得并显示图像的FT,所以我可以掩盖一些频率。我希望能够看到FT,所以我知道有多大,使蒙版,但是当我尝试,我得到了这样一个形象:
alt text
而不是像这些
alt text http://www.ceremade.dauphine.fr/~peyre/numerical-tour/tours/graphics_synthesis_fourier/index_03.png
一个我忘了一步吗?我正在加载图像,将其类型转换为CV_32FC1,获取矩阵,获得DFT,然后将得到的矩阵转换回图像。我会发布我正在使用的代码,如果它会有任何帮助?
或者如果有人链接到显示FT的例子?我只能找到那些用于卷积的。在OpenCV中显示傅立叶变换

编辑:我得到了图像的阶段?

+0

当然,这不是输入图像的相位。由于你的图像只有黑白两色 - 当它应该有一个灰度值范围时 - 我的猜测是你在转换时出现了一些错误。 – 2010-06-13 23:13:30

回答

2

我已经遇到过类似的麻烦,试图在OpenCV上显示图像上2D DFT的大小。我终于完成了一个工作实现。我不认为它是伟大的代码,它只能在256×256 8位(灰度)单通道图像上测试 - lenna.png(它可能需要进行调整以适当填充其他图像尺寸)。输入图像与重建图像之间的均方误差为零,因此它的工作方式应该如此。 OpenCV v2.1是必需的。

文件:mstrInclude.h

#ifndef _MASTER_INCLUDE_ 
    #define _MASTER_INCLUDE_ 

    // Standard 
    #include <stdio.h> 
    #include <string> 
    #include <sstream> 
    #include <iostream> 
    #include <cmath> 
    using namespace std; 

    // OpenCV2.1 
    #include "cv.h" 
    #include "highgui.h" 
    using namespace cv; 

    #define LOAD_IMAGE "lenna.png" 

    #endif // _MASTER_INCLUDE_ 

文件:main.cpp中

#include "mstrInclude.h" 
    void translateImg(Mat& imgIn, Mat& imgOut) 
    { 
     int i, j; 

     for (i = 0; i < imgIn.rows; i++) 
      for (j = 0; j < imgIn.cols; j++) 
       imgOut.at<double>(i,j) = imgIn.at<double>(i,j) * pow(-1.0, i+j); 
    } 
    void scaleImg(Mat& imgIn, Mat& imgOut, float scaleFactor) 
    { 
     int i, j; 

     for (i = 0; i < imgIn.rows; i++) 
      for (j = 0; j < imgIn.cols; j++) 
       imgOut.at<double>(i,j) = (double)scaleFactor * log(1.0 + imgIn.at<double>(i,j)); 
    } 

    void consoleOut(cv::Mat outMat, int rows = 5, int cols = 5) 
    { 
     rows = ((rows == -1 || rows >= outMat.rows) ? outMat.rows : rows); 
     cols = ((cols == -1 || cols >= outMat.cols) ? outMat.cols : cols); 

     for(int i = 0; i < rows; i++) 
     { 
      for(int j = 0; j < cols; j++) 
      { 
       cout << outMat.at<double>(i, j); 
       cout << " "; 
      } 
      cout << endl; 
     } 
    } 

    double calcMSE(Mat& imgOrig, Mat& imgReconst) 
    { 
     int valOrig = 0, valReconst = 0; 
     double MSE = 0.0; 

     for(int i = 0; i < imgOrig.rows; i++) 
     { 
      for (int j = 0; j < imgOrig.cols; j++) 
      { 
       valOrig = imgOrig.at<unsigned char>(i, j); 
       valReconst = imgReconst.at<unsigned char>(i, j); 

       MSE += pow((double)(valOrig - valReconst), 2.0); 
      } 
     } 
     return (MSE/(imgOrig.rows * imgOrig.cols)); 
    } 

    string convertInt(int number) // converts integer to string 
    { 
     stringstream ss; 
     ss << number; 
     return ss.str(); 
    } 

    int main(unsigned int argc, char* const argv[]) 
    { 
     int dftH, dftW; 
     cv::Mat imgIn; 

     imgIn = cv::imread(LOAD_IMAGE, 0); //grayscale 
     cv::imshow("Original Image", imgIn); 
     waitKey(); 

     dftH = cv::getOptimalDFTSize(imgIn.rows); 
     dftW = cv::getOptimalDFTSize(imgIn.cols); 

     Mat imgMod; 
     Mat imgPrecFFT(dftH, dftW, CV_64FC1, Scalar::all(0)); 
     imgIn.convertTo(imgMod, CV_64FC1); 
     imgPrecFFT = imgMod(cv::Range::all(), cv::Range::all()).clone(); 

     // translate image 
     std::vector<Mat> imgsTrans; 
     imgsTrans.push_back(Mat_<double>(imgIn.size(), CV_64FC1)); 
     imgsTrans.push_back(Mat_<double>(imgIn.size(), CV_64FC1)); 
     imgsTrans[1].setTo(Scalar::all(0), Mat()); 
     translateImg(imgPrecFFT, imgsTrans[0]); 

     Mat imgPrecTransFFT(imgIn.size(), CV_64FC2, Scalar::all(0)); 
     cv::merge(imgsTrans, imgPrecTransFFT); 

     // dft 
     cv::Mat imgFFT; 
     dft(imgPrecTransFFT, imgFFT, DFT_COMPLEX_OUTPUT); 
     cv::Mat imgDispFFT; 

     // calculate magnitude 
     Mat imgMagnitude(imgIn.size(), CV_64FC1); 
     std::vector<Mat> chans; 
     cv::split(imgFFT, chans); 
     cv::magnitude(chans[0], chans[1], imgMagnitude); 

     // scale magnitude image 
     Mat imgMagnitudeScaled(imgIn.size(), CV_64FC1); 
     scaleImg(imgMagnitude, imgMagnitudeScaled, 10.0); 

     // display magnitude image 
     cv::Mat imgDisp; 
     cv::convertScaleAbs(imgMagnitudeScaled, imgDisp); 
     imshow("Magnitude Output", imgDisp); 
     waitKey(); 

     // inverse dft 
     cv::split(imgFFT, chans); 
     chans[1].zeros(imgIn.size(), CV_64FC1); 
     cv::merge(chans, imgFFT); 
     cv::Mat invFFT; 
     cv::idft(imgFFT, invFFT, DFT_REAL_OUTPUT + DFT_SCALE); 

     // translate image back to original location 
     cv::split(invFFT, imgsTrans); 
     Mat imgAfterTrans(imgIn.size(), CV_64FC1); 
     translateImg(imgsTrans[0], imgAfterTrans); 
     imgAfterTrans.convertTo(imgDisp, CV_8UC1); 

     imshow("After Inverse Output", imgDisp); 
     waitKey(); 

     // calculate and output mean-squared error between input/output images 
     double MSE = calcMSE(imgIn, imgDisp); 
     cout<<endl<<"MSE: "<<MSE<<endl; 
     waitKey(); 

     return 0; 
    }