lunes, 4 de febrero de 2013

Laboratorio 1

Laboratorio 1 - Escala de grises y umbrales 

Hola, para esta primer entrada del laboratorio de Visión Computacional se nos pidió realizar un programa que dada una imagen cualquiera, obtener una copia de la imagen a escala de grises, luego por medio de umbrales, asignar pixeles, blanco, negro y gris (el mismo color) a la imagen.
Bien, dicho esto, voy a proceder a explicarles el método que usé para convertir mi imagen a escala de grises (creo que todos usamos el mismo método). Primeramente, obtuve de cada uno de los pixeles los valores de RGB, luego realicé un promedio con esos 3 valores. Por ejemplo:
Pixel1 = (65, 30, 14), el promedio es (65 + 30 + 14) / 3 = 36.33.
Seguido de eso igualé los valores de RGB del pixel al promedio obtenido, es decir:   
NuevoPixel = (36, 36, 36)


Algo así:

for x in xrange(im.size[0]):
  for y in xrange(im.size[1]):
   pix = im.load()
   tupla = pix[x, y]
 
   a = tupla[0]
   b = tupla[1]
   c = tupla[2]
   
   prom = int((a+b+c)/3)
   newTupla = (prom,prom,prom)
   im.putpixel((x, y), newTupla)   

   print tupla, "--", a,",",b,",",c
 im.save('meh.jpg')


Luego por medio de la función putpixel formo la imagen con los nuevos valores de RGB de cada pixel.


La imagen anterior es la imagen original que uso para realizar esta práctica, cuando ejecuto mi programa primero me sale la imagen original, luego en terminal me pregunta lo que deseo hacer, me dice que presione 1 para realizar la función de escala de grises o que presione 2 para usar la función de umbrales.

Si elegimos la opción 1 se ejecutará la siguiente función (transformar):

def transformar():
 i = 0
 x = 0
 y = 0
 im = Image.open("bla.jpg")
 
 for x in xrange(im.size[0]):
  for y in xrange(im.size[1]):
   pix = im.load()
   tupla = pix[x, y]
 
   a = tupla[0]
   b = tupla[1]
   c = tupla[2]
   
   prom = int((a+b+c)/3)
   newTupla = (prom,prom,prom)
   im.putpixel((x, y), newTupla)   

   print tupla, "--", a,",",b,",",c
 im.save('meh.jpg')

Si elegimos la opción 2 se ejecutará la siguiente función (umbrales):

#Funcion umbrales
#Se accede a ella presionando 2
def umbrales():
 i = 0
 x = 0  
 y = 0
 umbInferior = 77
 umbSuperior = 177
 im = Image.open("bla.jpg")
 
 for x in xrange(im.size[0]):
  for y in xrange(im.size[1]):
   pix = im.load()
   tupla = pix[x, y]
 
   a = tupla[0]
   b = tupla[1]
   c = tupla[2]
   
   prom = int((a+b+c)/3)
   if prom < umbInferior:
    prom = 0
   elif prom >= umbSuperior:
    prom = 255
   newTupla = (prom,prom,prom)
   im.putpixel((x, y), newTupla)   

   print tupla, "--", a,",",b,",",c
 im.save('meh2.jpg')


Cuando ejecutamos la primera opción el resultado de la imagen es la siguiente:


La imagen a a escala de grises, luego cuando ejecutamos la segunda opción el resultado de la imagen es la siguiente: 

La imagen a blanco y negro con algunos pixeles en gris, los pixeles en gris son porque quedaron en medio de los umbrales superior e inferior que puse. Es decir, si el pixel resultaba menor al umbral inferior (85), lo pintaba en negro, si el pixel resultaba mayor al umbral superior (170) lo pintaba de blanco, y si quedaba entre los valores de los umbrales el pixel permanecia en el valor gris.

Jugando con los umbrales

Bien, después de esto realicé algunas modificaciones a los valores de umbrales y pixeles para visualizar los cambios de las imagenes resultantes, en la siguiente imagen apliqué lo contrario, es decir, si el valor del pixel era menor al umbral inferior, al nuevo pixel le daba el valor de 255, y viceversa, de esa manera esperaba el resultado contrario (cambiar negros por blancos y blancos por negros).
El resultado es el siguiente:



Luego cerré un poco más los valores de los umbrales para observar el efecto resultante, lo que yo esperaba (obvio) era menos valores de grises, y que se aumentaran los pixeles blancos y negros, esto debido a que ya habría menos cabida para los pixeles grises, ya que se cerraron más los umbrales.
El resultado es el siguiente:
El resultado fue el esperado, una imagen con un mayor número de pixeles negros y blancos que la umbralización normal (umbral inferior = 85, umbral superior 170).

Después de esto, abrí el rango de los umbrales, osea, le di más cabida a los pixeles grises, pasé de los valores 117 para los umbrales inferiores y 137 para los umbrales inferiores a un 77 y 177 para los umbrales inferiores y superiores respectivamente. 

Y este fue el resultado (obviamente con un mayor número de pixeles grises que la imagen anterior, quedando con menos pixeles negros y blancos):


Bueno, ese fue todo mi trabajo para esta entrada 1 del laboratorio, la liga a mi git con el trabajo  es la siguiente: https://github.com/eddypre/VisionTriana/blob/master/Laboratorio1

Ahí mismo también pueden encontrar las versiones que fui realizando (son 3). Y aprovecho para comentarles que en ese mismo pool subiré todos mis avances de proyecto de esta materia.

Cualquier duda o aclaración pueden dejarla en comentarios.

Saludos!


martes, 22 de enero de 2013

Visión Computacional (puntos extras)

Aplicaciones de la visión computacional 

Hola, esta entrada trata sobre detección de rostros en imágenes a color y es para puntos extra en la materia de visión computacional.

La detección de rostros humanos juega un rol importante en aplicaciones como videos de vigilancia, acceso a sistemas mediante la lectura de rostros, etc.

Basado en una nueva técnica de compensación de luz y tansformación no linear de color, existen métodos que detectan regiones de la piel sobre imágenes completas y después genera rostros candidatos basados en la disposición espacial de la piel.

Algoritmo de detección de rostros.

El algoritmo de detección de rostros se compone de 2 módulos. 1) El primero es la localización de caras para encontrar rostros candidatos. 2) Detección de características faciales para la verificación y detección de rostros candidatos.

El algoritmo primero estima y aplica una corrección al color basado en una técnica de compensación de luces. La edición/corrección de los componentes rojo/verde/azul son no linearmente transformados en el espacio de colores YCbCr.
Los pixeles del tono de piel son detectados usando un modelo elíptico de piel en el espacio transformado. El parámetro del elipse corresponde al contorno de la constante de distancia Mahalanobis bajo la suposición de distribución Gaussiana del color de tono de piel.
Los pixeles de tono de piel detectado son segmentados iterativamente usando varianza de color dentro de los componentes de colo conectados, los cuales son agrupados después entre los candidatos de rostros basados en ambos arreglos espaciales de estos componentes y la similitud de sus colores.
El tamaño de pixeles de un rostro candidato puede variar desde 13x13 pixeles hasta cerca de tres cuartas partes de la imagen original.

La característica del módulo de detección facial rechaza las regiones de los rostros de los candidatos que no contienen ninguna característica facial como ojos, boca y límites del rostro.
El resultado es la detección facial encerrada en un elipse, con las características faciales, tales como la boca, nariz, ojos, dentro de tríangulos.

Como se muestra en la siguiente figura.





La detección del tono de piel y la compensación de luces están totalmente ligadas, ya que para poder realizar una correcta detección es necesario tener un bue ambiente iluminado, la técnica usada para compensación de luces es llamada "reference white",  y se trata de normalizar la apariencia de los colores, como se muestra en la siguiente figura.




Conclusión

La detección de rostros tiene una semejanza al procesamiento y detección de voz en cuanto a complejidad, pero sin duda son campos que están en constante mejoramiento, aunque pienso que siempre seguirán muy lejos de la perfección y detección exacta y precisa.


Este me parece un tema interesante para trabajar en el proyecto de esta materia.

Cualquier duda o aclaración pueden ponerla en comentarios. 

 Saludos!

lunes, 12 de noviembre de 2012

Reporte Grupal

Reporte grupal

Hola, esta entrada trata sobre el reporte grupal, el equipo para esta actividad está conformado por mi compañero Alejandro Avendaño, Jonathan Alvarado y yo (Carlos Triana), los ejercicios que teniamos que desarrollar para esta actividad son los siguientes:

Formulen el sistema que quieren controlar en términos de espacio de estados.
En la forma normal controlable.
También en la forma normal observable.

Utilizando los vectores y los valores propios, diagonalicen a un forma normal -Jordan

Las investigaciónes, desarrollos y cálculos realizados se encuentran en la siguiente liga (blog de mi compañero Alejandro Avendaño): http://autoycontrolave.blogspot.mx/2012/11/blog-post_12.html



Bibliografía:



Saludos!


martes, 6 de noviembre de 2012

Puntos extras

Control estructural por medio de sensores wireless y cómputo integrado

El origen del tema que escogí para esta entrada es el décimo tercero simposio anual internacional en materiales y estructuras inteligentes. Se llevó acabo en San Diego California en Febrero y Marzo del 2006.

A grandes rasgos el contenido de la publicación trata sobre el campo de la ingeniería estructural (o de estructuras, en específico la ingeniería civil) apoyado por la ingeniería informática-electrónica para la investigación de sensores wireless (todavía no implementados en la ingeniería civil) de bajo costo para su uso en sistemas de monitoreo estructural.

La finalidad de esta investigación e implementación es ahorrarse tanta labor y costos asociados  a las instalaciones hechas con largas extensiones de cables coaxiales en los actuales sistemas de control de estructuras, los autores mencionan que esta tecnología es el futuro para los sensores de control de estructuras.

Bien, lo que este sistema propone es que los sensores wireless son diseñados para cumplir 3 tareas principales en el sistema de control: 

1 - Los sensores inalámbricos son responsables de la recolección de datos de las respuestas estructurales.

2 - Los sensores inalámbricos son responsables del cálculo de las fuerzas de control.

3 - También son responsables de emitir comandos a los actuadores.

En la publicación se menciona que un prototipo de sistema "Wireless Structural Sensing and Control (WiSSCon)" fue presentado en el simposio.
Y para evaluar el desempeño de este prototipo se llevan acabo experimentos a media escala con 3 estructuras de acero en las que un amortiguador magnetoreológico está instalado. El funcionamiento del sistema de WiSSCon se ha demostrado que es efectivo y fiable.

Los autores y creadores de este sistema dicen que WiSSCon no es más que un prototipo diseñado para estar sensando y retroalimentando de información en "tiempo real" por wireless al sistema de control.  También mencionan que la comunicación por wireless es usada para la retroalimentación de la respuesta estructural para así calcular soluciones de control basadas en la información que se envío.

Para que les haga más sentido la transmisión de la información y cálculos realizados con la misma, dejo este gráfico que describe perfectamente el sistema (La imagen fue obtenida de la misma publicación: http://www-personal.umich.edu/~jerlynch/papers/SPIE2006Control.pdf)





La arquitectura del hardware de la unidad de control por wireless utilizado para este prototipo (WiSSCon) es la siguiente (se puede apreciar la interacción del cómputo embebido):

Y para los que creian que la clase de cómputo integrado no era tan importante, el módulo de control de señales (que se ilustra en la imagen siguiente) está hecho con mictrocontroladores ATmega128 (los usados en las tarjetas Arduino) y amplificadores operacionales, además de convertidores Digital-Analógicos.



Y así se ve en conjunto el módulo de control de la señal conectado al sensor wireless (básicamente es el aparato situado debajo de la estructura en la imagen 1, nótese la antena de emisión/recepción del módulo)




Campos de aplicación y conclusiones

En  la ingeniería civil, el mejoramiento a la respuesta (datos del movimiento de estructuras) de estructuras debido a la fuerte excitación dinámica es un reto difícil.

Como ya antes mencioné, el sistema WiSSCon ha demostrado que es efectivo y fiable por lo cual no dudo en la futura aplicación de este y similares sistemas de control en las estructuras civiles.

Las personas que trabajaron en esta investigación son: Yang Wang, Andrew Swartz, Jerome P. Lynch, Kincho H. Law, Kung-Chun Lu, Chin-Hsiung Loh

Y la liga de la publicación es:
http://www-personal.umich.edu/~jerlynch/papers/SPIE2006Control.pdf

Las palabras clave para encontrar la publicación aquí presentada fueron:
Keywords: structural control, wireless communication, embedded computing
 

La redacción total de este post fue hecha por mí, y todas las imágenes fueron obtenidas de la misma publicación.

PD: La publicación no contenía gran información de los temas tratados en la materia, por tal motivo no puse ecuaciones, técnicas o conceptos estudiados durante el semestre.


Saludos!
 


miércoles, 23 de mayo de 2012

Sistemas Distribuidos (Clase y Laboratorio)

Semana 16 -  Unión a VPN y clúster


Hola, esta última semana una parte del equipo de clúster nos juntamos con la idea de reunir a muchos nodos para formar un clúster más grande que el que ya habiamos hecho anteriormente. La idea era presentarlo en el salón el martes, para que luego los demás compañeros pudieran correr aplicaciones sobre él.

Bueno, solo pudimos reunir 7 máquinas, ya estando en el salón de clases los planes cambiaron a un mejor plano.

Decidimos unirnos al clúster que habían creado los compañeros Juan Carlos y Rafael. Los compañeros ofrecieron darnos acceso para unirnos a su servidor de VPN, para luego ser parte del clúster.

El día de hoy algunos  compañeros (los que reunimos las características del SO: "Ubuntu 10.04, 64 bits")  logramos conectarnos al clúster mediante la VPN antes mencionada. 

Lo que hicimos todos fue descargar los bash que creó el compañero Juan Carlos, los bash se encargaban de descargar algunos paquetes, copiar carpetas y archivos e instalar y configurar todo lo necesario.

Después de descargar y configurar todo, descargamos Ganglia para monitorear el clúster, también por medio de los bash.

Al final el compañero Rafael nos agregó al clúster y luego mediante el siguiente link (monitoreo) me di cuenta que ya estaba dentro del clúster.



A continuación les dejo algunas impresiones de pantalla que saqué:


Con esto me di cuenta la dirección ip que tenía asignada dentro del túnel de VPN, pueden notar como se creo una nueva conexión llamada "tun0-00" (mi ip es: 10.6.0.10)







Aquí mediante la herramienta de monitoreo se puede observar que el estado del nodo 10.6.0.10 es UP, también se logra ver el estado de actividad de mi nodo.







Y aquí se puede ver la actividad de los nodos que se agregaron al clúster la última hora, los que tienen instalado el ubuntu en su HDD les aparece su nombre de equipo (por ejemplo el del compañero Juan Carlos: "en rojo"), los que estabamos corriendo el SO en la USB solo nos aparece la dirección ip del equipo (mi dirección es 10.6.0.10, soy el de amarillo :p).






No quise poner nada de esto en la wiki porque ya había puesto información sobre Ganglia y también buena parte de esto ya estaba posteado, además no fui yo quien inició la implementación de esta buena herramienta.


Quiero nominar a mis compañeros:


- Juan Carlos: Por haber creado los .sh para descargar, instalar y configurar todo lo necesario.- http://jcecdps.blogspot.mx/2012/05/dps-class-contributions-week-15.html

- Rafael: Por haber implementado las herramientas de monitoreo y creado el servidor de VPN (junto con Juan).

-José:
Por habernos guiado a mí y otros 2 compañeros con la instalación y configuración para unirnos al clúster.


Lo que yo espero para la tarde de mañana es que podamos correr aplicaciones con todos los nodos que nos agregamos hoy y después comparar los tiempos de ejecución de los programas con los tiempos que se hacian antes de que nos agregaramos nosotros.

 Saludos!




jueves, 17 de mayo de 2012

Sistemas Distribuidos (Clase y Lab)

Reporte 15 - Complemento sobre investigación de Grids


Para la semana 15 de Sistemas Distribuidos, decidí complementar en la wiki sobre el tema que investigó mi compañero Rodolfo de grids computacionales, ya que ya había leido con anterioridad sobre estos temas pero no los había puesto en la wiki.


También estuve trabajando con RMI pero con bastantes fallas debido a que nunca pude hacer la conexión entre computadoras, Java me tomaba una ip desconocida a la mia y nunca se pudo establecer conectividad, investigaré ese tema posteriormente más a detalle. La conexión solo la he logrado en mi misma máquina, pero así no tiene chiste, no se aprovecha las ventajas de RMI.


Bueno, mi corta aportación está en esta liga:



Nominaciones:

  • Rodolfo: Por la aportación de Grids computacionales en la wiki.



Saludos! 



jueves, 10 de mayo de 2012

Reporte 14 - Benchmark (Clase)

Reporte 14 - Benchmark (Clase)


Anteriormente ya había hablado sobre benchmarks y pruebas que podemos realizarle a nuestro clúster, pero solo había comentado sobre teoría y algunas aplicaciones que nos podian servir al equipo clúster.


En esta ocasión para el reporte de la clase de esta semana instalé y corrí el System Profiler y Benchmark llamado "HardInfo".




 

HardInfo es una pequeña aplicación que muestra información sobre el hardware y sistema operativo.


El post de esta semana se encuentra en la siguiente liga:


Y para mayor información acerca de la aplicación HardInfo pueden visitar la página web del desarrollador:  http://hardinfo.berlios.de/HomePage


Saludos!