Um Weltkoordinaten aus Bildschirmkoordinaten mit OpenCV zu berechnen

8

Ich habe die intrinsischen und extrinsischen Parameter der Kamera mit OpenCV berechnet. Nun möchte ich Weltkoordinaten (x, y, z) aus Bildschirmkoordinaten (u, v) berechnen.

Wie mache ich das?

N.B. Da ich den Kinect benutze, kenne ich bereits die z-Koordinate.

Jede Hilfe wird sehr geschätzt. Danke!

    
Paul 17.08.2012, 14:32
quelle

2 Antworten

25

Zuerst, um zu verstehen, wie Sie es berechnen, würde es Ihnen helfen, wenn Sie etwas über das Lochkamera-Modell und die einfache perspektivische Projektion lesen. Einen kurzen Blick darauf werfen Sie dies . Ich werde versuchen, mit mehr zu aktualisieren.

Beginnen wir also mit dem Gegenteil, das beschreibt, wie eine Kamera funktioniert: Projizieren Sie einen 3D-Punkt im Weltkoordinatensystem auf einen 2d-Punkt in unserem Bild. Nach dem Kameramodell:

P_screen = I * P_world

oder (mit homogenen Koordinaten)

%Vor%

wo

%Vor%

ist die intrinsische 3x4-Matrix, wobei f der Brennpunkt und c das Projektionszentrum ist.

Wenn Sie das obige System lösen, erhalten Sie:

%Vor%

Aber Sie möchten das Gegenteil tun, also lautet Ihre Antwort:

%Vor%

z_world ist die Tiefe, die der Kinect Ihnen zurückgibt, und Sie wissen f und c von Ihrer Eigenkalibrierung, also wenden Sie für jedes Pixel die obigen an, um die tatsächlichen Weltkoordinaten zu erhalten.

Edit 1 (warum die obigen Weltkoordinaten entsprechen und welche Extrinsik wir während der Kalibrierung erhalten):

Überprüfen Sie zuerst dieses , es erklärt die verschiedenen Koordinatensysteme sehr gut .

Ihre 3d Koordinatensysteme sind: Objekt --- & gt; Welt --- & gt; Kamera. Es gibt eine Transformation, die Sie vom Objektkoordinatensystem zur Welt bringt, und eine andere, die Sie von der Welt zur Kamera bringt (die Extrinsik, auf die Sie sich beziehen). Normalerweise gehen Sie davon aus:

  • Entweder entspricht das Objektsystem dem Weltsystem,
  • oder, das Kamerasystem entspricht dem World-System

1. Beim Aufnehmen eines Objekts mit der Kinect

Wenn Sie mit Kinect ein Objekt erfassen, wird Ihnen vom Sensor die Entfernung von der Kamera zurückgegeben. Das bedeutet, dass die z-Koordinate bereits in Kamerakoordinaten ist. Wenn Sie x und y mithilfe der obigen Gleichungen konvertieren, erhalten Sie den Punkt in Kamerakoordinaten .

Nun wird das Weltkoordinatensystem von Ihnen definiert. Ein üblicher Ansatz besteht darin, anzunehmen, dass die Kamera sich bei (0,0,0) des Weltkoordinatensystems befindet. In diesem Fall entspricht die extrinsische Matrix tatsächlich der Identitätsmatrix und die von Ihnen gefundenen Kamerakoordinaten entsprechen Weltkoordinaten .

Hinweis: Da Kinect das z in Kamerakoordinaten zurückgibt, ist auch keine Transformation vom Objektkoordinatensystem zum Weltkoordinatensystem erforderlich. Nehmen wir beispielsweise an, Sie hätten eine andere Kamera, die Gesichter erfasst und für jeden Punkt die Entfernung von der Nase (die Sie als Mittelpunkt des Objektkoordinatensystems betrachteten) zurückgegeben. In diesem Fall würden wir, da die zurückgegebenen Werte im Objektkoordinatensystem liegen würden, in der Tat eine Rotations- und Translationsmatrix benötigen, um sie in das Kamerakoordinatensystem zu bringen.

2. Während der Kalibrierung der Kamera

Ich nehme an, Sie kalibrieren die Kamera mit OpenCV mit einer Kalibrierungskarte mit verschiedenen Posen. Der übliche Weg besteht darin, anzunehmen, dass das Board tatsächlich stabil ist und die Kamera sich bewegt anstatt des Gegenteils (die Transformation ist in beiden Fällen die gleiche). Das bedeutet, dass das Weltkoordinatensystem jetzt dem Objektkoordinatensystem entspricht. Auf diese Weise finden wir für jedes Bild die Ecken des Schachbretts und weisen ihnen 3D-Koordinaten zu, etwa wie folgt:

%Vor%

wobei noOfCornersInWidth , noOfCornersInHeight und squareSize von Ihrem Kalibrierungsboard abhängen. Wenn zum Beispiel noOfCornersInWidth = 4, noOfCornersInHeight = 3 und squareSize = 100 sind, erhalten wir die 3d Punkte

%Vor%

Also, hier sind unsere Koordinaten tatsächlich im Objektkoordinatensystem . (Wir haben willkürlich angenommen, dass die obere linke Ecke des Brettes (0,0,0) ist und die Koordinaten der restlichen Ecken entsprechend sind). Hier brauchen wir also die Dreh- und Transformationsmatrix, um uns vom Objekt (Welt) zum Kamerasystem zu bringen. Dies sind die Extrins, die OpenCV für jeden Frame zurückgibt.

Im Kinect Fall zusammengefasst:

  • Kamera- und Welt-Koordinatensysteme werden als gleich angesehen, daher ist dort keine Extrinsik notwendig.
  • Keine Transformation von Objekt zu Welt (Kamera) erforderlich, da der Kinect-Rückgabewert bereits im Kamerasystem vorhanden ist.

Bearbeiten 2 (Im verwendeten Koordinatensystem):

Dies ist eine Konvention und ich denke, es hängt auch davon ab, welche Treiber Sie verwenden und welche Art von Daten Sie zurückbekommen. Überprüfen Sie zum Beispiel das , das und derjenige .

Nebenbemerkung: Es würde Ihnen sehr helfen, wenn Sie eine Punktewolke visualisieren und ein wenig damit spielen. Sie können Ihre Punkte in einem 3D-Objektformat speichern (zB ply oder obj ) und dann einfach in ein Programm wie Meshlab importieren > (sehr einfach zu bedienen).

    
Sassa 17.08.2012, 18:56
quelle
0

Bearbeiten 2 (Im verwendeten Koordinatensystem):

Dies ist eine Konvention und ich denke, es hängt auch davon ab, welche Treiber Sie verwenden und welche Art von Daten Sie zurückbekommen. Überprüfen Sie zum Beispiel, dass, das und das.

  
    

Wenn Sie beispielsweise Microsoft SDK verwenden: dann ist Z nicht der Abstand zur Kamera, sondern der "planare" Abstand zur Kamera. Dies könnte die entsprechenden Formeln ändern.

  
    
Robby 18.02.2013 16:08
quelle