OpenCV傅立叶变换
生活随笔
收集整理的這篇文章主要介紹了
OpenCV傅立叶变换
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
對圖像進行傅立葉變換
首先按列(或者按行)進行傅立葉變換,得到一個變換的矩陣,然后再對變換的矩陣按行(或者按列)進行傅立葉變換,從而每個像素點可以得到一個復數相對應。
具體的代碼流程:
第一步將讀入的圖片轉成傅立葉變換速度最快的大小。
copyMakeBorder():主要用來對圖片加邊框。
copyMakeBorder(輸入圖片,輸出圖片,上部加多少個像素,下部。。。。,左部。。。。,右部。。。。,BORDER_CONSTANT,Scalar::all(0) );第二步定義一個兩通道的Mat對象,存儲dft變換的結果。
Mat planes[] = {Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F)}; Mat complexI; merge(planes,2,complexI);merge():將一個二維的Mat數組合并為一個兩通道的Mat對象。
merge(輸入的數組,數組的大小,輸出的多通道Mat );第三步進行傅立葉變換
dft(complexI,complexI);傅立葉變換將變換的結果存儲在complexI中,0通道存儲實部,1通道存儲虛部。
第四步取出變換的結果進行相應的處理
split():用來將多通道的Mat對象分為數組
magnitude():計算一個復數的模長
最后將圖片分為四部分重新拼組:
magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2)); int cx = magI.cols/2;int cy = magI.rows/2;Mat q0(magI, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant Mat q1(magI, Rect(cx, 0, cx, cy)); // Top-RightMat q2(magI, Rect(0, cy, cx, cy)); // Bottom-LeftMat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-RightMat tmp; q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp); q2.copyTo(q1);tmp.copyTo(q2);normalize(magI, magI, 0, 1, CV_MINMAX); magI.rows&-2得到不大于magI.rows的最大偶數完整的代碼:
#include <ros/ros.h> #include "opencv2/opencv.hpp"using namespace std; using namespace cv;int main(int argc,char** argv) {Mat srv = imread("/home/dynamicw/Project/C++_Project/opencvtest/src/lesson01/source/icon.png",0);Mat src = Mat::ones(srv.size(),srv.type());for(int row = src.rows/2;row < src.rows-1;row++){for(int col = 0;col < src.cols-1;col++){// if(row < col)src.at<uchar>(row,col) = 255;}}int m = getOptimalDFTSize(src.rows);//得到最佳的傅立葉變換的值int n = getOptimalDFTSize(src.cols);//同上cout << "m=" << m << endl;cout << "n=" << n << endl;Mat padded;copyMakeBorder(src,padded,0,m-src.rows,0,n-src.cols,BORDER_CONSTANT,Scalar::all(255));//為圖片添加邊框imshow("padded",padded);cout << "src size:" << src.size() << endl;cout << "padded size:" << padded.size() << endl;Mat planes[] = {Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F)};//定義一個mat的數組Mat complexI;merge(planes,2,complexI);//將數組合并為一個兩通道的mat對象dft(complexI,complexI);//對圖像進行傅立葉變換,將變換的結果實部存儲在第一個通道中,虛部存儲在第二個通道中split(complexI,planes);//將兩通道的Mat對象進行分離為一個二維數組magnitude(planes[0],planes[1],planes[0]);//求模長,將plane{0}的實部和plane{1}的虛部平方和再開方,并將結果存放在planes{0}中Mat magI = planes[0];//單獨對模長構成的圖像進行處理magI += Scalar::all(1);log(magI,magI);//M1 = log(M + 1)magI = magI(Rect(0,0,magI.cols&-2,magI.rows&-2));//mag.cols&-2得到小于mag.cols的最大偶數int cx = magI.cols/2;int cy = magI.rows/2;//將頻率圖分為四份Mat q0(magI,Rect(0,0,cx,cy));Mat q1(magI,Rect(cx,0,cx,cy));Mat q2(magI,Rect(0,cy,cx,cy));Mat q3(magI,Rect(cx,cy,cx,cy));//將對角線的兩部分進行交換,使原點位置在圖片的中心//去除前面加的邊框Mat tmp;q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);//標準化,將圖片中的值序列化在相應的范圍之內normalize(magI,magI,0,1,CV_MINMAX);imshow("src",src);imshow("sdf",magI);waitKey(0);return 0; }總結
以上是生活随笔為你收集整理的OpenCV傅立叶变换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux中export和source的
- 下一篇: Windows 7 Ubuntu 14