6. 对一幅灰度图像进行离散傅里叶变换,用图像的形式显示其(中心化后的)频谱。改变频谱,在进行 反变换,观察变换前后的区别
#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; }
声明:
博主是原悦乎教程网站长,博主写博客花费了大量精力,我的博客欢迎转载共享,但在 同时,希望保留我的署名权,不得用于商业用途。转载时请注明转载地址。未经特别说明,均采用“署名-非商业性使用-禁止演绎 2.5 中国大陆”授权。任何违反本协议的行为均属于非法行为。