[英]Undo np.fft.fft2 to get the original image
我刚刚开始学习图像频率域。
我有这个功能:
def fourier_transform(img):
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20*np.log(np.abs(fshift))
return magnitude_spectrum
我想实现这个功能:
def inverse_fourier_transform(magnitude_spectrum):
return img
但我不知道怎么做。
我的想法是使用magnitude_spectrum
来获取原始img
。
我该怎么做?
你在这里失去了阶段: np.abs(fshift)
。
np.abs
只需要你的数据的真实部分。 您可以通过以下方式分离振幅和相位:
abs = fshift.real
ph = fshift.imag
从理论上讲,您可以在 abs 上工作,然后通过np.fft.ifft2
将它们与相位和反向 FFT 结合在一起。
编辑:您可以尝试这种方法:
import numpy as np
import matplotlib.pyplot as plt
# single chanel image
img = np.random.random((100, 100))
img = plt.imread(r'path/to/color/img.jpg')[:,:,0]
# should be only width and height
print(img.shape)
# do the 2D fourier transform
fft_img = np.fft.fft2(img)
# shift FFT to the center
fft_img_shift = np.fft.fftshift(fft_img)
# extract real and phases
real = fft_img_shift.real
phases = fft_img_shift.imag
# modify real part, put your modification here
real_mod = real/3
# create an empty complex array with the shape of the input image
fft_img_shift_mod = np.empty(real.shape, dtype=complex)
# insert real and phases to the new file
fft_img_shift_mod.real = real_mod
fft_img_shift_mod.imag = phases
# reverse shift
fft_img_mod = np.fft.ifftshift(fft_img_shift_mod)
# reverse the 2D fourier transform
img_mod = np.fft.ifft2(fft_img_mod)
# using np.abs gives the scalar value of the complex number
# with img_mod.real gives only real part. Not sure which is proper
img_mod = np.abs(img_mod)
# show differences
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.subplot(122)
plt.imshow(img_mod, cmap='gray')
plt.show()
如果没有相位信息,您将无法恢复准确的原始图像,因此您不能只使用 fft2 的幅度。 要使用 fft2 恢复图像,您只需要调用 numpy.fft.ifft2。 请参阅下面的代码:
import numpy as np
from numpy.fft import fft2, ifft2, fftshift, ifftshift
#do the 2D fourier transform
fft_img = fftshift(fft2(img))
# reverse the 2D fourier transform
freq_filt_img = ifft2(ifftshift(fft_img))
freq_filt_img = np.abs(freq_filt_img)
freq_filt_img = freq_filt_img.astype(np.uint8)
请注意,如果您只想直接恢复原始图像,则不需要调用 fftshift 和 ifftshift,但我添加了它们,以防在中间进行一些绘图或其他一些需要将零频率居中的操作。
调用 numpy.abs() 或 freq_filt_img.real(假设每个像素为正值)恢复图像的结果应该是相同的,因为 ifft2 的虚部应该非常小。 当然,numpy.abs() 的复杂度是 O(n) 而 freq_filt_img.real 的复杂度是 O(1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.