Ich habe 5 Kameramatrizen berechnet ( c1, ... c5
), Kameramatrizen werden berechnet, indem ein 3D-Objekt an 5 verschiedenen Positionen platziert wird und für jede Position habe ich die Kameramatrix berechnet (und die Kamera ist konstant). Die Kameramatrix wird mit der SVD-Methode berechnet.
Jetzt möchte ich die Bündelanpassung in opencv
verwenden, um eine optimale Kameramatrix zu erhalten.
Ich fand die Dokumentation hier
Aber die Dokumentation ist nicht klar und ich konnte auch keinen Beispielcode finden.
Kann mir jemand erklären, wie ich die opencv Bundle-Anpassung nutzen kann, um optimal camera matrix
zu bekommen?
Siehe den Beispielcode auf Seite 155 von Bildverarbeitung mit OpenCV lernen . Etwas wie das:
%Vor%Wenn Sie MCVE bereitstellen, ist es einfacher zu helfen.
Bearbeiten: Gegeben, Sie haben 5 Schätzungen der gleichen K-Matrix. Die einfachste Methode besteht darin, einfach Ihre 5 Schätzungen zu mitteln, um ein genaueres K zu erhalten. Unter einigen milden Annahmen wird dies eine optimale Schätzung sein. Wenn sich die Reprojektionsfehler stark unterscheiden, können Sie einen gewichteten Durchschnitt berechnen.
Meine Antwort setzt voraus, dass Sie ein bestimmtes 3D-Objekt verwenden, dessen Abmessungen genau sind, um die inneren Parameter von einer Kamera aus mehreren Bildern des Objekts. Angesichts Ihres Kommentars zu @firefants Antwort denke ich, dass dies auf Ihre Frage zutrifft.
Der Begriff Kameramatrix ist sehr vage und kann auf verschiedene Arten verstanden werden:
Wie Sie sagen, dass Sie mehrere Bilder haben, aber Sie wollen eine einzige Kameramatrix, denke ich, dass Sie über die intrinsische Kameramatrix K sprechen.
Bündeleinstellung ist eine Technik, die verwendet wird, um ein allgemeineres Problem als die Kamerakalibrierung zu lösen, wobei sowohl die extrinsischen Kameraparameter (d. h. 3D-Orientierungen und -Positionen) als auch die 3D-Landmarken (z. B. 3D-Punkte) unbekannt sind. Wie @fireant bemerkt, ist es auch möglich, intrinsische Kameraparameter in diese globale Gelenkoptimierung einzubeziehen. Andererseits wird bei der Kamerakalibrierung davon ausgegangen, dass die 3D-Orientierungspunkte von einer einzelnen Kamera in mehreren Bildern erkannt und beobachtet werden. Daher wird für jedes Bild ein einzelner Satz intrinsischer Kameraparameter und eine Kamerapose optimiert.
Es ist zu verstehen, dass allgemeinere Optimierungsprobleme mehr Variablen betreffen, die optimiert werden müssen, und es daher schwieriger ist, sie gut zu beschränken. Wenn sie nicht gut eingeschränkt sind, werden sie Ihre Variablen auf eine Weise optimieren, die tatsächlich den globalen Fehler verringert, aber das entspricht nicht einer Lösung Ihres wirklichen Problems. Aus diesem Grund sollten Sie bei der Verwendung eines gemeinsamen Optimierungsalgorithmus immer versuchen, die Anzahl der zu optimierenden Variablen zu reduzieren.
Im Fall der VS-Kamerakalibrierung für Bundle Adjustment sollten Sie Bundle Adjustment nur verwenden, wenn Sie keine genaue Vorstellung der Positionen der 3D-Landmarken haben. Auch dann ist es wahrscheinlich eine bessere Idee, die Probleme zu entkoppeln, zum Beispiel durch vorheriges Kalibrieren des 3D-Objekts. Wenn Sie eine genaue Vorstellung von den Positionen der 3D-Landmarken haben, sollten diese nicht als zu optimierende Variablen betrachtet werden. Daher sollten Sie die Kamera-Kalibrierungstechnik verwenden.
Sie sagen, dass Sie mehrere ungenaue Schätzungen der Kameramatrix K haben und eine gemeinsame Optimierung durchführen möchten, um einen genaueren zu erhalten. Das Problem besteht darin, dass Sie, da Sie eine einzelne Kameramatrix schätzen möchten, den gemeinsamen Optimierungsalgorithmus mit nur einer ersten Schätzung versehen müssen.
Was Sie tun könnten, um Ihre mehreren ungefähren Schätzungen weiterhin zu verwenden, ist es, als erste Schätzung für den Optimierungsalgorithmus denjenigen auszuwählen, der der wahren Lösung am nächsten ist. Zu diesem Zweck können Sie mehrere heuristische Kriterien verwenden. Zum Beispiel können Sie den mit dem minimalen Reprojektionsfehler assoziierten auswählen, oder Sie können den mit dem Bild assoziierten verwenden, bei dem das Kalibrierungsobjekt am größten ist, usw.
Allerdings wird es wahrscheinlich bei der endgültigen Schätzung der Kameramatrix keinen großen Unterschied machen.
Angenommen, Sie haben ein Kalibrierobjekt mit charakteristischen Punkten. Es kann ein Standard-2D-Schachbrett oder ein asymmetrisches Kreisraster oder ein kalibriertes 3D-Objekt sein. Und angenommen, Sie haben eine Möglichkeit entwickelt, dieses Kalibrierungsobjekt in einem Bild zu erkennen (z. B. einen benutzerdefinierten Feature-Detektor oder ein Werkzeug, um die Position des Objekts manuell zu bestimmen). Dann können Sie einen Vektor allObjectPoints
definieren, der die 3D-Punkte auf dem Objekt enthält, die erkannt werden können. Dann können Sie für jedes Bild i
einen Vektor imagePoints_i
der erkannten 2D-Punkte als Beobachtungen einiger der 3D-Punkte des Objekts bestimmen (beachten Sie, dass einige Objektpunkte möglicherweise verdeckt sind, daher weniger Elemente als in allObjectPoints
). Da alle Objektpunkte identifizierbar sind (entweder direkt oder durch Argumentation), können Sie den Vektor objectPoints_i
bestimmen, der die 3D-Punkte des Objekts enthält, die tatsächlich in image i
beobachtet und konsistent mit imagePoints_i
geordnet sind.
Dann stapeln Sie alle objectPoints_i
Vektoren in einem großen Vektor von Vektoren objectPoints
. Ähnlich stapeln Sie alle imagePoints_i
Vektoren in einem großen Vektor von Vektoren imagePoints
. Sie können dann den Aufruf von calibrateCamera
mit dem Flag CV_CALIB_USE_INTRINSIC_GUESS
ausführen, um anzugeben, dass der Optimierungsalgorithmus den von Ihnen angegebenen Anfangswert verwenden soll.
Tags und Links opencv camera mathematical-optimization camera-calibration