24.12.07

El Historial

La idea del filtro de partículas es (en nuestro caso) seguir un objeto a través de un vídeo, por lo que es útil tener una estimación puntual para cada iteración, si guardamos esa iteración podemos realizar muchos "bonitos" cálculos sobre la trayectoria del objeto.

Con esa idea y también la del mínimos esfuerzo me puse a buscar una lista enlazada para guardarlo y me encontré con la libreria estándar de c++ que tiene una interfaz genial para las listas enlazadas y nos evita tener que escribir una cada vez que la necesitamos.

El uso es de lo mas simple:

Declarar una lista:
list < CvPoint >  historial;
Insertar un objeto:
historial.push_back(punto);
Iterar en la lista:
list < CvPoint > ::const_iterator actual = historial.begin();
while(actual!=historial.end())
actual++;

Si después de cada Resampling guardamos el centroide del conjunto de partículas tendremos un historial para hacer todos los cálculos que queramos.

14.12.07

La presentacion

El jueves 13 (13/12/2007) se celebro una reunión para explicar la parte hecha del proyecto y salieron varias ideas que he estado implementando poco a poco:

  1. El filtro de partículas debería dar una "estimación" de donde esta el objeto que se esta buscando tras cada iteración, he llamado a esto Centroide, es básicamente una partícula que nos dice la mejor estimación que tiene del objeto para cada frame.
  2. Las partículas deberían incorporar una "velocidad" para poder guardar un historial de lo que han hecho en el ultimo movimiento.
  3. Para las siguientes pruebas voy a usar unas 100 partículas para que haya menos posibilidades de que ninguna caiga dentro del objeto.
  4. Ahora tengo un sintetizador de vídeo que usa opencv, cortesía de Juanjo Pantrigo.
Bueno basándome en esas ideas y aunque con no demasiado tiempo por la cantidad de trabajo que he tenido la ultima semana he preparado un filtro funcional, de momento es muy sencillo y la única función discriminante que usa es: todos los pixeles deben estar a 0 salvo los del objeto.

Como he aprendido a usar el vlc para grabar vídeos desde el escritorio ahí va una de las pruebas que he hecho al filtro:




Aunque no se vea muy bien un cuadro rojo sigue al blanco durante el vídeo de una forma bastante aproximada :P

11.12.07

Implementacion parcial

Esta semana he conseguido una implementación parcial de lo que seria el conjunto de partículas y lo he probado con una imagen fija, la idea esta conseguida pero faltan bastantes mejoras.

La operación mas básica es lanzar las partículas sobre posiciones aleatorias, existe el problema de que ninguna caiga sobre el objeto que estamos buscando, para lo que se me ocurren dos soluciones, iterar hasta que alguna caiga o lanzar un numero mas grande de partículas.


Una vez están todas las partículas iniciadas, debemos discriminar las que han caído sobre el objeto de estudio de las que no, para esto hace falta una función que nos diga que es objeto y que no, en el caso que he probado es muy fácil porque lo que no es objeto esta todo en negro, pero puede no ser tan evidente y habría que hacer por ejemplo un vector de características del objeto. Como la función puede variar y la idea es que el filtro sea reutilizable he definido la función así:

void MultFuncion(IplImage* img,float (*evaluacion)(IplImage* img, Particula p));

Se le pasa un puntero a la función que se encarga de reconocer el objeto y esta función es responsabilidad del usuario del filtro (al menos por ahora).

Lo anterior solo cambia el peso de las partículas, pero lo que necesitamos es que las partículas "mas aptas" tengan hijos de forma proporcional a su peso, esto es lo que hace Resampling, tal como explique en otro post anterior.


Nos falta aplicar la dinámica, por el momento esta definida como sigue:

void Dinamica(int desviacionMax,int ancho, int alto);

La idea es cambiarla para que sea capaz de simular diferentes distribuciones, y para poder hacer experimentos con computación basada en palabras.


No entiendes realmente algo a menos que seas capaz de explicarselo a tu abuela.

Albert Einstein

Fin de la transmisión

9.12.07

El Radar

Los radares suelen usar ondas de radio como dice la wikipedia pero nada nos impide hacernos un radar casero con el lego, la idea es montar el ultrasonido sobre un motor para que gire, en principio 180º y valla tomando mediciones, después de eso lo que hará sera convertir las coordenadas polares que obtenemos en cartesianas, trasladarlo y pintarlo en la pantalla.

Después de un rato pegándome con la pantalla LCD, decidí usar un objeto Graphics, que permite pintar mas cómodamente.

Nota: Los matemáticos usan radianes, los grados son para la bebida, al pasarle grados a una función matemática que espera radianes salen unas cosas muy raras.

La función seno y coseno del API usan la aproximación de Chebyshev-Pade, que esperan radianes.

Esta es una foto de nuestro triunfante radar:


La primera implementación tenia el problema de que no aprovechaba bien la pantalla para mostrar los resultados pero finalmente esta arreglado.

Notas rápidas:
  • Se trata de girar el motor e ir tomando medidas con el ultrasonido
  • La mínima distancia que puede girar el motor con precisión son 2 grados (en la implementación se usan 3).
  • El rango del ultrasonido esta entre 2 y 130 cm aprox.
  • obtenemos dos medidas distancia y grados girados por el motor
  • x = distancia*cos(grados_girados); y = distancia*sin(grados_girados).
  • Las coordenadas en la pantalla son raras (0,0) esta en la esquina superior izquierda.
Aquí el resultado:




1. Un robot no puede hacer daño a un ser humano o, por inacción, permitir que un ser humano sufra daño. Siempre que no se tenga en cuenta el daño cerebral al intentar programarlo.
(visto por ahi)

5.12.07

Lanzando particulas

La idea de hoy es la siguiente, refinar las partículas para poder lanzarlas de forma aleatoria sobre una imagen, hay algunas cosas que hay que tener en cuenta:

  • Las partículas deberían tener el mismo tamaño
  • No se debe dibujar ninguna partícula hasta que haya terminado el estudio de la imagen!
  • Las partículas deben estar enteramente dentro de la imagen
Aquí un resultado improvisado:

Ahora necesito encontrar una función que sea capaz de dar una medida, dada una partícula que tanto se parece su contenido a la imagen que se está buscando, que genere una "firma", algo así como una cadena MD5 que al ser comparada con la del objeto original nos de un porcentaje de concordancia.

Sigo en la búsqueda...

2.12.07

Caracterizacion del Ultrasonido


Aunque en general se dice que el sensor de ultrasonido nos devuelve la posición la realidad es que tiene algún ruido para los valores muy cercanos y muy lejanos, tenemos que contar con ese ruido para poder controlar bien al robot, así que hacen falta algunas pruebas para comprobar en que valores existe ruido y que tan preciso es el sensor.



Esta es una gráfica que representa espacio real frente al espacio medido por el sensor, el sensor es muy preciso para valores entre 2 y 125 cm, pero fuera de esos valores tiene mucho ruido, eso es debido a la forma en que funcionan los ultrasonidos.