#include <stdio.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> void fft2(IplImage *src, IplImage *dst) { IplImage *image_Re = 0, *image_Im = 0, *Fourier = 0; //實部、虛部 image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); //實部 image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); //虛部 Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);//2 channels (image_Re, image_Im) cvConvertScale(src, image_Re, 1, 0);// Real part conversion from u8 to 64f (double) cvZero(image_Im);// Imaginary part (zeros) cvMerge(image_Re, image_Im, 0, 0, Fourier);// Join real and imaginary parts and stock them in Fourier image cvDFT(Fourier, dst, CV_DXT_FORWARD);// Application of the forward Fourier transform cvReleaseImage(&image_Re); cvReleaseImage(&image_Im); cvReleaseImage(&Fourier); } void fft2shift(IplImage *src, IplImage *dst) { IplImage *image_Re = 0, *image_Im = 0; int nRow, nCol, i, j, cy, cx; double scale, shift, tmp13, tmp24; image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); cvSplit(src, image_Re, image_Im, 0, 0); cvPow(image_Re, image_Re, 2.0); cvPow(image_Im, image_Im, 2.0); cvAdd(image_Re, image_Im, image_Re); cvPow(image_Re, image_Re, 0.5); cvAddS(image_Re, cvScalar(1.0), image_Re); // 1 + Mag cvLog(image_Re, image_Re); // log(1 + Mag) nRow = src->height; nCol = src->width; cx = nCol / 2; cy = nRow / 2; // image center for (j = 0; j < cy; j++){ for (i = 0; i < cx; i++){ tmp13 = CV_IMAGE_ELEM(image_Re, double, j, i); CV_IMAGE_ELEM(image_Re, double, j, i) = CV_IMAGE_ELEM(image_Re, double, j + cy, i + cx); CV_IMAGE_ELEM(image_Re, double, j + cy, i + cx) = tmp13; tmp24 = CV_IMAGE_ELEM(image_Re, double, j, i + cx); CV_IMAGE_ELEM(image_Re, double, j, i + cx) = CV_IMAGE_ELEM(image_Re, double, j + cy, i); CV_IMAGE_ELEM(image_Re, double, j + cy, i) = tmp24; } } double minVal = 0, maxVal = 0; cvMinMaxLoc(image_Re, &minVal, &maxVal); scale = 255 / (maxVal - minVal); shift = -minVal * scale; cvConvertScale(image_Re, dst, scale, shift); cvReleaseImage(&image_Re); cvReleaseImage(&image_Im); } int main() { IplImage *src; IplImage *Fourier; IplImage *dst; IplImage *ImageRe; IplImage *ImageIm; IplImage *Image; IplImage *ImageDst; double m, M; double scale; double shift; src = cvLoadImage("6013202130.bmp", 0); //加載源圖像,第二個參數表示將輸入的圖 Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2); dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2); ImageRe = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); ImageIm = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1); Image = cvCreateImage(cvGetSize(src), src->depth, src->nChannels); ImageDst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels); fft2(src, Fourier); //傅里葉變換 fft2shift(Fourier, Image); //中心化 cvDFT(Fourier, dst, CV_DXT_INV_SCALE);//實現傅里葉逆變換,並對結果進行縮放 cvSplit(dst, ImageRe, ImageIm, 0, 0); cvNamedWindow("源圖像", 0); cvShowImage("源圖像", src); //對數組每個元素平方並存儲在第二個參數中 cvPow(ImageRe, ImageRe, 2); cvPow(ImageIm, ImageIm, 2); cvAdd(ImageRe, ImageIm, ImageRe, NULL); cvPow(ImageRe, ImageRe, 0.5); cvMinMaxLoc(ImageRe, &m, &M, NULL, NULL); scale = 255 / (M - m); shift = -m * scale; //將shift加在ImageRe各元素按比例縮放的結果上,存儲為ImageDst cvConvertScale(ImageRe, ImageDst, scale, shift); cvNamedWindow("傅里葉譜", 0); cvShowImage("傅里葉譜", Image); cvNamedWindow("傅里葉逆變換", 0); cvShowImage("傅里葉逆變換", ImageDst); cvWaitKey(0); cvReleaseImage(&src); cvReleaseImage(&Image); cvReleaseImage(&ImageIm); cvReleaseImage(&ImageRe); cvReleaseImage(&Fourier); cvReleaseImage(&dst); cvReleaseImage(&ImageDst); cvDestroyAllWindows(); return 0; }