C++离散傅里叶变换

一、序言:

该教程基于之前的图像处理类MYCV,是对其的补充。

二、设计目标

对图像进行简单的离散傅里叶变换,并输出生成的频谱图。

三、需要提前掌握的知识

二维傅里叶变换公式:

四、详细步骤

1.首先定义一个方法,该方法对输入的图像进行傅里叶变换

输入:MyImage 源图像

输出:ComplexNu 进行离散傅里叶变换后的复数数组

定义:

static ComplexNumber* Dft2(MyImage const &Scr);

实现:

ComplexNumber* MyCV::Dft2(MyImage const &Scr){int width = Scr.m_width;int height = Scr.m_height;// 将 scr_data 转化为灰度
MyImage *grayimage = Gray(Scr);unsigned char* gray_data = grayimage->m_data;int gray_bytesPerLine = grayimage->m_bytesPerLine;// 将 gray_data 转化为 double 型,并去掉用于填充的多余空间double *double_data = new double[width*height];for(int i=0;i<height;i++)for(int j=0;j<width;j++){double_data[i*width+j]=(double)gray_data[i*gray_bytesPerLine+j];}// 对 double_data 进行傅里叶变换
ComplexNumber *dft2_data = new ComplexNumber[width*height];double fixed_factor_for_axisX = (-2 * PI) / height;// evaluate -i2π/N of -i2πux/N, and store the value for computing efficiencydouble fixed_factor_for_axisY = (-2 * PI) / width;// evaluate -i2π/N of -i2πux/N, and store the value for computing efficiencyfor (int u = 0; u<height; u++) {for (int v = 0; v<width; v++) {for (int x = 0; x<height; x++) {for (int y = 0; y<width; y++) {double powerX = u * x * fixed_factor_for_axisX; // evaluate -i2πux/Ndouble powerY = v * y * fixed_factor_for_axisY; // evaluate -i2πux/N
ComplexNumber cplTemp;cplTemp.m_rl = double_data[y + x*width] * cos(powerX + powerY);// evaluate f(x) * e^(-i2πux/N), which is equal to f(x) * (cos(-i2πux/N)+sin(-i2πux/N)i) according to Euler's formula
cplTemp.m_im = double_data[y + x*width] * sin(powerX + powerY);dft2_data[v + u*width] = dft2_data[v + u*width] + cplTemp;}}}}// 返回傅里叶数组return dft2_data;}

2.为了让傅里叶变换可视化,旭阳对其进行标准化和中性化

输入:ComplexNumber 离散傅里叶变换生成的复数数组

输出:MyImage 可视化后的图像

定义:

static MyImage* Dft22MyImage(ComplexNumber *Scr,int width,int height);

实现:

MyImage* MyCV::Dft22MyImage(ComplexNumber *Scr, int const width, int const height){// 将傅里叶数组归一化// 取模double mold[width*height];for(int i = 0 ;i<width*height;i++){mold[i] = Scr[i].get_mold();}// 获取最小值double min = mold[0];for(int i = 0;i<width*height;i++){if(mold[i]<min)min = mold[i];}// 获取去掉前几大值的最大值double maxqueue[20] = {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},max;for(int i = 0;i<width*height;i++){if(mold[i]>maxqueue[0])maxqueue[0] = mold[i];}for(int j =1;j<20;j++){for(int i = 0;i<width*height;i++){if(mold[i]>maxqueue[j]&&mold[i]<maxqueue[j-1])maxqueue[j] = mold[i];}}max = maxqueue[19];unsigned char *normalized_data = new unsigned char[width*height];for(int i=0;i<height;i++)for(int j=0;j<width;j++){unsigned char t = (unsigned char)((mold[i*width+j]-min)/(max-min)*255);if(t>255)t = 255;normalized_data[i*width+j]=t;}// 将图像中心化
unsigned char* center_data = new unsigned char[width*height];for (int u = 0; u<height; u++){for (int v = 0; v<width; v++) {if ((u<(height / 2)) && (v<(width / 2))) {center_data[v + u*width] =normalized_data[width / 2 + v + (height / 2 + u)*width];}else if ((u<(height / 2)) && (v >= (width / 2))) {center_data[v + u*width] =normalized_data[(v - width / 2) + (height / 2 + u)*width];}else if ((u >= (height / 2)) && (v<(width / 2))) {center_data[v + u*width] =normalized_data[(width / 2 + v) + (u - height / 2)*width];}else if ((u >= (height / 2)) && (v >= (width / 2))) {center_data[v + u*width] =normalized_data[(v - width / 2) + (u - height / 2)*width];}}}// 向中心化的数组填充空间int bytesPerLine = (width*8+31)/32*4;unsigned char *dst_data = new unsigned char[bytesPerLine*height];for(int i=0;i<height;i++)for(int j=0;j<width;j++){dst_data[i*bytesPerLine+j] = center_data[i*width+j];}return new MyImage(dst_data,width,height,MyImage::format::GRAY8);}

至此,离散傅里叶变换的方法实现完成,效果图如下:

如果上述教程或代码中有任何错误,欢迎批评和指证。

转载于:https://www.cnblogs.com/akakakkk/p/8541497.html

五、c++实现离散傅里叶变换相关推荐

  1. 《OpenCV3编程入门》学习笔记5 Core组件进阶(五)离散傅里叶变换(DFT)

    第5章 Core组件进阶 5.5 离散傅里叶变换(Discrete Fourier Transform,DFT) 5.5.1 离散傅里叶变换原理 1.对一张图像使用傅里叶变换就是把它分解成正弦和余弦, ...

  2. Android OpenCV (五十九):离散傅里叶变换

    离散傅里叶变换 对一张图像使用傅立叶变换就是将它分解成正弦和余弦两部分,也就是将图像从空间域(spatial domain)转换到频域(frequency domain). 这一转换的理论基础来自于以 ...

  3. OpenCV3.0中的离散傅里叶变换

    图像中的离散傅里叶变换的相关理论较为简单,频域里面,对于一幅图像,高频部分代表了图像的细节.纹理信息:低频部分代表了图像的轮廓信息. 这里我们直接讲解OpenCV3.0中的离散傅里叶变换 1.dft( ...

  4. 数字信号处理学习笔记(一)|离散傅里叶变换

    离散傅里叶变换(DFT) 离散傅里叶变换(Discrete Fourier Transform)的实质是有限长序列傅里叶变换的有限点离散采样,实现了频域离散化,使数字信号处理可以在频域采用数值运算的方 ...

  5. 单变量离散傅里叶变换DFT原理及实现

    一.单变量离散傅里叶变换 离散傅里叶变换公式: 根据公式,单变量离散傅里叶变是换将一维数组变换为傅里叶频率.设定一个大小为N的数组,t为X轴上的变量,取值为[0,n-1],f(t)为t=x出的值,计算 ...

  6. 如何理解离散傅里叶变换(一)实数形式傅里叶变换

    如何理解离散傅里叶变换(一) --实数形式傅里叶变换 ------------------------------------------------------------------------- ...

  7. 【OpenCV】OpenCV实战从入门到精通之 -- 离散傅里叶变换相关函数详解

    目录 1.dft()函数 2.返回DFT最优尺寸大小:getOptimalDFTSize()函数 3.扩充图像边界:copyMakeBorder()函数 4.计算二维矢量的幅值:magnitude() ...

  8. 【小白】Open-CV 学习笔记 -5.5.2 离散傅里叶变换相关函数详解

    目录 1.dft()函数 2.返回DFT最优尺寸大小:getOptimalDFTSize()函数 3.扩充图像边界:copyMakeBorder()函数 4.计算二维矢量的幅值:magnitude() ...

  9. (数字图像处理MATLAB+Python)第四章图像正交变换-第一节:离散傅里叶变换

    文章目录 一:一维离散傅里叶变换 (1)定义 (2)实例 二:一维快速傅里叶变换 (1)定义 (2)实例 三:二维离散傅里叶变换 (1)定义 (2)程序 四:二维离散傅里叶变换的性质 (1)可分性 ( ...

最新文章

  1. 递归式求时间复杂度的代入法与迭代法的举例讲解
  2. [翻译] ASP.NET Core 2.2 正式版发布
  3. Hibernate持久化对象三种状态
  4. db2查最新值的前一天值_现在的C1驾照值多少钱?最新价格曝光,老司机一看赚翻了...
  5. 所属的用户_关于chmod(变更用户对此文件的相关权限)超详细说明,小白秒懂
  6. 输入域html,我可以让HTML输入表单域成为可选的吗?
  7. 百度免费开放长语音识别功能
  8. ZZFAFA_BilibiliMusic_DownUrl
  9. 微信小程序登录后跳转tabbar页面
  10. java正则表达式判断整数_java正则表达式判断数字
  11. E.03.24 Colin Huang steps down as Pinduoduo chair
  12. 利润最大化下的模型cutoff测算
  13. leetcode-买卖股票的最佳时机含手续费
  14. 随身Q代理服务器大升级
  15. 科学绘图软件 Prism 安装教程
  16. MySQL 从 5.7 到 8.0
  17. teamviewer安装失败
  18. UML设计——网上信用卡管理系统分析与设计(新手)
  19. Win10系统修改时间设置
  20. 诚迈科技电话面试-昨天

热门文章

  1. adb: failed to install ebug.apk: Failure [INSTALL_FAILED_VERSION_DOWNGRADE]
  2. 【R语言文本挖掘】:分析单词和文档频率——TF-IDF
  3. Vidar-Team战队专访:AS WE DO, AS YOU KNOW.
  4. 华为HCIA-datacom 学习笔记17——IPv6基础
  5. ETL数据抽取---Apache Hop
  6. 《Python爬虫大数据采集与挖掘》期末考试考题汇总带答案
  7. 欢迎关注搜狗测试微信公众号
  8. 2022-2028中国聚合物增材制造系统市场现状研究分析与发展前景预测报告
  9. 【万人千题】大学生算法社区火爆开启,每日打卡学习,诚邀妳的加入
  10. 披着人皮的幽灵们……(读《死亡清扫日记》有感)