首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >二维FFT的归一化

二维FFT的归一化
EN

Stack Overflow用户
提问于 2013-10-18 07:51:54
回答 1查看 3.3K关注 0票数 3

在python中执行2D FFT时,我有一个关于规范化的简单问题。我的理解是,标准化因素可以通过使用数组来确定。

例如,在1d中,1,1,1的FFT会给出4+0j,0+0j,0+0j,0+0j,所以归一化因子应该是1/N=1/4。

在2D中,[1,1,1]的FFT会给出[4+0j,0+0j,0+0j,0+0j],因此归一化应该是1/MN=1/(2*2)=1/4。

现在假设我们有一个3000×3000矩阵,每个元素都有一个高斯分布值,平均值为0。当我们对此(归一化因子= 1/(3000*3000))进行FFT和归一化处理时,我们得到了10^-7阶的平均幂。

现在我们使用1000×1000元素子区域(归一化因子= 1/(1000*1000))重复这一点。我们从这里得到的平均功率是10^-6。我想知道为什么会有10种不同的因素。平均权力不应该是一样的吗?我是不是错过了一个额外的归一化因子?

如果我们说因子的差异实际上是9,那么我可以猜测这来自元素的数量(3000 x 3000有9倍于1000 x 1000的元素),但是这个额外因素的直观原因是什么呢?此外,我们如何确定绝对归一化因子,以获得“真实”的潜在平均力量?

任何洞察力都将受到极大的赞赏。提前感谢!

样本代码:

代码语言:javascript
运行
复制
import numpy as np
a   = np.random.randn(3000,3000)
af  = np.fft.fft2(a)/3000.0/3000.0
aP  = np.mean(np.abs(af)**2)

b   = a[1000:2000,1000:2000]
bf  = np.fft.fft2(b)/1000.0/1000.0
bP  = np.mean(np.abs(bf)**2)

print aP,bP

>1.11094908545e-07 1.00226264535e-06
EN

回答 1

Stack Overflow用户

发布于 2014-09-08 18:49:21

首先,需要注意的是,这个问题与1D和2DFFT之间的差异无关,而是与数组中元素数的总功率和平均功率尺度有关。

当您说9的因子来自a中的9x比b多的元素时,您是完全正确的。可能令人困惑的是,您注意到您已经通过np.fft.fft2(a)/3000./3000.np.fft.fft2(b)/1000./1000.进行了标准化--实际上,这些规范化是获得空间和频率域中的总功率(而不是平均功率)所必需的。要得到平均值,您必须再次除以数组大小。

你的问题实际上是关于Parseval定理,它说,在两个领域(空间/时间和频率)的总幂是相等的。它的声明,对DFT来说是。注意,尽管右边有1/N,但这不是平均功率,而是总功率。1/N的原因是DFT的标准化惯例。

在Python中,这意味着对于时间/空间信号sig,Parseval等效可以声明为:

np.sum(np.abs(sig)**2) == np.sum(np.abs(np.fft.fft(sig))**2)/sig.size

下面是一个完整的例子,从一些玩具案例开始(一维和二维数组填充了一个1s),并以您自己的案例结束。注意,我使用了.size属性numpy.ndarray,它返回数组中的元素总数。它相当于你的/1000./1000.等。希望这有帮助!

代码语言:javascript
运行
复制
import numpy as np

print 'simple examples:'

# 1-d, 4 elements:
ones_1d = np.array([1.,1.,1.,1.])
ones_1d_f = np.fft.fft(ones_1d)

# compute total power in space and frequency domains:
space_power_1d = np.sum(np.abs(ones_1d)**2)
freq_power_1d = np.sum(np.abs(ones_1d_f)**2)/ones_1d.size
print 'space_power_1d = %f'%space_power_1d
print 'freq_power_1d = %f'%freq_power_1d

# 2-d, 4 elements:
ones_2d = np.array([[1.,1.],[1.,1.]])
ones_2d_f = np.fft.fft2(ones_2d)

# compute and print total power in space and frequency domains:
space_power_2d = np.sum(np.abs(ones_2d)**2)
freq_power_2d = np.sum(np.abs(ones_2d_f)**2)/ones_2d.size
print 'space_power_2d = %f'%space_power_2d
print 'freq_power_2d = %f'%freq_power_2d

# 2-d, 9 elements:
ones_2d_big = np.array([[1.,1.,1.],[1.,1.,1.],[1.,1.,1.]])
ones_2d_big_f = np.fft.fft2(ones_2d_big)

# compute and print total power in space and frequency domains:
space_power_2d_big = np.sum(np.abs(ones_2d_big)**2)
freq_power_2d_big = np.sum(np.abs(ones_2d_big_f)**2)/ones_2d_big.size
print 'space_power_2d_big = %f'%space_power_2d_big
print 'freq_power_2d_big = %f'%freq_power_2d_big
print


# asker's example array a and fft af:
print 'askers examples:'
a = np.random.randn(3000,3000)
af = np.fft.fft2(a)

# compute the space and frequency total powers:
space_power_a = np.sum(np.abs(a)**2)
freq_power_a = np.sum(np.abs(af)**2)/af.size

# mean power is the total power divided by the array size:
freq_power_a_mean = freq_power_a/af.size

print 'space_power_a = %f'%space_power_a
print 'freq_power_a = %f'%freq_power_a
print 'freq_power_a_mean = %f'%freq_power_a_mean
print
# the central 1000x1000 section of the 3000x3000 original array:
b = a[1000:2000,1000:2000]
bf = np.fft.fft2(b)

# we expect the total power in the space and frequency domains 
# to be about 1/9 of the total power in the space frequency domains 
# for matrix a:
space_power_b = np.sum(np.abs(b)**2)
freq_power_b = np.sum(np.abs(bf)**2)/bf.size
# we expect the mean power to be the same as the mean power from
# matrix a:
freq_power_b_mean = freq_power_b/bf.size

print 'space_power_b = %f'%space_power_b
print 'freq_power_b = %f'%freq_power_b
print 'freq_power_b_mean = %f'%freq_power_b_mean
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19444373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档