martes, 28 de septiembre de 2010

Umbralizando

Después de estar trasteando con ciertas funciones, ahora lo que quiero hacer es seleccionar de una imagen un color determinado, para poder luego trabajar con ello.
El color elegido al azar entre los tres colores importantes es el rojo, así que con una imagen sencilla en la que hay círculos me quedo con los rojos que son los más molones. El resultado es el siguiente:




Como se puede observar ha sido una elección óptima, pero claro, el mundo no es perfecto para estas cosas, así que ahora me dedicaré a meter ruido en la imagen para que sea un poco más real.

viernes, 10 de septiembre de 2010

Acceso por punteros

Esta vez he accedido a la imagen por medio de punteros de la siguiente manera:
v=((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels+k];

De esta forma se accede a todos los pixeles de la imagen uno a uno. Para probarlo la transformación que he hecho a la imagen es restar 125 si el valor del pixel es mayor a 125, y sumar 125 si el valor era menor a 125. El resultado final ha sido:



miércoles, 8 de septiembre de 2010

Negativando

He cogido una imagen y accediendo pixel por pixel con la función cvGet2D, después he mirado el valor del pixel para cambiarlo (si estaba a 0 lo he cambiado a 255 y si tenía 255 a 0), y después he metido los nuevos valores en otra imagen con la función cvSet2D.

Con ello el resultado obtenido es el negativo de una imagen en blanco y negro.




Ahora lo intentaré hacer con punteros.

martes, 7 de septiembre de 2010

Tratando imágenes

Transformaciones de una imagen con las funciones ya definidas en opencv.

La primera transformación es pasar una imagen a escala de grises, para ello la función que he usado ha sido cvCvtColor.


La siguiente tranformación es una binarización de los canales de la imagen, usando la función cvThreshold.


Y por último he juntado las dos funciones anteriores, primero pasando la imagen a escala de grises y luego haciendo una binarización de ésta.




Las siguientes transformaciones en la imagen las haré a mano, accediendo pixel por pixel.

jueves, 11 de marzo de 2010

Encontrando los píxeles

Lo primero que hay que hacer, antes de nada, es saber los píxeles que nos interesan en la imagen. ¿Cómo vamos a hacer esto? Pues de momento de la forma más sencilla.

La idea es meter en un vector en qué posición están los píxeles que nos interesan (usaremos dos vectores, uno para las filas y otro para las columnas). El primer problema en este paso es que en un principio no sabemos la longitud que va a tener nuestra imagen, y por lo tanto, no sabemos la longitud con la que se deben crear esos vectores. Para solucionar este problema voy a usar la librería estándar de C++, en concreto la clase vector que permite acceder a los elementos como un array pero a la vez permite añadir elementos como si fuera una lista.

Para entender la librería he usado las siguientes páginas:
cplusplus (en)
Wiki (en)


La imagen a analizar es una sencilla que he creado con el gimp, en escala de grises, donde el cuadro blanco está entre los puntos (40,40) y (80,80).




Ejecutando mi programa consigo el siguiente resultado:



Viendo así que quedan identificados todos los puntos que nos interesan en la imagen.

sábado, 26 de septiembre de 2009

Primeras pruebas

Después de montar la caja y ajustar la cámara toca hacer las pruebas para ver cómo se capturarán mejor los gestos.

Las primeras pruebas son con folios, blancos, azules y verdes, a continuación un vídeo de prueba para cada color.

Folio blanco




Folio azul




Folio verde




Como se observa en los folios verde y azul la imagen es bastante oscura y por lo tanto no se distinguen bien los gestos, por lo que también he hecho pruebas con folios de acetato. En azul, verde y amarillo.

Acetato azul




Acetato verde




Acetato amarillo




El paso siguiente es comprobar en cual de todos los casos los gestos son reconocidos más fácilmente.

sábado, 28 de febrero de 2009

Primeros pasos

Como Roma no se hizo en una hora lo primero es empezar por cosas pequeñas y básicas, y en el mundo de la programación esto se llama un primer programa de acercamiento....

Así que he escrito un código que toma imágenes de la webcam y las muestra por pantalla, en principio la cámara da 320x240 de resolución porque la cámara sobre la que estoy recogiendo es la webcam del portátil y no tiene mayor resolución, aunque la idea es conseguir una cámara que dé al menos 1024x768 para no tener que reescalar para actuar sobre la pantalla.

cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH,320.0);
cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT,240.0);
cvSetCaptureProperty(capture,CV_CAP_PROP_FPS,30.0);

Las anteriores instrucciones son la forma que nos da la librería opencv para configurar la cámara, todas ellas actúan sobre una estructura CvCapture que representa la webcam.

A partir de este momento la cámara ya está configurada y le puedo pedir imágenes, esto se hace de la siguiente forma:
if(!cvGrabFrame(capture)){//pide un frame
printf("Algo malo ha pasado, llamar al SWAT\n");
exit(0);
}
Este if se pone porque no es buena idea intentar operar sobre una imagen que no existe.

Una vez que el frame se ha pedido hay que asignarlo a una estructura de tipo IplImage, también de opencv que permite operar sobre la imagen y también enseñarla por pantalla.

Para enseñarla por pantalla se hace lo siguiente:
cvShowImage("imgWin", img);
cvWaitKey(2);

Esto abre una ventana en la que se muestra la imagen que antes pedí a la webcam, resulta que hay que hacer que el programa espere un tiempo entre una imagen y otra para que se muestren correctamente (aun tratando de comprenderlo), por lo que la segunda instrucción hace una pausa de 2 milisegundos.

Si todo esto se pone en un bucle podría insertar la lógica del programa, pero esto lo dejo para próximos capítulos ...

Nota para buenos programadores: Cerrar la captura de la camara como si fuera un fichero
cvReleaseCapture(&capture);

Codigo del programa