es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Transformada discreta de Fourier: La inversa de una señal periódica en 2D resulta en una frecuencia duplicada.

Cuando se convierte una señal periódica 2D del espacio de imagen al espacio de Fourier y viceversa, la señal reconstruida tiene el doble de la frecuencia de la señal original (ver imagen abajo). Intenté usar la Transformada de Fourier Discreta de NumPy y OpenCV, ambas con el mismo resultado. El problema no ocurre al usar una TFD y TDF unidimensional.

¿Tiene alguna idea de cuál podría ser la fuente de este problema y cómo solucionarlo?

Horizontal cosine wave of frequency 1 (left). Reconstructed image after discrete Fourier transform and inverse discrete Fourier transform with frequency 2

Aquí hay un código de muestra en Python que demuestra el problema:

import matplotlib.pyplot as plt
import numpy as np

# ancho y alto de la imagen
w = 320
h = 320

# frecuencia de la onda coseno con respecto al ancho de la imagen
frecuencia = 1

# función para crear una onda coseno 2D horizontal
def crear_coseno_horizontal(frecuencia, w, h):
    img = np.zeros((h,w),np.float32)
    periodo_base = w/(2*np.pi)
    print(frecuencia)
    for x in range(0, w):
        img[0:, x] = np.cos(x*frecuencia/periodo_base)      
    return img

img = crear_coseno_horizontal(frecuencia, w, h)

# transformar del espacio de imagen al espacio de Fourier
dft = np.fft.fft2(img)
# transformar de nuevo del espacio de Fourier al espacio de imagen
im_back = np.fft.ifft2(dft)

# mostrar la imagen original y la imagen reconstruida lado a lado
ax1 = plt.subplot(1,2,1)
ax1.imshow(img, cmap='gray')
ax1.set_title("señal original")
ax2 = plt.subplot(1,2,2)
ax2.imshow(np.abs(im_back), cmap='gray')
ax2.set_title("señal después de la TFD y TDF")

Muchas gracias de antemano.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    La fuente del problema es la forma en que se define la DFT en 2D en numpy. En numpy, la DFT en 2D se define como la suma de exponenciales complejas con frecuencias que son múltiplos de la frecuencia fundamental. Esto significa que si la frecuencia fundamental es f, las frecuencias en el espacio de Fourier serán 0, f, 2f, 3f, …, (N-1)f, donde N es el número de píxeles en la imagen.

    Cuando tomamos la DFT en 2D de una señal, básicamente estamos descomponiendo esa señal en sus sinusoides constituyentes en estas frecuencias discretas en el espacio de Fourier. La DFT inversa toma estos sinusoides y reconstruye la señal original.

    En el ejemplo dado, la señal original es una onda coseno en 2D con una frecuencia f. Sin embargo, cuando tomamos la DFT en 2D de esta señal, se descompone en sinusoides en las frecuencias 0, f, 2f, 3f, …, (N-1)f. La DFT inversa toma estos sinusoides y reconstruye una señal que tiene el doble de la frecuencia de la señal original, es decir, una onda coseno de frecuencia 2f.

    Para solucionar este problema, simplemente podemos normalizar la salida de la DFT inversa dividiéndola por el número de píxeles en la imagen. Esto asegurará que la señal reconstruida tenga la misma amplitud que la señal original. Aquí está el código modificado:

    import matplotlib.pyplot as plt
    import numpy as np
    
    # ancho y alto de la imagen
    w = 320
    h = 320
    
    # frecuencia de la onda coseno en relación con el ancho de la imagen
    frequency = 1
    
    # función para crear una onda coseno horizontal en 2D
    def create_cos_horizontal(frequency, w, h):
        img = np.zeros((h,w),np.float32)
        base_period = w/(2*np.pi)
        print(frequency)
        for x in range(0, w):
            img[0:, x] = np.cos(x*frequency/base_period)      
        return img
    
    img = create_cos_horizontal(frequency, w, h)
    
    # transformar del espacio de la imagen al espacio de Fourier
    dft = np.fft.fft2(img)
    # transformar nuevamente del espacio de Fourier al espacio de la imagen y normalizar
    im_back = np.fft.ifft2(dft) * (w*h)
    
    # mostrar la imagen original y la imagen reconstruida lado a lado
    ax1 = plt.subplot(1,2,1)
    ax1.imshow(img, cmap='gray')
    ax1.set_title("señal original")
    ax2 = plt.subplot(1,2,2)
    ax2.imshow(np.abs(im_back), cmap='gray')
    ax2.set_title("señal después de la DFT y la DFT inversa") 
    

    Ten en cuenta la multiplicación por (w*h) en la línea im_back = np.fft.ifft2(dft) * (w*h) que realiza la normalización.

Comments are closed.