频域变换-傅里叶变换实验二

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

频域变换-傅里叶变换实验二

 

上一篇:Pytorch【直播】2019 年县域农业大脑AI挑战赛---初级准备(一)切图


下一篇:H-大时钟(扩展欧几里得)