c++ opencv triangulation

c++ - OpenCV undistortPoints y triangulatePoint dan resultados extraños(estéreo)



triangulation (1)

Estoy tratando de obtener coordenadas 3D de varios puntos en el espacio, pero obtengo resultados extraños tanto de undistortPoints() como triangulatePoints() .

Como ambas cámaras tienen una resolución diferente, las stereoCalibrate() por separado, obtuve errores RMS de 0,34 y 0,43 , luego usé stereoCalibrate() para obtener más matrices, obtuve un RMS de 0,708 y luego utilicé stereoRectify() para obtener matrices restantes Con eso en la mano, comencé a trabajar en las coordenadas reunidas, pero obtengo resultados extraños.

Por ejemplo, la entrada es: (935, 262) , y la salida (1228.709125, 342.79841) undistortPoints() es (1228.709125, 342.79841) para un punto, mientras que para otro es (934, 176) y (1227.9016, 292.4686) respectivamente. Lo cual es extraño, porque ambos puntos están muy cerca del centro del cuadro, donde las distorsiones son las más pequeñas. No esperaba que los moviera 300 píxeles.

Cuando se pasa a traingulatePoints() , los resultados se vuelven aún más extraños: he medido la distancia entre tres puntos en la vida real (con una regla) y he calculado la distancia entre píxeles en cada imagen. Como esta vez los puntos estaban en un plano bastante plano, estas dos longitudes (píxel y real) coincidían, como en | AB | / | BC | en ambos casos fue alrededor de 4/9. Sin embargo, triangulatePoints() me da resultados fuera de los rieles, con | AB | / | BC | siendo 3/2 o 4/2.

Este es mi código:

double pointsBok[2] = { bokList[j].toFloat()+xBok/2, bokList[j+1].toFloat()+yBok/2 }; cv::Mat imgPointsBokProper = cv::Mat(1,1, CV_64FC2, pointsBok); double pointsTyl[2] = { tylList[j].toFloat()+xTyl/2, tylList[j+1].toFloat()+yTyl/2 }; //cv::Mat imgPointsTyl = cv::Mat(2,1, CV_64FC1, pointsTyl); cv::Mat imgPointsTylProper = cv::Mat(1,1, CV_64FC2, pointsTyl); cv::undistortPoints(imgPointsBokProper, imgPointsBokProper, intrinsicOne, distCoeffsOne, R1, P1); cv::undistortPoints(imgPointsTylProper, imgPointsTylProper, intrinsicTwo, distCoeffsTwo, R2, P2); cv::triangulatePoints(P1, P2, imgWutBok, imgWutTyl, point4D); double wResult = point4D.at<double>(3,0); double realX = point4D.at<double>(0,0)/wResult; double realY = point4D.at<double>(1,0)/wResult; double realZ = point4D.at<double>(2,0)/wResult;

Los ángulos entre los puntos son bastante buenos, pero generalmente no:

`7,16816 168,389 4,44275` vs `5,85232 170,422 3,72561` (degrees) `8,44743 166,835 4,71715` vs `12,4064 158,132 9,46158` `9,34182 165,388 5,26994` vs `19,0785 150,883 10,0389`

Intenté usar undistort() en todo el marco, pero obtuve resultados igual de extraños. La distancia entre los puntos B y C no debería cambiar en todo momento, y sin embargo, esto es lo que obtengo:

7502,42 4876,46 3230,13 2740,67 2239,95

Cuadro por cuadro.

Distancia de píxeles (abajo) vs distancia real (arriba): debe ser muy similar:

Ángulo:

Además, ¿no deberían ambos undistortPoints() y undistort() dar los mismos resultados (otro conjunto de videos aquí)?


La función cv :: undistort realiza la no distorsión y la reproyección de una vez. Realiza la siguiente lista de operaciones:

  1. deshacer la proyección de la cámara (multiplicación con el inverso de la matriz de la cámara)
  2. aplicar el modelo de distorsión para deshacer la distorsión
  3. rotar por la matriz de rotación proporcionada R1 / R2
  4. el proyecto apunta a la imagen utilizando la matriz de proyección P1 / P2 proporcionada

Si pasa las matrices R1, P1 resp. R2, P2 de cv :: stereoCalibrate (), los puntos de entrada no se distorsionarán y rectificarán. La rectificación significa que las imágenes se transforman de tal manera que los puntos correspondientes tienen la misma coordenada y. No existe una solución única para la rectificación de imágenes, ya que puede aplicar cualquier traducción o escala a ambas imágenes, sin cambiar la alineación de los puntos correspondientes. Dicho esto, cv :: stereoCalibrate () puede cambiar bastante el centro de proyección (por ejemplo, 300 píxeles). Si desea una distorsión pura, puede pasar una Identity Matrix (en lugar de R1) y la cámara original Matrix K (en lugar de P1). Esto debería conducir a coordenadas de píxeles similares a las originales.