opencv之離散傅里葉變換(DFT)

 

opencv之離散傅里葉變換

函數解讀:

C++: int getOptimalDFTSize(int vecsize)

源碼解讀;

  1. <span style="font-size:18px;">int cv::getOptimalDFTSize( int size0 )  
  2. {  
  3.    int a = 0, b = sizeof(optimalDFTSizeTab)/sizeof(optimalDFTSizeTab[0]) -1;  
  4.    if( (unsigned)size0 >= (unsigned)optimalDFTSizeTab[b] )  
  5.        return -1;  
  6.    
  7.    while( a < b )//二分查找合適的size  
  8.     {  
  9.        int c = (a + b) >> 1;  
  10.        if( size0 <= optimalDFTSizeTab[c] )  
  11.            b = c;  
  12.        else  
  13.            a = c+1;  
  14.     }  
  15.    
  16.     returnoptimalDFTSizeTab[b];  
  17. }</span>  

optimalDFTSizeTab定義在namespace cv中,裏邊的數值爲2^x*3^y*5^z

static const int optimalDFTSizeTab[] = {1,2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16,…, 2123366400, 2125764000};

 copyMakeBorder

C++: void copyMakeBorder(InputArraysrc, OutputArray dst, int top, int bottom, int left,int right, int borderType, const Scalar& value=Scalar())

src: 源圖像

dst: 目標圖像,和源圖像有相同的類型,dst.cols=src.cols+left+right; dst.rows=src.rows+dst.top+dst.bottom

top:

bottom:

left:

right: 以上四個參數指定了在src圖像周圍附加的像素個數。

borderType: 邊框類型

value: 當borderType==BORDER_CONSTANT時需要指定該值。

示例代碼:

  1. <span style="font-size:18px;">#include <opencv2/core/core.hpp>  
  2. #include<opencv2/highgui/highgui.hpp>  
  3. #include<opencv2/imgproc/imgproc.hpp>  
  4. #include <iostream>  
  5.    
  6. using namespace cv;  
  7. using namespace std;  
  8.    
  9. int main(){  
  10.        Mat src = imread("fruits.jpg");  
  11.        if(!src.data)  
  12.        {  
  13.               return -1;  
  14.        }  
  15.    
  16.        Mat src_gray;  
  17.        cvtColor(src,src_gray,CV_RGB2GRAY);//灰度圖像做傅里葉變換  
  18.    
  19.        int m = getOptimalDFTSize(src_gray.rows);//2,3,5的倍數有更高效率的傅里葉轉換  
  20.        int n = getOptimalDFTSize(src_gray.cols);  
  21.    
  22.        Mat dst;  
  23.        ///把灰度圖像放在左上角,在右邊和下邊擴展圖像,擴展部分填充爲0;  
  24.        copyMakeBorder(src_gray,dst,0,m-src_gray.rows,0,n-src_gray.cols,BORDER_CONSTANT,Scalar::all(0));  
  25.        cout<<dst.size()<<endl;  
  26.    
  27.        //新建一個兩頁的array,其中第一頁用擴展後的圖像初始化,第二頁初始化爲0  
  28.        Mat planes[] = {Mat_<float>(dst), Mat::zeros(dst.size(), CV_32F)};  
  29.        Mat  completeI;  
  30.        merge(planes,2,completeI);//把兩頁合成一個2通道的mat  
  31.    
  32.        //對上邊合成的mat進行傅里葉變換,支持原地操作,傅里葉變換結果爲複數。通道1存的是實部,通道2存的是虛部。  
  33.        dft(completeI,completeI);  
  34.    
  35.        split(completeI,planes);//把變換後的結果分割到各個數組的兩頁中,方便後續操作  
  36.        magnitude(planes[0],planes[1],planes[0]);//求傅里葉變換各頻率的幅值,幅值放在第一頁中。  
  37.    
  38.        Mat magI = planes[0];  
  39.        //傅立葉變換的幅度值範圍大到不適合在屏幕上顯示。高值在屏幕上顯示爲白點,  
  40.        //而低值爲黑點,高低值的變化無法有效分辨。爲了在屏幕上凸顯出高低變化的連續性,我們可以用對數尺度來替換線性尺度:  
  41.        magI += 1;  
  42.        log(magI,magI);//取對數  
  43.        magI= magI(Rect(0,0,src_gray.cols,src_gray.rows));//前邊對原始圖像進行了擴展,這裏把對原始圖像傅里葉變換取出,剔除擴展部分。  
  44.    
  45.    
  46.        //這一步的目的仍然是爲了顯示。 現在我們有了重分佈後的幅度圖,  
  47.        //但是幅度值仍然超過可顯示範圍[0,1] 。我們使用 normalize() 函數將幅度歸一化到可顯示範圍。  
  48.        normalize(magI,magI,0,1,CV_MINMAX);//傅里葉圖像進行歸一化。  
  49.    
  50.    
  51.        //重新分配象限,使(0,0)移動到圖像中心,  
  52.        //在《數字圖像處理》中,傅里葉變換之前要對源圖像乘以(-1)^(x+y)進行中心化。  
  53.        //這是是對傅里葉變換結果進行中心化  
  54.        int cx = magI.cols/2;  
  55.        int cy = magI.rows/2;  
  56.    
  57.        Mat tmp;  
  58.        Mat q0(magI,Rect(0,0,cx,cy));  
  59.        Mat q1(magI,Rect(cx,0,cx,cy));  
  60.        Mat q2(magI,Rect(0,cy,cx,cy));  
  61.        Mat q3(magI,Rect(cx,cy,cx,cy));  
  62.    
  63.         
  64.        q0.copyTo(tmp);  
  65.        q3.copyTo(q0);  
  66.        tmp.copyTo(q3);  
  67.    
  68.        q1.copyTo(tmp);  
  69.        q2.copyTo(q1);  
  70.        tmp.copyTo(q2);  
  71.    
  72.         
  73.    
  74.        namedWindow("InputImage");  
  75.        imshow("InputImage",src);  
  76.    
  77.        namedWindow("SpectrumImage");  
  78.        imshow("SpectrumImage",magI);  
  79.    
  80.        waitKey();  
  81.        return0;  
  82. }</span>  

實驗結果:


代碼已上傳至gihub:opencv之離散傅里葉變換

轉載:http://blog.csdn.net/ubunfans/article/details/24787569

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章