zoukankan      html  css  js  c++  java
  • 频域变换-傅里叶变换实验二

    1读入一幅图像,对其进行傅里叶变换,并显示傅里叶变换结果。

    #include<opencv2/opencv.hpp>
    #include<iostream>
    using namespace std;
    using namespace cv;
    
    int main(int a, char **p)
    {
    
        Mat input = imread("pic1.jpg", CV_LOAD_IMAGE_GRAYSCALE); //以灰度图像的方式读入图片
        namedWindow("startwindow",WINDOW_NORMAL);
        imshow("startwindow", input);//显示原图
    
        Mat padded;
        int m = getOptimalDFTSize(input.rows); //获取最佳尺寸 
        int n = getOptimalDFTSize(input.cols);
          
        copyMakeBorder(input, padded, 0, m - input.rows, 0, n - input.cols, BORDER_CONSTANT, Scalar::all(0)); 
    
        Mat plane[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };//创建通道,zeros对图片进行初始化
        Mat complexI;
        merge(plane, 2, complexI);//合并通道
    
        //dft实现
        dft(complexI, complexI);//进行傅立叶变换,结果保存在自身
    
        //频谱计算,将实数和复数的值转换为幅度值
        split(complexI, plane);//分离通道
        magnitude(plane[0], plane[1], plane[0]);//获取幅度图像,0通道为实数通道,1为虚数,因为二维傅立叶变换结果是复数
        Mat magI = plane[0];
    
        //对数坐标转换
        magI += Scalar::all(1);
        log(magI, magI);
    
        //频谱平移
        magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));
        int cx = magI.cols / 2;
        int cy = magI.rows / 2;//一下的操作是移动图像,左上与右下交换位置,右上与左下交换位置 
        Mat part1(magI, Rect(0, 0, cx, cy)); //左上角
        Mat part2(magI, Rect(cx, 0, cx, cy));//右上角
        Mat part3(magI, Rect(0, cy, cx, cy));//左下角
        Mat part4(magI, Rect(cx, cy, cx, cy));//右下角
    
        Mat tmp; 
    
        part1.copyTo(tmp);
        part4.copyTo(part1);
        tmp.copyTo(part4); 
        part2.copyTo(tmp);
        part3.copyTo(part2);
        tmp.copyTo(part3); 
        
        //标准化
        normalize(magI, magI, 0, 1, CV_MINMAX);
    
        namedWindow("dft", WINDOW_NORMAL);
        imshow("dft",magI);
        waitKey();
        return 0;
    }

    2. 对不同类型的图像进行傅里叶变换,并分析其频域变换结果的区别。

            与上题一样,将输入图片的格式转变一下就OK 

    3. 实现对图像的反傅里叶变换,并显示反傅里叶变换结果。

     

    #include<opencv2/opencv.hpp>
    #include<iostream>
    using namespace std;
    using namespace cv;
    int main(int a, char **p)
    {
        Mat input=imread("F:\work_three_grade\DigitalImage\c.jpg",CV_LOAD_IMAGE_GRAYSCALE);
        namedWindow("input", CV_WINDOW_NORMAL);
        imshow("input", input);//显示原图
        int w = getOptimalDFTSize(input.cols);
        int h = getOptimalDFTSize(input.rows);//获取最佳尺寸,快速傅立叶变换要求尺寸为2的n次方
        Mat padded;
        copyMakeBorder(input, padded, 0, h - input.rows, 0, w - input.cols, BORDER_CONSTANT, Scalar::all(0));//填充图像保存到padded中
        Mat plane[] = { Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F) };//创建通道
        Mat complexIm;
        merge(plane, 2, complexIm);//合并通道
        dft(complexIm, complexIm);//进行傅立叶变换,结果保存在自身
        split(complexIm, plane);//分离通道
        magnitude(plane[0], plane[1], plane[0]);//获取幅度图像,0通道为实数通道,1为虚数,因为二维傅立叶变换结果是复数
        int cx = padded.cols / 2; int cy = padded.rows / 2;//一下的操作是移动图像,左上与右下交换位置,右上与左下交换位置
        Mat temp;
        Mat part1(plane[0], Rect(0, 0, cx, cy));
        Mat part2(plane[0], Rect(cx, 0, cx, cy));
        Mat part3(plane[0], Rect(0, cy, cx, cy));
        Mat part4(plane[0], Rect(cx, cy, cx, cy)); 
    
        part1.copyTo(temp);
        part4.copyTo(part1);
        temp.copyTo(part4);
    
        part2.copyTo(temp);
        part3.copyTo(part2);
        temp.copyTo(part3); 
         
        Mat _complexim;
        complexIm.copyTo(_complexim);//把变换结果复制一份,进行逆变换,也就是恢复原图
        Mat iDft[] = { Mat::zeros(plane[0].size(),CV_32F),Mat::zeros(plane[0].size(),CV_32F) };//创建两个通道,类型为float,大小为填充后的尺寸
        idft(_complexim, _complexim);//傅立叶逆变换
        split(_complexim, iDft); 
        magnitude(iDft[0], iDft[1], iDft[0]);//分离通道,主要获取0通道
        normalize(iDft[0], iDft[0], 1, 0, CV_MINMAX);//归一化处理,float类型的显示范围为0-1,大于1为白色,小于0为黑色
        namedWindow("idft", CV_WINDOW_NORMAL);
        imshow("idft", iDft[0]);//显示逆变换
     
        plane[0] += Scalar::all(1); 
        log(plane[0], plane[0]);
        normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
        namedWindow("dft",CV_WINDOW_NORMAL);
        imshow("dft", plane[0]);
        waitKey(100086110);
        return 0;
    }

       

     4. 对频域变换的结果进行处理,将一部频域结果置为零,进行反傅里叶变换,分析与原始图像的区别。

    #include<opencv2/opencv.hpp>
    #include<iostream>
    using namespace std;
    using namespace cv;
    int main(int a, char **p)
    {
        Mat input=imread("F:\work_three_grade\DigitalImage\c.jpg",CV_LOAD_IMAGE_GRAYSCALE);
        namedWindow("input", CV_WINDOW_NORMAL);
        imshow("input", input);//显示原图
        int w = getOptimalDFTSize(input.cols);
        int h = getOptimalDFTSize(input.rows);//获取最佳尺寸,快速傅立叶变换要求尺寸为2的n次方
        Mat padded;
        copyMakeBorder(input, padded, 0, h - input.rows, 0, w - input.cols, BORDER_CONSTANT, Scalar::all(0));//填充图像保存到padded中
        Mat plane[] = { Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F) };//创建通道
        Mat complexIm;
        merge(plane, 2, complexIm);//合并通道
        dft(complexIm, complexIm);//进行傅立叶变换,结果保存在自身
        split(complexIm, plane);//分离通道
        magnitude(plane[0], plane[1], plane[0]);//获取幅度图像,0通道为实数通道,1为虚数,因为二维傅立叶变换结果是复数
        int cx = padded.cols / 2; int cy = padded.rows / 2;//以下的操作是移动图像,左上与右下交换位置,右上与左下交换位置
        Mat temp;
        Mat part1(plane[0], Rect(0, 0, cx, cy));
        Mat part2(plane[0], Rect(cx, 0, cx, cy));
        Mat part3(plane[0], Rect(0, cy, cx, cy));
        Mat part4(plane[0], Rect(cx, cy, cx, cy)); 
    
        part1.copyTo(temp);
        //part4.copyTo(part1);
        temp.copyTo(part4);
        for (int i = 0; i < cx; i++)
        {
            for (int j = 0; j < cy; j++)
            {
                part1.at<int>(i, j) = 0;
            }
        }
         
        part2.copyTo(temp);
        part3.copyTo(part2);
        temp.copyTo(part3); 
         
        //将complexIm的一部分置为0,然后再进行反傅里叶变换
        for (int i = 0; i < cx; i++)
        {
            for (int j = 0; j < cy; j++)
            {
                complexIm.at<int>(i, j) = 0;
            }
        }
    
        Mat _complexim;
        complexIm.copyTo(_complexim);//把变换结果复制一份,进行逆变换,也就是恢复原图
        Mat iDft[] = { Mat::zeros(plane[0].size(),CV_32F),Mat::zeros(plane[0].size(),CV_32F) };//创建两个通道,类型为float,大小为填充后的尺寸
        idft(_complexim, _complexim);//傅立叶逆变换
        split(_complexim, iDft); 
        magnitude(iDft[0], iDft[1], iDft[0]);//分离通道,主要获取0通道
        normalize(iDft[0], iDft[0], 1, 0, CV_MINMAX);//归一化处理,float类型的显示范围为0-1,大于1为白色,小于0为黑色
        namedWindow("idft", CV_WINDOW_NORMAL);
        imshow("idft", iDft[0]);//显示逆变换
     
        plane[0] += Scalar::all(1); 
        log(plane[0], plane[0]);
        normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
        namedWindow("dft",CV_WINDOW_NORMAL);
        imshow("dft", plane[0]);
        waitKey(100086110);
        return 0;
    }

  • 相关阅读:
    进入用友通:提示"由于文件不可访问,内存磁盘空间不足无法打开ufsystem数据库"...
    HDOJ 1069 Monkey and Banana
    HDOJ 1087 Super Jumping! Jumping! Jumping!
    HDOJ 1209 Clock
    CodeForces Round #185 (Div. 2)A,B,C
    HDOJ 1465 不容易系列之一
    HDOJ 1114 PiggyBank
    HDOJ 1280 前m大的数
    HDOJ 1495 非常可乐
    HDOJ 1284 钱币兑换问题
  • 原文地址:https://www.cnblogs.com/loyolh/p/10058943.html
Copyright © 2011-2022 走看看