对fftshift的思考

2024-09-05 09:36
文章标签 思考 fftshift

本文主要是介绍对fftshift的思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先明确一下,我们这里考虑的二维数组的形式,因为我们主要的学习目标是图像处理

在这里插入图片描述

1. 偶数的情况

我们类比于一维中的情况,DFT中一个周期的对称中心是 M / 2 M/2 M/2,如果 M M M 恰好是一个偶数,那么 M / 2 M/2 M/2 会是一个具体的点,如果 M / 2 M/2 M/2 是一个奇数,则显然对称中心不存在某一个具体的点,它在两点之间。为了简单起见,我们现在只考虑 M M M 恰好是一个偶数的情况。

二维的情况其实很简单,将输入的数据乘 ( − 1 ) x + y (-1)^{x+y} (1)x+y,那么频谱就会位移 M / 2 M/2 M/2 N / 2 N/2 N/2

f ( x , y ) ( − 1 ) x + y ⇔ F ( u − M / 2 , v − N / 2 ) f(x, y)(-1)^{x+y} \Leftrightarrow F(u-M / 2, v-N / 2) f(x,y)(1)x+yF(uM/2,vN/2)

MATLAB为我们提供了一个函数来实现这个功能,而不用我们自己来对输入的 M × N M\times N M×N 的 data array 做处理。我们来观察一下。

array =[1,2,3,4;5,6,7,8;9,10,11,12;13,14,15,16];fft_array=fft2(array);
fft_array_shifted=fftshift(fft_array);array_ifft=ifft2(fft_array_shifted)

array_ifft =
1 -2 3 -4
-5 6 -7 8
9 -10 11 -12
-13 14 -15 16

完美符合要求,证明了对于偶数大小的矩阵来说,fftshift 确实成功实现了中心化,也就是对频谱位移了 M / 2 M/2 M/2 N / 2 N/2 N/2

2. 奇数的情况

那对于奇数大小的矩阵呢?我们来验证一下。

array =[1,2,3;4,5,6;7,8,9];fft_array=fft2(array);
fft_array_shifted=fftshift(fft_array);array_ifft=ifft2(fft_array_shifted)

array_ifft =

1.0000 + 0.0000i -1.0000 + 1.7321i -1.5000 - 2.5981i
-2.0000 + 3.4641i -2.5000 - 4.3301i 6.0000 + 0.0000i
-3.5000 - 6.0622i 8.0000 + 0.0000i -4.5000 + 7.7942i

很遗憾,对于奇数大小矩阵似乎无法正确实现频谱位移的功能。这是可以理解的,因为位移的点是整数,想要将频谱位移 M / 2 M/2 M/2 M M M 是奇数的情况下显然是无法实现的。实际上从一维度,我们可以更方便的理解这一点:

对于一维离散DFT,我们知道有
f ( x ) e j 2 π ( u 0 x / M ) ⇔ F ( u − u 0 ) f(x) e^{j 2 \pi\left(u_{0} x / M\right)} \Leftrightarrow F\left(u-u_{0}\right) f(x)ej2π(u0x/M)F(uu0)
fftshift 对频谱的位移效果,会导致 u 0 u_{0} u0 不是一个整数,那么如果 u 0 u_0 u0 不是个整数会发生什么?

array=[1,2,3];
array_fft=fft(array)array=[1,-2,3];
array_fft_another=fft(array)

array_fft =
6.0000 + 0.0000i -1.5000 + 0.8660i -1.5000 - 0.8660i
array_fft_another =
2.0000 + 0.0000i 0.5000 + 4.3301i 0.5000 - 4.3301i

事实上,他是连续形式傅里叶变化位移之后的直接抽样。上面的二维情况是同理。

这篇关于对fftshift的思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1138585

相关文章

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

【编程底层思考】详解Java的JUC多线程并发编程底层组件AQS的作用及原理

Java中的AbstractQueuedSynchronizer(简称AQS)是位于java.util.concurrent.locks包中的一个核心组件,用于构建锁和其他同步器。AQS为实现依赖于FIFO(先进先出)等待队列的阻塞锁和相关同步器提供了一套高效、可扩展的框架。 一、AQS的作用 统一同步状态管理:AQS提供了一个int类型的成员变量state,用于表示同步状态。子类可以根据自己

一道算法题引发的动态内存管理的思考

在做PKU2762时,需要建邻接表。 于是按部就班写了下面一个插入边到邻接表中的函数: const int VMAX = 1010;typedef struct Graph{int vex;Graph* next;}Graph;Graph ArcGraph[VMAX];void insert(int u, int v){Graph* t = new Graph;Graph*

go 和 java 技术选型思考

背景:       go和java我这边自身都在使用,感受比较深,java使用了有7年多,go也就是今年开始的,公司需要所以就学了使用,发现这两个语言都很好,需要根据场景选择,我写下我这边的看法。 关于go和java语言层面和特性就不说了,网上都有,我这边从我这边实际使用的场景情况来说,供大家参考。 给我最大的感受,php转go的不少,也是符合未来技术大趋势的,目前来看,java转go也比较

思考自己写博客的意义

感想 从今年2月份开始,我就要求自己以每周4篇的速度写博客。然而问题是:每周的空闲时间是不稳定的,这导致我没法保证花费相同的时间去输出稳定质量的博客。当时间不够时,我将面临选择:是减少数量来保证稳定的质量,还是降低质量来保证稳定的数量? 我选择的是——牺牲质量。因为,相比于“质量”,“数量”是准确可见的。我担心:一旦有一次没能完成目标数量,便会出现“破窗效应”,让我潜意识里再也不认同“目标”了

是时候重新思考你的Google广告策略了吗?

以产品为中心、仅以关键词为焦点的广告活动是 谷歌广告中常见的一种活动类型。 如果你销售复古女式T恤,你可能会设置基于“复古女式T恤”关键词的独立关键词广告活动。 对于许多B2C零售商来说,这种方法效果不错。但是,对于其他一些商家来说,基于产品和关键词的广告活动并不一定是最好的策略。 比如说,我们接手了一个新的B2B客户的谷歌广告账户,其所有广告活动都是以产品为中心、仅关注关键词的广告活动。

【编程底层思考】如何检测和避免线程死锁

一、什么是线程死锁? 线程死锁发生在多个线程因为争夺资源而相互阻塞,导致程序无法正常结束的情况。例如,线程A持有资源2并等待资源1,线程B持有资源1并等待资源2,这样就形成了死锁。 二、如何检测死锁? 使用jmap、jstack等命令行工具查看JVM的线程栈和堆内存情况,jstack可以显示死锁信息。使用VisualVM、JConsole等图形化工具进行排查。例如,JConsole可以连接到

【个人思考】 Java为什么解释执行时不直接解释源码?

起因 最近学习JVM,产生一个问题:Java为什么解释执行时不直接解释源码? 众所周知,Java 字节码是跨平台的,因此 Java 才能一次编译处处运行。但是,Java 源码本身也是跨平台的啊,为什么不可以省略编译为字节码这一步,直接将源码运行在虚拟机上?如果是效率问题,可不可以在设计 Java 语言的时候解决? 对于此问题,大部分回答诸如:“采用字节码的好处主要包括跨平台性、安全性、性

使用卫星仿真软件STK的一些应用和思考(星地链路、星间链路)

目录 任务描述利用STK建模星地协同系统3个GEO高轨卫星240/20/1 Walker-Star Constellation 低轨卫星星座地面站或者地面设备 链路建模与数据提取处理星地链路星间链路数据读取的几种方法最麻烦的方法使用Matlab与STK互联接口使用大规模使用Chain 总结 任务描述 在一个星地协同的空天地网络中,科研中可能需要建模星地链路以及星间链路,主要受