Bild in Weltkoordinaten transformieren



  • Hi,

    ich habe folgendes Problem. Ich will von einer Kinect Kamera von den Bild- zu den Weltkoordinaten transformieren, d.h. wenn ich ein Pixel im 2D Bild anklicke dann will ich die 3D Koordinate in Weltkoordinate haben. Dazu habe ich die Kamera bereits kalibriert. Also die intrinsische und extrinische Parameter der Kamera habe ich bereits.
    Der Bezug zum Weltkoordinaten System habe ich ein Schachbrett-Muster aufgenommen und mit OpenCV die Bildpunkte gefunden und mit den Weltpunkten verknüpft, so dass ich die Rotation und Vektor der Transformation habe.
    Von Weltkoordinate zu Bildkoordinate benutze ich die OpenCV Methode projectToImage nur ich bekomme es nicht andersrum hin! Habe schon versucht das manuell zu transformieren mit der Formel leider ohne Erfolg:
    pwelt=R1(pbild+Rt)p_{welt}=R^{-1}(p_{bild}+R*t)
    Wo ist mein Denkfehler bzw. wie kann ich Bild in Weltkoordinaten transfomieren?

    Gruss
    tesa



  • Es reicht nicht, ein einziges Schachbrettbild zu verwenden -- es sei denn, Du kennst schon mindestens einen Parameter (zB Brennweite oder Hauptpunkt). Das einfachste Lochkameramodell mit parametrisiertem Hauptpunkt hat 9 Freiheitsgrade. Das sind 6 Fhg, die beschreiben, wie Weltkoordinaten in "normalisierte Kamerakoordinaten" transformiert werden können. Weitere 3 Fhg sagen Dir, wie "normalisierte Kamerakoordinaten" auf Pixel abgebildet werden. Die Information, die Du über ein einziges Schachbrett bild bekommst, besitzt höchstens 8 Freiheitsgrade. Es ist eine sogenannte Homographie. Eine Homographie beschreibt eine perspektivische Abbildung von 2D nach 2D.

    cam_normalized = R * weltk + t  (extrinische Parameter R und t)
    pixel_pos = K * cam_normalized  (intrinsische Parameter K)
    
    R: 3x3 Rotationsmatrix
    t: 3d  Spaltenvektor
    K: 3x3 Kameramatrix
    
    K ist im einfachsten Fall von der Form
      |f 0 u0|
      |0 f v0|
      |0 0  1|
    

    wobei f der Brennweite in Pixel entspricht und u0;v0 die Pixelposition des Hauptpunktes ist. Es gibt noch zwei weitere Freiheitsgrade: "pixel_aspect_ratio" und "shear_factor". Die sagen dir, wie das Pixelgitter auf dem Sensor aussieht. Im einfachen Fall von oben ist die Annahme, dass es sich um ein orthogonales Gitter handelt, wobei Pixelbreite = Pixelhöhe gilt.

    Beachte, dass pixel_pos hier auch 3 Komponenten hat (homogene Koordinaten).

    Es sollte Dir klar sein, dass es keine eindeutige Lösung für 2D->3D Mapping nur anhand der Kameraparameter und einer einzigen Pixelkoodinate gibt; denn es gibt unendlich viele 3D-Punkte auf der Sichtlinie, die zum angeklickten Pixel gehört.

    Du kannst aber anhand einer Pixel-Koordinate mit K die normalisierte Kamerakoordinate berechnen und darüber einen Richtungsvektor der Sichtlinie bestimmen:

    sichtlinienrichtung = R^T * cam_normalized
                        = R^T * K^{-1} * pixel_pos
    

    Und über

    0 = R * projektionszentrum + t
    

    bekommst Du die Weltkoordinate des Projektionszentrum. Aus diesen beiden Informationen kannst Du Dir eine Sichtlinie zusammensetzen.


Anmelden zum Antworten