jueves, 11 de abril de 2013

Erode y Dilate




Erosionar y dilatar (erode y dilate) son dos métodos muy útiles en el tratamiento de imágenes que tienen gran utilidad en visión artificial.  

 

Erosionar (erode) es una operación realizada sobre imágenes, binarias o en escala de grises. No explicaré aquí la definición matemática, que puede verse en la correspondiente entrada de la wikipedia, pero si contaré resumidamente lo que hace. En una imagen binaria, representada como una matriz de unos y ceros (Matriz A), el proceso de erosión por un vector V formado por unos, consistiría en ir colocando el 1 central del vector en cada píxel iluminado (es decir, con valor 1 en la matriz); si el vector entra totalmente en la zona iluminada el píxel se respeta, de otra forma se convierte en 0. Es una especie de goma de borrar que solo borra cuando la goma sobresale un poco de la zona pintada. En una imagen con fondo blanco (valor 1) engrosará los píxeles representados en negro (valor 0). El siguiente ejemplo muestra la acción de esta operación; la imagen de la derecha es la original:


     

OpenCV proporciona un método llamado erode que realiza este trabajo. A continuación lo esencial del código  para generar el simple ejemplo de arriba:

                     cv::erode(image, image2, cv::Mat());
                     while(true)
                    {
                          cv::imshow("Erode", image2);
                          cv::imshow("NoErode", image);
                          if(cv::waitKey(30) > 0) break;
                    }


Donde cv::Mat() es en este caso una matriz vacía (la matriz que "erosiona"). Esta matriz vacía, que OpenCV interpreta como una matriz de 3x3, puede ser de cualquier otro tamaño. 

Este método tiene muchas utilidades en el tratamiento de imágenes, desde el punto de vista de la visión artificial se me ocurren también unas cuantas. Supongamos que tenemos una matriz que representa una serie de contornos, pero que por algún motivo algunos han quedado inconexos, aplicando un erode podemos unir algunos de los contornos más cercanos, tal y como muestra el ejemplo siguiente






  
Si una primera erosión no es suficiente podemos repetirla sucesivas veces sobre la misma imagen para lograr unir todos los contornos. No es necesario llamar a la función varias veces, ya que el propio método erode de OpenCV nos permite elegir el número de iteraciones. En ejemplo que nos ocupa y tras tres iteraciones el resultado el siguiente:




Como puede verse hemos unido todos los pequeños contornos, eso sí, a costa de engrosar una serie de puntos no representativos.  

La operación inversa o reciproca es la "dilatación" o dilation. Encontramos una definición matemática muy interesante en la wikipedia que deberíamos revisar si realmente deseamos conocer el proceso. No obstante no debemos tomar al pie de la letra en concepto de operación inversa (en sentido matemático), ya que no siempre la imagen dilatada o erosionada puede transformarse en lo que era aplicando la operación inversa, máxime si el proceso borra grupos enteros de píxeles. Eso le confiere una interesante aplicación a la combinación erode-dilate o dilate-erode. Por ejemplo, el siguiente código aplicado a la imagen de la izquierda permite eliminar los contornos más pequeños, eliminar los puntos y engrosar lo que podríamos considerar como más representativo:

                    cv::dilate(image, image2, cv::Mat(),cv::Point(-1,-1),2);
                    cv::erode(image2, image2, cv::Mat(),cv::Point(-1,-1),5);







Como se puede intuir las aplicaciones son múltiples; eliminar ruido, aislar elementos o unir zonas próximas, localizar los puntos más intensos, etc... Cada uno de los dos métodos aquí expuestos tienen un número mayor de opciones que aquí no se contemplan, para una referencia más exhaustiva no hay que dejar de visitar la página de la documentación de OpenCV.  




 

No hay comentarios:

Publicar un comentario