Kamera-pose-Schätzung (OpenCV PnP)
Ich versuche, ein globaler pose-Schätzung von einem Bild von vier bestimmten Merkmalen ermittelt, die mit bekannten globalen Positionen mit meiner webcam.
Ich habe viele stackexchange Fragen und ein paar Papiere, und ich kann nicht scheinen, um eine korrekte Lösung. Die position zahlen, die ich tun, um wiederholbar sind, aber in keiner Weise Linear proportional zu der Bewegung der Kamera. FYI ich bin mit C++, OpenCV 2.1.
Unter diesem link abgebildet ist, meine Koordinatensystemen und den test verwendeten Daten unten.
% Input to solvePnP():
imagePoints = [ 481, 831; % [x, y] format
520, 504;
1114, 828;
1106, 507]
objectPoints = [0.11, 1.15, 0; % [x, y, z] format
0.11, 1.37, 0;
0.40, 1.15, 0;
0.40, 1.37, 0]
% camera intrinsics for Logitech C910
cameraMat = [1913.71011, 0.00000, 1311.03556;
0.00000, 1909.60756, 953.81594;
0.00000, 0.00000, 1.00000]
distCoeffs = [0, 0, 0, 0, 0]
% output of solvePnP():
tVec = [-0.3515;
0.8928;
0.1997]
rVec = [2.5279;
-0.09793;
0.2050]
% using Rodrigues to convert back to rotation matrix:
rMat = [0.9853, -0.1159, 0.1248;
-0.0242, -0.8206, -0.5708;
0.1686, 0.5594, -0.8114]
So weit, kann jeder sehen, nichts falsch mit diesen zahlen? Ich würde es schätzen, wenn jemand überprüfen würden Sie zum Beispiel MatLAB (code oben ist m-Datei freundlich).
Ab diesem Punkt bin ich nicht sicher, wie man die Globale pose aus rMat und tVec.
Von dem, was ich gelesen habe diese Frage, um die pose aus rMat und tVec ist einfach:
position = transpose(rMat) * tVec % matrix multiplication
Aber ich vermute aus anderen Quellen, die ich gelesen habe ist es nicht so einfach.
, Um die position der Kamera in der realen Welt-Koordinaten, was muss ich tun?
Als ich bin nicht sicher, ob dies eine Implementierung problem (aber wahrscheinlich ein Theorie-problem) ich würde gerne für jemanden, der hat die solvePnP Funktion erfolgreich in OpenCV um diese Frage zu beantworten, obwohl alle Ideen sind auch willkommen!
Danken Ihnen sehr für Ihre Zeit.
- haben Sie vergessen, inverse tVec. Also der richtige Weg, dies zu tun ist -transponieren(rMat) * tVec
Du musst angemeldet sein, um einen Kommentar abzugeben.
Löste ich dieses vor einer Weile, Entschuldigung für das Jahr Verzögerung.
In der python-OpenCV 2.1 war ich mit, und die neuere version 3.0.0-dev, ich habe überprüft, dass, um die pose der Kamera im globalen Rahmen müssen Sie:
Jetzt pos ist die position der Kamera drückt sich in der globalen Rahmens (das gleiche frame die objectPoints dargestellt sind).
R ist eine Haltung matrix-DCM, das ist eine gute form, die zum speichern der Einstellung.
Wenn Sie benötigen, Euler-Winkel dann können Sie konvertieren die DCM Eulerschen Winkel gegeben, ein XYZ-rotation verwenden:
RQdecomp3x3
Funktion in OpenCV 3.0. Ich fand, es gibt mir die gleichen Ergebnisse wie die Umwandlung, die Sie manchmal im internet zu finden (z.B. hier nghiaho.com/?page_id=846):theta_x = atan2(R.at<double>(2,1), R.at<double>(2,2)); theta_y = atan2(-R.at<double>(2,0), sqrt(pow(R.at<double>(2,1), 2) + pow(R.at<double>(2,2),2))); theta_z = atan2(R.at<double>(1,0), R.at<double>(0,0));
Wenn du meinst mit globalen pose 4x4 Kamera-pose-matrix, die verwendet werden können, in OpenGL, so mache ich es
Ich denke, durch die Koordinaten-system ist notwendig, da OpenCV und OpenGL/VTK/etc. verwenden unterschiedliche Koordinatensysteme, wie in der Abbildung dargestellt OpenGL und OpenCV Koordinatensysteme
Gut, es funktioniert auf diese Weise aber jemand vielleicht eine bessere Erklärung.
position der Kamera wäre { - transpose( r ) * t } . Das ist es.
Und Sie haben alles richtig gemacht, außer , cv::solvePnp gibt (4 x 1) - Vektor für die übersetzung, wenn ich mich Recht entsinne , Sie hätten sich zu teilen x , y , z mit der w-Koordinate.