Ich versuche, 3D-Koordinaten von mehreren Punkten im Raum zu bekommen, aber ich bekomme ungerade Ergebnisse von beiden undistortPoints()
und triangulatePoints()
.OpenCV undistortPoints und triangulatePoint geben ungerade Ergebnisse (Stereo)
Da beide Kameras unterschiedliche Auflösungen haben, ich sie einzeln kalibriert habe, erhalten RMS-Fehler von 0,34
und 0,43
, verwendet dann stereoCalibrate()
mehr Matrizen zu erhalten, bekam einen RMS von 0,708
, und verwendet dann stereoRectify()
verbleibenden Matrizen zu erhalten. Damit habe ich die Arbeit an den gesammelten Koordinaten begonnen, aber ich bekomme seltsame Ergebnisse.
beispielsweise eingegeben wird: (935, 262)
und der Ausgang ist undistortPoints()
(1228.709125, 342.79841)
für einen Punkt, während für den anderen und es ist (934, 176)
(1227.9016, 292.4686)
sind. Das ist komisch, weil diese beiden Punkte sehr nah an der Bildmitte liegen, wo Verzerrungen am kleinsten sind. Ich habe nicht erwartet, dass es sie um 300 Pixel bewegt.
Bei der Übergabe an traingulatePoints()
werden die Ergebnisse noch seltsamer - ich habe den Abstand zwischen drei Punkten im wirklichen Leben (mit einem Lineal) gemessen und den Abstand zwischen den Pixeln auf jedem Bild berechnet. Da diesmal die Punkte auf einer ziemlich flachen Ebene lagen, stimmten diese beiden Längen (Pixel und Real) überein, wie in | AB |/| BC | in beiden Fällen war um 4/9. Aber triangulatePoints()
gibt mir Ergebnisse von den Schienen, mit | AB |/| BC | 3/2 oder 4/2 sein.
Dies ist mein Code:
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;
Die Winkel zwischen den Punkten sind ein bisschen sorta gut, aber in der Regel nicht:
`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`
Ich habe versucht undistort()
auf den gesamten Rahmen zu verwenden, aber bekam Ergebnisse genauso seltsam. Der Abstand zwischen B und C Punkte sollten so ziemlich unverändert zu allen Zeiten, und doch ist das, was ich bekommen:
7502,42
4876,46
3230,13
2740,67
2239,95
Frame für Frame.
Pixelabstand (unten) vs realem Abstand (oben) - sollte sehr ähnlich sein:
Winkel:
Auch sollten nicht beide undistortPoints()
und undistort()
das gleiche geben Ergebnisse (weitere Videos hier)?
Können Sie den für die Kalibrierung verwendeten Code und einige Beispielbilder für den Triangulationsteil hinzufügen? – AldurDisciple
Das könnte schwierig sein ... es gibt eine Menge davon. Ich werde versuchen, morgen nur relevante Teile zu posten – Petersaber
Das scheint wie eine verstimmte Kalibrierung - wenn Sie 'unverzerrt' auf einem Bild von nur einer Kamera verwenden (die Stereokalibrierung ignorierend), funktioniert es? Sie sollten in der Lage sein, die Eigen- schaften jeder Kamera einzeln zu kalibrieren und sicherzustellen, dass sie in Ordnung sind, und diese Werte dann als anfängliche Schätzung an die Stereokalibrierung übergeben, indem Sie das Flag "CV_CALIB_USE_INTRINSIC_GUESS" verwenden. – abarry