Mostrando entradas con la etiqueta Visión Computacional. Mostrar todas las entradas
Mostrando entradas con la etiqueta Visión Computacional. Mostrar todas las entradas

24 de mayo de 2013

Procesamiento de Imágenes con PyWavelets

Laboratorio de Visión Computacional
Puntos Extras

Objetivo: Implementar alguna clase de procesamiento de imágenes en Python mediante la Transformada Wavelet usando la herramienta PyWavelets.

Transformada Wavelet


Esta Transformada es eficiente para el análisis local de señales no estacionarias y de rápida transitoriedad y, al igual que la Transformada de Fourier con Ventana, mapea la señal en una representación de tiempo-escala. El aspecto temporal de las señales es preservado.

La diferencia está en que la Transformada Wavelet provee análisis de multiresolución con ventanas dilatadas. El análisis de las frecuencias de mayor rango se realiza usando ventanas angostas y el análisis de las frecuencias de menor rango se hace utilizando ventanas anchas.

Las Wavelets, funciones bases de la Transformada Wavelet, son generadas a partir de una función Wavelet básica, mediante traslaciones y dilataciones. Estas funciones permiten reconstruir la señal original a través de la Transformada Wavelet inversa.

Apliaciones


Dentro de los usos de esta poderosa herramienta podemos nombrar, además del análisis local de señales no estacionarias, el análisis de señales electrocardiográficas, sísmicas, de sonido, de radar, así como también es utilizada para la compresión y procesamiento de imágenes y reconocimiento de patrones.

Instalación de PyWavelets en Ubuntu


Lo primero que tenemos que hacer para poder trabajar con esta herramienta es instalar el paquete necesario para poder importarlo a nuestro script de python.

Se requiere tener instalado Python 2.6 o 2.7 y numpy para poder hacer uso de esta herramienta. Los pasos de instalación son los siguientes.
  1. Descargar desde el repositorio de GitHub el paquete .zip con los archivos fuente listos para instalar, desde el siguiente enlace: https://github.com/nigma/pywt
  2. Abrir un terminal e ir hasta la ruta donde se encuentra la carpeta comprimida.
  3. Descomprimir la carpeta con el nombre pywt-master.zip.
  4. ~$ unzip pywt-master.zip
    
  5. Entrar en el directorio creado.
  6. ~$ cd pywt-master/
    
  7. Ejecutar el archivo setup.py.
  8. ~$ sudo python setup.py install
    
  9. Escribir la contraseña en caso de ser necesario y esperar a la instalación.

Una vez logrado lo anterior podemos empezar a trabajar usando PyWavelets en python. Enseguida veamos un ejemplo de uso de esta herramienta para el procesamiento de imágenes.

Uso de PyWavelets para procesamiento de imágenes


Después de probar con los ejemplos que vienen incluidos en la carpeta comprimida, me causo curiosidad uno de los efectos que se pueden hacer con el uso de Wavelets, ya que este efecto lo había visto antes en una aplicación de iOS para edición de fotos, en donde podías poner una foto tuya como si estuviese pintada sobre un muro, y precisamente en base a esto realice mi programa.

Ejemplo


El script de python recibe desde línea de comandos tres parámetros necesarios y uno opcional. Estos parámetros son la imagen base, la imagen de textura, y el nombre de la imagen de salida, así como de forma opcional escribir como parámetro "sepia" para provocar este efecto en la imagen base de entrada.

Como ejemplo puse la siguiente imagen base de entrada.


La siguiente imagen fue la que use como textura.


Y el resultado de la unión de las dos imágenes es la siguiente.


Un ejemplo más utilizando una foto mía y la siguiente imagen de un muro de ladrillos como textura.


El resultado de la imagen de salida es la siguiente.


Tiempos de procesamiento

Probando con las mismas dos imágenes, se ejecuto el script 20 veces para evaluar el tiempo promedio que tarda el procesamiento de la imagen. Este tiempo no esta contando el tiempo que se tarda en abrir las imágenes ni el guardado de la imagen de salida, sólo es el tiempo que las funciones de PyWavelets necesitan.

Captura de una muestra.


El promedio de tiempo de ejecución para el último ejemplo fue de: 0.311 segundos.

Código



Detección de bordes


Por último les muestro otra de las aplicaciones que tiene PyWavelets. Es la forma en que se pueden obtener los bordes de una imagen. Anteriormente usábamos máscaras de convolución para poder obtener los bordes en una imagen, pero esta es otra forma fácil de hacerlo.

El código es el siguiente.


Y con esto podemos tener resultados como el siguiente.


Faltaría únicamente aplicar binarización para poder resaltar en blanco todos los bordes y dejar en negro todo lo demás.

Referencias:
Filip Wasilewski, "PyWavelets - Discrete Wavelet Transform in Python", 31 de Agosto de 2012. Recuperado el 24 de Mayo de 2013, de http://www.pybytes.com/pywavelets/

UNICEN, "Introducción a la Transformada Wavelet", 2006. Recuperado el 24 de Mayo de 2013, de http://www.exa.unicen.edu.ar/escuelapav/cursos/wavelets/apunte.pdf

13 de mayo de 2013

Detección de Libros

Visión Computacional
Proyecto

Esta es la entrada con el contenido fundamental para la entrega final del proyecto de Visión Computacional, que consistió en la presentación en grupo de nuestro proyecto, la entrega de un reporte y el código generado en un repositorio en línea con su respectiva explicación de uso.

Presentación



Reporte


En seguida se encuentra el documento incrustado aquí mismo, pero debido a que el contenido puede no llegar a ser claro de esta forma, dejo el enlace al documento en su versión pública.

Enlace al reporte:
https://docs.google.com/document/d/12nBI7A9WBVIUooWdVQ7FVE3OOCuliB1Ql_imLV_PiYo/pub


Código en repositorio


Todo el código y un par de imágenes de prueba se encuentran en el repositorio, y son descargables desde el siguiente enlace:


O desde una terminal con la siguiente instrucción:
~$ git clone https://github.com/ramonesteban/proyecto-vision.git

En los archivos del repositorio se encuentran incluidas las instrucciones para la instalación de los paquetes necesarios para ejecutar el programa y la explicación de como ejecutarlo.

9 de mayo de 2013

Actividad 9: Detección de Esquinas

Laboratorio de Visión Computacional
Actividad 9

Para la entrega de esta semana se nos pidió detectar esquinas en polígonos y hacer un "wire-frame" del mismo sobre la imagen. Utilizamos la técnica llamada Filtro Mediano, el cual es muy fácil de implementar, y este detecta esquinas de polígonos sin importar si son regulares o irregulares. El único problema se presenta cuando las esquinas de los polígonos son la unión de dos aristas con un ángulo interno muy grande.

Los pasos que se siguieron para esta tarea fueron los siguientes:
  • Aplicar filtro de escala de grises a la imagen.
  • Aplicar el filtro mediano para encontrar las esquinas.
  • Aplicar el filtro de binarización para resaltar estas esquinas.
  • Identificar las coordenadas de los puntos donde se encontraron las esquinas.
  • Detectar bordes en la imagen original.
  • Hacer un pequeño corte donde comienza una de las esquinas.
  • Usar BFS para seguir el camino del borde de la figura y marcar que puntos se unen con cuáles.
  • De lo anterior se obtienen los puntos pertenecientes a las esquinas de cada figura.
  • Y por último se dibujan círculos sobre estos puntos y líneas que los unen.

Pruebas


Imagen original e imagen con detección de bordes.


Detección de esquinas.


Esquinas y líneas.


Código


Enseguida los fragmentos de código relevantes. Si se quiere ver el código completo, pueden encontrarlo en el siguiente repositorio.



Y por último otro ejemplo más.




Referencias:
Elisa Schaeffer, "Detección de polígonos y esquinas", 2013 [En línea]. Disponible en: http://elisa.dyndns-web.com/~elisa/teaching/comp/vision/poligonos.pdf

1 de mayo de 2013

Actividad 8: Detección de Polígonos

Laboratorio de Visión Computacional
Actividad 8

Para esta semana de laboratorio la actividad fue detectar polígonos. Para la elaboración de esta entrega seguí la serie de pasos que se explica en el PDF visto en clase del cual se hace referencia al final de esta publicación.

Los resultados de una primer prueba con un solo polígono, en este caso un cuadrado.

Imagen original.


Imágenes después de usar máscaras.


Las intersección de las líneas.


Y el resultado.




Esta es la imagen original generada, y volví a colocar cuadrados ya que con estos no tuve problemas en la detección.


Ahora los cruces de líneas, y como pueden ver ahora hay algo de ruido, ya que para un solo lado de la figura repliqué dos veces la misma línea para mover una hacia su interior y otra a su exterior, lo cual debe ser solucionado detectando correctamente que el lugar hacia donde debe trasladarse la línea es hacia donde se encuentre el fondo de la figura.


Así es la salida en la ventana que se despliega.


Y como acostumbramos, en el terminal se imprime el porcentaje de la figura, su centro detectado y como extra, en base a su número de lados detectado, la impresión del nombre del polígono.


Código


En el siguiente gist hay fragmentos importantes de mi código. Las partes que también son elementales pero que ya se han repetido en entregas anteriores no las muestro, como la parte de convolución y búsqueda BFS para la detección de formas.


Por motivos de tiempo, no me fue posible mejorar este código, por eso es algo extenso y poco modular. Tiene muchas secciones de código que se pueden mejorar, entre ellas la parte en donde se obtiene theta para determinar la orientación de cada pixel, lo que me provocó el problema de no detectar eficientemente las líneas que no son horizontales o verticales, una vez arreglado esto debería de ser posible detectar polígonos simétricos que no forzosamente sean cuadrados.

Si en algún momento modifico este código los cambios no se verán aquí en este gist, pero pueden buscar en mi repositorio por nuevas versiones.


Referencias:
Detección de Polígonos, por Elisa Schaeffer, Abril 2013

24 de abril de 2013

Actividad 7: Detección de Agujeros

Laboratorio de Visión Computacional
Actividad 7

Para la actividad de la semana se nos pidió probar la detección de agujeros con fotos de objetos tomadas por nosotros mismos. Para cada punto encontrado como pico del histograma se trazo una línea recta que lo cruzaba, para los casos del histograma vertical y el horizontal, para después de esto observar las intersecciones de las líneas donde debería de encontrarse un agujero.

A diferencia del código presentado en la publicación de este mismo tema pero para la entrega de la clase, tenemos ahora el código correspondiente para el trazo de los histogramas sobre la imagen y también el código que dibuja las líneas que intersectan los puntos de los picos encontrados.

Como primer ejemplo tengo una imagen de un enchufe de electricidad, donde podemos notar como en la primer imagen donde se muestra el histograma encontramos dos picos para el caso del histograma vertical y dos para el horizontal también, que posteriormente se muestra que de los 4 puntos donde se intersectaron las 4 rectas, dos de ellos son marcados con punto amarillo porque se comprobó que correspondían a puntos donde se encontraba un agujero.



Luego tome una fotografía más a una de las caras de un rallador de quesos el cual contenía un total de 32 agujeros y probé con el programa para ver si era posible detectarlos a todos. El resultado, como se ve en las siguientes imágenes, fue de una detección casi perfecta donde todos menos el agujero de la esquina inferior derecha fue detectado, y la razón es porque en el histograma vertical el pico se encontró un poco más a la izquierda y las líneas que cruzaron no entraron en el espacio de este agujero, por lo que fue descartado como agujero, pero en todos los demás pareció no haber ningún problema.


Aquí esta el resultado al colorear todos los agujeros de un color morado y etiquetados con un ID cada uno de ellos.


Código



Otra prueba más fue con un plato con un solo agujero, donde podemos observar que en el histograma se ven claramente donde están esos picos (valles, si se analizan desde la otra perspectiva), y el cruce de las líneas de los correspondientes picos indican el lugar donde debe encontrarse el agujero.





Y por último una prueba más con un colador para las ollas de vapor que contiene varios agujeros en diferentes tamaños, donde el histograma también logra indicar donde están los picos donde se encuentran estos agujeros.


Se marca con un punto amarillo donde la intersección de las líneas logra pasa por un agujero detectado.


Y en la siguiente imagen vemos los agujeros perfectamente detectados, con el único detalle de que en la foto un destello de luz corta uno de los agujeros y los detecta como dos agujeros independientes, pero como se observa el agujero completo es rellenado con algún color cercano a morado.


Y como se hizo para la entrega de la clase, en cada una de las pruebas el programa imprime en terminal el lugar donde se encontró el agujero y el tamaño del agujero en porcentaje del tamaño de la imagen completa. Enseguida una muestra.


Referencias:
Elisa Schaeffer - Detección de Agujeros

21 de abril de 2013

Detección de Agujeros

Visión Computacional
Tarea 6

Para la entrega de esta semana se nos pidió hacer lo siguiente.
  • Agregar una rutina que detecta todos los agujeros en una imagen.
  • Los agujeros detectadas se marcan con un borde morado oscuro y un relleno de morado claro.
  • Un tono ligeramente diferente en cada agujero.
  • Se marca el centro de cada agujero con un punto amarillo.
  • Al centro de cada agujero se agrega una etiqueta del ID del agujero.
  • El programa imprime un listado que indica para cada ID el tamaño del agujero (como porcentajes del tamaño de la imagen).

Utilice la técnica de histograma lateral, que consiste en sumar las intensidades de todos los pixeles, primero por cada fila para obtener un histograma horizontal y luego por columna para obtener un histograma vertical.

Al tener las dos histogramas podemos ponerlos por encima de nuestra imagen para observar como se comporta el histograma cuando existe un agujero en la imagen.



Como podemos notar en la imagen anterior, donde se cruzan las líneas que cruzan los puntos mínimos de los dos histogramas podemos encontrar una zona oscura que será detectada como un agujero. Nota: El pixel de inicio en la imagen es el de la esquina superior izquierda, por lo que para la línea roja hay que entender que el mínimo es el que pareciera ser una elevación.

Ahora veamos otro ejemplo de la foto de una tabla de madera con dos perforaciones. En la segunda imagen podemos observar un paso intermedio al momento de estar buscando por las coincidencias en todos los mínimos detectados. Y por último como sale la imagen en el programa que escribí.



Para cada agujero encontrado se le marco con un número junto a su centro y se le relleno de un color de tonalidad morada.

Código



Más pruebas


Las fotos que use para hacer las pruebas fueron de capturas a una hoja de papel con perforaciones hechas con la punta de una pluma.



En este caso por la forma en que quedaba el histograma, el centro lo detecto algo desfasado.


Y en las siguientes dos pruebas incluyo la captura completa junto con la salida que se generaba en el terminal, con los tamaños de los agujeros en un porcentaje con respecto al tamaño de toda la imagen.






18 de abril de 2013

Actividad 6: Relleno de Elipses y Círculos

Laboratorio de Visión Computacional
Actividad 6

A diferencia del código mostrado en la publicación de la clase, este código diferencia entre elipses y círculos, ya que el método de cuerda-tangente puede ser usado para la detección de ambas figuras.

En este código una vez detectado el centro de la figura, a partir de este punto se usa BFS para ir coloreando todos los pixeles dentro del contorno del elipse. A cada elipse y círculo se le asigna un número y se imprimen sus semidiámetros o radios, según corresponda, y por último se imprime para cada uno un porcentaje del tamaño con respecto al tamaño total de la imagen.



Código



Pruebas


Imagen después de binarizar y obtener bordes de las figuras.


Imagen obtenida.


Salida en el terminal.



Imagen después de haber encontrado los bordes y haber binarizado, antes de mandarse al método que buscará posibles elipses y círculos.


Resultado obtenido.


Y por último una captura de la ventana desplegada junto a la terminal donde se muestran las figuras detectadas, en este caso elipses y círculos, y se muestra en donde se encontró su centro, si es un elipse los semidiámetros o si es un círculo su radio, así como el porcentaje que ocupa la figura en relación a la totalidad de pixeles de la imagen.