viernes, 8 de octubre de 2010

Clases

Llegado a este punto necesito hacer una pequeña recopilación de las clases que tengo ahora mismo y cómo funcionan cada una de ellas. Para poder ponerlo todo más bonito y ordenadito he usado el programa umbrello, de momento solo para poner en cada clase qué atributos tiene y qué funciones.



Esta clase MiImagen es que la que utilizo para tratar la imagen que me pasan. Tiene un atributo imagen que es donde se guarda el umbralizado que se realiza a la clase principal. Como se ve hay diferentes funciones de umbralizado para seleccionar cada color. Y por último hay una función para quitar ruido que se aplica sobre la imagen umbralizada.


Esta clase Rectángulo es la más bonita de todas, como se puede ver es la que tiene más funciones. Con esta clase es con la que simulo mis partículas. Cada rectángulo se define por la esquina superior izquierda (esquinaIA), esquina inferior derecha (esquinaDB), color de la partícula y peso.
A continuación explicaré cada una de las funciones:

  • setID: establece el ID de la partícula.
  • setColor: establece el color de la partícula.
  • getEsquinaIA: devuelve la esquina superior izquierda de la partícula.
  • getEsquinaDB: devuelve la esquina inferior derecha de la partícula.
  • getColor: devuelve el color de la patícula.
  • getPeso: devuelve el peso de la partícula.
  • getID: devuelve el ID de la patícula.
  • dibujar: dibuja la partícula en la imagen que se pasa por parámetro.
  • dispersar: mueve a la partícula de forma aleatoria tanto movimiento como se pasa por parámetro.
  • damePosicion: devuelve el punto central de la partícula.
  • dameAlto: devuelve el alto de la partícula.
  • dameAncho: devuelve el ancho de la partícula.
  • calcularPeso: calcula el peso de la partícula. Se le pasa por parámetro la imagen ya umbralizada, de tal forma que los píxeles importantes están en 255, lo que hace es sumar cuántos de esos píxeles están dentro de la partícula.
  • generarParticula: genera las partículas de forma aleatoria por la imagen, por eso se le pasa la imagen (para saber los bordes), el color de la partícula y el lado que se quiere que tenga.


La clase dedos es la que va a realizar nuestra búsqueda. Los atributos que tienen son un vector de partículas, que se generarán al crear el dedo, el número de partículas que se harán se pasa por parámetro al inicializar el dedo, así se reserva al principio del programa la memoria que se requiera en cada caso. Los atributos color y lado se pasarán también al inicializar.
A continuación explicaré cada una de las funciones:
  • setColor: establece el color que tendrán todas las partículas.
  • setLado: establece el lado que tendrán todas las partículas.
  • estimado: de todas las partículas que se tienen devolverá el resultado más óptimo, como solo va a haber un dedo de cada color solo puede haber un resultado más óptimo.
  • calcularPesos: calcula los pesos de todas las partículas.
  • dispersar: dispersa todas las partículas en la distancia que se indica.
  • generarAleatorios: genera todas las partículas de forma aleatoria.
  • dibujarCandidatos: una vez calculados los pesos de todas las partículas dibuja en la imagen las partículas que sean candidatas a ser el mejor estimado.

Actualmente las clases están de esta forma, aunque seguramente habrá que añadir otras más para poder seguir implementando el filtro. Ahora voy a dedicarme a implementar la clase ruleta, cuya funcionalidad explicaré en la siguiente entrada.

jueves, 7 de octubre de 2010

Reconociendo colores

Como la idea final del proyecto es que se reconozcan cuatro colores diferentes, que vana ser cada dedo, he realizado una imagen con los cuatro colores que me interesan:



A esa imagen le aplico un filtro, para umbralizar el color con el que me quiero quedar en cada paso. Después lanzo partículas de forma aleatoria por toda la imagen, y de todas las partículas lanzadas me quedo con las que tienen un peso mayor a 300. Quedando el siguiente resultado:









Ya tengo cómo trabajar con cada color en cada paso, pero claro, como esto ha empezado a complicarse un poco lo mejor es tener un esquema claro de todas las clases que tengo ahora mismo para saber qué funciones tiene cada una. Pero eso es algo que me guardo para la siguiente entrada.

miércoles, 6 de octubre de 2010

Vectores

He visto que para poder tener todo más ordenadito necesito usar la clase vector de c++, porque es lo mismo que yo haría para poder usar memoria dinámica y ya se sabe el dicho "si ya lo ha hecho otro, trabajo que me ahorro".

La clase vector sirve para poder tener listas dinámicas, de esta forma no tengo que andar comiéndome la cabeza con la reserva de memoria, la liberación o acceso a memoria que está usada.

Las diferentes funciones de esta clase que me van a interesar son:


size() -> dice el tamaño que tiene el vector.
operator[] -> accede a un elemento determinado.
at ->accede a un elemento determinado.
push_back -> añade un elemento al final del vector.
clear() -> libera la memoria usada por el vector.

martes, 5 de octubre de 2010

Lanzando partículas

Poco a poco voy haciendo un acercamiento al filtro de partículas para poder seguir los dedos.

Para ello el primer paso es generar partículas de forma aleatoria sobre una imagen. Las partículas, son los rectángulos que había creado antes, de la clase Rectángulo.

Lanzando un número suficiente de partículas se cubre la imagen que queremos.



Una vez lanzadas las partículas por toda la imagen, lo que interesa son las partículas que estén sobre la parte que nos interesa. Para seleccionar la parte que nos interesa usamos el umbralizado para el rojo como ya he puesto en una entrada anterior.

Una vez que tengo la imagen umbralizada lo que hago es trabajar con ella con las partículas. La forma de seleccionar la que me interesa es añadirle un peso a cada partícula, es decir, el peso en este caso es la cantidad de píxeles que me interesan están dentro de esa partícula. De ésta forma se puede ver cómo seleccionamos las partículas que nos interesan, en la imagen a continuación vemos que en amarillo están las de interés y en azul las que no.



Para que se observe mejor solo pintaré en la imagen las partículas que me interesan.



Una vez conseguido esto, voy a por el siguiente paso del filtro de partículas.

lunes, 4 de octubre de 2010

Simulando movimiento

Para poder seguir el movimiento de mis dedos por la pantalla necesito poder hacer que los rectángulos o partículas se muevan de forma aleatoria desde un punto en el que estén inicialmente una distancia que yo elija, me he creado en la clase rectángulo una función dispersar, a la que se le pasa el movimiento que se quiere conseguir.

void dispersar(int mov);


Para probar esta función me creo una partícula y hago que se disperse con diferentes valores, teniendo como resultado esto:

viernes, 1 de octubre de 2010

Clase Mano

Ahora he hecho una nueva clase, que contiene varios objetos de la clase anterior, así que para manejarlo me he creado las diferentes funciones:


void setRectangulo(Rectangulo r);
void restarRectangulo();

CvPoint posicionRectangulo (int id);
IplImage* dibujaRectangulo(IplImage* img);


Las funciones lo que hacen es añadir rectángulos en mi clase (hasta un límite de cuatro), también puede quitar uno que se haya añadido antes, la posición de un determinado rectángulo y por último dibujar todos los rectángulos.


jueves, 30 de septiembre de 2010

Clase rectángulo

Para poder tener todo un poco más ordenado me he creado una clase rectángulo.

Mis rectángulos se definen por la esquina de arriba a la izquierda, la esquina de abajo a la derecha, el color y un identificador.
Al crear un rectángulo se le pasan la posición de las esquinas, y el color y el identificador son opcionales, pudiendo ponerlos en otro momento. Las funciones para manejar estos atributos son las siguientes:

void setID(int i);
void setColor(CvScalar c);

CvPoint getEsquinaIA();
CvPoint getEsquinaDB();
CvScalar getColor();
int getID();



Después, como habrá que dibujar los rectángulos también me he puesto una función para que los dibuje:

IplImage* dibujar(IplImage* img);


Y por último, unas funciones para que me digan la posición del rectángulo (el punto central), la altura y la anchura del mismo:

CvPoint damePosicion ();
int dameAlto();
int dameAncho();


Para ver que funcionaba me he puesto a probar las diferentes funcionalidades en una foto, haciendo dos rectángulos.