1

使用 pyfftw 对 2D ndarray 进行 ifft 时,我发现生成的相位在许多位置上是不连续的。我的代码如下:

import numpy as np
import pyfftw
from scipy.fft import ifftshift,fftshift
import matplotlib.pyplot as plt

N = 256
kx = np.linspace(-np.floor(N/2),np.ceil(N/2)-1,N)
kX,kY = np.meshgrid(kx,kx)
kR = np.sqrt(kX**2 + kY**2)
mask = np.where((kR<=15),1,0)
ifft_obj = pyfftw.builders.ifft2(ifftshift(mask))
wave = fftshift(ifft_obj())

plt.imshow(np.angle(wave),cmap='jet')
plt.colorbar()

相位图如下 在此处输入图像描述 最小相位值是-3.141592653589793和最大值是3.141592653589793并且它们的差大于2pi。使用 scipy.fft 只会得到相同的结果。但是,当我转向 Matlab 时,结果看起来更合理。我的代码是:

N = 256;
kx = linspace(-floor(N/2),ceil(N/2)-1,N);
[kX,kY] = meshgrid(kx,kx);
kR = sqrt(kX.^2 + kY.^2);
mask = single(kR<=15);
wave = fftshift(ifft2(ifftshift(mask)));
imshow(angle(wave));
caxis([min(angle(wave),[],'all') max(angle(wave),[],'all')]);
axis image; colormap jet;colorbar;

相位图像是 在此处输入图像描述

我想知道是什么导致了 python 代码中的相位不连续以及如何纠正它。

4

2 回答 2

3

相位最好显示为单位圆上的角度。一个圆圈没有起点和终点。绕圈转不会产生不连续性。恰好添加 2*pi(绕圈一圈)不会改变相位,因此 +pi 和 -pi 是相同的相位。因此,这两个相位的绝对差不是 2*pi,而是零。如果考虑到微小的舍入误差,它几乎为零。

我的建议是使用“循环”配色方案(不知道更好的术语),其中在一端接近 +pi 而在另一端接近 -pi 以相同颜色为图形着色。

于 2020-06-11T09:30:43.050 回答
1

您的输入是对称的,这会导致纯实数变换(相位为 0 表示正值,π 表示负值)。但由于 FFT 算法的数值不准确,结果具有非常小的虚值。因此,相位稍微偏离 0 和 π。在您的彩色映射图像中,看不到与 0 的小偏差,但与 π 的小偏差会导致接近 -π 的值(正如VPfB 已经讨论过的)。

MATLAB 没有显示此问题,因为 MATLABifft识别输入是(共轭)对称的并输出纯真实图像。它只是忽略了那些小的虚值。

你可以在 Python 中做同样的事情

wave = np.real_if_close(wave, tol=1000)

这里的容差是np.finfo(wave.dtype).eps * tol(2.22 10 -13 for double float)。根据需要进行调整。

于 2020-06-11T14:18:00.390 回答