C++完成二維圖形的傅裡葉變換。本站提示廣大學習愛好者:(C++完成二維圖形的傅裡葉變換)文章只能為提供參考,不一定能成為您想要的結果。以下是C++完成二維圖形的傅裡葉變換正文
本文實例講述了C++完成二維圖形的傅裡葉變換的辦法。有必定的自創價值。分享給年夜家供年夜家參考。
詳細代碼以下:
// Fourier.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdio.h"
#include "math.h"
#include <cv.h>
#include <highgui.h>
#include "cxcore.h"
int main(int argc, char* argv[])
{
IplImage *img;
IplImage *simg;
CvMat *mat_R;
CvMat *mat_I;
CvMat *mat_SRC;
CvMat *mat_Row;
CvMat *mat_Col;
CvMat *dst;
CvMat *dst_R;
CvMat *dst_I;
CvMat *dst_Row;
CvMat *dst_Col;
int i,j,k;
double temp;
int height,width,step,channels;
//載入一幅圖片
img=cvLoadImage("c:\\1.bmp",0);
//mat_R初始化
mat_R=cvCreateMat(img->height,img->width,CV_64FC1);
//mat_I初始化
mat_I=cvCreateMat(img->height,img->width,CV_64FC1);
//mat_SRC初始化
mat_SRC=cvCreateMat(img->height,img->width,CV_64FC2);
//將圖片數據存入mat_R(實部)
cvConvert(img,mat_R);
//將虛部初始化為零
cvZero(mat_I);
//歸並實部、虛部
cvMerge(mat_R,mat_I,NULL,NULL,mat_SRC);
//創立雙通道double類型數組
dst=cvCreateMat(img->height,img->width,CV_64FC2);
dst_R=cvCreateMat(img->height,img->width,CV_64FC1);
dst_I=cvCreateMat(img->height,img->width,CV_64FC1);
//為輪回變量賦值
height=img->height;
width=img->width;
channels=2;
step=channels*width;
//部分變量,值為正一或負一
int check;
//將輸出數據乘以(-1)^(i+j),用於中間化
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
check=(i+j)%2>0?1:-1;
for(k=0;k<channels;k++)
{
mat_SRC->data.db[j*step+i*channels+k]=check*mat_SRC->data.db[j*step+i*channels+k];
}
}
}
//創立一個mat用於暫時存儲一行數據
CvMat mat_Header=cvMat(4,4,CV_64FC2);
mat_Row=cvCreateMat(1,width,CV_64FC2);
mat_Col=cvCreateMat(1,height,CV_64FC2);
//創立一個dst用於暫時存儲一行數據
dst_Row=cvCreateMat(1,width,CV_64FC2);
dst_Col=cvCreateMat(height,1,CV_64FC2);
//為輪回變量賦值
height=img->height;
width=img->width;
channels=2;
step=channels*width;
//行的傅裡葉變換
for(j=0;j<height;j++)
{
//獲得第j行數據
mat_Row=cvGetRow(mat_SRC,&mat_Header,j);
//正向傅裡葉變換
cvDFT(mat_Row,dst_Row,CV_DXT_FORWARD);
//履行輪回,賦值到dst
for(i=0;i<width;i++)
{
for(k=0;k<channels;k++)
{
dst->data.db[j*step+i*channels+k]=dst_Row->data.db[i*channels+k];
}
}
}
//列的傅裡葉變換
for(i=0;i<width;i++)
{
//獲得第i列
mat_Col=cvGetCol(dst,&mat_Header,i);
//正向傅裡葉變換
cvDFT(mat_Col,dst_Col,CV_DXT_FORWARD);
//履行輪回,賦值到dst
for(j=0;j<height;j++)
{
for(k=0;k<channels;k++)
{
dst->data.db[j*step+i*channels+k]=dst_Col->data.db[j*channels+k];
}
}
}
//分紅兩個矩陣
cvSplit(dst,dst_R,dst_I,NULL,NULL);
//創立暫時指針指向dst_R,dst_I
double *pR,*pI;
pR=(double *)dst_R->data.ptr;
pI=(double *)dst_I->data.ptr;
//創立一張用於顯示的圖象
simg=cvCreateImage(cvGetSize(img),8,1);
//為輪回變量賦值
height=simg->height;
width=simg->width;
channels=1;
step=channels*width;
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
for(k=0;k<channels;k++)
{
temp=pR[j*step+i*channels+k]*pR[j*step+i*channels+k]+pI[j*step+i*channels+k]*pI[j*step+i*channels+k];
temp=temp/(height*width);
simg->imageData[j*step+i*channels+k]=sqrt(temp);
}
}
}
cvNamedWindow("Mar",CV_WINDOW_AUTOSIZE);
cvShowImage("Mar",simg);
cvWaitKey(0);
cvReleaseMat(&mat_R);
cvReleaseMat(&mat_I);
cvReleaseMat(&mat_SRC);
//cvReleaseMat(&mat_Row);//這裡沒法正常釋放,有待處理
//cvReleaseMat(&mat_Col);
cvReleaseMat(&dst);
cvReleaseMat(&dst_R);
cvReleaseMat(&dst_I);
cvReleaseImage(&img);
cvReleaseImage(&simg);
return 0;
}
感興致的同伙可以調試運轉一下本文實例,法式十全十美的是會有內存洩露,重要是mat_Row,mat_Col,dst_Row,dst_Col,有才能的讀者可以對此停止修正與完美。信任會有新的收成。