Zentralperspektive "Umrechnung von Bild- zu Weltkoordinaten"

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen

Allgemein

Die Zentralprojektion wird genutzt, um 3-dimensionale Objekte im 2-dimensionalen Raum abzubilden. Dadurch werden Bilder erzeugt, die der Wahrnehmung des menschlichen Auges entsprechen oder mit einer Kamera fotografierten Szenerie. Das Bild entsteht durch die Projektion von einem 3-dimensionalen Gegenstand auf eine Ebene von einem Punkt ausgeht.

Einsatz im Carolo Cup Fahrzeug

Das Carolo Cup Auto fährt auf einer 820 mm breiten Straße, die Mittellinie ist gestrichelt. Die Segmente der Linie sind 200 mm lang und 20 mm breit. Sie folgen im Abstand von 200 mm aufeinander. Die Kamera filmt die Fahrt des Fahrzeugs aus einer festgelegten Perspektive und die Blickrichtung der Kamera ist fest in Fahrtrichtung.(Carolo Cup Regelwerg)


Die Umrechnung zwischen Bild- und Weltkoordinaten ist notwendig um die Spuren zu verifizieren. Für die Umrechnung von Bild- in Weltkoordinaten wurde mit Hilfe der festen Perspektive eine Funktion bild_zu_welt.m in Matlab aufgebaut. --> function [ w_kordinaten ] = bild_zu_welt( b_kordinaten)

Diese Funktion rechnet Bildkoordinaten in Weltkoordinaten um. Die Eingabe b_kordinaten und Ausgabe w_kordinaten sind (2; n)-Matrizen. Der Nullpunkt in Weltkoordinaten besitzt im Bildkoordinatensystem die Koordinaten (376;478), die y-Achse verläuft von rechts nach links am unteren Bildrand, und die x-Achse verläuft auf der Bildspalte 376 von unten nach oben.

Die Funktion in Matlab

Zu erst werden die Punkte der linken Geraden und der rechten Geraden gesetzt. Um die Abstände und zugehörigen Weltkoordinaten bestimmen zu können, wurde das Fahrzeug vor einem Schachbrettmuster positioniert.


 %Vier Punkte
 p_b_l1 = [165; 310];
 p_b_l2 = [280 ; 217];
 p_b_r1 = [585; 310];
 p_b_r2 = [470 ;217];


Danach wird der Fokuspunkt ermittelt. Das ist der Punkt, in dem sich alle parallelen vertikalen Linien schneiden. Um die Gerade des Horizonts zu bestimmen, wird ein Punkt auf der Höhe des Fokuspunktes erzeugt.


 % Linke Gerade (l1 - l2) mit rechter Geraden (r1-r2) scneiden --> Fokuspunkt
 fokus_p = schneide(p_b_l1,p_b_l2,p_b_r1,p_b_r2);
 % Zweiten Punkt auf der Höhe des Fokus erzeugen      
 horizont_hilfspunkt = [p_b_l1(1,1);fokus_p(2,1)];



 % waagerechter Schnitt mit linker Begrenzung
 P = schneide(p_b_l1, p_b_l2, b_kordinaten, b_kordinaten-[10.0;0.0]);
 % Nullpunkt der y-Achse ist die Bildmitte 
 y = 2*168*(b_kordinaten(1)-XS/2.0)/(P(1)-XS/2.0);


Um die Y-Weltkoordinate zu berechnen wird ein Parallele zum Horizont auf der Höhe des gesuchten Punkts gezogen. Der entstandene Schnittpunkt mit der L1/L2 Geraden (linke Begrenzung) wird in P gespeichert. Es wird ein Verhältnis aus P und dem gesuchten Punkt aufgestellt und mit der Breite von 2 Sachbrettfeldern multipliziert.



 % Abstände Berechnen <br />
 % Maßstab für Höhe im Bild <br />
 M1 = [378; 311]; <br />
 M2 = [378; 283]; <br />
 % Abstand von der Höhe eines Schachbrettfeldes zwischen M1 und M2  in der Mitte der Straße --> Lineal auf bauen <br />
 masstab = norm(schneide_Test(horizont_hilfspunkt, M1, [XS/2; YS], [XS/2+10; YS]) - schneide_Test(horizont_hilfspunkt, M2, [XS/2; YS], [XS/2+10; YS]));<br />
 R = schneide_Test(horizont_hilfspunkt, P, [XS/2; YS], [XS/2+10; YS]); % Schnittpunkt von HP<->P auf der x-Achse<br />
 x = (R(1)-p_b_l1(1))/masstab*168;<br />
 w_kordinaten = [x,y];<br />
 end<br />

Die X-Weltkoordinate wird mit Hilfe der bekannten Höhe eines Schachbrettfeldes berechnet. Die Punkte M1 und M2 liegen auf der Mittelelinie und auf den Eckpunkten eines Schachbrettfeldes. Mit Hilfe des Horizontpunktes werden 2 Geraden erzeugt, die Schnittpunkte mit der Bildunterkante bilden. Der Abstand zwischen den Schnittpunkten dient als Maßstab. Ein weiterer Schnittpunkt wird aus der Geraden Horizontpunkt P und der Bildkante gebildet. Aus diesem Punkt R wird die X-Koordinate berechnet.

Die Funktion in C

Um die Matlab Funktion bild_zu_welt.m in C Code umzusetzen, wurde der Matlab Coder verwendet. Aus diesem Grund unterscheidet sich der verwendete C-Code nur minimal von dem Matlab-Code und kann mit der obigen Beschreibung nachvollzogen werden. Eine Anleitung zum erzeugen von C Code mit Hilfe von Matlab am Beispiel dieser Funktion findet sich hier Von Matlab zu C Code