如何规范化numpy(实)fourier变换的谱,使parcevals定理适用?

2024-06-16 13:58:49 发布

您现在位置:Python中文网/ 问答频道 /正文

目前,我正在考虑拍摄一张照片及其光谱。帕切瓦尔定理说,两者的能量应该相等。然而,当我尝试在一些图像上测试这一点时,对于numpy real FFT函数来说似乎不是这样。在

这是我测试时使用的代码:

import numpy as np
from PIL import Image

im = np.array(Image.open('/images/building.jpeg'))
spectral_im = np.fft.rfft2(im, axes = (0,1), norm = 'ortho')

def getNorm(im):
    return np.sum(np.abs(im))

print('Norm of the image: %d' % getNorm(im))
print('Norm of the spectrum of the image: %f' % getNorm(spectral_im))
print('Difference between norms: %f' % (getNorm(im) - getNorm(spectral_im)))

我期望每个图像的规范之间的差异(大约)为0,但是对于我尝试过的每个图像,它的差别是一个数量级。谁能看出我做错了什么吗?在

在答案的帮助下,下面是正确的代码(请注意float64的额外转换,否则它们仍然不相等):

^{pr2}$

Tags: ofthe代码图像imageimportnumpynorm
2条回答

帕切瓦尔定理指出,信号的平方上的积分和傅里叶变换是相同的。因此getNorm函数应该定义为

def getNorm(im):
    return np.sum(np.abs(im)**2)

然后是FFT规范化问题。您需要按图像区域(尺寸乘积)规范化FFT:

^{pr2}$

最后,不要使用rfft来验证Parceval定理。rfft的问题是它知道光谱是对称的,所以它跳过了负的一半。然而,在积分(和)中缺少这一半。这听起来像是应该关闭一个因子2,但事实并非如此,因为DC(mean)组件被rfft完全保留(更多细节可以在here)中找到。最好使用普通的FFT(fft2)并省去一些麻烦。在

与Parceval定理中使用的形式相比,标准正向FFT中有一个额外的因子sqrt(N)。考虑到这一点,事情就会如期进行:

x = np.random.rand(200, 100)
f = np.fft.fft2(x)
np.allclose(np.sum(x ** 2),
            np.sum(abs(f) ** 2 / x.size))
# True

相关问题 更多 >