martes, 30 de abril de 2013

Problema de dobles contornos

Hay un hecho que había pasado desapercibido hasta el momento, y es la detección de contornos dobles, es decir, para una misma moneda se pintan dos elipses muy parecidas entre ellas. Esto se debe a que a veces se detecta la sombra de la moneda como un contorno y el borde de la moneda en sí como otro. 

Figura 1: Problema de elipses dobles

Para solventar dicho problema, se ha diseñado un algoritmo recursivo que calcula la distancia euclídea entre los centros de todas las monedas presentes en la imagen y, si esta distancia es menor que su radio, la elipse con mayor eje menor se elimina. De esta manera, se elimina el problema de las sombras en algunos casos además del ya comentado.

Figura 2: Problema solucionado

Justificación de la elección final

A continuación se presentan un conjunto de gráficos comparativos entre los distintos métodos probados anteriormente. Para la recogida de los datos utilizados en los gráficos se han utilizado un número total de 10 monedas variadas en tamaño y color, repitiendo cada prueba 50 veces. Por lo que los resultados representados se corresponden a la media de todas las medidas.

Figura 1: Limitaciones.

El porcentaje de las limitaciones que suponen la utilización de un método u otro se han calculado en base a las siguientes condiciones: Si el método necesita de un fondo con un determinado color, se le añade un 50%; Si para el correcto funcionamiento las monedas han de estar en una determinada posición, se añade  otro 50%.

Las limitaciones que presenta la transformada de Hough se deben a que las monedas necesitan estar distribuidas de tal forma que no formen una circunferencia entre ellas (se detectaría una falsa elipse).

Figura 2: Tiempo de ejecución.

El tiempo de ejecución se ha medido en base a lo siguiente: el inicio del contador coincide con el momento en que se recibe un frame de la cámara del dispositivo. Este se detiene cuando la aplicación dibuja en pantalla las elipses correspondientes a las monedas detectadas.

Figura 3: Precisión.

La precisión es el porcentaje de monedas acertadas durante la prueba, se puede observar que ningún método es perfecto, ya que siempre hay algún frame en el que no todas son detectadas.

Conclusiones:

El primer factor eliminatorio es la precisión, ya que para nuestro proyecto no es aceptable un porcentaje de detección inferior al 70%, este hecho descarta cuatro de los métodos analizados.

La decisión final entre los métodos restantes se tomó en base a las limitaciones que presentaban, ya que el método Canny no presentaba ninguna de las anteriormente comentadas además de no suponer una diferencia demasiado grande en cuanto a precisión respecto al Otsu. Además, el tiempo de ejecución tampoco es un factor decisivo (como se ha comentado en entradas anteriores).




domingo, 28 de abril de 2013

Detección por contornos: Solución final


Como se comentó en entradas anteriores, nuestro objetivo era detectar las siluetas de las monedas combinando el reconocimiento por color y el procesado Canny. Sin embargo, y tras varias pruebas, hemos realizado un algoritmo de detección basado únicamente en el procesado Canny y otros procedimientos que se detallarán más adelante. De este modo, se evitan las complicaciones asociadas al color (brillos, sombras y zonas de colores similares que provocan detecciones falsas).

Tras el pre-procesado de la imagen, se le aplica el algoritmo Canny para obtener una imagen binaria con los contornos definidos, que se almacenan en una lista de puntos. La imagen en este momento tiene el siguiente aspecto:

Figura 1: Contornos detectados.

Como se puede observar en la imagen, aparecen muchos contornos que no tienen que ver con las monedas en sí, por lo que se hace imprescindible aplicar una serie de condiciones a todos los contornos de la imagen para que puedan pasar a formar parte de la lista de contornos definitivos. Dichas condiciones se detallan a continuación:

- Si el contorno está formado por un número reducido de puntos, se elimina de la lista. Con esta condición se quitaran de la imagen todos los contornos pequeños.

- Se dibuja una elipse que contenga a los puntos, si el eje mayor o el menor son mayores que un número grande de puntos, se elimina el contorno asociado a la elipse. Esta condición permite eliminar elipses que se salgan del plano de la cámara, ya que no serán monedas sino detecciones falsas debido a los contornos.

- Si la relación axial (eje mayor/eje menor) de la elipse es menor o mayor que unos determinados umbrales, se elimina. Esto se debe a que normalmente las monedas tendrán una relación axial cercana a la unidad que se correspondería con una circunferencia, y por mucho que se incline la cámara dicha relación no superará nunca los umbrales mencionados.

- Finalmente, se dibuja el contorno (en blanco) sobre una imagen con fondo azul y la elipse asociada al mismo (en blanco) sobre una imagen con fondo negro. Se comparan las dos imágenes con el operador lógico AND, que devolverá una matriz con los puntos que coinciden entre la elipse y su contorno. Si el número de puntos coincidentes es menor que un umbral, es porque en realidad no se trataba de una moneda, sino una falsa detección.

La imagen resultante es la que se muestra a continuación: 

Figura 2: Imagen resultante RGB


Notas:

• Los números y umbrales comentados anteriormente se han calculado a partir de numerosas pruebas experimentales. 

• El algoritmo Canny, requiere dos umbrales (superior e inferior), que se fueron modificando mediante dos "seekbar" introducidas en la aplicación con este propósito y a través de las cuales se pudo concretar cuáles eran sus valores óptimos. En las siguientes imágenes se muestran tres ejemplos con distintos umbrales:

Figura 3: Imagen con demasiados contornos

Figura 4: Imagen con los umbrales seleccionados

Figura 5: El contorno de una moneda se pierde

Hay que tener en cuenta que las condiciones anteriores se aplican sobre cada contorno de la imagen, por lo que cuantos más contornos aparezcan en ella, mayor será el tiempo necesario para procesar la imagen. Por lo tanto, se tuvo que hacer también un balance entre tiempo de procesado y precisión del detector para identificar el valor de los umbrales.

Para ilustrar este hecho, se han representado en el siguiente gráfico el número de contornos obtenidos de una imagen con tres monedas sobre fondo blanco frente al tiempo de ejecución (se ha desarrollado así para mantener lo más constantes posibles el resto de las variables que influyen en la detección de los contornos y, por lo tanto, en el tiempo de ejecución).

Figura 6: Comparativa de tiempos

Se puede ver que el tiempo de ejecución aumenta exponencialmente con el número de contornos detectados en la imagen, por lo que se hace necesario elegir unos umbrales que generen el mínimo número de contornos posible sin perder los contornos necesarios para identificar a las monedas.

Detección por contornos: Pruebas intermedias


Alguna de las principales tareas que estamos llevando a cabo para nuestro proyecto están siendo la investigación y numerosas pruebas en el campo de la visión artificial, por lo que en esta entrada nos dedicaremos a enumerar los distintos métodos empleados para intentar realizar una detección correcta de las siluetas de las monedas antes de llegar a la solución final:


1) Detección sobre una imagen en blanco y negro:

Este método trata de transformar una imagen en escala de grises a blanco y negro, la idea era mantener con color negro únicamente las monedas y el resto de la imagen en blanco para así poder calcular los contornos con mayor facilidad.

Para su implementación es necesario establecer un umbral, se analizará la imagen pixel por pixel y en función de su color (si supera o no el umbral definido) se sobrescribirá cada pixel con un valor binario (blanco o negro). En este caso, el fondo sobre el que se encuentren las monedas es de vital importancia para su correcta detección. Se decidió colocarlas sobre un fondo blanco y establecer un umbral bastante alto, de esta manera el fondo se quedaría como está (blanco) y la moneda pasaría a ser mayormente negra (descartando los brillos que, obviamente aparecerían blancos).

Una vez implementado, se hicieron pruebas y aparecieron varios problemas: los contornos que se detectaban incluían las sombras que pudieran tener las monedas, por lo que la medida de los ejes para la identificación por tamaños sería una medida falsa. Además al cambiar a otro ambiente con distinto nivel de luz, el umbral dejaba de ser válido y era necesario ajustarlo manualmente. La idea para evitar este último problema era utilizar de alguna manera un umbral dinámico, el método de Otsu. 


2) Detección mediante el método de Otsu:

Dicho método convierte una imagen en grises a blanco y negro calculando el umbral óptimo en cada momento a partir del histograma de la misma. De esta manera, se obtiene un umbral dinámico válido para cualquier situación de luminosidad. Sin embargo, seguía apareciendo el problema de la detección de sombras con otra complicación añadida, como el método calcula el histograma de la imagen, no puede haber en toda la imagen algún objeto oscuro, ya que esto provocaría un descenso del umbral y por lo tanto los pixeles correspondientes a las monedas se tomarían como blancos y la detección sería errónea.

Para evitar la complicación de las sombras, se optó por cambiar el fondo de la imagen a negro, de manera que las monedas quedarían como superficies blancas y las sombras pasarían a formar parte del fondo. Finalmente, se invertiría el valor de cada pixel de la imagen para volver a la situación anterior (monedas negras y fondo blanco).

Figura 1: Imagen binaria mediante el método Otsu

  Figura 2: Imagen RGB resultante



Esta última modificación hizo que la detección fuera lo suficientemente buena para el clasificador por tamaños, pero estaba limitada a tener un fondo oscuro, por lo que se probaron otros métodos para poder hacer la detección independiente del fondo.


3) La transformada de Hough:

Este método se tuvo que implementar enteramente en C++ incluyendo el código en la carpeta jni del proyecto debido a que las librerías OpenCv para Java no incluían los métodos necesarios para su desarrollo.  

Este método se propuso inicialmente para detectar líneas rectas, pero con el paso del tiempo se ha utilizado para la detección de todo tipo de figuras geométricas siempre que sus ecuaciones se puedan describir con unos cuantos parámetros. En nuestro caso se empezó con la detección de círculos por su mayor simplicidad, pudiendo después extrapolarlo a elipses si los resultados obtenidos eran buenos. Los parámetros a tener en cuenta en este caso son tres: la posición del centro de la circunferencia (valores x e y) y el tamaño del radio, que son los parámetros que se utilizarán para su representación y para hacer la clasificación. 
Con este método evitaríamos además la necesidad de estar obligados a disponer de un fondo de un determinado tono.

Figura 3: Transformada de Hough


Figura 4: Problema de no-detección.


Una vez implementado, se hizo evidente el primer problema,  el método requiere un cálculo computacional demasiado grande como para poder hacerlo a tiempo real en un dispositivo móvil. Aun así esto no supondría un problema, ya que se podrían hacer dos hebras en la aplicación: una en la que solo se mostraran las imágenes captadas y otra que sería la encargada de coger unos cuantos frames del flujo continuo de vídeo y hacer los cálculos sobre ellos, siendo este comportamiento totalmente transparente al usuario.

Tras varias pruebas e intentos de mejora descartamos la implementación del método para elipses, ya que aunque las detecciones que hacía eran muy precisas, un gran número de las monedas presentes en la imagen no eran detectadas y en ocasiones aparecían falsas monedas.

Nota: En todos los métodos anteriores es necesario incluir un pre-procesado de la imagen como por ejemplo un filtro gaussiano para eliminar ruido o una normalización de la escala de grises (de 0 a 255).