Resumen ejecutivo
El presente documento expone la aproximación de la investigación respecto a la aplicación, detección y eliminación de anomalías en imágenes. En este caso, desde una perspectiva práctica y directa, utilizando el lenguaje de programación Python y Jupyter Notebooks.
El tipo de anomalía para la cual implementamos las técnicas de tratamiento es el
ruido blanco, el cual consta de una técnica aleatoria de aplicación de píxeles
blancos sobre las imágenes. Y para su eliminación implementamos la técnica de
aplicación de media.
Introducción
El ruido en una imagen es la alteración arbitraria de sus valores en brillo y color que
distorsiona la percepción visual de la misma. Esto puede ocurrir en distintos niveles,
desde un leve ‘polvo’, ‘rayado’, ‘oscilado’ u otro efecto de daño el cual puede dejar
irreconocible el concepto que la imagen proyectaba originalmente.
Las técnicas de eliminación de anomalías, en este sentido, pretenden corregir el
ruido que se presente en dichas imágenes con apoyo de tecnología digital.
Implementación
La implementación de la solución incorpora dos funciones generales: agregar_ruido
y medianizar_imagen. La función de agregar_ruido aplica ruido blanco
aleatoriamente en la imagen procesada, y la función medianizar_imagen aplica la
media en bloques de 3x3 píxeles para intentar eliminar el efecto del ruido. Los otros
bloques de código consumen estas funciones para generar la salida en imágenes.
Librería | Descripción de uso |
Random | Acceso a funciones aleatorias para aplicación de ruido |
cv2 | Acceso a funciones propias para tratamiento de imágenes |
numpy | Acceso a funciones y tipos de datos para manipular arreglos |
matplotlib | Proyección -ploteo- de resultados |
Tab. 1) Librerías utilizadas en la solución
Código
import random
import cv2
import numpy as np
from matplotlib import pyplot as plt
import os
#Función de ruido blanco
#en esta función aplicamos aleatoriamente pixeles blancos
#sobre toda la superficie de la imagen. Esto lo definimos como "ruido".
def agregar_ruido(img, cant_pixels):
#Obtenemos las dimensiones de la imagen
row , col = img.shape
#Aplicamos el ruido -blanco- a la cantidad de pixels deseada
for i in range(cant_pixels):
# Elegimos una coordenada al azar en Y
y_coord=random.randint(0, row - 1)
# Elegimos una coordenada al azar en X
x_coord=random.randint(0, col - 1)
# Aplicamos el ruido en la posición encontrada
img[y_coord][x_coord] = 255
return img
#Función en la que aplicamos la media a la imagen
#para difuminar defectos o anomalías
def medianizar_imagen(img_conruido):
#Obtenemos la composición de la imagen
#interpretada en un array de renglones y columnas
row, col = img_conruido.shape
#Se recorre la imágen, para cada area de 3x3
#buscamos la media en pixels y se reemplaza el pixel
#central con la media.
img_nueva = np.zeros([row, col])
for i in range(1, row-1):
for j in range(1, col-1):
temp = [img_conruido[i-1, j-1],
img_conruido[i-1, j],
img_conruido[i-1, j + 1],
img_conruido[i, j-1],
img_conruido[i, j],
img_conruido[i, j + 1],
img_conruido[i + 1, j-1],
img_conruido[i + 1, j],
img_conruido[i + 1, j + 1]]
temp = sorted(temp)
img_nueva[i, j]= temp[4]
return img_nueva.astype(np.uint8)
#Sección de manejo de imágenes
#Utilizamos variables auxiliares para almacenar los valores de las imágenes
#desde la inicial original, continuamos por la adición de ruido pasando a escala
#de grises y medianizamos. El filtro salt-and-pepper solo puede aplicarse a
#imagenes en escala de grises, por ello primero transformamos la imagen.
img = cv2.imread('diente.jpg')
imgGray = cv2.imread('diente.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imwrite('noise.jpg', agregar_ruido(imgGray,3000))
imgRuido = cv2.imread('noise.jpg', 0)
imgMedian = medianizar_imagen(imgRuido)
#Imprimimos la comparativa con matplotlib
#En este caso nos apoyamos con cv2.cvtColor especificando que estamos usando
#escala de grises para proyectar de nuevo la imagen
plt.figure(figsize=(18,18))
plt.subplot(231),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(232),plt.imshow(cv2.cvtColor(imgRuido, cv2.IMREAD_GRAYSCALE)),plt.title('Ruido')
plt.xticks([]), plt.yticks([])
plt.subplot(233),plt.imshow(cv2.cvtColor(imgMedian, cv2.IMREAD_GRAYSCALE)),plt.title('Medianizado')
plt.xticks([]), plt.yticks([])
plt.show()
Principales conclusiones
La aplicación de media para la eliminación de este tipo de anomalía en imágenes ha resultado ser suficientemente efectiva, pero debemos tener siempre en cuenta que el resultado final es una imagen totalmente distinta a lo que hubiera sido su original. Por esto diferentes técnicas de eliminación podrían ayudar a asimilar más el efecto de un original que la presente en casos de fotografías más detalladas o con mayores dimensiones, lo cual también implica mayor capacidad de procesamiento para abarcar todo el lienzo de la imagen.
Fig. 1) Proyección de resultados en original, con ruido y aplicada la media
Referencias y bibliografía
Median Filter Implementation In Python. (2018, 13 abril). Code Review Stack Exchange. Recuperado 22 de enero de 2022, de https://codereview.stackexchange.com/questions/191974/median-filter-implementation-in-python
GeeksforGeeks. (2021, 27 octubre). Add a «salt and pepper» noise to an image with Python. Recuperado 22 de enero de 2022, de https://www.geeksforgeeks.org/add-a-salt-and-pepper-noise-to-an-image-with-python/
Technologies, I., & Technologies, M. P. B. I. (2019, 26 junio). Image Processing Series #3 : Noise Removal From Image Using Python OpenCV – Instrovate. Instrovate Technologies. Recuperado 22 de enero de 2022, de https://instrovate.com/2019/06/26/image-processing-series-3-noise-removal-from-image-using-python-opencv/
GeeksforGeeks. (2021b, noviembre 9). Spatial Filters - Averaging filter and Median filter in Image Processing. Recuperado 22 de enero de 2022, de https://www.geeksforgeeks.org/spatial-filters-averaging-filter-and-median-filter-in-image-processing/