Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IFFT of FFT-image results in weird upside-down overlap of original image

In the following code I have a function which returns an image cropped to a centered circle of a certain radius. Then I perform fourier-tranformation of an image, and reverse fourier-transformation again, to restore the image, which works fine.

Then I have calculated, that a centered circle with radius of 43 of the energy spectrum (excluded here) will yield 99% of the energy of the original image. But when I try to apply my function "imgRadius" to the amplitude-spectrum (the fourier-transformed image), and then perform inverse-fourier-tranformation on that image, I get this weird upside-down overlap of the original image.

def imgRadius(img, radius):
    result = np.zeros(img.shape,np.float64)
    centerX = (img.shape[0])/2
    centerY = (img.shape[1])/2
    for m in range(img.shape[0]):
        for n in range(img.shape[1]):
            if math.sqrt((m-centerX)**2+(n-centerY)**2) < radius:
                result[m,n] = img[m,n]
    return result

imgpath = directory+"NorbertWiener.JPG"
img = cv.imread(imgpath, cv.IMREAD_GRAYSCALE)
norm_image = cv.normalize(img, None, alpha=0, beta=1, norm_type=cv.NORM_MINMAX, dtype=cv.CV_32F)
amp = (np.fft.fftshift(np.fft.fft2(norm_image)))
amp_log = np.log(np.abs(amp))
norm_amp = cv.normalize(amp_log, None, alpha=0, beta=1, norm_type=cv.NORM_MINMAX, dtype=cv.CV_32F)
restoredAMP = np.abs(np.fft.ifft2(np.fft.ifftshift(amp)))
radamp = imgRadius(norm_amp,43)
rest99 = np.abs(np.fft.ifft2((imgRadius(amp,43))))

plt.subplot(231),plt.imshow(norm_image, "gray", vmin=0, vmax=1),plt.title('Image')
plt.xticks([]), plt.yticks([])
plt.subplot(232),plt.imshow(norm_amp, "gray", vmin=0, vmax=1),plt.title('Amplitude')
plt.xticks([]), plt.yticks([])
plt.subplot(233),plt.imshow(restoredAMP, "gray", vmin=0, vmax=1),plt.title('Restored from amplitude')
plt.xticks([]), plt.yticks([])
plt.subplot(235),plt.imshow(rest99, "gray", vmin=0, vmax=1),plt.title('Restored from r=43')
plt.xticks([]), plt.yticks([])
plt.subplot(234),plt.imshow(radamp, "gray", vmin=0, vmax=1),plt.title('Amplitude r=43')
plt.xticks([]), plt.yticks([])
plt.show()

See the resulting subplots here

Does it somehow have anything to do with the fact that I use absolute values? I don't see how I should be able to plot the image without getting rid of the imaginary parts of the images, but I can see how maybe some information gets lost in the inverse fft.

I just don't get why I don't get problems when performing IFFT on the original amplitude spectrum.

like image 355
HamDerDolski Avatar asked Sep 07 '25 00:09

HamDerDolski


1 Answers

The problem happens here:

def imgRadius(img, radius):
    result = np.zeros(img.shape,np.float64)

You are creating a real-valued array, and copying over the complex values. Likely either the real component or the magnitude is written to the array. In any case, the complex-valued frequency domain data becomes real-valued. The inverse transform is a symmetric matrix.

To solve the problem, initialize result as a complex-valued array.

After this, make sure to use the real component of the inverse transform, not the magnitude, as Gianluca already suggested in their answer.

like image 110
Cris Luengo Avatar answered Sep 10 '25 11:09

Cris Luengo