C++中fftw库二维傅里叶变换笔记

article/2025/10/3 2:21:18

目录

1.相关基础知识参考链接

2.二维傅里叶变换作用简介

3.FFTW二维傅里叶变换输出分析

(1)原始输出数据​

(2)频谱中心化后的输出数据

4.频谱图绘制

5.二维傅里叶变换逆变换

6.从输出结果中分离各平面波并画出波形平面图

7.归一化方法及实现

8.频谱中心化实现

9. 图像(R,G,B)彩图二维傅里叶变换

10.二维傅里叶变换FFTW使用说明

11.r-c中正变换输出数据长度


1.相关基础知识参考链接

离散傅里叶变换(DFT)基础知识理解参考:

深入理解离散傅里叶变换(DFT) - 知乎

FFTW库基本使用参考:

FFTW3学习笔记2:FFTW(快速傅里叶变换)中文参考 - 爱国呐 - 博客园

关于FFTW库的使用和离散傅里叶变换的基础知识参考上述两篇优秀文章即可,我学习过程中也是参考上述文章进行学习的,此文着重于二维傅里叶变换方面FFTW库在实践过程中的问题及解决。

2.二维傅里叶变换作用简介

二维傅里叶变换:1个图像分解为若干复平面波之和,图像从空间域转至频域

平面波:在一个方向上存在一个正弦函数,在法线方向上将其拉伸(正弦平面波)

表示平面波所需参数:                                                        平面波举例:

        

 二维傅里叶变换过程图示:

将输入图像分解为若干平面波之和,图像每个点像素由RGB组成,FFTW输入计算时,需将RGB变为灰度值

平面波合成图解:

  

3.FFTW二维傅里叶变换输出分析

输出结果一半在分析前需进行频谱中心化,这样讲有助于分析,下面将分别记录。

(1)原始输出数据

  • FFTW二维傅里叶变换输出为和输入图像行列数(m,n)相同的元素为复数的矩阵。
  • 各复数元素,幅值·相位·频率 均可由复数的实部虚部计算得到,平面波的方向则由当前元素和所在区域的低频顶点(即直流)在数组中的距离和组成的向量来表示。如图中箭头所指方向,为(a+bi)所代表平面波的方向,由(a+bi)所在的点和4区域低频顶点所形成的向量代表方向
  • 矩阵整体以行列中心为分界线,将矩阵分为4个区域。1区和4区对应,2区和3区对应,对应区域中的复数值,实部相同,虚部互为相反数。
  • 此时输出各区域中,低频分量在四角部分,高频分量在中心部分。

(2)频谱中心化后的输出数据

频谱中心化:将4个区域的顺序对调(14对调  23对调),从而使输出低频在中心,高频在四周,这样有助于分析,更符合人们观察习惯。频谱中心化后,中心低频就是直流。建议第二种方法,第一种方法中心不确定,易出错

频谱中心化对各平面波幅度,相位,频率,方向均无影响,此时方向为矩阵中心指向元素所在位置,无影响。

注意:频谱中心化对输出数据的顺序进行了修改,若需要进行逆变换,则需再次进行一次频谱中心化操作,使数据恢复原始状态,否则逆变换结果有误。

4.频谱图绘制

频谱图:计算中心化后各点的幅值,对幅值进行归一化,将其大小控制在0-255之间,并以此值作为灰度值,绘制灰度图。

归一化目的:灰度图各点数值范围为0-255,而输出各点幅值数据大小并非在此范围中,即使全部在此范围中,也并非均匀分布,上述情况均会使成图效果低下,导致全黑或全白或其他情况。归一化后将数值范围限制在0-255中,并将数值按大小比例分布在范围内,成图效果好。

效果如下:(绘图使用Opencv)

               原图:                                                        中心化归一化频谱图:

                        

                    未中心化归一化频谱图:                                        中心化未归一化频谱图:

                                          

 以下几种情况会导致绘图结果不同

  • 灰度转换公式中RGB各通道所占比参数不同,从而直接影响之后的结果
  • 归一化过程中方式不同,归一化方法不唯一,不同方法导致灰度值不同,可能导致过亮过暗
  • 某些实现过程可能会忽略部分较小值,只关注主体,从而使图像展示不同

5.二维傅里叶变换逆变换

二维傅里叶逆变换:将图像由频域转为空间域,即将各平面波进行合成,从而形成图像

效果如下:

                                      原图:                                                                逆变换:

                            

                                       原图:                                                                  逆变换:

                                   

原图为RGB三色图,但由于在正向变换前将图片变为了灰度图,导致逆变换后的结果仍为灰度图,若想要对RGB图像变换而非灰度图,则对R,G,B三通道数值单独进行正变换,再依次逆变换后,将得到的三组数据合成RGB三色数据,即可得到原始三色图

 逆变换注意:

  • 若正向变换过程中使用了频谱中心化,则在逆变换结果中需再进行一次频谱中心化以抵消之前的变换,得到正确的图像,否则图像对应区域互相颠倒
  • Fftw库逆变换得到的结果需除以总样本数(m*n),才能得到正确的图像。若不除以则数值过大导致图像为全白(超出显示最大值,均按最大值处理)

6.从输出结果中分离各平面波并画出波形平面图

二维傅里叶变换的结果中每一个点代表一种平面波,每对关于中心对称的一对数值点,经过逆变换后,可得到相应平面波。

中心:输出结果的中心不一定在矩阵中心

如:(5,5)的矩阵中心为(3,3),但FFTW中二维傅里叶输出结果的中心可能在(3,4)(4,4)等(5,5)附近的点上(可能是小数),判断中心点需比较对角数据,从而计算出中心点的具体所在位置,若中心点找错,即导致所选的两对频点并不对称,逆变换的结果也就是错误的

对称频点:实部相同,虚部互为相反数

 例:

原图:大小(318*318)(0-317)

 

下图对应数据分别为左上角和右下角中5*5大小的输出结果

图中紫色部分数据相同,即(11)与(317317)相同,而不是(00)与(317317)相同,第0列和第0行无对称点

即对称点为(159,159),且第0列和第0行无对称点

成图流程:

  1. 1.  选定需要逆变换的一对频点,并将其余频点数据均置为0,才可正确显示此频点对应的平面
  2. 2.  若正变换进行过频谱中心化,则需再进行一次频谱中心化
  3. 3.  逆变换得到的结果需进行归一化处理,将数值固定在0-255范围内。(整体逆变换无需进行归一
  4. 化,因为各平面波之间数据互相作用,使得最终结果范围再可输出区间内,而单独对一个平面波逆
  5. 变换,此平面波的幅值可能过大或过小,此平面波只是原本图片的组成部分之一,直接输出结果通
  6. 常无法观察,全黑或全白/数值过小或数值过大,因此需要进行归一化处理)
  7. 注意:只有两点对称进行逆变换,变换结果的虚部才会近似为0可忽略,才可得到正确图像

效果如下:

​​​

!若所选取的频点对应频率过高,会导致一个像素内多次数据重复,从而使结果无法正确显示!

7.归一化方法及实现

流程:

1.求出各点幅值

2.对各点幅值加一并进行1og运算,减小范围(缩小数据分布间隔,使分布更均匀,成图效果更好)

3.求出2中最大值最小值之差,并用255除以其值得到步长scale

4.用最小值乘以步长得到偏差

5.各值乘以步长减去偏差即可

实现(使用Opencv):

double min1 = 0.0, max1 = 0.0;
minMaxLoc(backward, &min1, &max1);
double scale1 = 255 / (max1 - min1);
double shift1 = -min1 * scale1;
Mat myImage1;
convertScaleAbs(backward, myImage1, scale1, shift1);// 此代码未进行log过程,若有需要可添加
// 相关函数为Opencv中相关函数

8.频谱中心化实现

频谱中心化实现方法之前已经提及,此处给出实现:

互换区域中心化:

void fftshift(Mat source, Mat& dest)
{int row = source.rows;int col = source.cols;int halfRow = row / 2;int halfCol = col / 2;int temp = 0;for (size_t j = 0; j < row; j++){temp = (j + halfRow) % row;for (size_t i = 0; i < col; i++){*dest.ptr<float>(temp, i) = *source.ptr<float>(j, i);}}source = dest.clone();for (size_t i = 0; i < col; i++){temp = (i + halfCol) % col;for (size_t j = 0; j < row; j++){*dest.ptr<float>(j, temp) = *source.ptr<float>(j, i);}}}

输入乘以 (建议):

void fftshift2(Mat source, Mat& dest)
{int row = source.rows;int col = source.cols;int halfRow = row / 2;int halfCol = col / 2;for (int j = 0; j < col; j++){for (int i = 0; i < row; i++){*dest.ptr<float>(i, j) = *source.ptr<float>(i, j) * (pow(-1, i + j));}}
}

9. 图像(R,G,B)彩图二维傅里叶变换

RGB各单通道数据拿出分别进行变换,逆变换也是分别进行,最后再将各单通道数据组合

效果如下:

                                   原图:                                                        B通道正变换:

                             

                        G通道正变换:                                                        R通道正变换:

                                

                        B通道逆变换:                                                        G通道逆变换:

                                

                                R通道逆变换:                                        (B,G,R)逆变换组合:

                        ​​​​​​​        

10.二维傅里叶变换FFTW使用说明

1.二维图像输入应使用二维数组,但fftw中二维输入仍以一维数组方式存储,在调用方法时,指定二维输入的行列,以便于分割

2.复数类型中实数输入需转变为复数,虚部为0

3.空间申请需使用fftw内部给定的类型,防止内存出现错误

4.方法的创建放在输入赋值之前

5.使用fftw_destroy_planfftw_free释放方法和输入输出数据所占的空间

6.同一方法在不修改输入输出大小的前提下,可更改内部数据重复多次变换。

11.r-c中正变换输出数据长度

1.Fftw中所有rtc/ctr函数将正逆变换分开,输入是n个实数,而输出是n/2+1 个复数,输出只有n/2+1位,申请n空间,未初始化则n/2+1位后面则无数据,若未初始化则后面数据未知,因此应只为输出申请n/2+1空间或对n空间输出进行初始化即可(即所有rtc/ctr函数正变换输出只有n/2+1个数据有效)

分析时需注意所有rtc/ctr函数的正变换输出有效位数,切勿使用无效数据

2.非rtc/ctr函数的正变换n/2+1之后的数据为之前数据的对称,故使用此方法时可分析全部数据

3.所有rtc/ctr函数生成方法时仍需指定完整长度数值

未初始化:

初始化0:

初始化1:


http://chatgpt.dhexx.cn/article/i76CM7J8.shtml

相关文章

二维傅里叶变换的理解和使用

目录 似模似样的前言一维傅里叶二维傅里叶 似模似样的前言 最近的瑕疵检测项目需要在有纹理的产品上做很细致的检测。由于当前做项目使用的还是halcon居多&#xff0c;目前知道的方法还是傅里叶变换比较靠谱。 但仅靠halcon自带的样例并不能很好的理解和使用傅里叶&#xff0…

二维傅里叶变换频谱图的直观理解

众所周知&#xff1a;频谱中心代表低频&#xff0c;四周代表高频。 问&#xff1a;那&#xff08;u&#xff0c;v&#xff09;一点代表什么&#xff1f; 答&#xff1a; 1.当为水平方向的正弦图片时&#xff0c;二维傅里叶变换后&#xff0c;其只有u方向的频谱值&#xff1b; 2…

Matlab:二维傅里叶变换

Matlab:二维傅里叶变换 二维傅里叶变换二维衍射模式fft2 函数将二维数据变换为频率空间。例如,您可以变换二维光学掩膜以揭示其衍射模式。 二维傅里叶变换 以下公式定义 mn 矩阵 X 的离散傅里叶变换 Y。 i 是虚数单位,p 和 j 是值范围从 0 到 m–1 的索引,q 和 k 是值范围…

matlab二维傅里叶变换ffshift,形象理解二维傅里叶变换

点击上方“机器学习与生成对抗网络”,关注"星标" 获取有趣、好玩的前沿干货! 来自 | 知乎 阿姆斯特朗 链接 | https://zhuanlan.zhihu.com/p/110026009 文仅交流,侵删 1.回顾一下一维FT 公式: 通俗来讲,一维傅里叶变换是将一个一维的信号分解成若干个复指数波 …

傅里叶变换(二维离散傅里叶变换)

离散二维傅里叶变换 一常用性质&#xff1a; 可分离性、周期性和共轭对称性、平移性、旋转性质、卷积与相关定理&#xff1b; &#xff08;1&#xff09;可分离性&#xff1a; 二维离散傅里叶变换DFT可分离性的基本思想是DFT可分离为两次一维DFT。因此可以用通过计算两次一维…

二维傅里叶变换

fft2 函数将二维数据变换为频率空间。例如&#xff0c;可以变换二维光学掩膜以揭示其衍射模式。 二维傅里叶变换 以下公式定义 mn 矩阵 X 的离散傅里叶变换 Y。 和 是以下方程所定义的复单位根。 i 是虚数单位&#xff0c;p 和 j 是值范围从 0 到 m–1 的索引&#xff0c;q …

【深度好文】二维图像傅里叶变换 YYDS

1. 傅里叶变换原理 在数学中进行傅里叶变换为连续模拟信号&#xff0c;通常来说&#xff1a; 二维连续函数f(x,y)的傅里叶正变换为&#xff1a; 相应的傅里叶逆变换公式为&#xff1a; 但是在计算机领域&#xff0c;计算机一般处理的是数字信号&#xff0c;只能进行有限次计…

微信公众号开发模式没有域名怎么办?申请免费域名

微信公众号开发采用前后端分离模式&#xff0c;那么前端使用微信开发工具开发时&#xff0c;需要域名才能访问&#xff0c;那么域名从何而来呢&#xff1f; 1、申请域名 a)、NetApp申请免费域名 : https://natapp.cn/login b)、域名申请好以后&#xff0c;下载客户端&#xf…

freenom 申请免费域名

为了降低建站成本&#xff0c;可在freenom上申请免费域名&#xff0c;可以免费使用一年。 一. 注册域名 登录freenom.com&#xff0c;输入域名&#xff0c;检测通过后&#xff0c;输入邮箱&#xff0c;登录邮箱完成激活。 二. 配置DNS 上面申请的域名未绑定外网ip&#xff0c…

如何注册一个免费的网站空间和域名

https://www.jianshu.com/p/016c83f70d43 前几天想搞个网站玩玩&#xff0c;于是就上网搜哪里可以注册免费的网站空间和域名&#xff0c;折腾了好几天都没注册成&#xff0c;国内好像已经没有免费的了。只好用英文去搜国外的网站&#xff0c;才找到了一个能注册成功的&#xff…

Freenom免费域名申请

Freenom免费域名申请 准备条件操作流程注意选择域名确定并提交订单方法一(谷歌&#xff0c;FaceBook)方法二(开发者邮箱注册) 注册谷歌&#xff0c;Facebook 注册 防订单失败操作 准备条件 必须拥有一个 谷歌账号 或 Facebook 账号 亦或者 拥有一个 未注册Freenom的邮箱 登录 …

【免费域名】教你免费申请顶级域名

一、输入网址 &#xff1a;https://my.freenom.com/ 二、点击Service->Register a New Domain&#xff0c;注意这里有网络延时至少30秒 三、输入自己想要的域名&#xff0c;点击Check Avaliability&#xff0c;比如我的是abc5500&#xff0c;延时10秒 四、Get it now! ->…

免费域名证书最新申请方式大全

目前市场环境下&#xff0c;可获得域名SSL证书的方式有很多&#xff0c;一般有付费和免费划分。对于想免费使用域名SSL证书的朋友&#xff0c;这里收集整理了几个常用的SSL证书申请方式。 对于SSL证书的用处&#xff0c;简单的来说&#xff0c;就是加密数据传输&#xff0c;使…

免费域名申请及免费DNS解析

一&#xff1a;免费域名申请 1&#xff1a;freenom免费域名申请&#xff08;有效期12个月&#xff09; 我是通过科学上网才申请成功。普通方式申请容易出现各种问题不成功。因为freenom网站要连接国外各种服务器检测域名的可用性。 如下图申请成功的域名&#xff1a; 域名再DNS…

freenom域名申请教程

freenom域名申请教程 1. 注册&申请域名 打开freenom官网&#xff0c;注册一个账户【注意&#xff1a;如果没有明显的注册按钮&#xff0c;可以通过如下方式同时申请域名和注册账户】 打开域名申请【不用注册】 选择好了域名之后&#xff0c;点击Checkout&#xff1b;选择…

freenom免费域名的申请+cloudflare(域名代理解析)

视频网址:公众号知识浅谈回复 freenom+cloudflare 领取 第一步:注册 freenom{申请免费域名}: https://my.freenom.com/ 注册步骤 首页->partners->Devlopers->下滑找到Get a Random Domains Account today! 这句话,点击之后进入下一个页面 然后去邮箱激活,再次重复上…

免费申请国外免费域名超详细教程

注意事项&#xff1a; 1.需要准备好VPN&#xff08;因为是用的国外的&#xff0c;不会搭建的可以看我之前的笔记笔记地址&#xff09; 2.手机下载Gmail, 注册谷歌邮箱&#xff0c;国内手机号就可以注册手机邮箱 3.谷歌邮箱内验证freenom注册信息时候需要美区手机号验证。这里给…

freenom 加 cloudflare免费域名申请

https://www.freenom.com/zh/index.html?langzh 该网站管理 .tk .ml 等后缀 输入如 aaa.tk购买时需要账号&#xff08;免费购买&#xff09;&#xff0c;需要一个谷歌账号&#xff0c;可以 social login 购买成功后&#xff0c;可以看见域名 打开 https://dash.cloudflare.…

申请免费域名、配置域名以及https证书设置

如何申请免费域名 域名申请官方网站 https://my.freenom.com/clientarea.php 详细的申请教程可以查看都比根据地良心教程 https://doub.io/dbwz-3/ 我申请的免费域名 如何用刚申请到的域名 现在我们有了域名&#xff0c;接下来就是解析域名了&#xff0c;也就是域名配置绑定…

不花一分钱申请免费域名和ssl证书

最近想申请个域名做测试&#xff0c;在网上搜了下&#xff0c;找到了个免费申请的网站&#xff0c;顺便使用这个域名申请了ssl的证书(不用花任何钱)&#xff0c;整理了下分享出来。 如果是想要一个临时使用的域名可以按照下面的办法申请&#xff0c;如果是想长期使用&#xff…