opencv(Python/c++):离散傅里叶变换(DFT)

转载一个描述(来理解傅里叶变换):

在频域里,对于一副图像,高频部分代表了图像的细节,纹理信息,;低频信息代表了图像的轮廓信息。如果对一个图像使用低通滤波器,那么滤波后就只剩下轮廓了。。
因此,傅里叶变换在图像处理中可以做到图像增强与图像去噪,图像分割之边缘检测、图像特征提取,图像压缩等。

效果图

在这里插入图片描述

C++版本

源码:

#include <iostream>
#include <opencv/cv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

//主函数
int main(void)
{
    //读取原始图像
    Mat srcImage=imread("/home/liuxin/桌面/opencv/dog.jpeg",0);//灰度
    imshow("original",srcImage);

    //将输入图像延扩至最佳尺寸,边界用0填充
    int m=getOptimalDFTSize(srcImage.rows);
    int n=getOptimalDFTSize(srcImage.cols);

    Mat padded;//定义填充后的图像
    copyMakeBorder(srcImage,padded,0,m-srcImage.rows,0,n-srcImage.cols,BORDER_CONSTANT,Scalar::all(0));

    imshow("padded image",padded);



    //为傅里叶变换的结果分配存储空间
    Mat planes[]={Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F)};
    Mat complexI;//将planes数组组合合并成一个多通道的数组complexI
    merge(planes,2,complexI);

    //进行离散傅里叶变换
    dft(complexI,complexI);

    //将复数转换为幅值magitude
    split(complexI,planes);//将多通道数组complexI分离为几个单通道数组,planes[0]=Re(DFT(I),planes[1]=Im(DFT(I)));re是实数,Im是复数吧

    magnitude(planes[0],planes[1],planes[0]);
    Mat magnitudeImage=planes[0];



    //进行对数尺度缩放
    magnitudeImage+=Scalar::all(1);
    log(magnitudeImage,magnitudeImage);//求自然对数

    //剪切和重分布幅度图象限(若有奇数行或奇数列,进行频谱裁剪)
    magnitudeImage=magnitudeImage(Rect(0,0,magnitudeImage.cols&-2,magnitudeImage.rows&-2));

    //重新排列傅里叶图像中的象限,使得原点位于图像中心
    int cx=magnitudeImage.cols/2;
    int cy=magnitudeImage.rows/2;
    Mat q0(magnitudeImage,Rect(0,0,cx,cy));//ROI区域的左上
    Mat q1(magnitudeImage,Rect(cx,0,cx,cy));//ROI区域的右上
    Mat q2(magnitudeImage,Rect(0,cy,cx,cy));//ROI区域的左下
    Mat q3(magnitudeImage,Rect(cx,cy,cx,cy));//ROI区域的左上

    Mat tmp;//交换象限(左上与右下进行交换)
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);


    q1.copyTo(tmp);//右上与左下进行交换
    q2.copyTo(q1);
    tmp.copyTo(q2);

    //归一化,用0到1之间的浮点值,将矩阵变幻为可视的图像格式

    normalize(magnitudeImage,magnitudeImage,0,1,NORM_MINMAX);
    imshow("MAGNITUDE",magnitudeImage);

    while(1)
    {
        int key=cvWaitKey(10);
    if (key==27)
    {
        break;
    }
    }
    return(0);



}

猜你喜欢

转载自blog.csdn.net/weixin_42755384/article/details/88368642