Bildentzerrung und KOS-Transformation: Unterschied zwischen den Versionen
(125 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 3: | Zeile 3: | ||
'''Autoren:''' Luca_Di-Lillo, Tim Leonard Bexten<br/> | '''Autoren:''' Luca_Di-Lillo, Tim Leonard Bexten<br/> | ||
'''Betreuer:''' [[Benutzer:Ulrich_Schneider| Prof. Schneider]]<br/> | '''Betreuer:''' [[Benutzer:Ulrich_Schneider| Prof. Schneider]]<br/> | ||
=='''Programmablaufplan des VRmagic-Kameraprogramms mit KOS-Transformation'''== | |||
'''Autor:''' Tim Bexten<br/> | |||
[[Datei:HauptprogrammOSE2.png|300px|right|PAP des Kameraprogramms mit KOS-Transformatin]]<br> | |||
Der Programmablaufplan zur Erstellung der Draufsicht ist in der Abbildung zur Rechten dargestellt. Er bau auf allen Erkenntnissen auf, die in dem folgenen Wiki-Artikel beschrieben werden.<br> | |||
Zu Beginn werden die benötigten Variablen und #define's beschrieben und deklariert. Im Anschluss daran wird geprüft, ob die Parameter für die RS232-Kommunikation angeglegt sind. Wenn dies der Fall ist, wird die Kommunikation mit der dSPACE Karte gestartet. Diese sendet die Daten des Spurpolynoms an die Querregelung des Fahrzeugs. | |||
Wenn es nicht initaialisiert ist, startet der Verbindungsaufbau zur VRmagic Kamera dierekt. Wenn die Verbindung zur VRmagic Kamera hergestellt ist, werden die Einstellungen der VRmagic Kamera vorgenommen, wie Bespielsweise Belichtungszeit etc.<br> | |||
Danach sind alle Voreinstellungen vorgenommen worden und die Zyklusschleife kann beginnen.<br> | |||
Diese beginnt mit dem Aufnehmen Streckenbildes mit der VRmagic Kamera. Dieses Bild wird im VRmagic eigenen Dateiformat abgspeichert und in ein Graustufenbild gewandelt. | |||
Um mit der OpenCV Bildverarbeitung weiterarbeiten zu können, muss das Dateiformat von OpenCV geändert werden. Dies wird mit dem Graustufenbild durchgeführt. Nachdem das geschehen ist, können alle OpenCV Funktionen genutzt werden.<br> | |||
Daraufhin wird eine Schwellwertfilterung durchgeführt, um weiße und schwarze Stellen gut unterscheiden zu können. Über diese Filterung wird alles über einem gewissen 8 Bit Wert als weiß und alles daruter als schwarz eingestuft. Danach werden die ermittelten Kameraprameter herausgerechnet um das Bild zu entzerren. Danach wird eine Draufsicht erstellt die aus einer ROI des normalen Kamerabildes erstellt. Das Erstellen dieser Draufsicht wird im Folgen Artikel erläutert. Um das Bild für die folgende Kantenerkennung durch den Canny-Edge Filter vorzubereiten, wird ein Gaußfilter über das Bild der Draufsicht gelegt, um das Rauschen zu unterdrücken und ein bessers Kantenbild zu ermöglichen. Aus dem Kantenbild werden nun die Fahrbahnpunkte errechnet. Dieses ist in einem definierten Fahrzeugkoordinatensystem abgelegt.<br> | |||
Aus den X und Y-Koordinaten der Fahrbahnpunkte wird ein Spurpolynom errechnt, welches den Kurvenverlauf vor dem Fahrzeug abbildet. Das Polynom wird mit den a,b und c Parametern einer quadratischen Gleichung angegeben. Diese Parameter werden, sofern die RS232 Kommunikation eingerichtet ist, über die Schnittstelle verschickt.<br> | |||
Die Zyklusschleife ist danach abgeschlossen und die Schleife beginnt von vorn.<br> | |||
Wenn die Zyklusschleife verlassen wurde, werden die RS232 Kommunikation und die VRmagic Kamera geschlossen und das Programm beendet. | |||
<br> | |||
<br> | |||
<br> | |||
<br> | |||
<br> | |||
==='''Programmablaufplan des VRmagic-Kameraprogramms mit KOS-Transformation'''=== | |||
[[Datei:Schnittpunkte2.png|300px|right|PAP des Schnittpunktfindung]]<br> | |||
Die Schnittpunkte werden ermittelt, indem das erste Pixel gesucht wird, welches nicht schwarz ist. Diese suche wird nur auf elf Linien durchgeführt. Auf diesen Linien wird von der Mitte des Bildes aus gesucht wo der Fahrbahnrand beginnt. Der gefunden Punkt wird im Fahrzeugkoordinatensystem in einem Array entsprechend abgespeichert. | |||
<br> | |||
<br> | |||
<br> | |||
Dies ist nur ein vorläufiges Konzept und kann für bessere Performance optimiert werden, um Kurven besser erkennen zu können. | |||
== '''Inbetriebnahme der Kamera''' == | == '''Inbetriebnahme der Kamera''' == | ||
==== Ansteuerung mit CamLab am Fahrzeug ==== | ==== Ansteuerung mit CamLab am Fahrzeug ==== | ||
'''Autor:''' Tim Bexten<br/> | |||
[[Datei:CamLab.png|thumb|rechts|300px|Bereich zum Download der Software]] | [[Datei:CamLab.png|thumb|rechts|300px|Bereich zum Download der Software]] | ||
Um einen ersten Funktionstest der Kamera durchzuführen, wurde die Kamera über einen Ethernetkabel mit dem Laborrechner verbunden und das zugehörige Netzteil für die Stromversorgung angeschlossen. Das VRmagic Programm zum ausgeben des Kamerabildes "CamLab" ist auf allen Laborrechnern bereits installiert.<br> | Um einen ersten Funktionstest der Kamera durchzuführen, wurde die Kamera über einen Ethernetkabel mit dem Laborrechner verbunden und das zugehörige Netzteil für die Stromversorgung angeschlossen. Das VRmagic Programm zum ausgeben des Kamerabildes "CamLab" ist auf allen Laborrechnern bereits installiert.<br> | ||
Zeile 22: | Zeile 49: | ||
==== Implementierung der Kamera in Visual Studio ==== | ==== Implementierung der Kamera in Visual Studio ==== | ||
'''Autor:''' Luca Di-Lillo<br/> | |||
Die Kamera stellt Librarys für die Programmierung in C/C++ bereit, diese sind im SVN Ordner hinterlegt und müssen in die aktuelle Projektmappe im Explorer hinzugefügt werden. <br> | Die Kamera stellt Librarys für die Programmierung in C/C++ bereit, diese sind im SVN Ordner hinterlegt und müssen in die aktuelle Projektmappe im Explorer hinzugefügt werden. <br> | ||
In Visual Studio wählt man in dem Dropdown Menü in der oberen Leiste neben '''Debug x86''' aus (siehe Abbildung Visual Studio auf x86 einstellen rotes Rechteck), ohne diese Einstellung lässt sich das Programm nicht kompilieren. Im nächsten Schritt wählt man in dem Fenster '''Projektmappen-Explorer''' mit einem Rechtsklick die Projektmappe aus und öffnet '''Eigenschaften'''. Die Konfiguration des Eigenschaftsfensters muss auf '''Debug''' eingestellt sein und die Plattform auf '''Aktiv(Win32)''' (siehe Abbildung Zusätzliche Includeverzeichnisse rote Rechtecke). In diesem Fenster wählt man als erstes die Registerkarte '''C/C++''' aus (blaues Rechteck), dort fügt man jetzt unter dem Punkt '''Zusätzliche Includeverzeichnisse''' (grünes Rechteck), den Dateipfad '''C:\[Dateipfad auf eigenem Rechner]\VRMagic\include''' hinzu. Im nächsten Schritt muss man die Library Dateien mit dem Linker verlinken, dazu bleibt man in dem '''Eigenschaftsfenster''' und wählt die Registerkarte '''Linker''' aus und öffnet dort '''Allgemein''' (siehe Abbildung Zusätzliche Bibliotheksverzeichnisse rotes Rechteck). Dort wählt man jetzt den Punkt '''Zusätzliche Bibliotheksverzeichnisse''' (siehe grünes Rechteck) und fügt den Dateipfad '''C:\[Dateipfad auf eigenem Rechner]\VRMagic\lib''' hinzu. Nun öffnet man auch unter der Registerkarte '''Linker''' den Punkt '''Eingabe''' (siehe Abbildung Zusätzliche Abhängigkeiten rotes Rechteck), dort fügt man unter dem Punkt '''Zusätzliche Abhängigkeiten''' (siehe grünes Rechteck) folgendes hinzu: | In Visual Studio wählt man in dem Dropdown Menü in der oberen Leiste neben '''Debug x86''' aus (siehe Abbildung Visual Studio auf x86 einstellen rotes Rechteck), ohne diese Einstellung lässt sich das Programm nicht kompilieren. Im nächsten Schritt wählt man in dem Fenster '''Projektmappen-Explorer''' mit einem Rechtsklick die Projektmappe aus und öffnet '''Eigenschaften'''. Die Konfiguration des Eigenschaftsfensters muss auf '''Debug''' eingestellt sein und die Plattform auf '''Aktiv(Win32)''' (siehe Abbildung Zusätzliche Includeverzeichnisse rote Rechtecke). In diesem Fenster wählt man als erstes die Registerkarte '''C/C++''' aus (blaues Rechteck), dort fügt man jetzt unter dem Punkt '''Zusätzliche Includeverzeichnisse''' (grünes Rechteck), den Dateipfad '''C:\[Dateipfad auf eigenem Rechner]\VRMagic\include''' hinzu. Im nächsten Schritt muss man die Library Dateien mit dem Linker verlinken, dazu bleibt man in dem '''Eigenschaftsfenster''' und wählt die Registerkarte '''Linker''' aus und öffnet dort '''Allgemein''' (siehe Abbildung Zusätzliche Bibliotheksverzeichnisse rotes Rechteck). Dort wählt man jetzt den Punkt '''Zusätzliche Bibliotheksverzeichnisse''' (siehe grünes Rechteck) und fügt den Dateipfad '''C:\[Dateipfad auf eigenem Rechner]\VRMagic\lib''' hinzu. Nun öffnet man auch unter der Registerkarte '''Linker''' den Punkt '''Eingabe''' (siehe Abbildung Zusätzliche Abhängigkeiten rotes Rechteck), dort fügt man unter dem Punkt '''Zusätzliche Abhängigkeiten''' (siehe grünes Rechteck) folgendes hinzu: | ||
Zeile 29: | Zeile 57: | ||
==== Installation von OpenCV ==== | ==== Installation von OpenCV ==== | ||
'''Autor:''' Luca Di-Lillo<br/> | |||
Um das Kamerabild der VRMagic Kamera zu sehen und zu verabeiten wurde OpenCV verwendet. OpenCV bietet zahlreiche Möglichkeiten Bilder zu erkennen und zu verarbeiten. <br> | Um das Kamerabild der VRMagic Kamera zu sehen und zu verabeiten wurde OpenCV verwendet. OpenCV bietet zahlreiche Möglichkeiten Bilder zu erkennen und zu verarbeiten. <br> | ||
Für dieses Projekt wurde OpenCV 3.0.0 [https://sourceforge.net/projects/opencvlibrary/files/opencv-win/3.0.0/ (Downloadlink zu OpenCV 3.0.0)] verwendet, da diese eine x86 (32-Bit) Version enthält, die nötig ist, um OpenCV mit der VRMagic in Visual Studio lauffähig zu machen. Denn die Kamera ist nur mit '''x86''' kompatibel. <br> | Für dieses Projekt wurde OpenCV 3.0.0 [https://sourceforge.net/projects/opencvlibrary/files/opencv-win/3.0.0/ (Downloadlink zu OpenCV 3.0.0)] verwendet, da diese eine x86 (32-Bit) Version enthält, die nötig ist, um OpenCV mit der VRMagic in Visual Studio lauffähig zu machen. Denn die Kamera ist nur mit '''x86''' kompatibel. <br> | ||
Zeile 80: | Zeile 109: | ||
==== Darstellung des Kamerabildes mit OpenCV ==== | ==== Darstellung des Kamerabildes mit OpenCV ==== | ||
'''Autor:''' Luca Di-Lillo<br/> | |||
Damit das Live Bild der Kamera mit OpenCV ausgegeben und verarbeitet werden kann muss dieses zuerst in den OpenCV Typ Mat gewandelt werden. Dazu benötigt man eine Hilfsfunktion, die das Farbformat von VRMagic in das Farbformat von OpenCV wandelt, die Funktion ist im folgenden dargestellt. | Damit das Live Bild der Kamera mit OpenCV ausgegeben und verarbeitet werden kann muss dieses zuerst in den OpenCV Typ Mat gewandelt werden. Dazu benötigt man eine Hilfsfunktion, die das Farbformat von VRMagic in das Farbformat von OpenCV wandelt, die Funktion ist im folgenden dargestellt. | ||
<code><source lang=cpp> | <code><source lang=cpp> | ||
Zeile 130: | Zeile 160: | ||
==== Kantendetektion in OpenCV mit Canny Edge ==== | ==== Kantendetektion in OpenCV mit Canny Edge ==== | ||
'''Autor:''' Tim Bexten<br/> | |||
[[Datei:Orginalbild.png|thumb|rechts|300px|Orginalbild der Strecke in Graustufen]] | [[Datei:Orginalbild.png|thumb|rechts|300px|Orginalbild der Strecke in Graustufen]] | ||
[[Datei:KantenbildStrecke.png|thumb|rechts|300px|Binärbild der Strecke nach Kantendetektion]] | [[Datei:KantenbildStrecke.png|thumb|rechts|300px|Binärbild der Strecke nach Kantendetektion]] | ||
Zeile 135: | Zeile 166: | ||
Für die Kantendetektion wurde der weit verbreitete Algorithmus Canny Edge verwendet. OpenCV bietet für diesen Anwendungsfall bereits eine vorgefertigte Funktion an.<br> | Für die Kantendetektion wurde der weit verbreitete Algorithmus Canny Edge verwendet. OpenCV bietet für diesen Anwendungsfall bereits eine vorgefertigte Funktion an.<br> | ||
<br> | <br> | ||
<code><source lang=cpp> | |||
void Canny (InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false ) | |||
</source> </code> | |||
<br> | |||
* InputArray: Kamerabild in Graustufen (Datentyp: UMat, Mat) | * InputArray: Kamerabild in Graustufen (Datentyp: UMat, Mat) | ||
* OutputArray: Binärbild mit Kanten (Datentyp: UMat, Mat) | * OutputArray: Binärbild mit Kanten (Datentyp: UMat, Mat) | ||
Zeile 147: | Zeile 181: | ||
Die ''apertureSize'' stellt den Sobel-Operator ein, welchen die Canny-Funktion als Unterfunktion aufruft. Von der OpenCV Homepage wird empfolen diesen Interger-Wert auf "3" einzustellen.<br> | Die ''apertureSize'' stellt den Sobel-Operator ein, welchen die Canny-Funktion als Unterfunktion aufruft. Von der OpenCV Homepage wird empfolen diesen Interger-Wert auf "3" einzustellen.<br> | ||
Das letzte Argument ''L2gradient'' ist eine Flagge um der Funktion mitzuteilen, ob der Gradient des Bildes auf eine andere (genauere) Weise berechnet werden soll, siehe https://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=canny#canny86. Diese Bool-Variable wird standardmäßig auf "false" gesetzt. | Das letzte Argument ''L2gradient'' ist eine Flagge um der Funktion mitzuteilen, ob der Gradient des Bildes auf eine andere (genauere) Weise berechnet werden soll, siehe https://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=canny#canny86. Diese Bool-Variable wird standardmäßig auf "false" gesetzt. | ||
==== Entzerrung des Kamerabildes ==== | ==== Entzerrung des Kamerabildes ==== | ||
Wie in den vorhergegangenen Bildern zu sehen ist, weist das Kamerabild noch eine gewisse Verzerrung auf. Diese Verzerrungen entstehen durch die optischen Eigenschaften der Linse und dem internen Aufbau der Kamera. Diese Eigenschaften sind spezifisch für jedes Kamerasystem und sind somit unabhängig von der äußeren Bewegung und Position der Kamera. Diese Eigenschaften sind durch die optischen Komponenten, die fest in der Kamera verbaut sind bestimmt und somit bleiben sie beim Betrieb der Kamera immer konstant. Diese intrinsischen Kameraparameter werden benötigt, um den Zusammenhang zwischen den Punkten die auf den Pixeln des Kamerasensors abgebildet sind zu den echten Punkten in der Welt (Teststrecke) herzustellen. <br> | '''Autor:''' Tim Bexten<br/> | ||
Um die Abbildung der Bildpunkte die durch die Linse auf | Wie in den vorhergegangenen Bildern zu sehen ist, weist das Kamerabild noch eine gewisse Verzerrung auf. Diese Verzerrungen entstehen durch die optischen Eigenschaften der Linse und dem internen Aufbau der Kamera. Diese Eigenschaften sind spezifisch für jedes Kamerasystem und sind somit unabhängig von der äußeren Bewegung und Position der Kamera. Diese Eigenschaften sind durch die optischen Komponenten, die fest in der Kamera verbaut sind bestimmt und somit bleiben sie beim Betrieb der Kamera immer konstant. Diese intrinsischen Kameraparameter werden benötigt, um den Zusammenhang zwischen den Punkten die auf den Pixeln des Kamerasensors abgebildet sind zu den echten Punkten in der Welt (Teststrecke) herzustellen. <br> <br> | ||
Um die Abbildung der Bildpunkte die durch die Linse auf den Kamerasensor fallen darzustellen, muss eine Kalibrierungsmatrix K aufgestellt werden.<br><br> | |||
<math>K = \begin{pmatrix} | |||
f_x & 0 & 0\\ | |||
s & f_y & 0\\ | |||
c_x & c_y & 1 | |||
\end{pmatrix}</math> <br><br> | |||
Diese Kalibrierungsmatrix beinhaltet die bauteilspezifischen Parameter die die Kamera beschreiben. Die Komponenten cx,cy geben die Verschiebung des Koordinatenursprungs der Pixelkoordinaten an. Der Nullpunkt der Kamerakoordinaten, welcher in er mitte der Linse liegt wird nicht auf den Nullpunkt der Pixelkoordinaten abgebildet, da das Pixelkoordinatensystem in den meisten Fällen unten links oder oben links seinen Ursprung hat. Somit muss eine Verschiebung berücksichtigt werden.<br> | |||
Des Weiteren müssen die Faktoren fx und fy brücksichtigt werden, die die Brennweite der Kamera beinhalten. Die Brennweite der Kamera gibt den Abstand der Linse zum Kamerasensor an.<br> | |||
Die letzte Variable, die in der Kameramatrix vorkommt, ist die Scherung der Pixel s. Die Scherung gibt an, in welchem Winkel der Kamerasensor zur Linse steht. Für die verbaute VRmagic Kamera ist der Kamerasensor paralell zur Linse verbaut, somit muss keine Scherung berücksichtigt werden und s = 0. | |||
<br><br> | |||
Für eine gelungene Kalibrierung muss auch die radiale Verzerrung der verbauten Linse der VRmagic Kamera bestimmt werden. Verzerrung bei Linsen tritt auf, wenn Licht an den Rändern einer Linse stärker gebrochen wird als im Linsenzentrum. Bei der radialen Verzerrung wird zwischen der Kissenförmigen- und Tonnenförmigen-Verzerrung unterschieden. Die VRmagic Kamera weist durch ihre Linse eine kissenförmige Verzerrung auf. Die stärke der Verzerrung eines Bildpunktes, ist Abhängig von dessen Abstand zum Bildmittelpunkt. Dieses Verhältnis lässt sich durch folgende Gleichungen ausdrücken: | |||
[[Datei:Toolbox.png|mini|x400px|right|MATLAB Camera Calibrator Toolbox]] | |||
<br> | |||
<math>\begin{align} | |||
x_{verz} = x\cdot(1+k_1 \cdot r^{2}+k_2 \cdot r^{4}+k_3 \cdot r^{6})\\ | |||
y_{verz} = y\cdot(1+k_1 \cdot r^{2}+k_2 \cdot r^{4}+k_3 \cdot r^{6}) | |||
\end{align}</math><br> | |||
<math>\begin{align} | |||
mit: r^{2} = x^{2}+y^{2} | |||
\end{align} </math><br><br> | |||
Um diese Parameter zu bestimmen, müssen Bilder mit der VRmagic Kamera aufgenommen werden, bei denen ein Kalibrierungsobjekt mit bekannten Abmessungen aufgenommen wird. | |||
Für diese Aufgabe wird die Camera Calibrator Toolbox genutzt um die Parameter des verbauten Kamerasystems automatisiert zu bestimmen. Die Toolbox befindet sich in MATLAB unter dem Reiter ''Apps / Image Processing and Computer Vision''. Die Toolbox benötigt Kalibrierungsbilder von einem Schachbrettmuster mit bekannten Kantenlängen, wie in der Abbildung recchts zu sehen. Ein Schachbrettmuster wird verwendet, da das regelmäßige Muster des Schachbrettes einfach zu detektieren ist. Die Größe der einzelnen Kacheln auf dem Schachbrett muss zunächst vom Benutzer eingegeben werden.<br> | |||
Wenn die Kalibrierungsbilder in die Toolbox geladen wurden, kann man unter dem Reiter Options die radialen und tangentialen Verzerrungsparameter berechnen lassen. Durch einen Klick auf den Button ''Calibrate'' berechnet die Toolbox alle nötigen Verzerrungsparameter und die Kameramatrix. Im Anschluss daran, projiziert die Toolbox neue Schachbretteckpunkte als rote Kreuze zu sehen, zurück auf das Bild. Des Weiteren wird die Abweichung der Projektion zu erkannten Eckpunkten in Pixeln angegeben (siehe Abbildung oben rechts). Diese errechneten Parameter können an den MATLAB Workspace exportieren oder sie als Script speichern.<br><br> | |||
Um die VRmagic Kamera mit OpenCV zu kalibrieren müssen die ermittelten Werte in das C++ Programm übernommen werden. Danach muss das Kamerabild mit Hilfe der '''undistort'''-Funktion verändert werden. Die Funktion benötigt folgende Parameter:<br><br> | |||
<code><source lang=cpp> | |||
void undistort (InputArray Source, OutputArray Image, InputArray cameraMatrix, InputArray distCoeffs, InputArray newCameraMatrix=noArray()) | |||
</source> </code> | |||
* Source: Kamerabild in Graustufen (Datentyp: UMat, Mat) | |||
* Image: Kalibriertes Ausgabebild in Graustufen (Datentyp: UMat, Mat) | |||
* cameraMatrix: Die Kameramatrix erstellt aus der MATLAB Toolbox 3x3-Matrix | |||
* distCoeffs: Die Verzerrungsparameter erstellt aus der MATLAB Toolbox | |||
* newCameraMatrix: Für die Verwendung einer neuen Kameramatrix erstellt aus den verzerrten Bildern (standardmäßig = cameraMatrix) muss nicht extra angegeben werden. | |||
<br> | |||
[[Datei:Entzerrt.png|mini|x300px|right|Orginalbid (links) zu kalibriertem Bild (rechts)]] | |||
Nachdem die Parameter der Funktion übergeben wurden, erhält man ein entzerrtes Kamerabild. Es ist deutlich zu erkennen, dass die Straßemarkierungen im rechten Bild paralell verlaufen, wären im linken Bild eine deutliche Verzerrung vorliegt. | |||
<br> | |||
<br> | |||
<br> | |||
<br> | |||
<br> | |||
<br> | |||
<br> | |||
<br> | |||
==== Transformation in die Vogelperspektive ==== | |||
'''Autor:''' Luca Di-Lillo<br/> | |||
[[Datei: ROI bestimmung Draufsixht.jpg|mini|x230px|right|Bestimmung der region of interest]] | |||
Um die Linien optimal erkennen zu können, wurde eine Draufsicht auf die Straße erstellt. Für die Erstellung der Draufsicht OpenCV verwendet. Zuerst musste ausgewählt werden, aus welchem Bereich des Bildes eine Draufsicht erzeugt werden sollte, dazu wurde das Auto in einem Abstand von 200 mm vor das Schachbrettmuster in dem Fahrzeuglabor gestellt (siehe Abbildung "Bestimmung der region of interest") und mit der kalibrierten Kamera ein Bild von dem Schachbrett aufgenommen (siehe Abbildung "Bestimmung des zu transformierenden Bereichs"). Dann wurden vier Punkte in die Ecken der Rechtecke gezeichnet, aus denen sich ein großes Rechteck, dass den Bereich der Straße abbilden soll, ergibt. Die Pixelkoordinaten der region of interest (ROI) wurden gespeichert. | |||
Diese vier Punkte werden dann in einer Matrix, bestehend aus den x- und y-Koordinaten aller vier Punkte, gespeichert, mit Hilfe der OpenCV Funktion | |||
<code><source lang=cpp> | |||
getPerspectiveTransform(const Point2f src[], const Point2f dst[]) | |||
</source> </code> | |||
werden die gewählten Punkte, als neue Grenzwerte des Bildes definiert (siehe Abbildung "Transformierung der Koordinaten"). | |||
In der Abbildung ist gut zu erkennen, dass besonders das Bild im hinteren Bereich sehr gestreckt werden würde, deshalb interpoliert OpenCV an dieser Stelle, da das Ausgangs und Eingangsbild die selbe Größe haben. Ein weiterer Nachteil dieser Funktion ist, dass der Bereich außerhalb des blauen Rechtecks verloren geht und für weitere Bearbeitung in der Draufsicht nicht mehr genutzt werden kann, da allerdings die primäre Aufgabe der Kamera die Spur und die Stopplinien erkennen ist, ist es nicht von großer Bedeutung, dass große Teile des Bildes verloren gehen, solange die Spur in dem Bild zu erkennen ist. | |||
Die aktuelle Einstellung der Perspektiventransformation ist relativ einfach gehalten. Da die Eckpunkte des Schachbrettes per Hand mit einem Bildverarbeitungsprogramm erstellt wurden, sind die Werte ungenau. In Zukunft kann die Einstellung der Werte so realisiert werden, dass das Fahrzeug auf einen definierten Abstand zu einem Rechteck mit den Maßen der Straße gestellt wird, dieses Rechteck sollte im Kontrast zu der schwarzen Oberfläche stehen, sodass die Eckpunkt mit einer Kantenerkennung automatisch bestimmt werden können (siehe Abbildung "Konzept der Automatischen Kamerakalibierung"). Dadurch ist es möglich bei geänderter Kameraposition, die Werte schnell neu zu bestimmen. | |||
[[Datei: Bestimmung_des_Rechtecks.png|mini|x230px|left|Bestimmung des zu transformierenden Bereichs]] | |||
<div class="tleft" style="clear:none">[[Datei: Transformierung der Koordinaten.png|thumb|x230px|right|Transformierung der Koordinaten]]</div> | |||
[[Datei: Kalibrierung des autos Draufsicht.png|mini|x230px|zentriert|Konzept der Automatischen Kamerakalibierung]] | |||
Danach wird das Originalbild in eine Draufsicht transformiert, dazu wird die folgende Funktion verwendet. | |||
<code><source lang=cpp> | |||
warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar()) | |||
</source> </code> | |||
* scr ist das Originalbild | |||
* dst ist die neu erstellte Draufsicht | |||
* M ist die Koordinatentransformation, die mit getPerspectiveTransform erstellt wurde | |||
* dsize bestimmt die Größe des Ausgabebildes | |||
* flags bestimmt die Interpolationsmethode in diesem Fall Linear | |||
* borderMode ist die Pixel Extrapolationsmethode | |||
* borderValue wird bei der Extrapolationsmethode BORDER_CONSTANT gewählt und ist per default = 0 | |||
Nachdem diese Funktion ausgeführt wurde, kann man jetzt die Draufsicht sehen. In dem Beispiel (siehe Abbildung "Kamerabild und Draufsicht") wurde die Straße mit einem Schachbrett aufgenommen. In dem linken Bereich ist die normale Kameraperspektive mit einem blauen Rechteck, das den Bereich der Draufsicht darstellen soll, angezeigt. In dem rechten Bereich des Bildes ist die Draufsicht zu sehen, man kann gut erkennen, dass die Fahrbahnmarkierungen parallel zueinander stehen, die Rechtecke auf dem Schachbrettmuster alle die gleiche Größe haben und ebenfalls parallel zueinander sind. Im weiteren Verlauf, muss die Spurerkennung auf die Draufsicht angepasst werden, dazu muss diese Projekt in die [[OSE - Objekt - und Spurerkennung]] implementiert werden. Des Weiteren muss die Transformierung des Bildes noch auf dem Fahrzeug getestet werden, um die Rechenleistung zu minimieren, soll das Bild in ein Binärbild transformiert werden, da auf der Rundstrecke die Farben weiß für die Fahrbahnmarkierungen und schwarz für die Straße unterschieden werden müssen. | |||
[[Datei: Schachbrett auf transformierten Bild.PNG|thumb|1000px|zentriert|Kamerabild und Draufsicht]] | |||
=== Bestimmung des Fahrzeugfesten-Koordinatensystems === | |||
'''Autor:''' Tim Bexten<br/> | |||
Das Koordiantensystem für das Fahrzeug wurde vorgegeben durch das Schnittstellendokument. Es soll den Ursprung in der Mitte des Stoßfängers des Fahrzeugs haben. Die X-Achse soll in richtung der Hauptfahrtrichtung liegen und die Y-Achse soll orthogonal zur Fahrtrichtung und parallel zum Boden verlaufen. Der positive Abschnitt der Y-Achse befindet sich auf der linken Seite des Fahrzeuges, in Fahrtrichtung betrachtet.<br> | |||
Mit Hilfe dieser Vorgaben und dem festgelegten quadratischen Bereich, der vor dem Fahrzeug als Draufsicht beobachtet wird, können nun Rückschlüsse auf die realen Abstände vor dem Fahrzeug gezogen werden. Alle Punkte die erkannt werden können, sind innerhalb des weiß markierten Beieichs in Abbindung "Konzept der Automatischen Kamerakalibierung als Koordinatensystem" vorhanden.<br> | |||
==== Sichtbereich des Kameratestfahrzeugs ==== | |||
[[Datei: Kalibrierung des autos Draufsicht.png|mini|x230px|right|Konzept der Automatischen Kamerakalibierung als Koordinatensystem]] | |||
Der Sichtbereich auf der X-Achse beginnt, wie in Kapitel "Transformation in Vogelperspektive" beschrieben wurde, ab einem Abstand von 200 mm vor dem Fahrzeug. Die Breite auf der Y-Achse wurde anhand Anzahl der Schachbrettfelder und deren Breite bestimmt und auf 496,5 mm festgelegt. Mit Hilfe des selben Verfahrens wurde die Sichttiefe entlang der X-Achse ebenfalls auf einen Bereich von 1489,5 mm festgelegt. Daraus folgt, dass das Kamerafahrzeug in einem Bereich von [x = 200 mm bis 1689,5 mm und y = -248.25 mm bis 248.25 mm] das Straßenbild in Draufsicht erfassen kann. Somit ist ein körperfestes Koordinatensystem bestimmt, in dem erkannt Fahrspuren körperfest zum Fahrzeug mit einem definierten Abstand beschrieben werden können.<br> | |||
Das Kamerabild enthält in X-Richtung des Fahrzeug 478 Pixel und in Y-Richtung 752 Pixel. Die Umrechnung von Pixelkoordinaten in Fahrzeugkoordinaten findet über eine linear Transformation statt. Die Formel für die Umrechnungen sind folgende: | |||
<math> X Werte = x \; Pixel \cdot \frac{1489.5 mm}{478 Pixel} + 200 \; mm</math><br><br> | |||
<math> Y Werte = (y \; Pixel - 376\; Pixel \; Offset) \cdot \frac{496.5 \; mm}{752 \; Pixel} </math><br><br> | |||
Die daraus ermittelten Werte wurden getestet und im Testdokument "OSE_001_U_Pos_Draufsicht" dokumentiert und abgelegt. | |||
<br> | |||
==== Sichtbereich des Carolo-Cup-Fahrzeugs ==== | |||
Die Kalibrierung des Kamerafahrzeugs wurde nur für seperate Testzwecke vorgenommen. Um die KOS-Transformation auf dem vollständigen Carolo-Cup-Fahrzeug zu verwenden muss die Kalibrierung verändert werden, da auf dem Fahrzeug die Kamera an einer anderen Position verbaut ist.<br> | |||
Der Ablauf ist dennnoch der selbe, nur die Parameter des Sichtbereiches werden verändert. <span style="color:#FF0000"> BILD EINFÜGEN</span> <br> | |||
Die Formeln für die ROI ändern sich folgendermaßen:<br> | |||
<math> X Werte = x \; Pixel \cdot \frac{996 \; mm}{478 Pixel} + 461 \; mm</math><br><br> | |||
<math> Y Werte = (y \; Pixel - 376\; Pixel \; Offset) \cdot \frac{1162 \; mm}{752 \; Pixel} </math><br><br> | |||
=== Erkennen der Fahrspur === | |||
'''Autor:''' Luca Di Lillo<br/> | |||
[[Datei:Spurerkennung rechte Spur.png|mini|x200px|right|Fahrspur mit Spurerkennung, die horizontalen Linien beschreiben das Konzept]] | |||
Die Fahrbahn auf der Rundstrecke besteht aus weißen Linien auf schwarzem Hintergrund. Dadurch stehen diese im Kontrast zueinander und können über eine Kantenerkennung unterschieden werden. Um die Fahrspur zu erkennen wird sich nur auf den rechten Teil des Kamerabildes konzentriert, da die rechte Spur erkannt werden soll und somit der Rechenaufwand geringer wird. Der Ablauf der Spurerkennung gestalltet sich wie folgt, es wird an elf fest definierten Positionen in y-Richtung des Bildes in einer Schleife soweit nach rechts gelaufen, bis auf ein weißes Pixel gestoßen wird. Dieses Pixel wird als Spur angenommen und mit seinen x- und y-Koordinaten in einem Array gepspeichert. | |||
=== | === Berechnung des Spurpolynoms === | ||
'''Autor:''' Luca Di Lillo<br/> | |||
[[Datei:Spur mit Spurpolynom.png|mini|x200px|right|Spurerkennung mit Ausgabe des Spurpolynoms]] | |||
Damit das Fahrzeug geregelt entlang der ermittelten Fahrbahn fahren kann, muss ein Spurpolynom aus den erkannten Punkten auf der Fahrbahn ermittelt werden. Dazu wurde eine Funktion in Matlab geschrieben, die im [https://svn.hshl.de/svn/MTR_SDE_Praktikum/trunk/Software/Demos/Regression/Evaltuation_netwon_interpolation_beispiel_realewerte/polynom.m SVN Ordner] zu finden ist. Die Funktion erhält als Eingabeparameter eine Matrix mit einer Zeile in der n x-Werte stehen und eine Matrix mit einer Zeile in der n y-Werte stehen. Diese x- und y-Werte sind die Koordinaten der gefundenen Fahrspur. Ausgegeben werden die errechneten Koeffizienten für a, b und c, um eine Polynomfunktion der Form <math>y=ax^{2}+bx+c</math> zu bilden. Die Funktion arbeitet nach der [https://de.wikipedia.org/wiki/Polynominterpolation Newton Interpolation]. Damit die Funktion in dem C Programm der Kamera genutzt werden kann, muss aus dem Matlabcode C Code generiert werden. Dazu wird eine [https://de.wikipedia.org/wiki/Dynamic_Link_Library Dynamic Link Library (DLL)], sowie lib Dateien Header und C Code erzeugt, der dann in das Visual Studio Projekt eingebunden werden muss. Übergibt man der Funktion, die erkannten Punkte auf der Spur, wird das berechnete Spurpolynom in der Konsole ausgegeben. Das ausgegeben Spurpolynom kann in Matlab überprüft werden. Dazu wird mit den Koeffizient ein Polynomfunktion 2ten Grades gebildet und geplottet. In den selben Plot werden die einzelnen x- und y-Werte der gefundenen Spur eingetragen, dabei ist zu erkennen, dass die Funktion die Punkte miteinander verbindet. | |||
[[Datei:Plot aus Spurpolynom.png|mini|x200px|center|Plot aus Spurpolynom und Koordinaten]] |
Aktuelle Version vom 7. Februar 2020, 12:48 Uhr
Autoren: Luca_Di-Lillo, Tim Leonard Bexten
Betreuer: Prof. Schneider
Programmablaufplan des VRmagic-Kameraprogramms mit KOS-Transformation
Autor: Tim Bexten
Der Programmablaufplan zur Erstellung der Draufsicht ist in der Abbildung zur Rechten dargestellt. Er bau auf allen Erkenntnissen auf, die in dem folgenen Wiki-Artikel beschrieben werden.
Zu Beginn werden die benötigten Variablen und #define's beschrieben und deklariert. Im Anschluss daran wird geprüft, ob die Parameter für die RS232-Kommunikation angeglegt sind. Wenn dies der Fall ist, wird die Kommunikation mit der dSPACE Karte gestartet. Diese sendet die Daten des Spurpolynoms an die Querregelung des Fahrzeugs.
Wenn es nicht initaialisiert ist, startet der Verbindungsaufbau zur VRmagic Kamera dierekt. Wenn die Verbindung zur VRmagic Kamera hergestellt ist, werden die Einstellungen der VRmagic Kamera vorgenommen, wie Bespielsweise Belichtungszeit etc.
Danach sind alle Voreinstellungen vorgenommen worden und die Zyklusschleife kann beginnen.
Diese beginnt mit dem Aufnehmen Streckenbildes mit der VRmagic Kamera. Dieses Bild wird im VRmagic eigenen Dateiformat abgspeichert und in ein Graustufenbild gewandelt.
Um mit der OpenCV Bildverarbeitung weiterarbeiten zu können, muss das Dateiformat von OpenCV geändert werden. Dies wird mit dem Graustufenbild durchgeführt. Nachdem das geschehen ist, können alle OpenCV Funktionen genutzt werden.
Daraufhin wird eine Schwellwertfilterung durchgeführt, um weiße und schwarze Stellen gut unterscheiden zu können. Über diese Filterung wird alles über einem gewissen 8 Bit Wert als weiß und alles daruter als schwarz eingestuft. Danach werden die ermittelten Kameraprameter herausgerechnet um das Bild zu entzerren. Danach wird eine Draufsicht erstellt die aus einer ROI des normalen Kamerabildes erstellt. Das Erstellen dieser Draufsicht wird im Folgen Artikel erläutert. Um das Bild für die folgende Kantenerkennung durch den Canny-Edge Filter vorzubereiten, wird ein Gaußfilter über das Bild der Draufsicht gelegt, um das Rauschen zu unterdrücken und ein bessers Kantenbild zu ermöglichen. Aus dem Kantenbild werden nun die Fahrbahnpunkte errechnet. Dieses ist in einem definierten Fahrzeugkoordinatensystem abgelegt.
Aus den X und Y-Koordinaten der Fahrbahnpunkte wird ein Spurpolynom errechnt, welches den Kurvenverlauf vor dem Fahrzeug abbildet. Das Polynom wird mit den a,b und c Parametern einer quadratischen Gleichung angegeben. Diese Parameter werden, sofern die RS232 Kommunikation eingerichtet ist, über die Schnittstelle verschickt.
Die Zyklusschleife ist danach abgeschlossen und die Schleife beginnt von vorn.
Wenn die Zyklusschleife verlassen wurde, werden die RS232 Kommunikation und die VRmagic Kamera geschlossen und das Programm beendet.
Programmablaufplan des VRmagic-Kameraprogramms mit KOS-Transformation
Die Schnittpunkte werden ermittelt, indem das erste Pixel gesucht wird, welches nicht schwarz ist. Diese suche wird nur auf elf Linien durchgeführt. Auf diesen Linien wird von der Mitte des Bildes aus gesucht wo der Fahrbahnrand beginnt. Der gefunden Punkt wird im Fahrzeugkoordinatensystem in einem Array entsprechend abgespeichert.
Dies ist nur ein vorläufiges Konzept und kann für bessere Performance optimiert werden, um Kurven besser erkennen zu können.
Inbetriebnahme der Kamera
Ansteuerung mit CamLab am Fahrzeug
Autor: Tim Bexten
Um einen ersten Funktionstest der Kamera durchzuführen, wurde die Kamera über einen Ethernetkabel mit dem Laborrechner verbunden und das zugehörige Netzteil für die Stromversorgung angeschlossen. Das VRmagic Programm zum ausgeben des Kamerabildes "CamLab" ist auf allen Laborrechnern bereits installiert.
Falls es nicht installiert sein sollte, kann das Programm von der VRmagic Homepage heruntergeladen werden:
https://www.vrmagic.com/de/vrmagic-imaging/service-support/
Der richtige Typ der Software, für den entspechenden Rechner kann unter dem Punkt "USBPlattform/Software" ausgewählt und heruntergeladen werden, siehe Bild.
Nachdem das Programm heruntergeladen wurde, muss die ZIP-Datei entpackt werden und die "Setup"-Datei ausgeführt werden. Für nähere Informationen zur Installation, ist in der ZIP-Datei eine README-Dokument enthalten.
"WICHTIG: Admin-Rechte von Nöten!!!"
Nachdem die Installation erfolgreich abgeschlossen wurde, kann das Programm "CamLab" ausgeführt werden.
Nachdem das Programm geöffnet wurde kann die VRmagic Kamera mit dem CamLab kommunizieren. Die angeschlossene Kamera kann in dem Dropdown-Menü ausgewählt werden. Dies kann nach dem ersten mal anschließen etwas dauern, bis das Programm die Ethernetverbindung zur Kamera findet. Im Anschluss daran kann die Bildausgabe gestartet werden.
Wenn die Kamera ausgewählt wurde, öffnet sich ein erweiteretes Menü. In diesem Menü können alle möglichen Konfigurationen vorgenommen werden, die die VRmagic Kamera anbietet (Format, Timing, Sensor, Filter etc.). Mit einem Klick auf den Button "Grab" kann die Bildwiedergabe gestartet werden. Es können auch Snapshots erstellt werden, die auf dem Rechner gespeichert werden können.
Mit diesem Programm wurde ein erster Funktionstest der Kamera durchgeführt, welcher Grundlage für weitere Ansterungskonzepte mit Visual Studio ist.
Implementierung der Kamera in Visual Studio
Autor: Luca Di-Lillo
Die Kamera stellt Librarys für die Programmierung in C/C++ bereit, diese sind im SVN Ordner hinterlegt und müssen in die aktuelle Projektmappe im Explorer hinzugefügt werden.
In Visual Studio wählt man in dem Dropdown Menü in der oberen Leiste neben Debug x86 aus (siehe Abbildung Visual Studio auf x86 einstellen rotes Rechteck), ohne diese Einstellung lässt sich das Programm nicht kompilieren. Im nächsten Schritt wählt man in dem Fenster Projektmappen-Explorer mit einem Rechtsklick die Projektmappe aus und öffnet Eigenschaften. Die Konfiguration des Eigenschaftsfensters muss auf Debug eingestellt sein und die Plattform auf Aktiv(Win32) (siehe Abbildung Zusätzliche Includeverzeichnisse rote Rechtecke). In diesem Fenster wählt man als erstes die Registerkarte C/C++ aus (blaues Rechteck), dort fügt man jetzt unter dem Punkt Zusätzliche Includeverzeichnisse (grünes Rechteck), den Dateipfad C:\[Dateipfad auf eigenem Rechner]\VRMagic\include hinzu. Im nächsten Schritt muss man die Library Dateien mit dem Linker verlinken, dazu bleibt man in dem Eigenschaftsfenster und wählt die Registerkarte Linker aus und öffnet dort Allgemein (siehe Abbildung Zusätzliche Bibliotheksverzeichnisse rotes Rechteck). Dort wählt man jetzt den Punkt Zusätzliche Bibliotheksverzeichnisse (siehe grünes Rechteck) und fügt den Dateipfad C:\[Dateipfad auf eigenem Rechner]\VRMagic\lib hinzu. Nun öffnet man auch unter der Registerkarte Linker den Punkt Eingabe (siehe Abbildung Zusätzliche Abhängigkeiten rotes Rechteck), dort fügt man unter dem Punkt Zusätzliche Abhängigkeiten (siehe grünes Rechteck) folgendes hinzu:
- vrmusbcam2.lib
Bildverarbeitung
Installation von OpenCV
Autor: Luca Di-Lillo
Um das Kamerabild der VRMagic Kamera zu sehen und zu verabeiten wurde OpenCV verwendet. OpenCV bietet zahlreiche Möglichkeiten Bilder zu erkennen und zu verarbeiten.
Für dieses Projekt wurde OpenCV 3.0.0 (Downloadlink zu OpenCV 3.0.0) verwendet, da diese eine x86 (32-Bit) Version enthält, die nötig ist, um OpenCV mit der VRMagic in Visual Studio lauffähig zu machen. Denn die Kamera ist nur mit x86 kompatibel.
Nach abgeschlossenem Download, wird die OpenCV.exe gestartet und in einem gewünschten Verzeichnis installiert. Um OpenCV richtig zu implementieren, sucht man im Windows Suchmenü nach Systemsteuerung und dort wählt man die Einstellung System aus. Unter System wählt man nun als Administrator in der oberen linken Ecke Erweiterte Systemeinstellungen aus. Jetzt öffnet sich ein Fenster namens Systemeinstellungen, dort wählt man den Button Umgebungsvariablen aus und sucht dort in Systemvariablen, die Variable Path (siehe Abbildung Umgebungsvariablen) und wählt den Button Bearbeiten aus. Jetzt Öffnet sich das Fenster Umgebungsvariable bearbeiten (siehe Abbildung Umgebungsvariablen bearbeiten), dort betätigt man den Button Neu. Jetzt fügt man den Dateipfad zu den OpenCV bin Dateien hinzu C:\[Dateipfad auf eigenem Rechner]\openCV 3.0.0\opencv\build\x86\vc12\bin, dabei ist darauf zu achten, dass man x86 und vc12 auswählt, andere Konfigurationen sind mit der Kamera nicht lauffähig. Achtung bei einigen Windows Versionen sieht das Fenster Umgebungsvariablen bearbeiten anders aus, dort befindet sich lediglich eine Textbox mit verschiedenen Dateipfaden, sollte dies der Fall sein, trennt man den letzten Pfad mit einem Semikolon und fügt den Pfad zu OpenCV hinten an.
Nach diesen Einstellungen wird ein Projekt (Konsolenanwendung in C++) in Visual Studio geöffnet oder erstellt. In Visual Studio wählt man in dem Dropdown Menü in der oberen Leiste neben Debug x86 aus (siehe Abbildung Visual Studio auf x86 einstellen rotes Rechteck), ohne diese Einstellung lässt sich das Programm nicht kompilieren. Im nächsten Schritt wählt man in dem Fenster Projektmappen-Explorer mit einem Rechtsklick die Projektmappe aus und öffnet Eigenschaften. Die Konfiguration des Eigenschaftsfensters muss auf Debug eingestellt sein und die Plattform auf Aktiv(Win32) (siehe Abbildung Zusätzliche Includeverzeichnisse rote Rechtecke). In diesem Fenster wählt man als erstes die Registerkarte C/C++ aus (blaues Rechteck), dort fügt man jetzt unter dem Punkt Zusätzliche Includeverzeichnisse (grünes Rechteck), den Dateipfad C:\[Dateipfad auf eigenem Rechner]\openCV 3.0.0\opencv\build\include hinzu. Im nächsten Schritt muss man die Library Dateien mit dem Linker verlinken, dazu bleibt man in dem Eigenschaftsfenster und wählt die Registerkarte Linker aus und öffnet dort Allgemein (siehe Abbildung Zusätzliche Bibliotheksverzeichnisse rotes Rechteck). Dort wählt man jetzt den Punkt Zusätzliche Bibliotheksverzeichnisse (siehe grünes Rechteck) und fügt den Dateipfad C:\[Dateipfad auf eigenem Rechner]\openCV 3.0.0\opencv\build\x86\vc12\lib hinzu. Nun öffnet man auch unter der Registerkarte Linker den Punkt Eingabe (siehe Abbildung Zusätzliche Abhängigkeiten rotes Rechteck), dort fügt man unter dem Punkt Zusätzliche Abhängigkeiten (siehe grünes Rechteck) folgendes hinzu:
- opencv_ts300d.lib
- opencv_world300d.lib
Darstellung des Kamerabildes mit OpenCV
Autor: Luca Di-Lillo
Damit das Live Bild der Kamera mit OpenCV ausgegeben und verarbeitet werden kann muss dieses zuerst in den OpenCV Typ Mat gewandelt werden. Dazu benötigt man eine Hilfsfunktion, die das Farbformat von VRMagic in das Farbformat von OpenCV wandelt, die Funktion ist im folgenden dargestellt.
/***************************
*Quelle: VRmagic Holding AG*
****************************/
int toCvType(VRmColorFormat f_color_format)
{
int cv_type(-1);
switch (f_color_format)
{
case VRM_ARGB_4X8:
cv_type = CV_8UC4;
break;
case VRM_BGR_3X8:
cv_type = CV_8UC3;
break;
case VRM_BAYER_BGGR_8:
case VRM_BAYER_GBRG_8:
case VRM_BAYER_GRBG_8:
case VRM_BAYER_RGGB_8:
case VRM_GRAY_8:
cv_type = CV_8UC1;
break;
case VRM_BAYER_BGGR_16:
case VRM_BAYER_GBRG_16:
case VRM_BAYER_GRBG_16:
case VRM_BAYER_RGGB_16:
case VRM_GRAY_16:
cv_type = CV_16UC1;
break;
default:
break;
}
return cv_type;
}
Mit Hilfe der Funktion kann das Kamerabild jetzt in ein Mat gewandelt werden, dazu werden die Parameter des VRMagic Bildes an das Mat Bild übergeben. Danach wird der Mat Datentyp in ein UMat gewandelt, um die Auslastung der CPU zu verringern, mit Hilfe von imshow() wird das Bild dann in einem Fenster angezeigt.
VRmColorFormat color_format_src = p_gray_src_img->m_image_format.m_color_format;
/*Wandlung des Kamerabilds in ein Mat, um das Bild mit OpenCV zu verarbeiten*/
Mat src_image(cvSize(p_gray_src_img->m_image_format.m_width, p_gray_src_img->m_image_format.m_height), toCvType(color_format_src),(void*)p_gray_src_img->mp_buffer, p_gray_src_img->m_pitch);
src_image.copyTo(src_UMat_image); //Kopiert die Mat in eine UMat, um die Auslastung der CPU zu verringern
imshow("Live Bild", src_UMat_image); //Zeigt das Bild an
Kantendetektion in OpenCV mit Canny Edge
Autor: Tim Bexten
Nachdem das Kamerabild der VRmagic Kamera und in eine OpenCV-Matrix (UMat) umgewandelt wurde, kann eine Kantendetektion durchgeführt werden. OpenCV bietet verschiedene Algorithmen zur detektion von Kanten in einem Kamerabild an.
Für die Kantendetektion wurde der weit verbreitete Algorithmus Canny Edge verwendet. OpenCV bietet für diesen Anwendungsfall bereits eine vorgefertigte Funktion an.
void Canny (InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false )
- InputArray: Kamerabild in Graustufen (Datentyp: UMat, Mat)
- OutputArray: Binärbild mit Kanten (Datentyp: UMat, Mat)
- threshold1: Parameter 1 für Hysterese
- threshold2: Parameter 2 für Hysterese
- apertureSize: Einstellung des Sobel-Operators = 3
- L2gradient: Flag zur Angabe ob anderer Gradient berechnet werden soll (Vorgabe "false")
Die Funktion wird durch ihren Namen "Canny()" aufgerufen. Sie besitzt keinen Rückgabewert. Die Canny-Funktion besitzt zwei Hauptparameter. Als ersten Parameter benötigt die Funktion ein Graustufenbild indem die Kanten detektiert werden sollen, siehe Bild "Orginalbild der Strecke in Graustufen". Dies muss als eine Matrix übergeben werden. Der zweite Hauptparameter ist das Rückgabebild der Canny-Funktion, welches eine Matrix der selben Größe des Originalbildes ist und die detektierten Kanten in einem Binärbild enthält, siehe Bild "Binärbild der Strecke nach Kantendetektion".
Die nächsten zwei Parameter, threshold1 und threshold2 sind Schwellwerte für die Kantenerkennung. Diese double-Werte können für den jeweiligen Verwendungsfall angepasst werden. Sie sind Verantwortlich für das Edge linking der Canny-Funktion.
Die apertureSize stellt den Sobel-Operator ein, welchen die Canny-Funktion als Unterfunktion aufruft. Von der OpenCV Homepage wird empfolen diesen Interger-Wert auf "3" einzustellen.
Das letzte Argument L2gradient ist eine Flagge um der Funktion mitzuteilen, ob der Gradient des Bildes auf eine andere (genauere) Weise berechnet werden soll, siehe https://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=canny#canny86. Diese Bool-Variable wird standardmäßig auf "false" gesetzt.
Entzerrung des Kamerabildes
Autor: Tim Bexten
Wie in den vorhergegangenen Bildern zu sehen ist, weist das Kamerabild noch eine gewisse Verzerrung auf. Diese Verzerrungen entstehen durch die optischen Eigenschaften der Linse und dem internen Aufbau der Kamera. Diese Eigenschaften sind spezifisch für jedes Kamerasystem und sind somit unabhängig von der äußeren Bewegung und Position der Kamera. Diese Eigenschaften sind durch die optischen Komponenten, die fest in der Kamera verbaut sind bestimmt und somit bleiben sie beim Betrieb der Kamera immer konstant. Diese intrinsischen Kameraparameter werden benötigt, um den Zusammenhang zwischen den Punkten die auf den Pixeln des Kamerasensors abgebildet sind zu den echten Punkten in der Welt (Teststrecke) herzustellen.
Um die Abbildung der Bildpunkte die durch die Linse auf den Kamerasensor fallen darzustellen, muss eine Kalibrierungsmatrix K aufgestellt werden.
Diese Kalibrierungsmatrix beinhaltet die bauteilspezifischen Parameter die die Kamera beschreiben. Die Komponenten cx,cy geben die Verschiebung des Koordinatenursprungs der Pixelkoordinaten an. Der Nullpunkt der Kamerakoordinaten, welcher in er mitte der Linse liegt wird nicht auf den Nullpunkt der Pixelkoordinaten abgebildet, da das Pixelkoordinatensystem in den meisten Fällen unten links oder oben links seinen Ursprung hat. Somit muss eine Verschiebung berücksichtigt werden.
Des Weiteren müssen die Faktoren fx und fy brücksichtigt werden, die die Brennweite der Kamera beinhalten. Die Brennweite der Kamera gibt den Abstand der Linse zum Kamerasensor an.
Die letzte Variable, die in der Kameramatrix vorkommt, ist die Scherung der Pixel s. Die Scherung gibt an, in welchem Winkel der Kamerasensor zur Linse steht. Für die verbaute VRmagic Kamera ist der Kamerasensor paralell zur Linse verbaut, somit muss keine Scherung berücksichtigt werden und s = 0.
Für eine gelungene Kalibrierung muss auch die radiale Verzerrung der verbauten Linse der VRmagic Kamera bestimmt werden. Verzerrung bei Linsen tritt auf, wenn Licht an den Rändern einer Linse stärker gebrochen wird als im Linsenzentrum. Bei der radialen Verzerrung wird zwischen der Kissenförmigen- und Tonnenförmigen-Verzerrung unterschieden. Die VRmagic Kamera weist durch ihre Linse eine kissenförmige Verzerrung auf. Die stärke der Verzerrung eines Bildpunktes, ist Abhängig von dessen Abstand zum Bildmittelpunkt. Dieses Verhältnis lässt sich durch folgende Gleichungen ausdrücken:
Um diese Parameter zu bestimmen, müssen Bilder mit der VRmagic Kamera aufgenommen werden, bei denen ein Kalibrierungsobjekt mit bekannten Abmessungen aufgenommen wird.
Für diese Aufgabe wird die Camera Calibrator Toolbox genutzt um die Parameter des verbauten Kamerasystems automatisiert zu bestimmen. Die Toolbox befindet sich in MATLAB unter dem Reiter Apps / Image Processing and Computer Vision. Die Toolbox benötigt Kalibrierungsbilder von einem Schachbrettmuster mit bekannten Kantenlängen, wie in der Abbildung recchts zu sehen. Ein Schachbrettmuster wird verwendet, da das regelmäßige Muster des Schachbrettes einfach zu detektieren ist. Die Größe der einzelnen Kacheln auf dem Schachbrett muss zunächst vom Benutzer eingegeben werden.
Wenn die Kalibrierungsbilder in die Toolbox geladen wurden, kann man unter dem Reiter Options die radialen und tangentialen Verzerrungsparameter berechnen lassen. Durch einen Klick auf den Button Calibrate berechnet die Toolbox alle nötigen Verzerrungsparameter und die Kameramatrix. Im Anschluss daran, projiziert die Toolbox neue Schachbretteckpunkte als rote Kreuze zu sehen, zurück auf das Bild. Des Weiteren wird die Abweichung der Projektion zu erkannten Eckpunkten in Pixeln angegeben (siehe Abbildung oben rechts). Diese errechneten Parameter können an den MATLAB Workspace exportieren oder sie als Script speichern.
Um die VRmagic Kamera mit OpenCV zu kalibrieren müssen die ermittelten Werte in das C++ Programm übernommen werden. Danach muss das Kamerabild mit Hilfe der undistort-Funktion verändert werden. Die Funktion benötigt folgende Parameter:
void undistort (InputArray Source, OutputArray Image, InputArray cameraMatrix, InputArray distCoeffs, InputArray newCameraMatrix=noArray())
- Source: Kamerabild in Graustufen (Datentyp: UMat, Mat)
- Image: Kalibriertes Ausgabebild in Graustufen (Datentyp: UMat, Mat)
- cameraMatrix: Die Kameramatrix erstellt aus der MATLAB Toolbox 3x3-Matrix
- distCoeffs: Die Verzerrungsparameter erstellt aus der MATLAB Toolbox
- newCameraMatrix: Für die Verwendung einer neuen Kameramatrix erstellt aus den verzerrten Bildern (standardmäßig = cameraMatrix) muss nicht extra angegeben werden.
Nachdem die Parameter der Funktion übergeben wurden, erhält man ein entzerrtes Kamerabild. Es ist deutlich zu erkennen, dass die Straßemarkierungen im rechten Bild paralell verlaufen, wären im linken Bild eine deutliche Verzerrung vorliegt.
Transformation in die Vogelperspektive
Autor: Luca Di-Lillo
Um die Linien optimal erkennen zu können, wurde eine Draufsicht auf die Straße erstellt. Für die Erstellung der Draufsicht OpenCV verwendet. Zuerst musste ausgewählt werden, aus welchem Bereich des Bildes eine Draufsicht erzeugt werden sollte, dazu wurde das Auto in einem Abstand von 200 mm vor das Schachbrettmuster in dem Fahrzeuglabor gestellt (siehe Abbildung "Bestimmung der region of interest") und mit der kalibrierten Kamera ein Bild von dem Schachbrett aufgenommen (siehe Abbildung "Bestimmung des zu transformierenden Bereichs"). Dann wurden vier Punkte in die Ecken der Rechtecke gezeichnet, aus denen sich ein großes Rechteck, dass den Bereich der Straße abbilden soll, ergibt. Die Pixelkoordinaten der region of interest (ROI) wurden gespeichert. Diese vier Punkte werden dann in einer Matrix, bestehend aus den x- und y-Koordinaten aller vier Punkte, gespeichert, mit Hilfe der OpenCV Funktion
getPerspectiveTransform(const Point2f src[], const Point2f dst[])
werden die gewählten Punkte, als neue Grenzwerte des Bildes definiert (siehe Abbildung "Transformierung der Koordinaten"). In der Abbildung ist gut zu erkennen, dass besonders das Bild im hinteren Bereich sehr gestreckt werden würde, deshalb interpoliert OpenCV an dieser Stelle, da das Ausgangs und Eingangsbild die selbe Größe haben. Ein weiterer Nachteil dieser Funktion ist, dass der Bereich außerhalb des blauen Rechtecks verloren geht und für weitere Bearbeitung in der Draufsicht nicht mehr genutzt werden kann, da allerdings die primäre Aufgabe der Kamera die Spur und die Stopplinien erkennen ist, ist es nicht von großer Bedeutung, dass große Teile des Bildes verloren gehen, solange die Spur in dem Bild zu erkennen ist.
Die aktuelle Einstellung der Perspektiventransformation ist relativ einfach gehalten. Da die Eckpunkte des Schachbrettes per Hand mit einem Bildverarbeitungsprogramm erstellt wurden, sind die Werte ungenau. In Zukunft kann die Einstellung der Werte so realisiert werden, dass das Fahrzeug auf einen definierten Abstand zu einem Rechteck mit den Maßen der Straße gestellt wird, dieses Rechteck sollte im Kontrast zu der schwarzen Oberfläche stehen, sodass die Eckpunkt mit einer Kantenerkennung automatisch bestimmt werden können (siehe Abbildung "Konzept der Automatischen Kamerakalibierung"). Dadurch ist es möglich bei geänderter Kameraposition, die Werte schnell neu zu bestimmen.
Danach wird das Originalbild in eine Draufsicht transformiert, dazu wird die folgende Funktion verwendet.
warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
- scr ist das Originalbild
- dst ist die neu erstellte Draufsicht
- M ist die Koordinatentransformation, die mit getPerspectiveTransform erstellt wurde
- dsize bestimmt die Größe des Ausgabebildes
- flags bestimmt die Interpolationsmethode in diesem Fall Linear
- borderMode ist die Pixel Extrapolationsmethode
- borderValue wird bei der Extrapolationsmethode BORDER_CONSTANT gewählt und ist per default = 0
Nachdem diese Funktion ausgeführt wurde, kann man jetzt die Draufsicht sehen. In dem Beispiel (siehe Abbildung "Kamerabild und Draufsicht") wurde die Straße mit einem Schachbrett aufgenommen. In dem linken Bereich ist die normale Kameraperspektive mit einem blauen Rechteck, das den Bereich der Draufsicht darstellen soll, angezeigt. In dem rechten Bereich des Bildes ist die Draufsicht zu sehen, man kann gut erkennen, dass die Fahrbahnmarkierungen parallel zueinander stehen, die Rechtecke auf dem Schachbrettmuster alle die gleiche Größe haben und ebenfalls parallel zueinander sind. Im weiteren Verlauf, muss die Spurerkennung auf die Draufsicht angepasst werden, dazu muss diese Projekt in die OSE - Objekt - und Spurerkennung implementiert werden. Des Weiteren muss die Transformierung des Bildes noch auf dem Fahrzeug getestet werden, um die Rechenleistung zu minimieren, soll das Bild in ein Binärbild transformiert werden, da auf der Rundstrecke die Farben weiß für die Fahrbahnmarkierungen und schwarz für die Straße unterschieden werden müssen.
Bestimmung des Fahrzeugfesten-Koordinatensystems
Autor: Tim Bexten
Das Koordiantensystem für das Fahrzeug wurde vorgegeben durch das Schnittstellendokument. Es soll den Ursprung in der Mitte des Stoßfängers des Fahrzeugs haben. Die X-Achse soll in richtung der Hauptfahrtrichtung liegen und die Y-Achse soll orthogonal zur Fahrtrichtung und parallel zum Boden verlaufen. Der positive Abschnitt der Y-Achse befindet sich auf der linken Seite des Fahrzeuges, in Fahrtrichtung betrachtet.
Mit Hilfe dieser Vorgaben und dem festgelegten quadratischen Bereich, der vor dem Fahrzeug als Draufsicht beobachtet wird, können nun Rückschlüsse auf die realen Abstände vor dem Fahrzeug gezogen werden. Alle Punkte die erkannt werden können, sind innerhalb des weiß markierten Beieichs in Abbindung "Konzept der Automatischen Kamerakalibierung als Koordinatensystem" vorhanden.
Sichtbereich des Kameratestfahrzeugs
Der Sichtbereich auf der X-Achse beginnt, wie in Kapitel "Transformation in Vogelperspektive" beschrieben wurde, ab einem Abstand von 200 mm vor dem Fahrzeug. Die Breite auf der Y-Achse wurde anhand Anzahl der Schachbrettfelder und deren Breite bestimmt und auf 496,5 mm festgelegt. Mit Hilfe des selben Verfahrens wurde die Sichttiefe entlang der X-Achse ebenfalls auf einen Bereich von 1489,5 mm festgelegt. Daraus folgt, dass das Kamerafahrzeug in einem Bereich von [x = 200 mm bis 1689,5 mm und y = -248.25 mm bis 248.25 mm] das Straßenbild in Draufsicht erfassen kann. Somit ist ein körperfestes Koordinatensystem bestimmt, in dem erkannt Fahrspuren körperfest zum Fahrzeug mit einem definierten Abstand beschrieben werden können.
Das Kamerabild enthält in X-Richtung des Fahrzeug 478 Pixel und in Y-Richtung 752 Pixel. Die Umrechnung von Pixelkoordinaten in Fahrzeugkoordinaten findet über eine linear Transformation statt. Die Formel für die Umrechnungen sind folgende:
Die daraus ermittelten Werte wurden getestet und im Testdokument "OSE_001_U_Pos_Draufsicht" dokumentiert und abgelegt.
Sichtbereich des Carolo-Cup-Fahrzeugs
Die Kalibrierung des Kamerafahrzeugs wurde nur für seperate Testzwecke vorgenommen. Um die KOS-Transformation auf dem vollständigen Carolo-Cup-Fahrzeug zu verwenden muss die Kalibrierung verändert werden, da auf dem Fahrzeug die Kamera an einer anderen Position verbaut ist.
Der Ablauf ist dennnoch der selbe, nur die Parameter des Sichtbereiches werden verändert. BILD EINFÜGEN
Die Formeln für die ROI ändern sich folgendermaßen:
Erkennen der Fahrspur
Autor: Luca Di Lillo
Die Fahrbahn auf der Rundstrecke besteht aus weißen Linien auf schwarzem Hintergrund. Dadurch stehen diese im Kontrast zueinander und können über eine Kantenerkennung unterschieden werden. Um die Fahrspur zu erkennen wird sich nur auf den rechten Teil des Kamerabildes konzentriert, da die rechte Spur erkannt werden soll und somit der Rechenaufwand geringer wird. Der Ablauf der Spurerkennung gestalltet sich wie folgt, es wird an elf fest definierten Positionen in y-Richtung des Bildes in einer Schleife soweit nach rechts gelaufen, bis auf ein weißes Pixel gestoßen wird. Dieses Pixel wird als Spur angenommen und mit seinen x- und y-Koordinaten in einem Array gepspeichert.
Berechnung des Spurpolynoms
Autor: Luca Di Lillo
Damit das Fahrzeug geregelt entlang der ermittelten Fahrbahn fahren kann, muss ein Spurpolynom aus den erkannten Punkten auf der Fahrbahn ermittelt werden. Dazu wurde eine Funktion in Matlab geschrieben, die im SVN Ordner zu finden ist. Die Funktion erhält als Eingabeparameter eine Matrix mit einer Zeile in der n x-Werte stehen und eine Matrix mit einer Zeile in der n y-Werte stehen. Diese x- und y-Werte sind die Koordinaten der gefundenen Fahrspur. Ausgegeben werden die errechneten Koeffizienten für a, b und c, um eine Polynomfunktion der Form zu bilden. Die Funktion arbeitet nach der Newton Interpolation. Damit die Funktion in dem C Programm der Kamera genutzt werden kann, muss aus dem Matlabcode C Code generiert werden. Dazu wird eine Dynamic Link Library (DLL), sowie lib Dateien Header und C Code erzeugt, der dann in das Visual Studio Projekt eingebunden werden muss. Übergibt man der Funktion, die erkannten Punkte auf der Spur, wird das berechnete Spurpolynom in der Konsole ausgegeben. Das ausgegeben Spurpolynom kann in Matlab überprüft werden. Dazu wird mit den Koeffizient ein Polynomfunktion 2ten Grades gebildet und geplottet. In den selben Plot werden die einzelnen x- und y-Werte der gefundenen Spur eingetragen, dabei ist zu erkennen, dass die Funktion die Punkte miteinander verbindet.