Consideramos que vamos a procesar una matriz img
$5 \times 5$ con un operador f
$3 \times 3$ con la muestra central en el origen:
$\mathbf{f} = \dfrac{1}{9}\; \begin{bmatrix} -1 & -1 & -1 \\ -1 & \underline{8} & -1 \\ -1 & -1 & -1 \end{bmatrix}.$
Asi luce el operador:
Para calcular la convolución circular 2D entre el operador y la imagen procedemos de la siguiente manera. Hacemos zero-padding para obtener el operador $\mathbf{f}$ embebido en una matriz de dimensiones iguales a la imagen a procesar ($\mathbf{f}_{pad}$) y luego ordenamos el vector para que tenga la fase deseada ($\mathbf{f}_{c}$):
Ahora si, podemos hacer las TDF 2D del operador con la fase correcta y la matriz a filtrar, operar en el dominio transformado y finalmente antitransformar para obtener el resultado:
Verificamos el resultado de la convolución circular por medio de scipy.signal.convolve2d
utilizando boundary="wrap"
:
from scipy.signal import convolve2d
convc = convolve2d(image, kernel, mode="same", boundary="wrap")
...
True
Para calcular la convolución lineal 2D entre el operador $\mathbf{f}$ y la imagen $\mathbf{y}$ procedemos de la siguiente manera. Hacemos zero-padding para obtener el operador y la imagen a procesar embebidos en una matriz de dimensiones iguales a la dimensión de la convolución lineal 2D. Operamos en frecuencia, volvemos al dominio original y finalmente removemos efectos de borde:
Verificamos el resultado de la convolución lineal sin efectos de borde por medio de scipy.signal.convolve2d
:
from scipy.signal import convolve2d
conv = convolve2d(image, kernel, mode="same", boundary="fill", fillvalue=0)
...
True
Procesamos una imagen para intentar reducir el patrón de ruido coherente. Para ello operamos sobre la imagen dada con el filtro $\mathbf{f}$ de promedio simple $3\times 3$:
$\mathbf{f} = \dfrac{1}{9}\; \begin{bmatrix} 1 & 1 & 1 \\ 1 & \underline{1} & 1 \\ 1 & 1 & 1 \end{bmatrix}.$
Otro filtro para realizar una tarea seimilar es el pasa bajas conocido como desenfoque Gausiano (Gaussian blur), el cual es ampliamente utilizado en el procesamiento de imágenes:
$ g_{ij} = \dfrac{1}{2\pi\sigma^2} \exp\left({-\dfrac{i^2+j^2}{2\sigma^2}}\right),$ para $i,j = -M/2,...,M/2$ y $\sigma \in \mathbb{R}$ un parámetro a elegir según el diseño de interés.
A modo informativo, el filtro de Hanning,
$\mathbf{f} = \dfrac{1}{6}\; \begin{bmatrix} 0 & 1 & 0 \\ 1 & \underline{2} & 1 \\ 0 & 1 & 0 \end{bmatrix},$
suele utilizarse para remover artefactos de procesamiento en métodos potenciales, e.g., luego de aplicar la reducción al polo en anomalías magnéticas.
Los filtros pueden aplicarse en varias pasadas (passes) sobre el dato hasta obtener resultados aceptables.
Lectura de la imagen:
img = plt.imread("./moonlanding.png").astype(float)
img = img - img.mean()
...
(474, 630)
Ordenamos el operador considerando el tamaño de la imagen a procesar y el dominio periódico impuesto por la TDF 2D:
Realizamos la convolución 2D circular por medio de la TDF y visualizamos:
Vemos los espectros de amplitud (con zero padding) de la imagen original, la imagen procesada y la imagen residual:
Verificamos el resultado de la convolución 2D circular por medio de scipy.signal.convolve2d
:
True
Calculamos la convolución lineal 2D y removemos los efectos de borde:
Verificamos el resultado de la convolución 2D lineal por medio de scipy.signal.convolve2d
:
True
Eso es todo por hoy.