jueves, 21 de febrero de 2013

Actividad 3 Lab : Convex hull

Para esta semana la tarea fue procesar una imagen para obtener el convex hull o envoltura convexa que es la unión de los puntos que se encuentran en el borde o silueta de una figura y que al unirse no cortan la imagen. Se explica mejor en la siguiente imagen:



Para lograr esta actividad, hayvarias técnicas que se pueden seguir como: Graham Scan, Chan´s Algorithm, Jarvis March, Divide and Conquer. Yo utilice Jarvis March.

Lo que hace este algoritmo es tomar un punto e ir buscando el siguiente punto de manera que el nuevo sea el que tenga el mayor o menor(dependiendo de que variación se elija) ángulo formado con respecto al punto anterior.
Ya al momento de realizar esto sobre la imagen, dado que ya tenemos la matriz de los valores de los píxeles es fácil solo checar cuales puntos están más un lado que otros.

Para el código combine el código de la tarea de la clase para detección de formas(bfs) con el algoritmo de jarvis(tome como referencia el algoritmo que viene en wikipedia para ordenar las partes y el código de un tipo, que dejo el link al final).

El código aquí:



El resultado final fue este:



No trabaja correctamente ya que falta que cierre una línea, creo es porque no estoy tomando bien los recorridos de los puntos dentro del convex hull para dibujar las líneas.

Otros intentos fallidos:




El link de mi git: https://github.com/alexgzz/Vision-Computacional
_________________________________________________________________________________
Enlaces:
http://en.wikipedia.org/wiki/Gift_wrapping_algorithm
http://www.exa.unicen.edu.ar/catedras/aydalgo2/docs/Teorica-5.pdf
http://www.pythonware.com/library/pil/handbook/

martes, 19 de febrero de 2013

Detección de formas

Aquí la idea es identificar las diferentes formas en una imagen y colorearlas de diferentes colores(random),  únicamente se pintará gris el fondo de la imagen.

Para llegar a esto es necesario combinar algunas técnicas que ya hemos estado usando como filtros, binarización, detección de bordes...

La imagen con la que trabaja esta parte debe de ser una en la cual los bordes se hayan detectado y diferenciado de lo demás y que éstos se encuentren bien definidos( esto se puede lograr aplicando binarización).

La imagen que utilicé es una ya con bordes detectados y con un proceso de binarización para que estos no tengan discontinuidades.



Para la detección de formas tomé como referencia el código de la Dra. Elisa, y el proceso consiste en recorrer uno a uno los píxeles de la imagen e ir checando el color del píxel, y como la imagen esta en negro y blanco solamente, si es negro(0,0,0) se comienzan a checar sus vecinos hasta encontrar un borde(píxel blanco(255,255,255)) y se pintan de un color al azar.


 


Para colorear en gris el fondo lo que hice fué almacenar los colores(sus valores rgb) de cada píxel que se iban usando en la imagen, posteriormente almacene en una lista cuantas veces se repetía cada uno, tomé el valor más grande de estos, busqué su lugar en esta nueva lista y con el lugar obtenido, solo fuí a la lista de colores y saque el valor que se encontraba en esa posición.(creo que esto se entiende mejor en el código :P)

Aquí pongo el código:


Y aquí otros ejemplos:










Como se puede observar en las últimas imágenes, en algunas zonas no se definen bien los colores y el pintado del fondo gris tiene deficiencias, creo yo que es por la gran cantidad formas y bordes de la imagen, ya que la inicial y la última al ser algo más sencillas se ve mejor el trabajo.

jueves, 14 de febrero de 2013

Avtividad 2 Lab - Ruido "Sal y Pimienta"

Esta actividad consta de dos partes, la primera era generar una especie de ruido llamado Sal y Pimienta(este nombre debido a las pequeñas manchas blancas y negras que se generan) y la segunda parte era tratar de remover este ruido de una imagen.

Para la primera parte, la generación de estos puntos la realicé tomando puntos aleatorios en la imagen y después pinté el píxel eligiendo el color aleatoriamente tomándolo de una lista con cuatro valores diferentes. 

En el programa, se recorren todos los píxeles uno a uno, para la elección del punto se genera un número entero random(entre 0 y 250) y después se verifica si ese número es uno de los tres valores del píxel en cuestión, sí lo es, se escoge un valor aleatoriamente de una lista con valores predeterminados y se utiliza para cambiar el valor del píxel.

Aquí los resultados:



El jugar con algunos parámetros del código, se pueden generar éstas imágenes también:





Y el código que utilicé:



Para la segunda parte, utilicé el código que ya había usado para hacer borrosa las imágenes añadiendo algunas modificaciones, con la idea que ahora debería buscar solo puntos negros y blancos y tratar de difuminarlos, obteniendo los valores de los píxeles adyacentes, sacando un promedio de estos valores y cambiando el valor anterior por este promedio obtenido.

Aquí esta el código:



Y aquí los resultados:


Como se ve, si lo comparamos con la imagen que tiene ruido no se quitaron totalmente las manchas, pero si disminuyó considerablemente o al menos lo suficiente para que se note.

lunes, 11 de febrero de 2013

Detección de Bordes

La actividad para esta entrada es realizar un programa que detecte los bordes en una imagen y los ponga en color blanco y el resto de la imagen la ponga en color negro.

Para poder lograr esto es necesario que la imagen pase por varios procesos hasta que se logre el cometido. Los principales procesos son: a partir de la imagen original(a color) obtener una imagen en escala de grises y a este resultado aplicar una especie de filtro que vuelve la imagen un poco borrosa para que sea más fácil identificar los bordes. 
Ya con la imagen gris y un poco borrosa se procede a identificar los bordes, esto se puede hacer aplican un proceso llamado convolución, que se basa en aplicar una máscara que recorre todos los píxeles buscando variaciones en comparación con los píxeles cercanos.

En caso de que después de aplicar estas técnicas la imagen final no muestre los bordes bien definidos, se puede recurrir a seguir aplicando otras técnicas como normalización para suavizar un poco la imagen y binarización en caso de que la imagen siga teniendo tintes de grises.

En mi caso, según yo, no es necesario aplicar normalización o binarización, porque la imagen muestra bordes bien definidos.

La máscara que utilicé se basa en la obtención del diferencial de gradiente por medio del método del operador de Prewitt o Sobel. Estos operadores calculan las variaciones de intensidad de cada píxel en comparación con otros. 
Para aplicar éstos operadores es necesario multiplicar los valores de cada píxel (yo sólo utilice el primero ya que la imagen al ser gris tiene el mismo valor en los tres espacios) por cada valor de unas matrices pre-establecidad llamadas kernel; en estos casos se usan dos kerneles por operador ya que uno analiza en la dirección de "x" y otro en la dirección "y".

#las matrices
Operadores Sobel
Operadores Prewitt


El resultado de hacer estas operaciones es obtener las variaciones de intensidad o gradientes en "x" y "y". A partir de esto se puede aplicar una formula para obtener el gradiente total en "x" y "y". La formula:



El resultado de pasarla a escala de grises:
Y el código para hacer esto:



El resultado de aplicar el filtro donde la imagen se vuelve borrosa:

Y el código para lograr esto:



El resultado de aplicar las técnicas de los operadores de Prewitt y Sobel:

                           
                                  Operador Prewitt
Operador Sobel













Y el código para esto:



Otras imágenes:
Siguiendo el mismo proceso de las anteriores.



Original -> Escala de Grises -> Borrosa -> Bordes


Los tiempos del procesamiento de las imágenes en la parte de la detección de los bordes van desde 0.40 segundos hasta 0.47 segundos, algo rápido, pero supongo que es por que no se usaron imágenes muy grandes.
_________________________________________________________________________________
Enlaces:
http://en.wikipedia.org/wiki/Prewitt_operator
http://en.wikipedia.org/wiki/Sobel_operator

jueves, 7 de febrero de 2013

Actividad 1 de Laboratorio - Escala de grises, Umbral, Imágenes Borrosas

En esta actividad la tarea es era aplicar filtros a las una imagen para cambiar su aspecto, yo realice los filtros  escala de grises y el un umbral para que cambie a blanco y negro. Me quede a medio camino con el de volverla borrosa.

Dejo el link del github, ahí estan los códigos: https://github.com/alexgzz/Vision-Computacional

Escala de Grises
El primero que hice fue el de escala de grises. Aquí algunos resultados, jugando con los valores del umbral y la imagen de la cual se partió.
       Imagen Original:
       
 Resultados:                                                                                          
                          
                                  Promedio de los 3 colores
Elección del valor más grande

                             
Elección del valor más pequeño

Este filtro se aplico utilizando la librería PIL para Python, obteniendo una lista con todos los valores de los pixeles de la imágen en formato RGB (1,2,3) mediante la función .load() y recorriendo esto pixel por pixel. El formato de grises se logra estableciendo el mismo valor en los tres espacios del color del pixel, por ejemplo (0,0,0).

  • En la primera imagen se obtuvo el promedio de los tres valores de cada pixel y se sobrescribió en cada pixel.
  • En la segunda se obtuvo el valor más grande de los tres que formaban cada pixel y se sobre escribió en cada pixel. 
  • En la tercera se hice lo mismo que en la segunda, solo que con el valor más mínimo.

Umbral Binario
Para la conversión a blanco y negro, se cargo la imágen original con PIL y se obtuvieron los valores RGB de cada pixel, para establecer si un pixel debería ser blanco o negro, se obtuvo el promedio de los tres valores de cada pixel y se comparo un umbral, dependiendo si pasaba o no, se convertiría en negro o blanco. Aquí algunos resultados:

                
Imágen Original
Aplicando promedio y umbral 125













También en este caso se podía partir de una imagen previamente convertida a escala de grises, así solo sería necesario leer un valor de los tres ya que todos sería exactamente iguales. Se establece el umbral si lo pasa toma negro y si no, blanco. Algunos resultados, todos con umbral 125, pero partiendo de diferentes escalas de grises:


                   
                          Partiendo de grises con valores máximos

Partiendo de grises con valores mínimos













Lo de volverlo borrosa me quede a medio camino, pero lo que avance esta en el repositorio.

Tambíén trate de hacer algo para cargar las imagenes en una ventana y que se pudieron visualizar ya con los filtros que se manejaron aquí. El código también esta en el git y aquí dejo una captura: