Bueno, realmente el concepto es más amplio de lo que se expresa en el título. La tarea sería mas bien convertir los puntos que delimitan el suelo, expresados mediante coordenadas 2D (y en un sistema de referencia de la imagen tomada por la cámara), a puntos 3D en el sistema de referencia absoluto (en el que se define la posición del robot, ..).
Aquí es donde entra en juego la biblioteca Progeo.
La idea es que, a través de los parámetros de la cámara, dado un pixel, se pueda calcular su correspondiente punto en 3D (con respecto a la cámara).
Aquí tenéis la receta que explica cómo funciona y qué hay que hacer para utilizar esta biblioteca. A lo que añado modificar el Makefile para que al compilar enlace con el «Progeo.h».
El primer paso previo al uso de progeo es calibrar la cámara, esto es, pasarle todos los parámetros correspondientes de la cámara (extrínsecos e intrinsecos) necesarios para realizar las conversiones. Estos (en la versión 4.2.1 de jde) son:
- HPoint3D position; /* camera 3d position in mm */
- HPoint3D foa; /* camera 3d focus of attention in mm */
- float roll; /* camera roll position angle in rads */
- float fdist; /* focus distance in mm*/
- float u0,v0; /* pixels */
El primero, position, coincide con la ubicación del robot en sus componentes X e Y, y la Z indicando la altura a la que se encuentra la cámara sobre le robot. Hay que tener en cuenta que estas coordenadas serán relativas al robot, y por tanto nuestras X e Y serán 0.0 y 0.0.
El foa va a indicar la orientación de la cámara, es decir, hacia donde está mirando. Para ello hay que indicarle un punto 3D. En nuestro caso, la cámara mira hacia delante del robot y por ello un punto válido podría ser (100.0 0.0 200.0), o cualquier punto que se encuentre delante de él. roll será 0, dado que la cámara no estará inclinada con respecto a la vertical.
Por último, para calcular fdist, u0 y v0, seguiremos lo expuesto en la receta anterior de progeo.
Para aplicar todos estos parámetros tendremos que utilizar la función update_camera_matrix, y con esto ya estamos preparados para utilizar progeo.
Como podéis comprobar, esta biblioteca se compone principalmente de dos funciones: project y backproject. En nuestro caso nos interesa la segunda, backproject, con la que, proporcionándole un punto de la imagen (un pixel en 2D) obtendremos la proyección en 3D de este.
Previamente, el punto 2D perteneciente al pixel de la imagen tendremos que convertirlo de gráfico a óptico (Xóptica=239-Ygráfica e Yóptica=Xgráfica).
Project trabaja en el sistema de referencia solidario al robot (relativo). Esto es importante a tener en cuenta, dado que el punto que obtengamos tendrá como origen de coordenadas la posición del robot.
Una vez que obtenemos el punto con el backproject tendremos que construir el rayo proyectado (recta formada por la posición de la cámara y el punto obtenido) y calcular su intersección con el suelo (el plano con la componente Z=0).
Por último, traduciremos el punto obtenido (sistema de referencia relativo al robot) al sistema de referencia absoluto del mundo, para lo cual utilizaremos la función «relativas2absolutas».
Con todo esto habremos calculado, para cada pixel «frontera» de la imagen (aquellos que nos representan el suelo) su correspondiente punto en el mundo y estaremos preparados para comenzar a segmentar…