Kameraposenschätzung aus Homographie oder mit der Funktion solvePnP ()

8

Ich versuche eine statische Augmented-Reality-Szene über einem Foto mit 4 definierten Übereinstimmungen zwischen koplanaren Punkten in einer Ebene und einem Bild zu erstellen.

Hier ist ein Schritt für Schritt:

  1. Der Benutzer fügt ein Bild mithilfe der Kamera des Geräts hinzu. Nehmen wir an, dass es ein Rechteck enthält, das mit einer Perspektive aufgenommen wurde.
  2. Benutzer definiert die physische Größe des Rechtecks, das in der horizontalen Ebene liegt (YOZ in Bezug auf SceneKit). Nehmen wir an, das Zentrum ist der Ursprung der Welt (0, 0, 0), so dass wir für jede Ecke leicht (x, y, z) finden können.
  3. Der Benutzer definiert uv-Koordinaten im Bildkoordinatensystem für jede Ecke des Rechtecks.
  4. Die SceneKit-Szene wird mit einem Rechteck gleicher Größe erstellt, das in derselben Perspektive sichtbar ist.
  5. Andere Knoten können in der Szene hinzugefügt und verschoben werden.

Ich habe auch die Position der iPhone-Kamera relativ zur Mitte des A4-Papiers gemessen. Für diese Aufnahme wurde also die Position (0, 14, 42.5) in cm gemessen. Auch mein iPhone war leicht auf den Tisch (5-10 Grad)

Mit diesen Daten habe ich SCNCamera eingerichtet, um die gewünschte Perspektive der blauen Ebene auf dem dritten Bild zu erhalten:

%Vor%

Dies gibt mir einen Bezug, um mein Ergebnis mit zu vergleichen.

Um AR mit SceneKit zu erstellen, muss ich:

  1. Passen Sie SCNCameras FOV so an, dass es mit der tatsächlichen Kamera übereinstimmt.
  2. Berechnen Sie Position und Rotation für den Kamera-Knoten mit 4 Korrelationen zwischen den Weltpunkten (x, 0, z) und den Bildpunkten (u, v)

H - Homographie; K - Intrinsische Matrix; [R | t] - Extrinsische Matrix

Ich habe zwei Ansätze ausprobiert, um eine Transformationsmatrix für die Kamera zu finden: mit solvePnP von OpenCV und manueller Berechnung von Homographie basierend auf 4 koplanaren Punkten.

Manueller Ansatz:

1. Finde die Homographie

Dieser Schritt ist erfolgreich, da die UV-Koordinaten des Ursprungs der Welt korrekt zu sein scheinen.

2. Intrinsische Matrix

Um die Matrix des iPhone 6 zu erhalten, habe ich diese App verwendet, die gab mir folgendes Ergebnis von 100 Bildern von 640 * 480 Auflösung:

Wenn das Eingangsbild ein Bildseitenverhältnis von 4: 3 hat, kann ich die obige Matrix abhängig von der Auflösung skalieren

Ich bin mir nicht sicher, aber es fühlt sich hier wie ein potenzielles Problem an. Ich habe cv :: calibrationMatrixValues ​​verwendet, um fovx auf die berechnete intrinsische Matrix zu überprüfen, und das Ergebnis war ~ 50 °, während es nahe bei 60 ° liegen sollte.

3. Kamera-Pose-Matrix

%Vor%

Ergebnis:

Da ich die ungefähre Position und Orientierung für dieses spezielle Bild gemessen habe, kenne ich die Transformationsmatrix, die das erwartete Ergebnis liefern würde und es ist ganz anders:

Ich bin auch etwas besorgt über 2-3 Element der Referenzrotationsmatrix, die -9.1 ist, während es stattdessen nahe Null sein sollte, da es eine sehr geringe Rotation gibt.

OpenCV-Ansatz:

Es gibt eine solvePnP Funktion in OpenCV für diese Art von Problemen, also habe ich versucht, es anstelle von zu verwenden das Rad neu erfinden.

OpenCV in Objective-C ++:

%Vor%

Verwendung in Swift:

%Vor%

Ausgabe:

Das Ergebnis ist besser, aber weit von meinen Erwartungen entfernt.

Einige andere Dinge, die ich auch versucht habe:

  1. Diese Frage ist sehr ähnlich, obwohl ich nicht verstehe, wie die akzeptierte Antwort ohne intrinsics funktioniert.
  2. dekomposeHomographyMat gab mir auch nicht das Ergebnis, das ich erwartet hatte

Ich bin wirklich mit diesem Problem beschäftigt, daher würde jede Hilfe sehr geschätzt werden.

    
alexburtnik 16.05.2017, 17:30
quelle

1 Antwort

4

Eigentlich war ich mit OpenCV einen Schritt weiter von der Arbeitslösung entfernt.

Mein Problem mit dem zweiten Ansatz war, dass ich vergessen habe, die Ausgabe von solvePnP zurück in das SpriteKit-Koordinatensystem zu konvertieren.

Beachten Sie, dass die Eingabe (Bild- und Weltpunkte) tatsächlich korrekt in das OpenCV-Koordinatensystem konvertiert wurde ( convertObjectPoints: und convertImagePoints:withSize: Methoden)

Also hier ist eine feste Methode findCameraPose mit einigen Kommentaren und Zwischenergebnisse gedruckt:

%Vor%

Anmerkungen:

  1. RotX matrix bedeutet Drehung um 180 Grad um die x-Achse, wodurch jeder Vektor von OpenCV transformiert wird Koordinatensystem zu SpriteKit

  2. Rodrigues Methode transformiert Rotationsvektor in Rotationsmatrix (3x3) und umgekehrt

alexburtnik 26.06.2017, 00:03
quelle