c++ opencv triangulation

c++ - OpenCV triangulatePoints la destreza



triangulation (1)

El sistema de coordenadas OpenCV es diestro, la respuesta here brinda un ejemplo ilustrativo sobre el sistema de cámara OpenCV. Supongo que la confusión es sobre rvec y tvec , este último no da la traducción de la cámara, pero apunta al origen mundial. La primera respuesta here explica basado en un ejemplo. Puede obtener la matriz de proyección real a partir de la salida de solvePnP mediante una simple multiplicación de matrices, los detalles están here en la primera respuesta.

Tengo dos cámaras unidas rígidamente una al lado de la otra mirando en direcciones paralelas.

Matriz de proyección para cámara izquierda

Matriz de proyección para la cámara derecha

Cuando realizo triangulatePoints en los dos vectores de los puntos correspondientes, obtengo la colección de puntos en el espacio 3D. Todos los puntos en el espacio 3D tienen una coordenada Z negativa .

Entonces, para llegar al fondo de esto ...

Mi suposición era que OpenCV usa el sistema de coordenadas de la mano derecha.

El recordatorio de la destreza:

Supongo que la orientación inicial de cada cámara se dirige en la dirección positiva del eje Z.

Entonces, al usar las matrices de proyección como las que presenté al principio, supongo que las cámaras están posicionadas en el espacio así:

Esta suposición está en conflicto con lo que observo cuando obtengo valores negativos de Z para los puntos traingulados. La única explicación que puedo pensar es que OpenCV de hecho usa el sistema de coordenadas de la mano izquierda. Entonces, con las matrices de proyección que dije al principio, así es como las cámaras están posicionadas en el espacio:

Esto indicaría que mi cámara izquierda en esta situación no está en el lado izquierdo . Y es por eso que estoy obteniendo profundidad negativa para los puntos.

Además, si intento combinar triangulatePoints con solvePnP tengo problemas.

Uso la salida de triangulatePoints como una entrada para solvePnP . Espero obtener las coordenadas de la cámara cerca del origen del sistema de coordenadas 3D. Espero que la posición calculada de la cámara coincida con las matrices de proyección utilizadas al principio. Pero esto no está sucediendo. Obtengo algunos resultados totalmente desordenados, faltando los valores esperados por más de 10 veces la longitud de línea base.

Ejemplo

Este ejemplo es una representación más completa del problema que lo que se indicó anteriormente.

points3D

Here está el código para generar estos puntos.

Movin, configurando la cámara A y la cámara D ...

Mat cameraMatrix = (Mat_<double>(3, 3) << 716.731, 0, 660.749, 0, 716.731, 360.754, 0, 0, 1); Mat distCoeffs = (Mat_<double>(5, 1) << 0, 0, 0, 0, 0); Mat rotation_a = Mat::eye(3, 3, CV_64F); // no rotation Mat translation_a = (Mat_<double>(3, 1) << 0, 0, 0); // no translation Mat rt_a; hconcat(rotation_a, translation_a, rt_a); Mat projectionMatrix_a = cameraMatrix * rt_a; Mat rotation_d = (Mat_<double>(3, 1) << 0, CV_PI / 6.0, 0); // 30° rotation about Y axis Rodrigues(rotation_d, rotation_d); // convert to 3x3 matrix Mat translation_d = (Mat_<double>(3, 1) << 100, 0, 0); Mat rt_d; hconcat(rotation_d, translation_d, rt_d); Mat projectionMatrix_d = cameraMatrix * rt_d;

¿Cuáles son las coordenadas de píxeles de los points3D cuando se observan por las proyecciones A y D ?

Mat points2D_a = projectionMatrix_a * points3D; Mat points2D_d = projectionMatrix_d * points3D;

Los puse en vectores:

vector<Point2f> points2Dvector_a, points2Dvector_d;

Después de eso, genero los puntos 3D nuevamente.

Mat points3DHomogeneous; triangulatePoints(projectionMatrix_a, projectionMatrix_d, points2Dvector_a, points2Dvector_d, points3DHomogeneous); Mat triangulatedPoints3D; transpose(points3DHomogeneous, triangulatedPoints3D); convertPointsFromHomogeneous(triangulatedPoints3D, triangulatedPoints3D);

Ahora, triangulatedPoints3D comienza así:

y son idénticos a points3D .

Y luego el último paso.

Mat rvec, tvec; solvePnP(triangulatedPoints3D, points2Dvector_d, cameraMatrix, distCoeffs, rvec, tvec);

rvec y tvec resultantes:

Tenía la esperanza de obtener algo más similar a las transformaciones utilizadas en la creación de projectionMatrix_d , es decir, la traducción de (100, 0, 0) y la rotación de 30 ° alrededor del eje Y.

Si uso transformaciones invertidas al crear una matriz de proyección, como esta:

Mat rotation_d = (Mat_<double>(3, 1) << 0, CV_PI / 6.0, 0); // 30° rotation about Y axis Rodrigues(-rotation_d, rotation_d); // NEGATIVE ROTATION Mat translation_d = (Mat_<double>(3, 1) << 100, 0, 0); Mat rt_d; hconcat(rotation_d, -translation_d, rt_d); // NEGATIVE TRANSLATION Mat projectionMatrix_d = cameraMatrix * rt_d;

entonces obtengo rvec y tvec :

Y eso tiene mucho más sentido. Pero luego cambio la transformación de inicio para que la rotación sea negativa CV_PI / 6.0 -> -CV_PI / 6.0 y los rvec y tvec resultantes son:

Me gustaría encontrar una explicación de por qué está sucediendo esto. ¿Por qué estoy obteniendo resultados tan extraños de solvePnP ?