Verwendung der opencv Bundle-Anpassung

9

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?

    
Deepak 13.07.2016, 18:17
quelle

2 Antworten

8

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.

    
fireant 26.07.2016 21:59
quelle
5

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.

Kurzer Hinweis zu den Bedeutungen von 'Kameramatrix'

Der Begriff Kameramatrix ist sehr vage und kann auf verschiedene Arten verstanden werden:

  • Die Kamerapose T = [R | t], auch extrinsische Kameraparameter genannt.
  • Die intrinsische Kameramatrix K = [fx, s, cx; 0, fy, cy; 0, 0, 1].
  • Die Kameraprojektionsmatrix P = K. [R | t].

Wie Sie sagen, dass Sie mehrere Bilder haben, aber Sie wollen eine einzige Kameramatrix, denke ich, dass Sie über die intrinsische Kameramatrix K sprechen.

Warum sollten Sie Bundle Adjustment nicht verwenden

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.

Anfangsschätzung für die Optimierung

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.

Verwendung von 'calibrateCamera' für diese Aufgabe

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.

    
AldurDisciple 27.07.2016 08:12
quelle