繁体   English   中英

撤消 np.fft.fft2 以获取原始图像

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM