Python Pytork';s-FFT不保持线性
我不确定这是否是一个bug,或者我对索引/移位有些误解。当我试图计算傅里叶域中的差分时,计算中出现了一些错误。对于一个简单的情况,考虑一个身份核K,这样对于任何信号X都遵循x -k*x=0。此外,x-kox=0。然而,当我使用pytorch计算傅里叶域中的残差时,我没有得到数值为0的解Python Pytork';s-FFT不保持线性,python,pytorch,fft,Python,Pytorch,Fft,我不确定这是否是一个bug,或者我对索引/移位有些误解。当我试图计算傅里叶域中的差分时,计算中出现了一些错误。对于一个简单的情况,考虑一个身份核K,这样对于任何信号X都遵循x -k*x=0。此外,x-kox=0。然而,当我使用pytorch计算傅里叶域中的残差时,我没有得到数值为0的解 import torch from torch.fft import rfftn, irfftn from PIL import Image from torchvision.transforms import
import torch
from torch.fft import rfftn, irfftn
from PIL import Image
from torchvision.transforms import ToTensor
from torch.nn.functional import pad
from matplotlib import pyplot as plt
# Let X be an input image.
with Image.open("barbara.png") as im:
X = ToTensor()(im)[0,...]
# Let K be a convolutional identity kernel.
K = torch.zeros((3,3))
K[1,1] = 1.0
# Full convolution shape.
cnvShape = (X.shape[0] + K.shape[0] - 1, X.shape[1] + K.shape[1] - 1)
# Apply DFT. Uncentered zero-padding to full shape.
Xhat = rfftn(X, s=cnvShape, dim=(0,1))
Khat = rfftn(K, s=cnvShape, dim=(0,1))
# Calculate convolution via Fourier domain.
XKhat = Xhat * Khat
XK = irfftn(XKhat, s=cnvShape)[1:-1,1:-1]
# Difference in spatial domain. Is numerically close to 0.
R = X - XK
# Difference in Fourier domain. This should be numerically close to 0.
Shat = Xhat - XKhat
S = irfftn(Shat)
plt.subplot(1,2,1)
plt.imshow(R)
plt.colorbar()
plt.subplot(1,2,2)
plt.imshow(S)
plt.colorbar()
plt.show()
# Center zeropad image FFT, produces numerically 0 solution.
That = rfftn(pad(X, (1,1)*2), s=cnvShape) - XKhat
T = irfftn(That)
plt.imshow(T)
plt.colorbar()
plt.show()
这导致
从上一个图中,我可以看到傅里叶域中的运算发生了某种变化,但这不是直观的。我还想弄清楚如何在傅里叶域中实现一致性运算,因为这只是我需要计算的一个小样本。我知道fftshift,但这在这里似乎不合适,因为这种移位似乎不具有负频率和正频率。那么,索引中发生了什么?会发生什么?特别是关于锚定位置的部分(您将
K
的中心值设置为零,但实际上应该将1
放在左上角)。请注意,我在pytorch有复杂数据类型之前就写了这个答案。我想是的,还有一些问题需要澄清。所以锚定是FFT移位,因此你也要ifftshift返回。所以,当卷积两个锚定在0索引上的信号时,这只会周期性地扩展索引0周围的支持度,对吗?因此可以保持线性。fftshift用于表示直流分量居中的信号频谱。这不是你的问题。你的问题是你不符合惯例。更详细地说,DFT仅适用于离散的周期信号。因此,这只是一个惯例,我们将t=0分量解释为。惯例是始终将t=0分量解释为信号的第一个分量。因此,当您设置K=[0,1,0]时,您并没有将K定义为恒等式(即δ(t)),而是将其定义为δ(t-1),因此当您应用此内核时,结果是左移。如果您改为K[0,0]=1.0
和XK=irfftn(XKhat,s=cnvShape)[:-2,:-2]
那么我相信你会得到你期望的结果。这些评论加上链接帮了我的忙。锚定小内核在技术上是不正确的。取而代之的是,我用中心零填充内核,然后锚定中心。所以,这是一个多一点的工作,但我得到了它的工作。