Crea il risultato fft2 dall'array rfft2

Nov 06 2020

Sto cercando di ricreare il risultato di un pieno fft2 manipolando il risultato di un rfft2. La documentazione afferma che rfft2 calcola solo i coefficienti positivi poiché i coefficienti negativi hanno una simmetria con quelli positivi quando l'input è reale. Ciò sarebbe estremamente utile per array di grandi dimensioni poiché il calcolo di rfft2 è molto più veloce dell'intero fft2.

Quindi il codice seguente è che sto provando a ricreare fft2 dall'output di rfft2. Ho provato tutti i tipi di manipolazioni dell'array "left" e non riesco a far sì che "lo stesso" sia vero ovunque. Qualche idea?

import numpy as np
import matplotlib.pyplot as plt

from skimage.data import camera

frame = camera()

full_fft = np.fft.fft2(frame)
real_fft = np.fft.rfft2(frame)

left = real_fft[:, :-1].copy()
right = np.flipud(left[:, ::-1])

sim_fft2 = np.hstack((left, right))

same = np.isclose(full_fft, sim_fft2)

plt.figure()
plt.imshow(same)

plt.figure()
plt.imshow(np.log(np.abs(full_fft)))

plt.figure()
plt.imshow(np.log(np.abs(sim_fft2)))

Risposte

1 Will.Evo Nov 09 2020 at 16:11

Ho capito la simmetria eseguendo fft2 su un array 6x6 che quindi richiedeva solo la programmazione di una funzione per convertire l'output di un rfft2 in modo che fosse uguale a un fft2. Di seguito è riportata quella funzione e un'immagine della simmetria.

def _rfft2_to_fft2(im_shape, rfft):
    fcols = im_shape[-1]
    fft_cols = rfft.shape[-1]

    result = numpy.zeros(im_shape, dtype=rfft.dtype)

    result[:, :fft_cols] = rfft

    top = rfft[0, 1:]

    if fcols%2 == 0:
        result[0, fft_cols-1:] = top[::-1].conj()
        mid = rfft[1:, 1:]
        mid = numpy.hstack((mid, mid[::-1, ::-1][:, 1:].conj()))
    else:
        result[0, fft_cols:] = top[::-1].conj()
        mid = rfft[1:, 1:]
        mid = numpy.hstack((mid, mid[::-1, ::-1].conj()))

    result[1:, 1:] = mid

    return result