domingo, 19 de abril de 2015

Pica 1

El objetivo de esta parte de la reconstrucción es encontrar en la imagen derecha la correspondencia del punto que seleccionamos de forma manual en la imagen izquierda.

Los pasos seguidos para cumplir el objetivo son los siguientes:

- Seleccionar en la imagen de la cámara izquierda el punto que se quiere corresponder.

- Se almacena un parche de 7x7 píxeles centrado en punto seleccionado.

- Retroproyectamos el punto 2D.

- Calculamos dos puntos 3D utilizando la ecuación paramétrica del rayo de retroproyección.

- Se proyectan los puntos calculados en el paso anterior en la imagen de la derecha.

- Se calcula la ecuación de la linea epipolar utilizando los dos puntos proyectados.

- Se comparan los parches que se obtienen a lo largo de la línea epipolar con el parche almacenado. La comparación se realiza mediante diferencia de cuadrados, por lo que el parche más parecido al patrón es el que menor valor devuelva.

- Una vez obtenida la correspondencia en la imagen derecha, se retroproyecta igual que se hizo en el Pica 2 y se obtiene el punto 3D intersecando los rayos.

A continuación se muestra un video con los resultados obtenidos:


sábado, 18 de abril de 2015

Pica 2

Como ya se ha comentado anteriormente, nuestro primer objetivo es conseguir realizar con éxito la tarea Pica 2.

En esta primera iteración de la solución global el usuario tiene que seleccionar de forma manual un punto de una de las imágenes y su correspondencia en la otra. En nuestro caso las imágenes tienen el siguiente aspecto:

Una vez que se han seleccionado el mismo punto en las dos imágenes, se hace la retroproyección de estos puntos. Al hacer esto obtendremos un rayo que pasa por el centro óptico de la cámara y por el punto 3D que estamos buscando.

En la imagen se observan los rayos de retroproyección generados.

Por último, hay que calcular el punto en el que los rayos de retroproyección se cortan, ya que es ese el punto 3D que ha generado ambos rayos. En la práctica, es muy difícil que estos rayos se corten, ya que la calibración de las cámaras no es exacta y tampoco es totalmente precisa la selección de la correspondencia de los puntos en ambas imágenes. Por lo tanto, es necesario obtener los puntos de dichos rayos que minimizan la distancia entre ellos, y una vez obtenidos, calcular el punto medio del vector que los une.

Pic_d2lines
En nuestro caso los rayos serian P y Q; y los puntos que minimizan la distancia entre los rayos serian P(Sc) y Q(Tc).

Para realizar estos calculos se ha utilizado las ecuaciones paramétricas de las rectas y se ha adaptado el algoritmo que se explica en el siguiente enlace: http://geomalgorithms.com/a07-_distance.html

Una vez implementado el cálculo del punto que minimiza la distancia, este es el resultado:
Se observa que donde los rayos "se cortan" se ha dibujado una esfera de color verde.

Práctica 2: Reconstrucción 3D

En esta nueva serie de entradas se explicará el objetivo de la práctica y los pasos que se han seguido para desarrollar la solución.

El objetivo es reconstruir un mundo 3D compuesto por una colección de objetos utilizando un par de cámaras montadas sobre un robot.

Como es un problema complejo, se va a dividir en 3 tareas que se abordarán de forma incremental:

- Pica 2: El objetivo de esta tarea es seleccionar mediante clicks de ratón un píxel en una de las imágenes y su correspondencia en la otra imagen. Una vez conocidas las correspodencias hay que seleccionar el punto de cruce de los rayos retroproyectados, o en su defecto, el punto que minimiza la distancia entre ellos.

- Pica 1: Apoyandonos en el código del punto anterior, el objetivo ahora es seleccionar un punto en una de las imágenes y elegir de forma automática la correspondencia en la otra imagen. Para ello se empleará la restricción epipolar.

- Pica 0: Por último, se implementará el código necesario para realizar la reconstrucción del mundo 3D de forma automática, seleccionando los puntos de interés de ambas imágenes.

jueves, 2 de abril de 2015

Vuelta final

El siguiente paso es adecuar la velocidad de desplazamiento del robot a la carretera que se observa en la imagen.

Para ello se le asigna una velocidad por defecto al robot, que varia de forma fija dependiendo del número de píxeles de carretera que se observan en cada una de las alturas definidas. Para el caso de la línea superior, también se tiene en cuenta la posición del centro observado de la carretera además de eliminar una franja a cada lado de la imagen para que no interfieran las zonas de carretera que se observan que no pertenecen al trazado donde se encuentra el robot.

Debido a que al aumentar la velocidad de desplazamiento el robot adquiere una mayor inercia, se han tenido que ajustar los valores del controlador PID que controla el giro para que el robot se mantenga en la pista. También se ha decidido que si el robot pierde de vista en algún momento la carretera gire en el mismo sentido y velocidad que en el último instante en el que vió la pista.

Con todo esto se ha conseguido dar una vuelta completa al circuito de Montmelo en 2:49 medido con un cronómetro, aunque el vídeo indique que la duración es mayor.


Primera vuelta al circuito

Como se comentó en la entrada anterior, ya tenemos la referencia de dónde se tiene que encontrar la carretera en la imagen en el caso de que nuestro robot se encuentre en la posición correcta.

Para calcular el error lo que se hace es calcular el centro de la carretera en la imagen que recibe el robot en cada una de las alturas que hemos definido y restarle la posición de referencia.

Con el fin de simplificar lo máximo posible el controlador y después de realizar diferentes pruebas, para calcular el giro que tiene que realizar el robot únicamente es necesario utilizar la información que nos proporciona el error de la línea central de la imagen.

El objetivo que se ha fijado en la primera prueba es comprobar que el funcionamiento del controlador encargado del giro se comporta de forma correcta. Para ello se ha fijado la velocidad del robot de forma constante a 20 (para no tener que ocuparnos tanto de la velocidad como del giro en la primera aproximación de la solución), y se ha conseguido completar una vuelta al circuito en unos 9 minutos.




Calculo del error

Después de hacer pruebas, se ha realizado una optimización muy sencilla a la hora de aplicar el filtro HSV a la imagen capturada por el robot.

Dicha optimización consiste en detectar donde se encuentra la línea del horizonte del mundo en la imagen, ya que la parte de la imagen que nos interesa (la carretera) se encuentra en el suelo y no va a encontrarse en ningún píxel superior del horizonte.


Una vez que hemos localizado la altura de esta línea, únicamente aplicamos el filtro HSV a partir de esa altura, lo que nos ahorra aproximadamente la mitad de los píxeles de la imagen.


El siguiente paso consiste en estimar el error que se observa en la imagen de la carretera que observa el robot comparado con algún tipo de referencia. Dicha referencia la encontramos colocando el robot en la recta principal del circuito. En esta posición, el robot se encuentra en la posición ideal, por lo que el error es 0. La referencia la tomamos calculando en que posición se encuentra el centro de la carretera en la imagen.


Debido a que la línea que encontramos nos proporciona más información de la necesaria para nuestro propósito, almacenamos la posición del la línea a 5 alturas diferentes en la imagen. Con esta información ya podemos calcular el error para implementar el controlador PID.