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;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值