SigSys15 Ampelphasenerkennung

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen

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.

Projektracking

Projektablaufplan

Abbildung 1: Projektablaufplan der Ampelphasenerkennung

In diesem Kapitel wird die Funktionsweise der Ampelphasenerkennung näher erläutert. In der linken Abbildung (Abbildung 1) 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 weiter 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 es soll dadurch der Einfluss anderer Farben nicht die Ampelphasen mit beeinflussen. 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 bedinkt von denen der in der Natur vorkommen 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 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 Augenmerkmal bei der robusten Farberkennung sowie einer robusten Unterscheidung der Farbe.










Farbraum in MatLab

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()", welches 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 das jedes Pixel im Bild durch seine Position gekennzeichnet ist und durch die Mischung aus den Werten R, G und B. Dabei liegen die RGB-Werte im Intervall von 0 bis 255. Das bedeutet, das 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.

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 diesen 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. Zusätzlich kann durch unterschiedliche Belichtung eines Objektes der Farbton sich ändern. Das bedeutet, dass auch die drei Werte (RGB) sich ändern. Daher ist eine Farbfilterung in einem RGB-Raum ungegeignet.[1]

Um effektiv eine Farbe im Bild zu filtern, wurde das RGB-Bild in den HSV-Farbraum ü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 Vermengenung der Farbe mit weiß und die Helligkeit gibt die Amplitude des Lichts an. [2]

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 heut zu Tage 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 von einander 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 gekappelt 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:     Ampelpahsenerkennung                      %
%                                                        %
% 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 und das Command-Window bereinigt werden. 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".

Nachdem 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 rote 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 wurde (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 gelben Anteil, einer gelben Phase mit roten 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:     Ampelpahsenerkennung                      %
%                                                        %
% 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 2: 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 2). 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 dem 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 3: grüne Ampelphase
Abbildung 4: 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 3). 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 eine einfache suche nach der grünen Farbe reicht nicht aus. 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 4 zu erkennen. Diese Abbildung zeigt die gleiche Ampel wie Abbilundg 3 aus der Nähe (hier wurde in das linke Bild gezoomt). An dem rechten Bild ist deutlich zu erkennen alleine in der Ampel untershiedliche grün Töne sich ergeben und auch nicht die gesamte Fläche ausgeleuchtet ist. All diese Bedingungen stellen eine große Herausforderung, um das Bild auszuwerten.




Filterung der roten Farbe

Filterung der gelben Farbe

Analyse der rot-gelben Ampelphase

Weblinks

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.

→ zurück zum Hauptartikel: Signalverarbeitende Systeme SoSe2015