opencv之傅里葉變換


一、離散傅里葉變換

  離散傅里葉變換是高數中的內容了,自己都不大記得具體的原理了,在這里先復習並記錄下來,方便以后查閱。英文全稱為Discrete Fourier Transform,簡稱DFT,是指傅里葉變換在時域和頻域都呈現離散的形式,將時域的信號采樣變換為在離散時間傅里葉變換頻域的采樣。在形式上做變換的兩端的序列是有限長的,實際上這兩組序列都應當被認為是離散周期信號的主值序列。即使對有限序列的信號做DTF,也應當對其進行周期延拓成為周期信號在進行變換。通常使用快速傅里葉變換來高效計算DFT。

  對於一張圖片進行傅里葉變換就是將它分解為正弦和余弦兩部分,以完成從空間域到頻域的轉換。在轉換到頻域時以復數的形式存在,因此變換后的結果需要使用實數圖像和虛數圖像,或者幅度圖像加相位圖像的形式。但是在實際處理當中僅僅使用了幅度圖像(magitude Image),因為幅度圖像包含了幾乎所有的原圖像的幾何信息。但是如果想用傅里葉逆變換就需要同時保留幅度圖像和相位圖像,才能實現對原圖像的操作。

  在頻域里,對於一幅圖像,高頻部分代表了圖像的、紋理信息;低頻部分則代表了圖像的輪廓信息。如果圖像受到的噪聲恰好在某個特定的頻率范圍內,就可以使用濾波器來恢復原來的圖像。因此傅里葉變換在圖像處理中可以做到圖像增強和去噪、圖像分割之邊緣檢測、圖像特征提取和壓縮等。

二、opencv傅里葉變換的處理函數

  ˇdft()函數

1 void dft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0);

ˇ第一個參數:InputArray類型的src,輸入矩陣,可以為實數或者虛數。

ˇ第二個參數:OutputArray類型的dst,運算結果保存在這里,其尺寸和類型取決於第三個參數

ˇ第三個參數:int類型的flags。轉換的標識符,默認值為0,取值可以為:

1 DFT_INVERSE       -----> 一維或者二維逆變換 2 DFT_SCALE         -----> 輸出結果以1/N進行縮放,通常結合DFT_INVERSE使用
3 DFT_ROWS        -----> 對輸入矩陣的每行進性正向或者逆向變換,用於在處理多種矢量的時候用於減小資源開銷,通常用於三維或者高維變換的操作
4 DFT_COMPLEX_OUTPUT  -----> 進行一維或者二維實數數組的正變換。其結果是復數陣列,擁有復數的共軛對稱性也可以寫成一個同樣尺寸的實數陣列
5 DFT_REAL_OUTPUT    -----> 進行一維或二維復數數組反變換。其結果是一個同樣大小的復矩陣,如果輸入的矩陣具有共軛對稱性,便會輸出實數矩陣

ˇ第四個參數:默認為0,非0時,函數會假設只有輸入矩陣的一個非0行包含非0元素(設置了DFT_INVERSE)或只有輸出矩陣的第一個非0行包含非0元素(設置了DFT_INVERSE)。這樣的話,函數就可以對其它進行更高效的處理,以節省時間開銷,尤其是在計算矩陣卷積時非常有效。

 

  ˇgetOPtimalDFTSize()返回DFT最優尺寸大小

 

1 int getOptimalDFTSize(int vecsize);

 

該函數的參數即向量尺寸,圖像的rows、cols

 

 

  ˇcopyMakeBorder()擴充圖像邊界

1 void copyMakeBorder(InputArray src, OutPutArray dst, int top, int bottom, int left, int right, int borderType, const Scalar& value = Scalar());

ˇ第一個參數:輸入的原圖像

ˇ第二個參數:輸出結果,需和原圖片有一樣的尺寸和類型,且size大小為Size(src.cols + left + right, src.rows + top + bottom)

ˇ第三~六個參數:向四個方向擴充多少像素,例如top = 2;即向上邊界擴充兩個像素寬度的邊界

ˇ第七個參數:邊界類型,常用取值為BORDER_CONSTANT

ˇ第八個參數:默認值Scalar(),標記BORDER_CONSTANT時,改參數表示邊界值

 

  ˇmagnitude()計算二維矢量的幅值

 

1 void magnitude(InputArray x, InputArray y, OutputArray maginute);

 

ˇ第一個參數:輸入的矢量的浮點型X坐標值,即實部

ˇ第二個參數:輸入的矢量的浮點型Y坐標值,即虛部

ˇ第三個參數:輸出的maginute,與x有相同的尺寸和類型

 

  ˇlog()計算自然對數

1 void log(InputArray src, OuyputArray dst);

ˇ第一個參數:輸入的圖像

ˇ第二個參數:得到的對數值

 

  ˇnormolize()矩陣歸一化

1 void normalize( InputArray src, OutputArry dst, double alpha = 1, double beta = 0, int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray() );

ˇ第一個參數:輸入的原圖像

ˇ第二個參數:運算結果的存放,與原圖像擁有相同大小和類型

ˇ第三個參數:歸一后的最大值,默認為1

ˇ第四個參數:歸一后的最大值,默認為0

ˇ第五個參數:歸一化類型,NORM_L1、NORM_L2、NORM_INF、NORM_MINMUX等

ˇ第六個參數:默認值-1,此時與src類型相同,若設置大於0折與src尺寸相同

ˇ第七個參數:可選的操作掩膜,默認noArray()

三、離散傅里葉變換測試

 1 // DTF.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
 2 //采用傅里葉變換將圖片從空間域轉換到頻域
 3 //
 4 
 5 #include <iostream>
 6 #include <opencv2/core/core.hpp>
 7 #include <opencv2/highgui/highgui.hpp>
 8 #include <opencv2/imgproc/imgproc.hpp>
 9 
10 using namespace std;
11 using namespace cv;
12 
13 int main(int argc, char** argv)
14 {
15     system("color 2f");
16 
17     //這里必須是灰度圖片
18     Mat srcImage = imread("1.jpg", 0);
19     if (!srcImage.data)
20     {
21         cout << "載入圖片出錯" << endl;
22         return -1;
23     }
24     imshow("原圖像", srcImage);
25 
26     int m = getOptimalDFTSize(srcImage.rows);
27     int n = getOptimalDFTSize(srcImage.cols);
28 
29     Mat padded;
30     copyMakeBorder(srcImage, padded, 0, m - srcImage.rows, 0, n - srcImage.cols, BORDER_CONSTANT, Scalar::all(0));
31 
32     Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };
33     Mat complexI;
34     merge(planes, 2, complexI);
35 
36     dft(complexI, complexI);
37 
38     split(complexI, planes);
39     magnitude(planes[0], planes[1], planes[0]);
40     Mat magnitudeImage = planes[0];
41 
42     magnitudeImage += Scalar::all(1);
43     log(magnitudeImage, magnitudeImage);
44 
45     magnitudeImage = magnitudeImage(Rect(0, 0, magnitudeImage.cols & -2, magnitudeImage.rows & -2));
46     int cx = magnitudeImage.cols / 2;
47     int cy = magnitudeImage.rows / 2;
48     Mat q0(magnitudeImage, Rect(0, 0, cx, cy));
49     Mat q1(magnitudeImage, Rect(cx, 0, cx, cy));
50     Mat q2(magnitudeImage, Rect(0, cy, cx, cy));
51     Mat q3(magnitudeImage, Rect(cx, cy, cx, cy));
52 
53     Mat tmp;
54     q0.copyTo(tmp);
55     q3.copyTo(q0);
56     tmp.copyTo(q3);
57 
58     q1.copyTo(tmp);
59     q2.copyTo(q1);
60     tmp.copyTo(q2);
61 
62     normalize(magnitudeImage, magnitudeImage, 0, 1, NORM_MINMAX);
63     imshow("頻譜賦值", magnitudeImage);
64     waitKey();
65 
66 
67     return 0;
68 }
View Code

 

累了累了休息會

 


免責聲明!

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



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