简体   繁体   English

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

[英]Undo np.fft.fft2 to get the original image

I've just started to learn about images frecuency domain.我刚刚开始学习图像频率域。

I have this function:我有这个功能:

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

And I want to implement this function:我想实现这个功能:

def inverse_fourier_transform(magnitude_spectrum):

    return img

But I don't know how.但我不知道怎么做。

My idea is to use magnitude_spectrum to get the original img .我的想法是使用magnitude_spectrum来获取原始img

How can I do it?我该怎么做?

You are loosing phases here: np.abs(fshift) .你在这里失去了阶段: np.abs(fshift)

np.abs takes only real part of your data. np.abs只需要你的数据的真实部分。 You could separate the amplitudes and phases by:您可以通过以下方式分离振幅和相位:

abs = fshift.real
ph = fshift.imag

In theory, you could work on abs and join them later together with phases and reverse FFT by np.fft.ifft2 .从理论上讲,您可以在 abs 上工作,然后通过np.fft.ifft2将它们与相位和反向 FFT 结合在一起。

EDIT: You could try this approach:编辑:您可以尝试这种方法:

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()

You cannot recover the exact original image without the phase information, so you cannot only use the magnitude of the fft2.如果没有相位信息,您将无法恢复准确的原始图像,因此您不能只使用 fft2 的幅度。 To use the fft2 to recover the image, you just need to call numpy.fft.ifft2.要使用 fft2 恢复图像,您只需要调用 numpy.fft.ifft2。 See the code below:请参阅下面的代码:

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)

Note that calling fftshift and ifftshift is not necessary if you just want to recover the original image directly, but I added them in case there is some plotting to be done in the middle or some other operation that requires the centering of the zero frequency.请注意,如果您只想直接恢复原始图像,则不需要调用 fftshift 和 ifftshift,但我添加了它们,以防在中间进行一些绘图或其他一些需要将零频率居中的操作。

The result of calling numpy.abs() or freq_filt_img.real (assuming positive values for each pixel) to recover the image should be the same because the imaginary part of the ifft2 should be really small.调用 numpy.abs() 或 freq_filt_img.real(假设每个像素为正值)恢复图像的结果应该是相同的,因为 ifft2 的虚部应该非常小。 Of course, the complexity of numpy.abs() is O(n) while freq_filt_img.real is O(1)当然,numpy.abs() 的复杂度是 O(n) 而 freq_filt_img.real 的复杂度是 O(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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