Ir al contenido principal

Reconstruccion3D: Descripción y primeros pasos

En esta práctica se abordará el tema de la reconstrucción de puntos 3D a partir de dos cámaras calibradas. Para ello, gracias al entorno de Gazebo, contamos con un robot que incorpora un par estéreo calibrado del que se conoce su posición y separación. Al mundo de Grazebo se le han añadido una serie de objetos 3D de forma que las cámaras puedan captarlos para efectuar la reconstrucción. Así mismo, también tenemos a nuestra disposión un visor de puntos 3D a través del cual podremos ver el resultado. Al igual que en la práctica anterior, se parte de un script donde poder añadir código y una serie de librerías que facilitarán muchas operaciones.


Para efectuar una reconstrucción es necesario conocer la posición que ocupa el punto 3D en las dos imágenes. Obviamente no se dispone de dicha información, por lo que hay que escoger un punto en una de las imágenes y buscar su homólogo en la otra. Es importante escoger bien los puntos, ya que cuanta más textura contengan más fácil será encontrarlos en la otra imagen. En principio con realizar un simple filtro de bordes se podrían obtener puntos suficientes para efectuar una buena reconstrucción. Sin embargo, buscar cada uno de los puntos por toda la otra imagen conlleva un coste computacional muy alto. Es necesario acotar la búsqueda de alguna forma. 



Una de las principales técnicas empleadas para la reducción del tiempo de matching es el cálculo de la línea epipolar. En reconstrucción 3D, la línea epipolar de un pixel es la recta resultante de la proyección en la otra imagen de todos los posibles puntos 3D que proyectan en el pixel elegido. Por tanto, el homólogo de un punto en la imagen A se encuentra siempre a lo largo de esa línea epipolar en la imagen B. Para calcularla es necesario conocer al menos dos puntos 3D que se encuentren en el rayo de retropoyección del pixel. Este rayo es el formado por la posición del pixel en el mundo y el punto focal de la cámara. Si proyectamos de nuevo esos dos puntos en el plano de la otra imagen podremos unirlos para obtener la línea epipolar.

La librería de pyProgeo nos facilita mucho estas acciones. Con dos simples funciones, 'graficToOptical' y 'backproject' se puede hacer un cambio de coordenadas necesario y retropoyectar el punto. La instrucción 'backproject' sólo nos devuelve un punto en 3D que pertenece al rayo, pero uniendo con la posición de la cámara podemos formar una recta, de donde sacar todos los puntos que queramos.




A continuación se puede proyectar los puntos del rayo en la otra imagen, realizando el proceso inverso con las funciones 'project' y 'opticalToGrafic'. Es posible que alguno de los puntos no caigan dentro de la imagen, pero no pasa nada porque están en el mismo plano. Con proyectar dos es suficiente para formar la epipolar. Una vez los dos puntos estén proyectados, se puede extraer de ellos la ecuación de la recta que los une, de la forma y = x*m + b.



 Debido a que las dos cámaras se encuentran a la misma altura, la pendiente de la recta debería de ser cero. He podido comprobar que efectivamente obtengo un 0 casi siempre, aunque con algunos decimales, por lo que puedo decir que de momento voy por el buen camino. En la próximas entradas del blog continuaré con esta práctica, buscando la forma de encontrar el homólogo del punto inicial en la epipolar que acabo de calcular.

Comentarios

Entradas populares de este blog

Reconstruccion3D: emparejamiento de puntos y cálculo del punto 3D

Como se comentaba en la entrada anterior, una vez tenemos la línea epipolar calculada podemos buscar el punto homólogo correspondiente. Para ello es necesario establecer una métrica para comparar ambos puntos. Tomar simplemente los valores RGB de los puntos no parece la forma más fiable, puesto que puede ser que haya más de un punto similar. Lo ideal sería tomar una región o parche centrada en los puntos. De esta forma la comparación será mucho más fiable y discriminante a lo largo de la epipolar. Es necesario establecer una métrica para comparar ambos parches. Una de las más sencillas es el MSE (Mean Square Error), que promedia el resultado de restar los valores en escala de grises de cada uno de los elementos del parche. Existen otras métricas como comparar histogramas o la correlación, pero considero que es mejor comenzar con la más simple. Como se trata de una diferencia, hay que calcular el MSE entre todas las posibles combinaciones a lo largo de la epipolar. El punto...

Reconstrucción3D: resultados

Tras describir cual ha sido el procedimiento que he seguido durante la práctica, es hora de analizar los resultos. Para visualizar mejor los puntos he decidido utilizar un visor de puntos 3D externo, Meshlab. He notado que a medida que se van pintando los puntos obtenidos en el visor que se adjunta con Gazebo el tiempo de ejecución aumento. Por ello he optado por ir almacenando los puntos en una lista para finalmente guardarlos en un fichero .obj. De esta manera, una vez finalizada la ejecución, es posible cargar el archivo en el visualizador y y observar el resultado de la reconstrucción. Debido a un fallo de programación la reconstrucción salía con los contornos bien dibujados pero en un plano 2D dentro del mundo. Después de arreglar ese pequeño error en una condición, he podido representar los bordes de las figuras en tres dimensiones. Sin embargo, el resultado obtenido tampoco era del todo bueno. Era posible intuir alguna de las figuras pero realmente no estaba bien. Revisando el...

FollowLine: diseño con un PID

En esta siguiente aproximación me he centrado en introducir el controlador PID en el sistema. Tras estudiar su funcionamiento teórico me he decantado por crear una nueva clase que contenga las tres constantes fijas: Kp, Kd y Ki, además de un método que compute la fórmula y devuelva el resultado. Las constantes anteriormente mencionadas no tienen ningún tipo de valor por defecto, dependen mucho del problema a tener en cuenta. Por ello, he obtenido sus valores óptimos mediante prueba y error. Realmente es un trabajo costoso y que toma tiempo, pero si se hece bien el resultado puede ser muy bueno. Para este caso en concreto, he comprobado que apenas se producen cambios en el comportamiento del robot cuando omito la constante Ki, por lo que la fijaré a 0. No entiendo bien porque parece funcionar mejor sin ella, pero realmente lo hace. También he observado que cuando Kd es mucho más grande que Kp el robot sigue las rectas increiblemente, sin oscilar, pero es poco estable en curvas. Sin e...