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

Python 撤消np.fft.fft2以获取原始图像,python,numpy,opencv,fft,Python,Numpy,Opencv,Fft,我刚刚开始了解图像频率域 我有这个功能: 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): retur

我刚刚开始了解图像频率域

我有这个功能:

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
我想实现这个功能:

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
但我不知道怎么做

我的想法是使用
幅度谱
获得原始的
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()

您在这里失去了阶段:
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)

注意,如果你只想直接恢复原始图像,就不需要调用FFTHSHIFT和IFFTSHIFT,但是如果在中间或其他需要零频率居中的操作中进行一些绘图,我就添加了FFTSHIFT和IFFTSHIFT。


调用numpy.abs()或freq_filt_img.real(假设每个像素为正值)来恢复图像的结果应该是相同的,因为ifft2的虚部应该非常小。当然,numpy.abs()的复杂度为O(n),而freq_filt_img.real的复杂度为O(1)

如果没有相位信息,则无法恢复精确的原始图像,因此不能仅使用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)

注意,如果你只想直接恢复原始图像,就不需要调用FFTHSHIFT和IFFTSHIFT,但是如果在中间或其他需要零频率居中的操作中进行一些绘图,我就添加了FFTSHIFT和IFFTSHIFT。



调用numpy.abs()或freq_filt_img.real(假设每个像素为正值)来恢复图像的结果应该是相同的,因为ifft2的虚部应该非常小。当然,numpy.abs()的复杂性是O(n),而freq\u filt\u img.real的复杂性是O(1)

你不能仅用maniuts来实现,相位信息是lost@harold谢谢我该怎么做才能不丢失相位信息?使用
f
就可以了,或者(更复杂的)绝对值和角度。什么是方便的取决于你想在频率空间中应用什么样的处理为什么假设图像是在时域中?我看到你将图像发送到fft调用中,将其转换为频域。。。为什么不考虑图像生活在频域中,所以它的第一个过渡将进入时域。这并不排除创建傅里叶逆变换步骤的需要,但它可能会使思考必要的数据转换变得更容易。。。我写了一个逆fft,用golang将图像发送到音频(频域->时域)。。如果您不想自己制作这个函数,许多fft库都附带了相应的ifft函数,只需返回fshift而不是magnity_频谱。您可以重新应用fftshift和ifft2以重新获取输入图像。您不能仅使用手动模式,相位信息是lost@harold谢谢我该怎么做才能不丢失相位信息?使用
f
就可以了,或者(更复杂的)绝对值和角度。什么是方便的取决于你想在频率空间中应用什么样的处理为什么假设图像是在时域中?我看到你将图像发送到fft调用中,将其转换为频域。。。为什么不考虑图像生活在频域中,所以它的第一个过渡将进入时域。这并不排除创建傅里叶逆变换步骤的需要,但它可能会使思考必要的数据转换变得更容易。。。我写了一个逆fft,用golang将图像发送到音频(频域->时域)。。如果您不想自己制作这个函数,许多fft库都附带了相应的ifft函数,只需返回fshift而不是magnity_频谱。您可以重新应用fftshift和ifft2,以重新获得输入图像。当从numpy import abs作为NPAB计算幅值和相位时,您指的是log(fshift)而不是fshift?
;print(npabs(3+4j))
给了我
5.0
——根据numpy docs,假设是
5
的真实部分
3+4j
。对于复杂输入a+ib,绝对值为\sqrt{a^2+b^2}。如果x是标量,则这是标量。@GBOFI是对的。您可以说
abs
返回数据的真实部分。没有。If返回震级。这是一个重要的区别!在计算幅值和相位时,您是指log(fshift)而不是fshift吗?
来自numpy import abs作为NPAB;print(npabs(3+4j))
给了我
5.0
——根据numpy docs,假设是
5
的真实部分
3+4j
。对于复杂输入a+ib,绝对值为\sqrt{a^2+b^2}。如果x是标量,则这是标量。@GBOFI是对的。您可以说
abs
返回数据的真实部分。没有。If返回震级。这是一个重要的区别!“调用numpy.abs()或freq_filt_img.real来恢复图像的结果应该是相同的[…]”,除非