• 离散傅里叶变换


     1 #include<opencv2/opencv.hpp>
     2 #include<iostream>
     3 
     4 using namespace std;
     5 using namespace cv;
     6 
     7 int main() {
     8     //以灰度图读取原始图像并显示
     9     Mat srcImage = imread("C:\Users\Nelsoner\Desktop\Camera Roll\05.jpg", 0); 
    10 
    11     if (!srcImage.data) {
    12         cout << "读取图片出错!" << endl;
    13         return false;
    14     }
    15     imshow("原始图像", srcImage);
    16 
    17     //ShowHelpText();
    18 
    19     //将输入图像延扩到最佳的尺寸,边界用0补充
    20     int m = getOptimalDFTSize(srcImage.rows);
    21     int n = getOptimalDFTSize(srcImage.cols);
    22 
    23     //将添加的像素初始化为0
    24     Mat padded;
    25     copyMakeBorder(srcImage, padded, 0, m - srcImage.rows, 0, n - srcImage.cols, BORDER_CONSTANT, Scalar::all(0));
    26 
    27     //为傅里叶变换的结果(实部和虚部)分配存储空间
    28     //将planes数组组合合并成一个多通道的数组complexI
    29     Mat planes[] = { Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F) };
    30     Mat complexI;
    31     merge(planes, 2, complexI);
    32 
    33     //进行就地离散傅里叶变换
    34     dft(complexI, complexI);
    35 
    36     //将复数转换为幅值,即=>log(1+sqrt(Re(DFT(I))^2+Im(DFT(I))^2))
    37     split(complexI, planes);   //将多通道数组complexI分离成几个单通道数组,planes[0] = Re(DFT(I),planes[1] = Im(DFT(I)))
    38     magnitude(planes[0], planes[1], planes[0]);
    39     Mat magnitudeImage = planes[0];
    40 
    41     //进行对数尺度(logarithmic scale)缩放
    42     magnitudeImage += Scalar::all(1);
    43     log(magnitudeImage, magnitudeImage);  //求自然对数
    44 
    45                                           //剪切和重分布幅度图象限
    46                                           //若有奇数行或奇数列,进行频谱裁剪
    47     magnitudeImage = magnitudeImage(Rect(0, 0, magnitudeImage.cols &-2, magnitudeImage.rows&-2));
    48 
    49     //重新排列傅里叶图像中的象限,使得原点位于图像中心
    50     int cx = magnitudeImage.cols / 2;
    51     int cy = magnitudeImage.rows / 2;
    52     Mat q0(magnitudeImage, Rect(0, 0, cx, cy));   //ROI区域的左上
    53     Mat q1(magnitudeImage, Rect(cx, 0, cx, cy));   //ROI区域的右上
    54     Mat q2(magnitudeImage, Rect(0, cy, cx, cy));   //ROI区域的左下
    55     Mat q3(magnitudeImage, Rect(cx, cy, cx, cy));   //ROI区域的右下
    56 
    57                                                     //交换象限(左上与右下进行交换)
    58     Mat tmp;
    59     q0.copyTo(tmp);
    60     q3.copyTo(q0);
    61     tmp.copyTo(q3);
    62 
    63     //交换象限(右上与左下进行交换)    Mat tmp;
    64     q1.copyTo(tmp);
    65     q2.copyTo(q1);
    66     tmp.copyTo(q2);
    67 
    68     //归一化,用0到1之间的浮点值将矩阵变换为可视的图像格式
    69     normalize(magnitudeImage, magnitudeImage, 0, 1, CV_MINMAX);
    70 
    71     //显示效果图
    72     imshow("频谱赋值", magnitudeImage);
    73     waitKey();
    74 
    75     return 0;
    76 }

  • 相关阅读:
    (转)搜索Maven仓库 获取 groupid artifactId
    idea自用快捷键(非常实用)
    (2)一起来看下使用mybatis框架的insert语句的源码执行流程吧
    (1)复习jdbc操作,编译mybatis源码,准备为你的简历加分吧
    关于CPU核心,线程,进程,并发,并行,及java线程之间的关系
    数组排序
    泛型类、泛型方法、类型通配符的使用
    数组的三种声明方式总结、多维数组的遍历、Arrays类的常用方法总结
    Java基本数据类型总结、类型转换、常量的声明规范,final关键字的用法
    JAVA基础语法——标识符、修饰符、关键字(个人整理总结)
  • 原文地址:https://www.cnblogs.com/Nelsoner/p/6770016.html
Copyright © 2020-2023  润新知