SigSys15 Ampelphasenerkennung: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
 
(26 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 4: Zeile 4:
== Motivation ==
== Motivation ==
Ein Bild einer Ampel soll mittels eines MatLab-Programms auf die entsprechende Ampelphase ermittelt werden und die erkannte Phase soll im Bild eingezeichnet werden.
Ein Bild einer Ampel soll mittels eines MatLab-Programms auf die entsprechende Ampelphase ermittelt werden und die erkannte Phase soll im Bild eingezeichnet werden.
<br>
<br>
<br>


== Ziel ==
== Ziel ==
Eine Ampel soll anhand ihrer Ampelphase analysiert und diese ausgegeben werden.
Eine Ampel soll anhand ihrer Ampelphase analysiert und diese ausgegeben werden.
 
<br>
<br>
<br>


== Aufgabe ==
== Aufgabe ==
Zeile 15: Zeile 20:
#Berechnen, welche Phase die Ampel aktuell hat  
#Berechnen, welche Phase die Ampel aktuell hat  
#Markierung der Ampelphase im Bild  
#Markierung der Ampelphase im Bild  
 
<br>


== Einleitung ==
== Einleitung ==
Zeile 23: Zeile 28:


Das hier vorgestellte Projekt wurde mit MatLab 2014a entwickelt und getestet. Die Nutzung anderer Versionen, insbesonderer älterer MatLab Versionen, kann zu Fehler oder zu unerwarteten Ereignissen führen. Daher wird empfohlen MatLab 2014a zu nutzen.
Das hier vorgestellte Projekt wurde mit MatLab 2014a entwickelt und getestet. Die Nutzung anderer Versionen, insbesonderer älterer MatLab Versionen, kann zu Fehler oder zu unerwarteten Ereignissen führen. Daher wird empfohlen MatLab 2014a zu nutzen.
<br>
<br>
<br>


== Konzept und Projektplanung  ==
== Konzept und Projektplanung  ==
Zeile 76: Zeile 84:
<br><br><br>
<br><br><br>
<br><br><br>
<br><br><br>
<br>
<br>


== Projektablaufplan ==
== Projektablaufplan ==
Zeile 84: Zeile 94:


Zusätzlich sei an dieser Stelle angemerkt, dass der Projektablaufplan eine vereinfachte Darstellung des entwickelten Programms darstellt, um einen guten Überblick zu schaffen und eine einfache Einarbeitung in die Thematik zu ermöglichen. Im weiteren Verlauf werden konkrete Bezüge zur Farberkennung, Farbfilterung sowie Postionserkennung und der Funktionsweise erläutert. Insgesamt jedoch liegt das Augenmerk bei der robusten Farberkennung sowie einer robusten Unterscheidung der Farbe.
Zusätzlich sei an dieser Stelle angemerkt, dass der Projektablaufplan eine vereinfachte Darstellung des entwickelten Programms darstellt, um einen guten Überblick zu schaffen und eine einfache Einarbeitung in die Thematik zu ermöglichen. Im weiteren Verlauf werden konkrete Bezüge zur Farberkennung, Farbfilterung sowie Postionserkennung und der Funktionsweise erläutert. Insgesamt jedoch liegt das Augenmerk bei der robusten Farberkennung sowie einer robusten Unterscheidung der Farbe.
<br>
<br>
<br>
<br>
<br>
<br>
Zeile 112: Zeile 120:


Um effektiv eine Farbe im Bild zu filtern, wurde das RGB-Bild in den HSV-Farbraum (H=hue, S=saturation, V=value) übertragen. Dabei liefert dieser Farbraum den Farbwinkel, die Sättigung und die Helligkeit. Für das vorliegende Projekt ist der Farbwinkel von besonderer Bedeutung, da dieser alle Farbtöne in einer Variable erfasst. Um den Farbton mittels des Farbwinkels zu bestimmen wird eine Angabe von 0° bis 360° genutzt. Diese Angabe reicht aus, um alle benötigten Farben zu beschreiben. Durch den Farbton ist es nun möglich robust nach bestimmten Farben zu suchen bzw. nach diesen zu filtern. Des Weiteren gibt die Sättigung die Vermengung der Farbe mit weiß und die Helligkeit gibt die Amplitude des Lichts an. Der beschriebene Sachverhalt zu dem HSV-Farbraum kann ebenfalls aus der Abbildung 5 entnommen werden.<ref>[https://de.wikipedia.org/wiki/HSV-Farbraum]''Information zum HSV-Farbraum''. Wikipedia. Abgerufen am 17. Mai 2015.</ref>
Um effektiv eine Farbe im Bild zu filtern, wurde das RGB-Bild in den HSV-Farbraum (H=hue, S=saturation, V=value) übertragen. Dabei liefert dieser Farbraum den Farbwinkel, die Sättigung und die Helligkeit. Für das vorliegende Projekt ist der Farbwinkel von besonderer Bedeutung, da dieser alle Farbtöne in einer Variable erfasst. Um den Farbton mittels des Farbwinkels zu bestimmen wird eine Angabe von 0° bis 360° genutzt. Diese Angabe reicht aus, um alle benötigten Farben zu beschreiben. Durch den Farbton ist es nun möglich robust nach bestimmten Farben zu suchen bzw. nach diesen zu filtern. Des Weiteren gibt die Sättigung die Vermengung der Farbe mit weiß und die Helligkeit gibt die Amplitude des Lichts an. Der beschriebene Sachverhalt zu dem HSV-Farbraum kann ebenfalls aus der Abbildung 5 entnommen werden.<ref>[https://de.wikipedia.org/wiki/HSV-Farbraum]''Information zum HSV-Farbraum''. Wikipedia. Abgerufen am 17. Mai 2015.</ref>
<br>
<br>
<br>
<br>
<br>
Zeile 210: Zeile 216:


Abschließend ruft die Startdatei die Funktion "Modul_Ausgabe()" auf, welche dann anhand der Binärbilder die Ampelphase ausgibt und im originalen Bild die Position der Ampelphase einzeichnet. Für eine detailierte Beschreibung dieser Funktion siehe das Kapitel "Ausgabe der Ampelphase".
Abschließend ruft die Startdatei die Funktion "Modul_Ausgabe()" auf, welche dann anhand der Binärbilder die Ampelphase ausgibt und im originalen Bild die Position der Ampelphase einzeichnet. Für eine detailierte Beschreibung dieser Funktion siehe das Kapitel "Ausgabe der Ampelphase".
<br>
<br>
<br>
<br>
<br>
Zeile 264: Zeile 269:
[[Datei:Dialog_Bild_einlesen.jpg|gerahmt|links|x250px|Abbildung 6: Dialog zum einlesen von Bildern in MatLab]]
[[Datei:Dialog_Bild_einlesen.jpg|gerahmt|links|x250px|Abbildung 6: Dialog zum einlesen von Bildern in MatLab]]
Die obere Funktion gibt eine Information im Command-Window mit dem Befehl "disp()" aus, um den Anwender zu informieren, dass dieser ein Bild auswählen soll. Damit jedoch der Anwender ein Bild bequem aussuchen kann, wird mit dem Befehl "uigetfile()" ein Dialog aufgerufen, in welchem der Anwender sein Bilder auswählen kann. Der Dialog ist im Bild links dargestellt (Abbildung 6). Neben der Information im Command-Window, steht eine Information auf dem oberen Rahmen des Dialogs, welche noch einmal den Hinweis darauf gibt, dass ein Bild ausgesucht werden soll. Sobald der Anwender sein Bild ausgesucht hat, wird der Bildpfad und der Bildname gespeichert. Damit MatLab jedoch das Bild einlesen kann, muss der Pfad mittels "addpath()" für die MatLab Umgebung bekannt gemacht werden. Anschließend wird mithilfe des Bildnamens und des Befehls "imread()" das ausgesuchte Bild in der Variable "Bild" hinterlegt. Bevor die Funktion die Variable zurückliefert, erfolgt eine weitere Ausgabe im Command-Window. Diese informiert den Anwender darüber, dass jetzt tatsächlich nach der Ampelphase gesucht wird. Dieser Hinweis soll dem Anwender die Sicherheit geben, dass seine Bildauswahl erfolgreich war und das die Software jetzt weiter arbeitet und nicht abgestürtzt ist.
Die obere Funktion gibt eine Information im Command-Window mit dem Befehl "disp()" aus, um den Anwender zu informieren, dass dieser ein Bild auswählen soll. Damit jedoch der Anwender ein Bild bequem aussuchen kann, wird mit dem Befehl "uigetfile()" ein Dialog aufgerufen, in welchem der Anwender sein Bilder auswählen kann. Der Dialog ist im Bild links dargestellt (Abbildung 6). Neben der Information im Command-Window, steht eine Information auf dem oberen Rahmen des Dialogs, welche noch einmal den Hinweis darauf gibt, dass ein Bild ausgesucht werden soll. Sobald der Anwender sein Bild ausgesucht hat, wird der Bildpfad und der Bildname gespeichert. Damit MatLab jedoch das Bild einlesen kann, muss der Pfad mittels "addpath()" für die MatLab Umgebung bekannt gemacht werden. Anschließend wird mithilfe des Bildnamens und des Befehls "imread()" das ausgesuchte Bild in der Variable "Bild" hinterlegt. Bevor die Funktion die Variable zurückliefert, erfolgt eine weitere Ausgabe im Command-Window. Diese informiert den Anwender darüber, dass jetzt tatsächlich nach der Ampelphase gesucht wird. Dieser Hinweis soll dem Anwender die Sicherheit geben, dass seine Bildauswahl erfolgreich war und das die Software jetzt weiter arbeitet und nicht abgestürtzt ist.
<br>
<br>
<br>
<br>
<br>
Zeile 385: Zeile 391:
Aus dem Quellcode geht hervor, dass die obige Funktion ein Bild als Eingabeparamter übergeben bekommt. Anschließend erfolgt eine Konvertierung des RGB-Bildes in den HSV-Farbraum. Darauffolgend werden die Farbwerte des Bildes in die Variable "Farbwert", sowie die der Sättigung in die Variable "Sättigung" gespeichert. Im nächsten Schritt erfolgt die Erfassung aller Pixel, die einen geringen Grünanteil besitzen und werden auf ihre Grauwerte reduziert. Das Ergebnis ist in der linken Abbildung zu sehen.  Werden jetzt Abbildung 7 und Abbildung 9 verglichen, so ist deutlich zu erkennnen, dass die Abbildung 9 weniger Farben besitzt. Dieser Schritt ist insofern nützlich, da dieser nicht relevante Informationen aus dem Bild entfernt bzw. reduziert. Allerdings sind die grünen Pixel der Büsche und Bäume noch da. Damit diese nicht zufällig als die grüne Ampelphase erkannt werden, erfolgt im weiteren Verlauf mithilfe der for-Schleifen eine weitere Filterung. Hierbei  
Aus dem Quellcode geht hervor, dass die obige Funktion ein Bild als Eingabeparamter übergeben bekommt. Anschließend erfolgt eine Konvertierung des RGB-Bildes in den HSV-Farbraum. Darauffolgend werden die Farbwerte des Bildes in die Variable "Farbwert", sowie die der Sättigung in die Variable "Sättigung" gespeichert. Im nächsten Schritt erfolgt die Erfassung aller Pixel, die einen geringen Grünanteil besitzen und werden auf ihre Grauwerte reduziert. Das Ergebnis ist in der linken Abbildung zu sehen.  Werden jetzt Abbildung 7 und Abbildung 9 verglichen, so ist deutlich zu erkennnen, dass die Abbildung 9 weniger Farben besitzt. Dieser Schritt ist insofern nützlich, da dieser nicht relevante Informationen aus dem Bild entfernt bzw. reduziert. Allerdings sind die grünen Pixel der Büsche und Bäume noch da. Damit diese nicht zufällig als die grüne Ampelphase erkannt werden, erfolgt im weiteren Verlauf mithilfe der for-Schleifen eine weitere Filterung. Hierbei  
findet eine zielgereichtete Suche nach den benötigten Pixel statt. Die in den for-Schleifen eingestellten Werte wurden dabei empirisch bei verschiedenen Bilder, mit grünen Ampelphasen, ermittelt. Das Besondere hierbei ist, dass alle Pixel, die nicht in das Schema passen, "entfernt" werden. Das bedeutet, dass jedes Pixel, welches nicht den gesuchten Wert aufweist, wird auf "0" gesetzt, d.h. das dieses Pixel schwarz gefärbt wird. Das Ergebnis dieser Filterung kann in der rechten Abbildung (Abbildung 10) betrachtet werden. Aus dieser ist deutlich zu entnehmen, dass nur die grüne Farbe der Ampelphase noch zu sehen ist. Allerdings ist an dieser Stelle die Funktion noch nicht beendet. Das HSV-Bild wird zurück in den RGB-Farbraum konvertiert und anschließend als Binärbild gespeichert. Das Binärbild enthält an der Stelle der grünen Pixel nun weiße Pixel. Die Farbe selbst wird im weiteren Verlauf nicht mehr benötigt, sondern nur die Pixel. Des Weiteren wird dieses Binärbild in die Variable "BinaerBild_gruen" in der Startdatei hinterlegt, damit eine nachträgliche Verwechslung, um welche gefundene Ampelphase es sich handeln könnte, ausgeschlossen wird. Dadurch wird das originale Bild ausschließlich auf die grüne Ampelphase reduziert. Der Vorteil dieser starken Reduzierung liegt in der Einfachheit der Variable. Wenn diese in MatLab geöffnet wird, wird eine große Matrix mit vielen Nullen angezeigt. An den Stellen, an denen die grünen Pixel der Ampelphase gefunden wurden, steht eine "1". Dies ermöglicht ein einfaches und schnelles Arbeiten mit diesem Bild, da keine weiteren Informationen stören bzw. Einfluss nehmen.
findet eine zielgereichtete Suche nach den benötigten Pixel statt. Die in den for-Schleifen eingestellten Werte wurden dabei empirisch bei verschiedenen Bilder, mit grünen Ampelphasen, ermittelt. Das Besondere hierbei ist, dass alle Pixel, die nicht in das Schema passen, "entfernt" werden. Das bedeutet, dass jedes Pixel, welches nicht den gesuchten Wert aufweist, wird auf "0" gesetzt, d.h. das dieses Pixel schwarz gefärbt wird. Das Ergebnis dieser Filterung kann in der rechten Abbildung (Abbildung 10) betrachtet werden. Aus dieser ist deutlich zu entnehmen, dass nur die grüne Farbe der Ampelphase noch zu sehen ist. Allerdings ist an dieser Stelle die Funktion noch nicht beendet. Das HSV-Bild wird zurück in den RGB-Farbraum konvertiert und anschließend als Binärbild gespeichert. Das Binärbild enthält an der Stelle der grünen Pixel nun weiße Pixel. Die Farbe selbst wird im weiteren Verlauf nicht mehr benötigt, sondern nur die Pixel. Des Weiteren wird dieses Binärbild in die Variable "BinaerBild_gruen" in der Startdatei hinterlegt, damit eine nachträgliche Verwechslung, um welche gefundene Ampelphase es sich handeln könnte, ausgeschlossen wird. Dadurch wird das originale Bild ausschließlich auf die grüne Ampelphase reduziert. Der Vorteil dieser starken Reduzierung liegt in der Einfachheit der Variable. Wenn diese in MatLab geöffnet wird, wird eine große Matrix mit vielen Nullen angezeigt. An den Stellen, an denen die grünen Pixel der Ampelphase gefunden wurden, steht eine "1". Dies ermöglicht ein einfaches und schnelles Arbeiten mit diesem Bild, da keine weiteren Informationen stören bzw. Einfluss nehmen.
<br>
<br>
<br>
<br>
<br>
Zeile 630: Zeile 635:
[[Datei:Gelb_Ampelphase_reduziert.jpg|gerahmt|rechts|x220px|Abbildung 14: gelbe Ampelphase mit reduzierten Farbwerten]]
[[Datei:Gelb_Ampelphase_reduziert.jpg|gerahmt|rechts|x220px|Abbildung 14: gelbe Ampelphase mit reduzierten Farbwerten]]
Die oben dargelegte Funktion geht bei der Filterung genauso vor, wie bei den beiden anderen Ampelphasenerkennungen auch. Allerdings sind hier die Werte für die Filterung angepasst. Die linke Abbildung (Abbildung 13) zeigt eine gelbe Ampelphase, welche stark mit Sonnenstrahlen "belichtet" ist, sodass das obere Verkehrszeichen "gelber" ist als die Ampelphase selbst. Allerdings kann der Filter hier Zielgerichtet die gelbe Ampelphase erkennen (siehe Abbidlung 14).   
Die oben dargelegte Funktion geht bei der Filterung genauso vor, wie bei den beiden anderen Ampelphasenerkennungen auch. Allerdings sind hier die Werte für die Filterung angepasst. Die linke Abbildung (Abbildung 13) zeigt eine gelbe Ampelphase, welche stark mit Sonnenstrahlen "belichtet" ist, sodass das obere Verkehrszeichen "gelber" ist als die Ampelphase selbst. Allerdings kann der Filter hier Zielgerichtet die gelbe Ampelphase erkennen (siehe Abbidlung 14).   
<br>
<br>
<br>
<br>
<br>
Zeile 845: Zeile 851:
Das Projekt der Ampelphasenerkennung war eine spannende und herausfordernde Aufgabe. Dadurch konnten viele wichtige Erkenntnisse über die Farbräume sowie den Aufbau von digitalen Bildern gesammelt werden. Die Komplexitität bzw. größte Schwierigkeit des Projektes war die Ermittlung korrekter Werte für die Filterung, da diese in keiner Literatur bzw. Webseiten behandelt wurden. Auch die Verifizierung der Ergebnisse, dass die Ampelphase tageszeitunabhängig gefunden werden muss, war eine anspruchsvolle Aufgabe.   
Das Projekt der Ampelphasenerkennung war eine spannende und herausfordernde Aufgabe. Dadurch konnten viele wichtige Erkenntnisse über die Farbräume sowie den Aufbau von digitalen Bildern gesammelt werden. Die Komplexitität bzw. größte Schwierigkeit des Projektes war die Ermittlung korrekter Werte für die Filterung, da diese in keiner Literatur bzw. Webseiten behandelt wurden. Auch die Verifizierung der Ergebnisse, dass die Ampelphase tageszeitunabhängig gefunden werden muss, war eine anspruchsvolle Aufgabe.   
Insgesamt betrachtet, kann über das vorliegende Projekt gesagt werden, dass es in der Lage ist robust bei einer Ampel alle Ampelphasen zu erkennen, unabhänigig von der Tageszeit. Außerdem bietet das Projekt aufgrund des modularen Aufbaus einen Mehrwert für andere Projekte, da die Module bzw. die Funktionen einfach kopiert und ggf. die Parameter angepasst werden können.
Insgesamt betrachtet, kann über das vorliegende Projekt gesagt werden, dass es in der Lage ist robust bei einer Ampel alle Ampelphasen zu erkennen, unabhänigig von der Tageszeit. Außerdem bietet das Projekt aufgrund des modularen Aufbaus einen Mehrwert für andere Projekte, da die Module bzw. die Funktionen einfach kopiert und ggf. die Parameter angepasst werden können.
<br>
<br>
<br>
<br>
<br>
Zeile 850: Zeile 857:
== Ausblick ==
== Ausblick ==
Das Projekt Ampelphasenerkennung kann in der aktuellen Form immer noch erweitert werden. Beispielsweise könnte das Projekt so erweitert werden, dass es defekte Ampeln (keine Ampelphase vorhanden) erkennen kann und somit rät die Verkehrszeichen zu nutzen.
Das Projekt Ampelphasenerkennung kann in der aktuellen Form immer noch erweitert werden. Beispielsweise könnte das Projekt so erweitert werden, dass es defekte Ampeln (keine Ampelphase vorhanden) erkennen kann und somit rät die Verkehrszeichen zu nutzen.
<br>
<br>
<br>


== Youtube-Video ==
== Youtube-Video ==
Zum Projektabschluss fand eine Videoaufnahme, um die Ergebnisse des Projekts "Ampelphasenerkennung" aufzuzeigen, statt. Das Youtube-Video befindet sich unter dem folgendem Link [https://www.youtube.com/watch?v=edRw6M5H7Q4].
Zum Projektabschluss fand eine Videoaufnahme, um die Ergebnisse des Projekts "Ampelphasenerkennung" aufzuzeigen, statt. Das Youtube-Video befindet sich unter dem folgendem Link [https://www.youtube.com/watch?v=edRw6M5H7Q4].
<br>
<br>
<br>


== Download des Pogramms ==
== Download des Pogramms ==
Das Programm kann hier heruntergeladen werden: [[Datei:Ampelphasenerkennung MatLab 2014a.zip]]
Das Programm kann hier heruntergeladen werden: [[Datei:Ampelphasenerkennung MatLab 2014a.zip]]
<br>
<br>
<br>


== Ampelbilder zum Testen des Programms ==
== Ampelbilder zum Testen des Programms ==
Zeile 870: Zeile 886:


</gallery>
</gallery>
<br>


== Quellen ==
== Quellen ==

Aktuelle Version vom 21. Juni 2015, 20:31 Uhr

Autor: Andre Merkel
Betreuer: Prof. Schneider

Motivation

Ein Bild einer Ampel soll mittels eines MatLab-Programms auf die entsprechende Ampelphase ermittelt werden und die erkannte Phase soll im Bild eingezeichnet werden.


Ziel

Eine Ampel soll anhand ihrer Ampelphase analysiert und diese ausgegeben werden.


Aufgabe

  1. Einarbeitung in die Farberkennung
  2. Bild einlesen und Farbe filtern
  3. Erkennung von Farben bei unterschiedlichen Tageszeiten
  4. Berechnen, welche Phase die Ampel aktuell hat
  5. Markierung der Ampelphase im Bild


Einleitung

Im Rahmen der Lehrveranstaltung „Signalverarbeitende Systeme“ des Studiengangs „Business and Systems Engineering“ im Sommersemester 2015 gab es die Aufgabe ein Projekt im Bereich der Bildverarbeitung durchzuführen. Die vorliegende Dokumentation befasst sich mit dem Auswerten von Ampelphasen.

Detailliert bestand die Aufgabe darin, ein Bild mit einer Ampel einzulesen und diese anschließend zu analysieren. Da es sich um Ampelphasen handelt, ist die Erkennung von Farben besonders relevant für dieses Projekt. Zusätzlich sollten die Ampelphasen ungeachtet der Tageszeit (Tag oder Nacht) stabil erkannt werden. Sobald die Ampelphase erkannt wurde, sollte ebenfalls diese auf dem Bild gekennzeichnet werden.

Das hier vorgestellte Projekt wurde mit MatLab 2014a entwickelt und getestet. Die Nutzung anderer Versionen, insbesonderer älterer MatLab Versionen, kann zu Fehler oder zu unerwarteten Ereignissen führen. Daher wird empfohlen MatLab 2014a zu nutzen.


Konzept und Projektplanung

Im folgenden wird das Konzept und die Projektplanung vorgestellt:

0 Festlegung des Projektthemas innerhalb der Lehrveranstaltung „Signalverarbeitende Systeme“


1 Projektvorbereitung

1.1 Recherche über Farbräume und digitale Bilder

1.2 Planung der anstehenden Aufgaben

1.3 Einarbeitung in die Farbfilterung und Farbreduzierung


2 Projektdurchführung

2.1 Entwurf eines Black-Box-Modell

2.2 Entwicklung mehrere Farbfilter Algorithmen

2.3 Farbfilter testen

2.4 Farbfilter bewerten und auswählen

2.5 Implementierung eines Farbfilters

2.6 Implementierung Nebenfunktionen (z.B. Funktion zum einfügen von Bildern)

2.7 Umfangreiche Tests der Software und Anpassung von Parameter


3 Projektabschluss

3.1. Auswertung des Projekts

3.2. Abschließen der Dokumentation

Im fogenden ist ein Gantt-Diagramm sowie eine dazugehörige Zeitachse, welche mit dem Programm MS Project 2013 erstellt wurden. Dabei wurde das Diagramm erstellt und nach diesem gearbeitet.

Abbildung 1: Gantt-Diagramm der Ampelphasenerkennung
Abbildung 2: Zeitachse der Ampelphasenerkennung



























Projektablaufplan

Abbildung 3: Projektablaufplan der Ampelphasenerkennung

In diesem Kapitel wird die Funktionsweise der Ampelphasenerkennung näher erläutert. In der linken Abbildung (Abbildung 3) ist die Struktur des Programms hinterlegt. Zu Beginn muss das Hauptprogramm aufgerufen werden, welches ein Bild einliest. Nachdem dies geschehen ist, leitet das Hauptprogramm das eingelesene Bild an die Farbfilterung und Farbreduzierung weiter. Hierbei wird das eingelesene Bild nur auf die gesuchte Farbe gefiltert und alle anderen Farben werden aus dem Bild entfernt, sodass innerhalb diesen Schritts alle nicht gesuchten Farben auf ihre Grauwerte reduziert werden. Dieser Vorgang ist sehr entscheidend für das weitere Vorgehen, denn der Einfluss anderer Farben soll auf die Ampelphasenerkennung so gering wie möglich sein. Im selben Schritt erfolgt ebenfalls die Betrachtung des Bildes, ob die entsprechenden Farben "grün", "gelb" und "rot" vorliegen. An dieser Stelle sei angemerkt, dass die Farben der Ampel sich nur bedingt von denen der in der Natur vorkommenen Farben unterscheiden. Da nun das Bild auf die gesuchten Farben reduziert wurde, wird nach diesen explizit gesucht. Wird eine entsprechende Farbe gefunden, so wird das Bild weitergeleitet, um festzustellen welche Farbe tatsächlich gefunden wurde. Nach der Ermittlung der Farbe, wird die Position der gefundenen Ampelphase mit einem roten Viereck im Ursprungsbild eingezeichnet. Dadurch hat der Anwender die Bestätigung, dass die Ampelphase gefunden wurde.

Zusätzlich sei an dieser Stelle angemerkt, dass der Projektablaufplan eine vereinfachte Darstellung des entwickelten Programms darstellt, um einen guten Überblick zu schaffen und eine einfache Einarbeitung in die Thematik zu ermöglichen. Im weiteren Verlauf werden konkrete Bezüge zur Farberkennung, Farbfilterung sowie Postionserkennung und der Funktionsweise erläutert. Insgesamt jedoch liegt das Augenmerk bei der robusten Farberkennung sowie einer robusten Unterscheidung der Farbe.












Farbraum in MatLab

Abbildung 4: RGB-Farbraum [1]
Abbildung 5: HSV-Farbraum [2]

In diesem Kapitel wird der eingesetzte Farbraum, in welchem gearbeitet wird, näher erläutert. Durch dieses Kapitel wird eine Grundlage und das Verständnis für späteres Vorgehen geschaffen.

Das Einlesen von Bildern in MatLab geschieht mit dem Befehl "imread()", welcher eine Bilddatei als Variable in den Workspace speichert. Das Bild selbst liegt nun in MatLab im RGB-Farbraum. Charakteristisch für diesen Farbraum ist zunächst, dass diese Variable in MatLab als eine Matrix vorliegt. Allerdings besitzt diese Matrix neben Zeilen und Spalten auch eine Angabe für den jeweiligen Farbton. Dabei wird diese Farbangabe mit RGB abgekürtzt. Die Abkürzung RGB steht für R = rot, G = grün und B = blau. Das beudetet, dass jedes Pixel im Bild durch seine Position gekennzeichnet ist und aus der Mischung aus den Werten R, G und B besteht. Dabei liegen die RGB-Werte im Intervall von 0 bis 255. Das bedeutet, dass ein Farbton aus der Mischung von drei Zahlen repräsentiert wird. Hierdurch ergibt sich, dass Farben, wie blau, einen gewissen Anteil an rot und grün besitzen. Allerdings gibt es auch die Möglichkeit, einen oder zwei Farbangaben auf null zu setzen, um einen entsprechenden Farbton zu erhalten. Der beschriebene Sachverhalt zu dem RGB-Farbraum kann ebenfalls aus der Abbildung 4 entnommen werden.

Liegt ein Bild im RGB-Farbraum vor, so kann dieses mit dem Befehl "imshow()" angezeigt werden. Das menschliche Auge empfindet die Darstellung von RGB-Bildern als natürlich und anschaulich. Allerdings ist dieser Farbraum weniger geeignet, um in diesem zu arbeiten. Die Problematik dabei ergibt sich, dass jeder Farbton durch drei Zahlen repräsentiert wird. Eine Filterung bzw. die Suche nach einer bestimmten Farbe geht immer mit der Prüfung aller drei Werte einher. Außerdem ändert sich der Farbton eines Objektes in Abhängigkeit seiner Belichtung. Das bedeutet, dass auch die drei Werte (RGB) sich ändern. Daher ist eine Farbfilterung in einem RGB-Raum ungegeignet.[3]

Um effektiv eine Farbe im Bild zu filtern, wurde das RGB-Bild in den HSV-Farbraum (H=hue, S=saturation, V=value) übertragen. Dabei liefert dieser Farbraum den Farbwinkel, die Sättigung und die Helligkeit. Für das vorliegende Projekt ist der Farbwinkel von besonderer Bedeutung, da dieser alle Farbtöne in einer Variable erfasst. Um den Farbton mittels des Farbwinkels zu bestimmen wird eine Angabe von 0° bis 360° genutzt. Diese Angabe reicht aus, um alle benötigten Farben zu beschreiben. Durch den Farbton ist es nun möglich robust nach bestimmten Farben zu suchen bzw. nach diesen zu filtern. Des Weiteren gibt die Sättigung die Vermengung der Farbe mit weiß und die Helligkeit gibt die Amplitude des Lichts an. Der beschriebene Sachverhalt zu dem HSV-Farbraum kann ebenfalls aus der Abbildung 5 entnommen werden.[4]








Startdatei

In diesem Kapitel findet die Vorstellung und Erläuterung der Startdatei statt, sowie eine Einleitung in die Funktionsweise sowie den konkreten Aufbau der entwickelten Software.

Insgesamt betrachtet, ist die entwickelte Software modular aufgebaut, da dies viele Vorteile mit sich bringt und heutzutage ein Standard in der Entwicklung von Softwareprojekten darstellt. Die modulare Programmierung hat den besonderen Vorteil, dass jedes Modul für sich alleine entwickelt und getestet werden kann, ohne dass das gesamte Projekt fertig sein muss. Außerdem können Verbesserung an den einzelnen Modulen unabhängig voneinander geschehen, auch dann wenn das Projekt fertig ist. Das liegt darin, das an sich nur die Schnittstellen eingehalten werden müssen, da die Logik in den Modulen vom Rest der Software gekapselt ist. Dies ermöglicht auch das Austauschen von Modulen bei einem fertigen Projekt, ohne dass an anderen Stellen der Software der Quellcode angepasst werden muss. Ein weiterer Vorteil der modularen Programmierung ist die Wiederverwendbarkeit von den Modulen. Wie bereits erwähnt, ist die Logik der Module vom restlichen Quellcode gekapselt und kann daher selbst in anderen Projekten einbezogen werden, sofern die Schnittstellen eingehalten werden.

Im nächsten Schritt wird die Startdatei betrachtet. Diese heißt "HauptSkript.m" und dient dem koordiniertem Aufruf von Funktionen, um die Ampelphasen zu erkennen. Um den Aufbau des Projekts besser zu erläutern wird zunächst der Quellcode betrachtet:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              Signalverarbeitende Systeme               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Projekt:     Ampelphasenerkennung                      %
%                                                        %
% Autor:       Andre Merkel                              %
%                                                        %
% Studiengang: Business and Systems Engineering          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%                                                        %
% Beschreibung: Mit diesem Skript wird die               %
%               Ampelphasenerkennung ge-                 %
%               startet.                                 %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% Implementierung: MatLab 2014a                          %     
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% letzte Änderung: 28.05.2015                            %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all
close all
clc

%% Bild einlesen
Bild = Modul_Bild_einlesen;

%% Bild nach farb-Pixel absuchen

BinaerBild_gruen = 0;
BinaerBild_gelb  = 0;
BinaerBild_rot   = 0;

% Feststellung der grünen Ampelphase
BinaerBild_gruen = Modul_gruen_erkennen(Bild);


% Feststellung der roten bzw. rot-gelben Ampelphase
if (length(find(BinaerBild_gruen==1))) == 0
    
    % Erfassung der roten Ampelphase
    BinaerBild_rot = Modul_rot_erkennen(Bild);
 
    % Erfassung der gelben Ampelphase
    BinaerBild_gelb = Modul_gelb_erkennen(Bild);
 
    % Auswertung der rot-gelben Ampelphase (falls vorhanden)
    if (length(find(BinaerBild_rot(:,:)==1))) > 0  && (length(find(BinaerBild_gelb(:,:)==1))) > 0
   
        % Auswertung, ob es sich tatsächlich um eine rot-gelbe Ampelphase handelt
        [BinaerBild_rot, BinaerBild_gelb] = Modul_rot_gelb_Auswertung(BinaerBild_rot, BinaerBild_gelb);
    
    end
 
end


%% Ausgabe
Modul_Ausgabe(BinaerBild_gruen, BinaerBild_gelb, BinaerBild_rot, Bild);


Zu Beginn des Skripts erfolgt der Aufruf von "clear all", "close all" und "clc" Befehlen. Dies sorgt dafür, dass alle Variablen aus dem Workspace gelöscht, alle geöffneten Figuren geschlossen werden und das Command-Window bereinigt wird. Diese Vorgehenweise sorgt dafür, dass keine Variablen einen Einfluss auf die Ausführung des Projekts ausüben können.

Im nächsten Schritt erfolgt das Einlesen eines ausgewählten Bildes, welches in die Variable "Bild" gespeichert wird. Für eine detailierte Beschreibung dieser Funktion siehe das Kapitel "Bilder einlesen".

Nach dem Einlesen des Bildes findet eine Initialsierung der Variablen "BinaerBild_gruen", "BinaerBild_gelb" und "BinaerBild_rot" statt. Diese Variablen dienen dem Speichern von Bildinformation im binären Bereich. Das bedeutet, dass sobald eine entsprechende Farbe im Bild gefunden wurde, diese Information in ein Binärbild übertragen wird.

Der nächste Schritt beinhaltet den Aufruf der Funktion "Modul_gruen_erkennen()". Diese Funktion dient der Farbfilterung und der Suche nach der grünen Ampelphase. Die Funktion arbeitet robust und ist in Lage zwischen dem grün einer Ampel und bspw. dem Grün von Bäumen und Büschen zu unterscheiden. Für eine detailierte Beschreibung dieser Funktion siehe das Kapitel "Filterung der grünen Farbe".

Sofern keine grüne Ampelphase gefunden wurde, findet eine weitere Analyse des Bildes statt. Hierfür wird nach roter und gelber Ampelphase gesucht. Im Gegensatz zu der grünen Ampelphase muss nach der roten und gelben Ampelphase im Verbund gesucht werden. Der Grund hierfür liegt darin, dass im roten Licht der Ampel ein gewisser gelber Anteil vorkommen kann und umgekehrt. Daher findet zuerst der Aufruf der Funktion "Modul_rot_erkennen()", welche nach der roten Ampelphase sucht und anschließend erfolgt eine Suche nach der gelben Phase mit der Funktion "Modul_gelb_erkennen()". Für eine detailierte Beschreibung dieser Funktionen siehe das Kapitel "Filterung der roten Farbe" und "Filterung der gelben Farbe".

Anschließend erfolgt eine Prüfung, ob ein roter und gelber Anteil gefunden wurden (bezogen auf die Ampelphase). Trifft dieser Fall ein, so findet eine weitere Analyse statt. Mithilfe der Funktion "Modul_rot_gelb_Auswertung()" wird überprüft, ob es sich um eine rote Phase mit gelbem Anteil, einer gelben Phase mit rotem Anteil oder ob es sich tatsächlich um eine rot-gelben Phase handelt. Für eine detailierte Beschreibung dieser Funktion siehe das Kapitel "Analyse der rot-gelben Ampelphase".

Abschließend ruft die Startdatei die Funktion "Modul_Ausgabe()" auf, welche dann anhand der Binärbilder die Ampelphase ausgibt und im originalen Bild die Position der Ampelphase einzeichnet. Für eine detailierte Beschreibung dieser Funktion siehe das Kapitel "Ausgabe der Ampelphase".


Bilder einlesen

Im vorliegenden Kapitel erfolgt die Erläuterung der Funktionweise des Einlesens eines Bildes.

Wie bereits oben beschrieben, wird die Funktion "Modul_Bild_einlesen" zu Beginn des Programms aufgerufen. Für eine bessere Auseinandersetzung mit dieser Funktion, wird im folgenden der Quellcode betrachtet:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              Signalverarbeitende Systeme               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Projekt:     Ampelphasenerkennung                      %
%                                                        %
% Autor:       Andre Merkel                              %
%                                                        %
% Studiengang: Business and Systems Engineering          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%                                                        %
% Beschreibung: Dient dem Einlesen eines Bildes.         %
%               Das Bild muss im jpg-Format vorliegen.   %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% Implementierung: MatLab 2014a                          %     
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% letzte Änderung: 28.05.2015                            %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function Bild = Modul_Bild_einlesen

% Information zum Dialog
disp('Bitte wählen Sie ein Bild aus, in welchem die Ampel erkannt werden soll')

% Dialog zum Einlesen des Bildes
[BildName, BildPfad] = uigetfile('*.jpg','Bitte wählen Sie ein Bild aus');

% Pfad des Bildes hinzufügen
addpath(BildPfad);

Bild = imread(BildName);
disp('Die Ampelphase wird gesucht...')

end


Abbildung 6: Dialog zum einlesen von Bildern in MatLab

Die obere Funktion gibt eine Information im Command-Window mit dem Befehl "disp()" aus, um den Anwender zu informieren, dass dieser ein Bild auswählen soll. Damit jedoch der Anwender ein Bild bequem aussuchen kann, wird mit dem Befehl "uigetfile()" ein Dialog aufgerufen, in welchem der Anwender sein Bilder auswählen kann. Der Dialog ist im Bild links dargestellt (Abbildung 6). Neben der Information im Command-Window, steht eine Information auf dem oberen Rahmen des Dialogs, welche noch einmal den Hinweis darauf gibt, dass ein Bild ausgesucht werden soll. Sobald der Anwender sein Bild ausgesucht hat, wird der Bildpfad und der Bildname gespeichert. Damit MatLab jedoch das Bild einlesen kann, muss der Pfad mittels "addpath()" für die MatLab Umgebung bekannt gemacht werden. Anschließend wird mithilfe des Bildnamens und des Befehls "imread()" das ausgesuchte Bild in der Variable "Bild" hinterlegt. Bevor die Funktion die Variable zurückliefert, erfolgt eine weitere Ausgabe im Command-Window. Diese informiert den Anwender darüber, dass jetzt tatsächlich nach der Ampelphase gesucht wird. Dieser Hinweis soll dem Anwender die Sicherheit geben, dass seine Bildauswahl erfolgreich war und das die Software jetzt weiter arbeitet und nicht abgestürtzt ist.







Filterung der grünen Farbe

Das vorliegende Kapitel behandelt die Funkionsweise und Aufbau der Erkennung der grünen Ampelphase.

Abbildung 7: grüne Ampelphase
Abbildung 8: grüne Ampelphase Ausschnitt

Bevor jedoch eine Auseinandersetzung mit dem Quellcode stattfindet, folgt zunächst eine Betrachtung der grünen Ampelphase als solche. Hierfür wird das selbstgeschossene Bild herangezogen (Abbildung 7). Der Mensch benötigt nur einen kurzen Blick, um zu erkennen, dass es hierbei um eine grüne Ampelphase handelt. Ganz im Gegenteil ist es, sobald eine automatische Suche nach dieser grünen Ampelphase stattfinden soll. Zu einem liegt die Problematik darin, dass das Bild viele Informationen hat. Das bedeutet, dass eine einfache Suche nach der grünen Farbe nicht ausreicht. Der Grund hierfür liegt darin, dass die Bäume bzw. Büsche ebenfalls grün sind. Zum anderen liegt das Bild in einem RGB-Farbraum vor, dass, wie bereits erwähnt, ungeeignet ist um eine Farbfilterung durchzuführen. Außerdem besitzt die grüne Ampelphase keine gleich bleibende grüne Farbe über die gesamte Fläche der Scheibe. Dies ist deutlich an der Abbildung 8 zu erkennen. Diese Abbildung zeigt die gleiche Ampel wie Abbilundg 7 aus der Nähe (hier wurde in das linke Bild gezoomt). An dem rechten Bild ist deutlich zu erkennen, dass innerhalb der Ampelscheibe sich untershiedliche grüne Farbtöne ergeben. Hinzu kommt, dass die Ampelscheibe nicht gleichmäßig ausgeleuchtet ist. All diese Bedingungen stellen eine große Herausforderung dar, um das Bild auszuwerten.




Da jetzt die Problematik soweit erläutert wurde, folgt im nächsten Schritt die Vorstellung des Quellcodes:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              Signalverarbeitende Systeme               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Projekt:     Ampelphasenerkennung                      %
%                                                        %
% Autor:       Andre Merkel                              %
%                                                        %
% Studiengang: Business and Systems Engineering          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%                                                        %
% Beschreibung: Dient der Filterung von                  %
%               grünen Pixeln.                           %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% Implementierung: MatLab 2014a                          %     
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% letzte Änderung: 28.05.2015                            %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [BinaerBild] = Modul_gruen_erkennen(RGB_Img)
%% Farbe hervorheben

% Zunächst muss die grüne Farbe hervorgehoben werden, indem
% die restlichen Farben grau gesetzt werden

% Bild in den HSV-Farbraum konvertieren
HSV_Img = rgb2hsv(RGB_Img);  

% Farbwert bzw Farbwinkel erfassen 
Farbwert = 360.*HSV_Img(:,:,1);

% Sättigung der Farbe erfassen
Saettigung = HSV_Img(:,:,2);  

% Erfassen der rot und gelb Anteile im Bild
Restfarbe = (Farbwert > 190) ;

% Die erfasste Restfarbe in der Sättigung auf "0" setzen
Saettigung(Restfarbe) = 0;  

% Die neuen Werte speichern
HSV_Img(:,:,2) = Saettigung;

% Das obere Verfahren sorgte dafür, das alle nicht grün-Anteile
% nun grau Vorliegen. Als nächstes werden die grünen-Pixel erfasst
% und einheitlich grün gefärbt, sodass alle grünen Pixel genau den 
% gleichen Wert aufweisen. Dadurch ist es später einfacher zu prüfen,
% welche Pixel grün sind und welche nicht. Die restlichen Pixel werden
% schwarz gefärbt (Ausblendung der nicht benötigten Farbe). 

%% Erfassung der Pixelfarbe

for i=1:length(HSV_Img(:,1,1))
    
    for j=1:length(HSV_Img(1,:,1))
        
        R = HSV_Img(i, j, 1);
        G = HSV_Img(i, j, 2);
        B = HSV_Img(i, j, 3);
        
        hP = 360*R;
        
        if  (G < 0.75 || B < 0.75) || (hP < 120) 
            
            % nicht-grüne Pixel schwarz färben
            HSV_Img(i, j, 1) = 0;
            HSV_Img(i, j, 2) = 0;
            HSV_Img(i, j, 3) = 0;
            
        else
            
            % grüne Pixel einheitlich färben
             HSV_Img(i, j, 1) = 0.4;
             HSV_Img(i, j, 2) = 1;
             HSV_Img(i, j, 3) = 1;
        end
    end
end

%% Pixel abspeichern, zählen und in den RGB-Raum konvertieren

% Das Bild zurück in den RGB-Farbraum konvertieren
gruen_Bild = hsv2rgb(HSV_Img);    

% binäres Bild erzeugen
BinaerBild = im2bw(gruen_Bild);

end


Abbildung 9: grüne Ampelphase mit reduziertem Farbanteil
Abbildung 10: grüne Ampelphase ohne restlichen Farben

Aus dem Quellcode geht hervor, dass die obige Funktion ein Bild als Eingabeparamter übergeben bekommt. Anschließend erfolgt eine Konvertierung des RGB-Bildes in den HSV-Farbraum. Darauffolgend werden die Farbwerte des Bildes in die Variable "Farbwert", sowie die der Sättigung in die Variable "Sättigung" gespeichert. Im nächsten Schritt erfolgt die Erfassung aller Pixel, die einen geringen Grünanteil besitzen und werden auf ihre Grauwerte reduziert. Das Ergebnis ist in der linken Abbildung zu sehen. Werden jetzt Abbildung 7 und Abbildung 9 verglichen, so ist deutlich zu erkennnen, dass die Abbildung 9 weniger Farben besitzt. Dieser Schritt ist insofern nützlich, da dieser nicht relevante Informationen aus dem Bild entfernt bzw. reduziert. Allerdings sind die grünen Pixel der Büsche und Bäume noch da. Damit diese nicht zufällig als die grüne Ampelphase erkannt werden, erfolgt im weiteren Verlauf mithilfe der for-Schleifen eine weitere Filterung. Hierbei findet eine zielgereichtete Suche nach den benötigten Pixel statt. Die in den for-Schleifen eingestellten Werte wurden dabei empirisch bei verschiedenen Bilder, mit grünen Ampelphasen, ermittelt. Das Besondere hierbei ist, dass alle Pixel, die nicht in das Schema passen, "entfernt" werden. Das bedeutet, dass jedes Pixel, welches nicht den gesuchten Wert aufweist, wird auf "0" gesetzt, d.h. das dieses Pixel schwarz gefärbt wird. Das Ergebnis dieser Filterung kann in der rechten Abbildung (Abbildung 10) betrachtet werden. Aus dieser ist deutlich zu entnehmen, dass nur die grüne Farbe der Ampelphase noch zu sehen ist. Allerdings ist an dieser Stelle die Funktion noch nicht beendet. Das HSV-Bild wird zurück in den RGB-Farbraum konvertiert und anschließend als Binärbild gespeichert. Das Binärbild enthält an der Stelle der grünen Pixel nun weiße Pixel. Die Farbe selbst wird im weiteren Verlauf nicht mehr benötigt, sondern nur die Pixel. Des Weiteren wird dieses Binärbild in die Variable "BinaerBild_gruen" in der Startdatei hinterlegt, damit eine nachträgliche Verwechslung, um welche gefundene Ampelphase es sich handeln könnte, ausgeschlossen wird. Dadurch wird das originale Bild ausschließlich auf die grüne Ampelphase reduziert. Der Vorteil dieser starken Reduzierung liegt in der Einfachheit der Variable. Wenn diese in MatLab geöffnet wird, wird eine große Matrix mit vielen Nullen angezeigt. An den Stellen, an denen die grünen Pixel der Ampelphase gefunden wurden, steht eine "1". Dies ermöglicht ein einfaches und schnelles Arbeiten mit diesem Bild, da keine weiteren Informationen stören bzw. Einfluss nehmen.


Filterung der roten Farbe

Das vorliegende Kapitel behandelt die Funkionsweise und Aufbau der Erkennung der roten Ampelphase.

Da die Vorgehensweise und der Aufbau der roten Ampelphasenerkennung, die der grünen Ampelphasenerkennung ähnelt, wird der Fokus bei der Beschreibung des Quellcodes auf einige Besonderheiten gelegt. Dies soll eine unnötige Wiederholung vermeiden. Daher wird an dieser Stelle auf das Kapitel "Filterung der grünen Farbe" verwiesen.

Der Quellcode, um eine rote Ampelphase zu erkennen, ist wie folgt aufgebaut:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              Signalverarbeitende Systeme               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Projekt:     Ampelphasenerkennung                      %
%                                                        %
% Autor:       Andre Merkel                              %
%                                                        %
% Studiengang: Business and Systems Engineering          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%                                                        %
% Beschreibung: Dient der Filterung von roten Pixeln.    %
%                                                        %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% Implementierung: MatLab 2014a                          %     
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% letzte Änderung: 28.05.2015                            %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [BinaerBild] = Modul_rot_erkennen(RGB_Img)
%% Farbe hervorheben

% Zunächst muss die rote Farbe hervorgehoben werden, indem
% die restlichen Farben grau gesetzt werden

% Bild in den HSV-Farbraum konvertieren
HSV_Img = rgb2hsv(RGB_Img);

% Farbwert bzw Farbwinkel erfassen
Farbwert = 360.*HSV_Img(:,:,1);    

% Sättigung der Farbe erfassen
Saettigung = HSV_Img(:,:,2);          

% Erfassen der grün und gelb Anteile im Bild
Restfarbe = (Farbwert > 10) & (Farbwert < 340);

% Die erfasste Restfarbe in der Sättigung auf "0" setzen
Saettigung(Restfarbe) = 0; 

% Die neuen Werte speichern
HSV_Img(:,:,2) = Saettigung;          

%% Erfassung der Pixelfarbe

% Das obere Verfahren sorgte dafür, das alle nicht rot-Anteile
% nun grau Vorliegen. Als nächstes werden die roten Pixel erfasst
% und einheitlich rot gefärbt, sodass alle roten Pixel genau den 
% gleichen Wert aufweisen. Dadurch ist es später einfacher zu prüfen,
% welche Pixel rot sind und welche nicht. Die restlichen Pixel werden
% schwarz gefärbt (Ausblendung der nicht benötigten Farbe).

for i=1:length(HSV_Img(:,1,1))
    
    for j=1:length(HSV_Img(1,:,1))
        
        R = HSV_Img(i, j, 1);
        G = HSV_Img(i, j, 2);
        B = HSV_Img(i, j, 3);
        
        if (G < 0.75 || B < 0.75) 
            
            % nicht-rote Pixel schwarz färben
            HSV_Img(i, j, 1) = 0;
            HSV_Img(i, j, 2) = 0;
            HSV_Img(i, j, 3) = 0;
            
        else
            
            % rote Pixel einheitlich färben
            HSV_Img(i, j, 1) = 1;
            HSV_Img(i, j, 2) = 1;
            HSV_Img(i, j, 3) = 1;
        end
        
    end
    
end

%% Pixel abspeichern, zählen und in den RGB-Raum konvertieren 

% Das Bild zurück in den RGB-Farbraum konvertieren
rot_Bild = hsv2rgb(HSV_Img);  

% binäres Bild erzeugen
BinaerBild = im2bw(rot_Bild);

% rote Pixel eintragen
for i=1:length(BinaerBild(:,1))
    
    for j=1:length(BinaerBild(1,:))
        
        if rot_Bild(i,j,1) == 1
            
            BinaerBild(i,j) = 1;
            
        end
    end
end

end


Abbildung 11: rote Ampelphase
Abbildung 12: rote Ampelphase mit reduzierten Farbwerten

Wie bereits oben erwähnt, ähnelt dieser Quellcode dem aus Kapitel "Filterung der grünen Farbe". Der einzige wichtige Unterschied liegt hier in der Vorfilterung, in welcher alle Pixel mit geringem Rotanteil auf ihre Grauwerte reduziert werden. Dies wurde ebenfalls empirisch erfasst. Zum Vergleich dienen die Abbildungen 11 und 12. Anhand der rechten Abbildung ist die Vorfilterung noch deutlicher zu erkennen als im Kapitel zuvor. Ebenfalls liefert diese Funktion ein Binärbild mit den nötigen Information an die Startdatei zurück.











Filterung der gelben Farbe

Das vorliegende Kapitel behandelt die Funkionsweise und Aufbau der Erkennung der gelben Ampelphase.

Da die Vorgehensweise und der Aufbau der roten Ampelphasenerkennung, die der grünen sowie roten Ampelphasenerkennung ähnelt, wird der Fokus bei der Beschreibung des Quellcodes auf einige Besonderheiten gelegt. Dies soll eine Redundanz vermeiden. Daher wird an dieser Stelle auf das Kapitel "Filterung der grünen Farbe" verwiesen.

Der Quellcode, um eine rote Ampelphase zu erkennen, ist wie folgt aufgebaut:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              Signalverarbeitende Systeme               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Projekt:     Ampelphasenerkennung                      %
%                                                        %
% Autor:       Andre Merkel                              %
%                                                        %
% Studiengang: Business and Systems Engineering          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%                                                        %
% Beschreibung: Dient der Filterung von gelben Pixeln.   %
%                                                        %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% Implementierung: MatLab 2014a                          %     
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% letzte Änderung: 28.05.2015                            %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [BinaerBild] = Modul_gelb_erkennen(RGB_Img)
%% Farbe hervorheben

% Zunächst muss die gelbe Farbe hervorgehoben werden, indem
% die restlichen Farben grau gesetzt werden

% Bild in den HSV-Farbraum konvertieren
HSV_Img = rgb2hsv(RGB_Img);         %# Convert the image to HSV space

% Farbwert bzw Farbwinkel erfassen
Farbwert = 360.*HSV_Img(:,:,1);

% Sättigung der Farbe erfassen
Saettigung = HSV_Img(:,:,2);         

% Erfassen der grün und gelb Anteile im Bild
Restfarbe = (Farbwert < 10) | (Farbwert > 30);  % [< 38, > 60]

% Die erfasste Restfarbe in der Sättigung auf "0" setzen
Saettigung(Restfarbe) = 0;  

% Die neuen Werte speichern
HSV_Img(:,:,2) = Saettigung;          

%% Erfassung der Pixelfarbe

% Das obere Verfahren sorgte dafür, das alle nicht gelb-Anteile
% nun grau Vorliegen. Als nächstes werden die gelben Pixel erfasst
% und einheitlich gelb gefärbt, sodass alle roten Pixel genau den 
% gleichen Wert aufweisen. Dadurch ist es später einfacher zu prüfen,
% welche Pixel rot sind und welche nicht. Die restlichen Pixel werden
% schwarz gefärbt (Ausblendung der nicht benötigten Farbe).

for i=1:length(HSV_Img(:,1,1))
    
    for j=1:length(HSV_Img(1,:,1))
        
        R = HSV_Img(i, j, 1);
        G = HSV_Img(i, j, 2);
        B = HSV_Img(i, j, 3);
        
        hP = 360*R;
        
        if  (G < 0.5 || B < 0.5) %|| (hP < 30) 
            
            HSV_Img(i, j, 1) = 0;
            HSV_Img(i, j, 2) = 0;
            HSV_Img(i, j, 3) = 0;
            
        else
            
             HSV_Img(i, j, 1) = 0.13;
             HSV_Img(i, j, 2) = 1;
             HSV_Img(i, j, 3) = 1;
   
        end
        
    end
    
end
%% Pixel abspeichern, zählen und in den RGB-Raum konvertieren 

% Das Bild zurück in den RGB-Farbraum konvertieren
gelb_Bild = hsv2rgb(HSV_Img);  

% binäres Bild erzeugen
BinaerBild = im2bw(gelb_Bild);

end


Abbildung 13: gelbe Ampelphase
Abbildung 14: gelbe Ampelphase mit reduzierten Farbwerten

Die oben dargelegte Funktion geht bei der Filterung genauso vor, wie bei den beiden anderen Ampelphasenerkennungen auch. Allerdings sind hier die Werte für die Filterung angepasst. Die linke Abbildung (Abbildung 13) zeigt eine gelbe Ampelphase, welche stark mit Sonnenstrahlen "belichtet" ist, sodass das obere Verkehrszeichen "gelber" ist als die Ampelphase selbst. Allerdings kann der Filter hier Zielgerichtet die gelbe Ampelphase erkennen (siehe Abbidlung 14).













Analyse der rot-gelben Ampelphase

In dem vorliegenden Kapitel wird die Analyse der rot-gelben Ampelphase behandelt.

Die Analyse der rot-gelben Ampelphase stellt an sich keine Filterung wie in den Kapiteln zuvor dar. Das liegt darin, dass in roten Ampeln auch ein Anteil an gelben Pixeln existieren können, die der gelben Ampelphase gleich sind und umgekehrt. Daher würde an dieser Stelle eine Filterung wie in den oberen Kapiteln beschrieben wird nicht zielführend sein.

Um die Vorgehensweise der rot-gelben Ampelphase besser zu erläutern wird zunächst der Quellcode betrachtet:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              Signalverarbeitende Systeme               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Projekt:     Ampelphasenerkennung                      %
%                                                        %
% Autor:       Andre Merkel                              %
%                                                        %
% Studiengang: Business and Systems Engineering          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%                                                        %
% Beschreibung: Mit diesem Skript wird die Ampelphase    %
%               berechnet, ob es sich um eine "rote",    %
%               "gelbe2 oder eine "rot-gelbe" Phase      %
%               handelt.                                 %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% Implementierung: MatLab 2014a                          %     
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% letzte Änderung: 28.05.2015                            %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [Binaer_rot, Binaer_gelb] = Modul_rot_gelb_Auswertung(BinaerBild_rot, BinaerBild_gelb)
%% Schwellwerte für rot und gelb setzen

Schwell_rot = 23; % in Prozent

Schwell_gelb = 23; % in Prozent

%% gelbe Pixel, die zu weit entfernt liegen löschen

[Zeile, Spalte] = find(BinaerBild_rot==1);

rot_Vertikal = round((min(Zeile) + max(Zeile)) / 2);

BinaerBild_gelb(1:rot_Vertikal,:) = 0; % gelbe Pixel oberhalb der roten Pixel entfernen


%% rot- und gelb-Anteile in Prozent berechnen     

sumPixel = length(find(BinaerBild_rot(:,:)==1)) + length(find(BinaerBild_gelb(:,:)==1));
      
rotPix_Anteil = length(find(BinaerBild_rot(:,:)==1)) / sumPixel * 100;

gelbPix_Anteil = length(find(BinaerBild_gelb(:,:)==1)) / sumPixel * 100;

%% Schwellwert prüfen

% Liegt der rot-Anteil zu niedrig, gilt dies als Rauschen und wird entfernt
if rotPix_Anteil < Schwell_rot
    
    Binaer_rot = zeros(length(BinaerBild_rot(:,1)), length(BinaerBild_rot(1,:)));

else
    
    Binaer_rot = BinaerBild_rot;
    
end


% Liegt der gelb-Anteil zu niedrig, gilt dies als Rauschen und wird entfernt
if gelbPix_Anteil < Schwell_gelb
    
    Binaer_gelb = zeros(length(BinaerBild_rot(:,1)), length(BinaerBild_rot(1,:)));
    
else
    
    Binaer_gelb = BinaerBild_gelb;
    
end

end


Abbildung 15: gelbe Ampelphase mit Rotanteil[5]
Abbildung 16: gelbe Ampelphase nach rot-Filterung[6]

Die obere Funktion wird immer dann aufgerufen, sobald die gelbe und rote Ampelphasenerkennung die Farben gefunden haben. An dieser Stelle wird dann überprüft, ob tatsächlich eine rot-gelbe Ampelphase vorliegt. Als Erstes wird ein Schwellwert festgelegt, welcher aussagt, dass unterhalb dieses Wertes es keine rot-gelbe Ampelphase vorliegt, sondern eine rote bzw. gelbe Ampelphase. In der oberen Funktion wird ein Schwellwert von 23% festgelegt. Dieser Wert wurde empirisch ermittelt. Für einen Beispiel wird an dieser Stelle die Abbildung 15 herangezogen. An diesem Bild ist schon in dem Ausgangszustand zu erkennen, dass innerhalb der gelben Ampelphase auch ein roter Anteil existiert. Das Ergebnis nach der roten Ampelphasenerkennung ist in der Abbildung 16 zu sehen. In diesem ist ein gewisser Teil rot. Daher errechnet die obige Funktion das Verhältnis zwischen den roten und gelben Pixel. Abschließend erfolgt eine Überprüfung, ob der Schwellwert überschritten wird. In diesem Fall wird der Schwellwert der roten Pixel nicht überschritten, daher gelten diese als Rauschen und werden entfernt. Dadurch entsteht also eine korrekte Erkennung der gelben Ampelphase.







Ausgabe der gefundenen Ampelphase

In diesem Kapitel wird aufgezeigt wie die erkannte Ampelphase dem Anwender angezeigt wird.

Zunächst wird der Quellcode betrachtet, mit welchen die Ausgabe stattfindet:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              Signalverarbeitende Systeme               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Projekt:     Ampelphasenerkennung                      %
%                                                        %
% Autor:       Andre Merkel                              %
%                                                        %
% Studiengang: Business and Systems Engineering          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%                                                        %
% Beschreibung: Mit diesem Skript wird die Ampelphase    %
%               dem Benutzer angezeigt.                  %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% Implementierung: MatLab 2014a                          %     
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                        %
% letzte Änderung: 28.05.2015                            %
%                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function Modul_Ausgabe(BinaerBild_gruen, BinaerBild_gelb, BinaerBild_rot, Bild)

if (length(find(BinaerBild_gruen==1))) == 0 && (length(find(BinaerBild_gelb==1))) ==0  && (length(find(BinaerBild_rot==1))) == 0
    
    msgbox('Es wurde keine Ampelphase erkannt.','Ampelphasenerkennung');
    return;
    
end

figure; imshow(Bild)
hold on

if (length(find(BinaerBild_gruen==1))) > 0
    
    [Xmin_gruen, Xmax_gruen, Ymin_gruen, Ymax_gruen] = Submodul_Kasten_berechnen(BinaerBild_gruen);
    Submodul_Plot_Rahmen(Xmin_gruen, Xmax_gruen, Ymin_gruen, Ymax_gruen);
    
    myicon = imread('Ampel_gruen.png');
    msgbox('Es wurde eine grüne Ampelphase erkannt','Ampelphasenerkennung','custom',myicon)
    
elseif (length(find(BinaerBild_gelb==1))) > 0 && (length(find(BinaerBild_rot==1))) > 0
    
    [Xmin_rot, Xmax_rot, Ymin_rot, Ymax_rot] = Submodul_Kasten_berechnen(BinaerBild_rot);
    Submodul_Plot_Rahmen(Xmin_rot, Xmax_rot, Ymin_rot, Ymax_rot);
    
    [Xmin_gelb, Xmax_gelb, Ymin_gelb, Ymax_gelb] = Submodul_Kasten_berechnen(BinaerBild_gelb);
    Submodul_Plot_Rahmen(Xmin_gelb, Xmax_gelb, Ymin_gelb, Ymax_gelb);
    
    myicon = imread('Ampel_rot_gelb.png');
    msgbox('Es wurde eine rot-gelbe Ampelphase erkannt','Ampelphasenerkennung','custom',myicon)
    
elseif (length(find(BinaerBild_rot==1))) > 0
    
      
    
    [Xmin_rot, Xmax_rot, Ymin_rot, Ymax_rot] = Submodul_Kasten_berechnen(BinaerBild_rot);
    Submodul_Plot_Rahmen(Xmin_rot, Xmax_rot, Ymin_rot, Ymax_rot);
    
    myicon = imread('Ampel_rot.png');
    msgbox('Es wurde eine rote Ampelphase erkannt','Ampelphasenerkennung','custom',myicon)
    
elseif (length(find(BinaerBild_gelb==1))) > 0
    
    [Xmin_gelb, Xmax_gelb, Ymin_gelb, Ymax_gelb] = Submodul_Kasten_berechnen(BinaerBild_gelb);
    Submodul_Plot_Rahmen(Xmin_gelb, Xmax_gelb, Ymin_gelb, Ymax_gelb);
    
    myicon = imread('Ampel_gelb.png');
    msgbox('Es wurde eine gelbe Ampelphase erkannt','Ampelphasenerkennung','custom',myicon)
    
end


end


Abbildung 17: gefundene gelbe Ampelphase[7]

Die obige Funktion bekommt die jeweiligen Binärbilder als Argumente übergeben. Diese prüft diese jetzt auf Inhalt und imformiert den Anwender um die gefundene Ampelphase. Das Ergebnis ist in der linken Abbildung (Abbildung 17) zu sehen. Hierzu wird das originale Bild mit dem Dialog geplotet, welche Ampelphase gefunden wurde. In dieser Abbildung ist deutlich zu entnehmen, dass eine gelbe Ampelphase erkannt wurde und keine rote bzw. rot-gelbe Ampelphase. Ebenfalls wurde die gelbe Ampelphase mit einem roten Viereck umrandet.














Fazit

Das Projekt der Ampelphasenerkennung war eine spannende und herausfordernde Aufgabe. Dadurch konnten viele wichtige Erkenntnisse über die Farbräume sowie den Aufbau von digitalen Bildern gesammelt werden. Die Komplexitität bzw. größte Schwierigkeit des Projektes war die Ermittlung korrekter Werte für die Filterung, da diese in keiner Literatur bzw. Webseiten behandelt wurden. Auch die Verifizierung der Ergebnisse, dass die Ampelphase tageszeitunabhängig gefunden werden muss, war eine anspruchsvolle Aufgabe. Insgesamt betrachtet, kann über das vorliegende Projekt gesagt werden, dass es in der Lage ist robust bei einer Ampel alle Ampelphasen zu erkennen, unabhänigig von der Tageszeit. Außerdem bietet das Projekt aufgrund des modularen Aufbaus einen Mehrwert für andere Projekte, da die Module bzw. die Funktionen einfach kopiert und ggf. die Parameter angepasst werden können.


Ausblick

Das Projekt Ampelphasenerkennung kann in der aktuellen Form immer noch erweitert werden. Beispielsweise könnte das Projekt so erweitert werden, dass es defekte Ampeln (keine Ampelphase vorhanden) erkennen kann und somit rät die Verkehrszeichen zu nutzen.


Youtube-Video

Zum Projektabschluss fand eine Videoaufnahme, um die Ergebnisse des Projekts "Ampelphasenerkennung" aufzuzeigen, statt. Das Youtube-Video befindet sich unter dem folgendem Link [10].


Download des Pogramms

Das Programm kann hier heruntergeladen werden: Datei:Ampelphasenerkennung MatLab 2014a.zip


Ampelbilder zum Testen des Programms


Quellen

  1. [1]Information zum RGB-Farbraum. Wikipedia. Abgerufen am 17. Mai 2015.
  2. [2]Information zum HSV-Farbraum. Wikipedia. Abgerufen am 17. Mai 2015.
  3. [3]Information zum RGB-Farbraum. Wikipedia. Abgerufen am 17. Mai 2015.
  4. [4]Information zum HSV-Farbraum. Wikipedia. Abgerufen am 17. Mai 2015.
  5. [5]gelbe Ampel. Ruhrnachrichten. Abgerufen am 10. Mai 2015.
  6. [6]gelbe Ampel. Ruhrnachrichten. Abgerufen am 10. Mai 2015.
  7. [7]gelbe Ampel. Ruhrnachrichten. Abgerufen am 10. Mai 2015.
  8. [8]kleine grüne Ampel. RWTH Aachen University Fakultät für Maschinenwesen. Abgerufen am 3. Mai 2015.
  9. [9]rot-gelbe Ampelphase. Autobild.de Fakultät für Maschinenwesen. Abgerufen am 10. Juni 2015.

→ zurück zum Hauptartikel: Signalverarbeitende Systeme SoSe2015