PRÁCTICA 2: RECONSTRUCCIÓN 3D DESDE VISIÓN


Reconstrucción 3d a partir de un par estéreo


En este ejercicio de recontrucción 3d a partir de dos imágenes de un par estéreo existen 3 partes principales:

1 - Selección de puntos de interés
2 - Búsqueda de homólogos
3 - Triangulación 

Cada una de estas partes se desglosa en varios pasos que se cuentan a continuación. 

Selección de puntos de interés

Después de capturar cada una de las imágenes recibidas por cada cámara se llama a una función que encuentra los bordes de estas con Canny, aplicando primero un filtrado bilateral (filtro bilateral opencv). Para este filtrado se ponen valores altos para los sigma values (150), exgaerando el efecto del blur, eliminando detalles innecesarios para la reconstrucción 3D que únicamente introducen ruido. Por tiempos de procesado y por la calidad de los resultados obtenidos el tamaño del filtro se deja en size=5.

Después de tener los bordes de las imágenes se llama a otra función que devuelve las coordenadas de los pixeles detectados como borde, que serán nuestros puntos de interés.

Búsqueda de homólogos


Pasos para la búsqueda de homólogos. Elaboración propia.


En primer lugar las coordenadas de los puntos de interés 2D en coordenadas de imagen se pasan a coordenadas de cámara, para poder lanzar un rayo de retroproyección desde el centro óptico a través de estos. La función HAL.bakcproject devuelve un punto 3d sobre este rayo a una profundidad arbitraria, así que a partir de este se pueden tomar otros 2 puntos 3D a diferente profundidad que luego se proyectarán sobre la imagen derecha para poder trazar la linea epipolar. Así, con las funciones HAL.project('right', point3d) y HAL.opticalToGrafic('right', point2d) se consiguen las coordenadas de los puntos 2d que definen la linea epipolar en la imagen derecha. 

En el código se desarrolla también una función que permite ver el segmento que une esos dos puntos proyectados (que sería un trocito de la linea epipolar para el punto 2d de la imagen izquierda que la ha originado). Cada linea epipolar quedaría a la altura de cada uno de esos segmentos y tendría esa dirección, pero cruzaría la imagen desde el margen izquierdo al margen derecho.


segmento de la linea epipolar para cada punto de la imagen izquierda


Con esta linea epipolar ya se puede comenzar con la búsqueda de homólogos como tal, teniendo en cuenta la restricción epipolar (es decir, sabiendo que el homólogo va a estar en la linea epipolar o un poquito por encima o un poquito por debajo).

Para ello se crea una función que compara un patch centrado en un punto de interés de la imagen izquierda con el patch del mismo tamaño colocado sobre cada uno de los puntos de interés de la imagen derecha que caen en la franja epipolar. La métrica que se utiliza para comparar es la SSD, de tal forma que para cada punto de la imagen izquierda se seleccione el punto de la imagen derecha que ha dado el mínimo ssd. 

Además luego se filtran los puntos encontrados de forma que, aquellos que su ssd mínimo difiera mucho (media + 0.8*desviación típica) del resto de ssds se descartaban. 


algunas parejas de homólogos encontrados


Se observa que los homólogos se están encontrando bien aparentemente.

Triangulación


En primer lugar se hizo una prueba para traingular de forma sencilla tal y como se explica en el pdf del link recomendado desde unibotics (triangulación simple). Este método se basa en que la profundidad es directamente proporcional a la disparidad, y para poder aplicarlo es necesario saber a priori la distancia focal y la baseline (linea que une los dos centros ópticos). Para sacar la profundidad de un punto:

z = (f*b)/d, donde f es la distancia focal, b la linea base y d la disparidad entre las coordenadas horizontales del punto en ambas imagenes. Una vez se tiene esta se obtienen x e y.

Esta forma de triangular no daba buenos resultados, no sé del todo bien si porque he desarrollado mal la función o porque es un modelo demasiado simple para el problema que estamos tratando. 

En cualqueir caso he dejado la función en el código (profundidad_y_color) 
para poder comparar. Se obtenía la siguiente reconstrucción 3d:



Reconstrucción 3d resultante del primer método de triangulación simple. Muy mala calidad.


A continuación se prueba a triangular buscando el punto de distancia mínima a 2 rectas en el espacio 3d,  exigiendo  además que la distancia de ese punto a las dos rectas este por debajo de un cierto umbral para tener ese punto en cuenta a la hora de reconstruir. 


Triangulación a partir de puntos homólogos. Elaboración propia.


Con este método, la reconstrucción 3d resultante queda como se muestra en la figura siguiente. Se intuye el esqueleto del pato, la caja de cereales, Browser, las setitas pequeñas, Mario, Luigi y los cubos. Bien es cierto que se observan algunos puntos reconstruidos en zonas incorrectas (flotando sueltos en el espacio 3d) y alguno errores de reconstrucción apreciables sobre todo para los cubos amarillo y morado. 








Comentarios

Entradas populares de este blog

PRÁCTICA 1: CONTROL VISUAL.

PRÁCTICA 3: AUTOLOCALIZACIÓN VISUAL BASADA EN MARCADORES