Rückprojektion?



  • Ich entwickle eine Software für eine Webcam, die einen roten Punkt auf einer weißen Obrfläche erkennen soll. Wenn man die Kamera direkt senkrecht in die Mitte vor die weiße Fläche steht funktioniert das ohne Probleme.

    Nun möchte ich aber, dass man die Kamera auch z.B. weiter nach rechts unten vor die Fläche stellen kann, so dass sie die Fläche schräg sieht und dann die Koordinaten umrechnet.

    also im Endeffekt hab ich die Eckpunkte des Vierecks, wie die Kamera es sieht und den roten Punkt, der sich irgendwo innerhalb des Vierecks befindet.
    Nun ist das Viereck dass die Kamera sieht nicht die ursprüngliche weiße Fläche, sondern nur eine Projektion, da die Kamera schräg draufgugckt.

    Wie kann ich nun anhand dieser vier Eckpunkte die Koordinaten des roten Punkts in dem Koordinatensystem der weißen Fläche, statt dem der Kamera berechnen?
    (Näherungsverfahren solange es nicht allzu ungenau ist, würdes auch tun)



  • Wie viele Freiheitsgrade hast du mit der Cam ?

    Kannst du die Kamera z.B. in drei Dimensionen( x-, y-, z-Richtung ) mit dem PC steuern ?

    Auch drehen( um die x-, y-, z-Achse ) ?

    Ansonsten brauchst du ja nur jede Verschiebung, Drehung der Kamera rückgängig zu machen, bzw. zurückzurechnen.

    Sollte das nicht gehen, warum auch immer, dann brauchst du
    (3D-Steuer-Fähigkeit vorausgesetzt) wenigstens zwei Ortsvektoren und zwei Normalenvektoren.

    Einen Referenz-Ortsvektor für den Koordinatenursprung der Kamera und einen Referenz-Normalenvektor für die Neigung der Kamerafläche.

    Einen Ortsvektor, der die aktuelle Position des Ursprungs der Kamera speichert und einen Normalenvektor, der sich die aktuelle Neigung der Kamerafläche merkt.

    Dann könnte man alle Punkte der Fläche "vor die Kamera berechnen", oder umgekehrt mit der Kamera zum Referenzpunkt fahren.

    In beiden Fällen müssten dann die Ortsvektoren übereinstimmen und die Normalenvektoren parallel sein( Vektorprodukt = 0 ).



  • Wenn du die Abbildung von zwei nicht parallelen (am besten orthogonalen aber nicht notwendig) Vektoren kennst dann kannst du das Umrechnen der Koordinaten mit der Hilfe einer Matrix und einer Verschiebung machen.

    Ich würde einfach noch 3 weitere Punkte einführen : blau, schwarz und grün. Von oben gekuckt ist der schwarze Punkt dein Zentrum und der grüne ist auf Distanz 1 (Einheit kannst du wählen) nach oben. Der blaue auf Distanz 1 nach rechts. Kannst also wenn du die 3 Punkten kennst ein Axenkreuz malen.

    Von der Seite gekuckt bestimmst du erst einmal die Positionen der 4 Punkte auf der Kamera. Sei P dein roter Punkt, B blau, O schwarz und G grün.

    Ohne ' sind es Koordinaten auf der Kamera und mit auf dem Blatt. Ich gebe den Koordinaten mal Namen:
    P(x_p, y_p) -> P'(x, y)
    O(x_o, y_o) -> O'(0, 0)
    B(x_b, y_b) -> O'(1, 0)
    G(x_g, y_g) -> O'(0, 1)
    Als erstes ziehst du von P O ab damit beide Zentren übereinstimmen. Das Resultat ist P*(x_p - x_o, y_p - y_o).

    Seien i(x_b-x_o, y_b-y_o) und j(x_g-x_o, y_g-y_o) deine Einheitsvektoren.

    Die Matrix

    |x_b-x_o x_g-x_o|
    |y_b-y_o y_g-y_o|
    

    bildet also P' auf P* ab falls rechts-multipliziert. Wir wollen aber die andere Richtung also berechnen wir das Inverse

    |y_g-y_o x_o-x_g|
    |y_o-y_b x_b-x_o|
    

    So nun sind wir eigentlich fertig:

    x = (y_g - y_o) * (x_p - x_o) + (x_o - x_g) * (y_p - y_o)
    y = (y_o - y_b) * (x_p - x_o) + (x_b - x_o) * (y_p - y_o)

    Um bessere Resultate zu erhalten würde ich die Einheit möglichst groß wählen. Das sollte am genausten werden. Du kannst am Ende ja einfach nochmal skalieren wenn Kommazahlen dich stören.

    PS: Das ganze ist ohne Gewähr.


Anmelden zum Antworten