Ir al contenido

Visión por Computadora: Eliminación de Ruido en Imágenes

Introducción

En el mundo de la visión por computadora, mejorar la calidad de las imágenes es fundamental para obtener resultados precisos y fiables. Una de las tareas más comunes es la eliminación de ruido, un tipo de anomalía que puede distorsionar la información visual. En esta entrada, exploraremos cómo eliminar el ruido en imágenes utilizando técnicas de procesamiento de imágenes en Python, apoyándonos en las poderosas librerías OpenCV, numpy y matplotlib.


El ruido en las imágenes es un problema frecuente que afecta la calidad visual y la precisión en la interpretación de datos. Este ruido puede tener diversas fuentes, como condiciones ambientales adversas, defectos en el sensor de la cámara o errores de transmisión. En esta ocasión, nos enfocaremos en el ruido sal y pimienta, que se manifiesta como puntos blancos y negros dispersos en la imagen.

Para abordar este problema, utilizaremos métodos de filtrado que nos permiten suavizar la imagen y reducir el ruido. A través de este proceso, podremos mejorar la calidad de las imágenes y facilitar el análisis posterior.


Importación de Librerías


Para comenzar, es necesario importar las librerías esenciales para el procesamiento de imágenes. Utilizaremos OpenCV para las operaciones de imagen, numpy para las operaciones matemáticas y manipulación de matrices, y matplotlib para la visualización.

Carga de Imágenes


Primero, cargaremos una imagen en escala de grises utilizando OpenCV. 

´

Adición de Ruido


Para ilustrar el proceso, agregaremos ruido sal y pimienta a la imagen original.

El ruido sal y pimienta se agregó a las imágenes para simular condiciones adversas y probar la eficacia de los métodos de eliminación de anomalías. Este tipo de ruido se caracteriza por la aparición de píxeles blancos y negros aleatorios que degradan la calidad de la imagen, imitando imperfecciones comunes en la adquisición de imágenes digitales.


Para agregar el ruido, definimos la función:  

agregar_ruido_salpimienta_manual. 


Esta función recorre manualmente cada píxel de la imagen y decide aleatoriamente si convertirlo en 'sal' (blanco) o 'pimienta' (negro).


  1. Hacemos una copia de la imagen original.
  2. Obtenemos las dimensiones de la imagen (número de filas y columnas).
  3. Recorremos cada píxel de la imagen utilizando dos bucles anidados "for i in range(filas) y for j in range(cols)".
  4. Generamos un número aleatorio rand = np.random.rand().
  5. Decidimos basándonos en el número aleatorio:
    1. Si rand < nivel_sal, el píxel se convierte en 'sal' (blanco, valor 255).
    2. Si rand < nivel_pimienta, el píxel se convierte en 'pimienta' (negro, valor 0).
    3. Si el número aleatorio no cae en las condiciones anteriores, el píxel mantiene su valor original.

Para invocar la función anterior:


  1. Se asignan valores de los argumentos de la función para la probabilidad de sal y pimienta.
  2. Aplicación del Ruido: Llamamos a la función agrega_ruido_salpimienta_manual con la imagen y las probabilidades de 'sal' y 'pimienta'.
  3. Mostrar las Imágenes: Usamos plt.imshow para mostrar la imagen original y la imagen con ruido añadido.

Eliminación de Ruido


Para eliminar el ruido, utilizaremos el filtro de la mediana, que es muy eficaz para eliminar el ruido sal y pimienta, ya que reemplaza el valor de cada píxel por la mediana de los píxeles circundantes, preservando los bordes de la imagen.


Filtro de la Mediana Manual


La función filtro_mediana_manual aplica el filtro de mediana de manera manual, permitiendo un control detallado del proceso. A continuación, explicamos los pasos necesarios para implementar esta función:


  1. Calcular el tamaño del borde: Se determina el tamaño del borde como la mitad del tamaño del kernel (borde = kernel_size // 2). Por ejemplo, si el tamaño del kernel es 5 (kernel_size = 5), entonces borde = 5 // 2 = 2. Esto asegura que el kernel se ajuste completamente a los píxeles de la imagen sin salirse de sus límites.
  2. Inicializar la imagen de salida filtrada: Se crea una imagen de salida con dimensiones reducidas para evitar problemas de borde, utilizando np.zeros para inicializar la matriz con ceros. Esto se hace para evitar problemas de borde cuando se aplica el kernel.
    1. np.zeros crea una matriz llena de ceros con la forma y el tipo de datos especificados.
    2. (filas - 2 * borde, cols - 2 * borde) son las dimensiones de la nueva imagen filtrada, eliminando los píxeles de margen en todos los lados de la imagen.
    3. dtype=np.uint8 especifica que los elementos de la matriz serán enteros sin signo de 8 bits, estándar para representar imágenes en escala de grises.
  3. Recorrer la imagen: Se recorre cada píxel desde el borde hasta filas - borde y desde el borde hasta cols - borde. Para un kernel de tamaño 5x5, esto significa que debemos empezar desde el píxel (2, 2) y detenernos en el píxel (filas - 2, cols - 2) para evitar problemas de borde.
  4. Extraer ventana y calcular mediana: Para cada píxel, se extrae una submatriz de tamaño kernel_size x kernel_size centrada en el píxel actual y se calcula la mediana de los valores en esta ventana utilizando np.median(ventana).
  5. Aplicación del filtro: Se aplica el filtro de media a la imagen con ruido, generando una imagen filtrada.
  6. Mostrar Imágenes: Utiliza matplotlib (plt) para mostrar la imagen original, la imagen con ruido y la imagen filtrada.


Filtro de la Mediana con OpenCV


OpenCV proporciona la función cv2.medianBlur, que aplica un filtro de mediana, especialmente eficaz para eliminar el ruido sal y pimienta preservando los bordes de la imagen.


Comparación de Resultados


Comparemos la imagen original con las imágenes filtradas utilizando ambos métodos (manual y OpenCV).


Medición y Comparación


Para evaluar el desempeño del filtro, utilizaremos el Error Cuadrático Medio (MSE, por sus siglas en inglés), una métrica comúnmente usada para comparar la calidad de las imágenes filtradas respecto a la original.


Comparación de Imágenes

Para determinar qué tan efectivos son los filtros, compararemos las imágenes filtradas obtenidas tanto con el filtro manual como con el filtro de OpenCV respecto a la imagen original. Esto lo haremos mediante el cálculo del MSE, que nos ayudará a medir cuál método proporciona una imagen más cercana a la original.


Pasos del Cálculo del MSE


  1. Diferencia de Píxeles: Para cada píxel en la posición [i,j], se calcula la diferencia entre los valores del píxel en la imagen original I[i,j] y la imagen filtrada K[i,j].
  2. Cuadrado de la Diferencia: La diferencia obtenida en el paso anterior se eleva al cuadrado para evitar valores negativos y penalizar las grandes diferencias.
  3. Sumatoria de Cuadrados: Se suman todos los valores de las diferencias al cuadrado de todos los píxeles de la imagen.
  4. Promedio de la Suma: La suma obtenida se divide por el número total de píxeles, obteniendo así el promedio de los errores al cuadrado.
  5. Implementación en Python: Usando numpy, estos pasos se pueden realizar de manera eficiente mediante operaciones en matrices (arrays).

Interpretación del MSE

  1. MSE Bajo: Indica que la imagen filtrada es muy similar a la original, lo cual es deseable.
  2. MSE Alto: Señala que hay una gran diferencia entre la imagen filtrada y la original, indicando que el filtro no ha sido muy efectivo.
  3. Comparación Relativa: Al comparar los valores de MSE de diferentes métodos, el método con el MSE más bajo es considerado el mejor.


Al aplicar estos principios, podemos evaluar de manera objetiva cuál filtro de mediana es más efectivo para eliminar el ruido sal y pimienta, mejorando así la calidad de nuestras imágenes.


Descarga el Jupyter Notebook de este ejemplo en GitHub


Conclusiones


Después de aplicar y comparar ambos métodos de eliminación de ruido, podemos observar los valores del Error Cuadrático Medio (MSE) obtenidos:


• MSE del filtro manual: 54.388496123020786

• MSE del filtro OpenCV: 54.67334673097535


Ambos métodos son eficaces para reducir el ruido sal y pimienta en las imágenes. Sin embargo, el filtro manual tiene un MSE ligeramente menor, lo que indica una mejor preservación de la imagen original en comparación con el filtro de OpenCV. Esta pequeña diferencia puede ser crucial dependiendo de la aplicación específica y el nivel de precisión requerido.


En esta entrada, hemos explorado cómo eliminar el ruido sal y pimienta en imágenes utilizando técnicas de procesamiento de imágenes en Python, específicamente con las librerías OpenCV, numpy y matplotlib. A través de ejemplos prácticos y comparaciones detalladas, hemos demostrado cómo aplicar filtros de mediana y medir su efectividad utilizando el Error Cuadrático Medio (MSE).


Esperamos que este artículo te haya sido útil y te motive a seguir explorando el fascinante mundo de la visión por computadora y el procesamiento de imágenes. Pero esto es solo la punta del iceberg. ¿Qué otros secretos esconden las técnicas avanzadas de procesamiento de imágenes? ¿Podrían estas técnicas revelar detalles ocultos en imágenes que nunca imaginaste? 


No te pierdas nuestras próximas entradas, donde desvelaremos más misterios y profundizaremos en técnicas aún más sofisticadas.


Si tienes alguna pregunta o deseas profundizar en algún tema, no dudes en dejar tus comentarios. ¡Hasta la próxima!




Compartir
Iniciar sesión dejar un comentario