Legosortiermaschine Bildverarbeitung

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen

Dies ist ein Unterarikel von der Legoteil_Zählmaschine, welcher den genauen Aufbau der Bildverarbeitung beschreibt.


Schnittstellen

Damit die Bildverarbeitung und damit auch das Erkennen der Legoteile erfolgreich verlaufen kann, müssen zunächst die Legoteile vereinzelt in die Bildverarbeitungsbox gelangen (Separierung). Sobald ein Legoteil erkannt wurde, wird es aus der Box per Druckluft gefördert und muss anschließend sortiert werden. Damit das Legoteil richtig sortiert wird, wird dem jeweiligen Legoteil anhand der ID eine Box zugeorndet. Der Schnittstellenplan lässt sich zusammengefasst folgendermaßen darstellen:

Abbildung 7: Schnittstellen der Legoteilerkennung


[1] [2]

Mechanischer Aufbau

Um die Lichtreflexionen und Schatten an den Legoteilen während der Bilderkennung zu vermeiden, wurde ein neues Konzept entwickelt. Wenn ein Legoteil sich auf einem halb-transparentem Milchglas befindet (siehe Skizze), wird zuerst die untere Beleuchtung eingeschaltet und mittels einem Durchlichtverfahren die genaue Kontur des Legoteils mit der Kamera ermittelt. Hier können bereits einige Merkmale genau extrahiert werden (geometrische) und eine Maske erzeugt werden. Anschließend wird das untere Licht ausgeschaltet und das obere Licht eingeschaltet. Nach diesem Schritt wird mit Hilfe der Maske, nur in dem Bereich wo das Legoteil liegt, die Farbe ermittelt.

Abbildung 8: BV-Box Funktionskonzept Skizze



Im nächsten Schritt wurde die Idee mit Hilfe eines CAD-Programms ausgearbeitet. Die Konstruktion wurde für den ersten Prototypen einfach gehalten und sich so für miteinander verschraubte Holzbretter entschieden. In der unteren Box am oberen Rand wurde die halb-transparente Plexiglasplatte angebracht. In einem bestimmten Abstand wurde unter der Plexiglasscheibe eine weitere Ebene mit LEDs platziert. Der Abstand wurde so gewählt, dass bei angeschalteten LEDs das Licht durch das Plexiglas optimal gestreut wird (ohne helle Punkte, ohne Licht-Spots). In der oberen Box wurde im Deckel eine Bohrung durchgeführt, wo die Stromleitungen der Kamera und der LEDs durchlaufen können. Die LEDs wurden in rechteckiger Form angeordnet und von innen an Deckplatte befestigt (siehe Abbildung 9). Auf einer weiteren halb-transparenten Plexiglasplatte wurde die Kamera befestigt. Für die Kamera wurde eine weitere Bohrung erzeugt. In der oberen Box wurden Ein- und Ausgänge für die Legoteile erzeugt, sowie eine Aussparung für eine flache Druckluftdüse. Zur besseren Vorstellung befindet sich unter den folgenden Link das CAD-Modell als 3dxml-Datei: BV_Box_Komplett.3dxml. Der 3dxml viewer ist unter folgenden Link zu finden: Link

Abbildung 9: CAD-Konzept BV-Box



Anhand des CAD-Modells wurde die Bildverarbeitungsbox fertiggestellt und in Gesamtsystem integriert. Desweiteren wurde eine "Drosselklappe" prototypisch für die Vor-Separierung in Y-Richtung realisiert.

Abbildung 10: BV-Box fertiggestellt


[1] [2]

Grober Ablauf der Legoteilerkennung


Abbildung 11: Grober Ablaufplan Legoteilerkennung


[1] [2]

Matlabimplementierung

Das einzelne Programm für die Erkennung von Legoteilen befindet sich hier: Bildverarbeitung_Main_V1. Die einzelne Funktion für ein späteres Gesamtprogramm wurde ebenfalls geschrieben und befindet sich hier: AutomatischesZaehlen. der Funktion wird ein kalibriertes Kameraobjekt, die Schnittstelle zur Datenbank, die serielle Schnittstelle zum Arduino und das Kalibrierbild übergeben. Als Rückgabewert wird eine Liste mit den gezählten Legoteil-IDs zurückgegeben.


Ablaufplan:
Ablaufplan Legoteilerkennung


Parametrisierung der Kamera:
Für die Einstellungen der Paramter wurde das Matlabtool Image Acquisition Toolbox benutzt. Dort wurden einzelne Parameter so ausgetestet/eingestellt, dass sich zum einen die Legoteile beim Durchlichtverfahren gut vom Hintergrund abgrenzen und zum anderen die unterschiedlichen Legofarben beim Auflichtverfahren erkennen lassen. Folgende Einstellungen wurden getroffen:

cam.BacklightCompensation = 0;
cam.Tilt = 0;
cam.Sharpness = 128;
cam.Pan = 0;
cam.Saturation = 128;
cam.Brightness = 128;
cam.Contrast = 128;
cam.Gain = 0;

cam.ExposureMode = 'manual';
cam.FocusMode = 'manual';
cam.WhiteBalanceMode = 'manual';

cam.WhiteBalance = 4000;
cam.Focus = 10;
cam.Exposure = -3;




Kamera-Kalibrierung:
Obwohl die Parameter der Kamera konstant und unverändert waren, stellte sich heraus, dass das Bild der Kamera bei einigen Programmstarts trotzdem heller war. Um Neustarts des Programms zu vermeiden wurde so eine Kalibrierfunktion geschrieben, welche anhand eines aufgenommenen Bildes erkennt, ob die Kameraeinstellungen korrekt vorgenommen.
Dabei wird in einer Schleife ein Kameraobjekt erzeugt und mit den oben aufgeführten Einstelllungen/Parametern versehen. Nun wird ein Bild mit diesen Einstellungen geschossen (im Auflichtverfahren) und mit einem zuvor gespeicherten Bild (siehe Abbildung 12), welches die richtigen Einstellungen beinhaltet, verglichen. Sollten sich die durchschnittliche Helligkeiten der Bilder Unterschiede aufweisen, wird das Kameraobjekt neu erzeugt und der Vorgang wiederholt sich, bis die richtigen Einstellungen getroffen wurden.
Zusammenfassend beschreibt folgendes Diagramm den Ablauf der Selbstkalibrierung:

Abbildung 12: Kalibrierbild

Ablaufplan Kamerakalibrierung
Das Kalibrierbild befindet sich im folgenden Ordner: Calib_Img und die Kalibrierfunktion hier: Cam_Configuration_Check_V1


Legoteilerkennung:
Die Legoteilerkennung erfolgt in einer Schleife, in welcher jeder einzelne Frame ausgewertet wird. Zum Beenden der Schleife und damit des Programms muss hier die Escape-Taste gedrückt werden.


Vorverarbeitung, Segmentierung & Nachverarbeitung:
Zunächst wird das im Durchlichtverfahren aufgenommene Bild zugeschnitten, damit unnötige Bildregionen nicht bearbeitet werden müssen. Die Anzahl an Pixeln, welche in Höhe und Breite weggeschnitten werden, wurde experimentell ermittelt und so ausgelegt, dass sich das größte Legoteil immer im Blickfeld befindet.
Daraufhin erfolgt die Binarisierung bzw. Segmentierung. Die Schwellwerte für die jeweiligen Farbkanäle und die Funktion zur Binarisierung wurden mithilfe des Matlabtools Color Thresholder ermittelt. Sollte sich im Laufe des Projektes die Kamerabox verändern (z.B. mehr LEDs eingebaut oder ein anderer Lichteinfall) muss diese Funktion ersetzt werden, da es sonst zu Segmentierungsfehlern kommen kann.

Abbildung 13: Segmentierung der Legoteile mithilfe des Color Thresholder Tools


Die Funktion zur Segmentierung findet man hier: createBinary_V3
Im Anschluss werden noch kleine, einzelne Pixel im Hintergrund und im Legoteil gelöscht. Damit ist das Bild bereinigt und vollständig segmentiert.


Legoteilerfassung:
Damit ein Legoteil erfasst werden kann, müssen folgende Kriterien eingehalten werden:

  1. Legoteil muss sich an der Kante befinden
  2. Legoteil muss sich in einer Ruhelage befinden
  3. Es darf nur ein Legoteil im Bild vorhanden sein

Sollte mehr als ein Legoteil ein Bild sein, werden alle vorhandenen Legoteile in der Box herausgepustet und als "nicht erkannt" deklariert.


Farbliches Merkmale extrahieren:

Abbildung 14: Farberkennung

Damit die Farbe erkannt werden kann, wird das Auflichtverfahren angewendet. Die Funktion "FARBERKENNUNG_V2" bekommt als Übergabewerte zwei Matrizen:

  • RGB-Bild aus Auflichtverfahren und Binärbild vom erkannten Objekt
  • mit Hilfe der Übergabeparameter wird eine 3D-Farbmaske erstellt (3D --> RGB).
    • Farbmaske: Aus dem Originalbild werden nur die Pixel in die Masken übernommen, die im Binärbild dem Objekt zugeordnet werden können (weiße Pixel)
  • Anschließend werden Mittelwerte für Rot-, Grün- und Blau-Anteil berechnet.


Zuordnung zur nächstgelegenen Farbe:

  • Es werden die RGB-Mittelwerte mit einer Farbtabelle verglichen:
    • die Differenzen von jedem Farbanteil zur Farbtabelle werden ermittelt. Davon werden die Differenzen des Farbanteils mit dem größten Wert (Abweichung) gespeichert.
    • Anschließend wird der minimalste Wert von den maximalen Abweichungen ermittelt --> Es wird genau die Farbe ermittelt, welches die kleinste Abweichung zu der Legoteil-Farbe hat.


Die ermittelte Farbe wird als String zurückgegeben. Es können weitere Farben im Nachhinein hinzugefügt werden oder Farbschwellwerte verändert werden, falls sich die Lichtverhältnisse in der Kamerabox durch Umbauten verändern. Dazu muss in der Funktion Bildverarbeitung_Main_V1 folgende Stelle unkommentiert sein:

%% Merkmalsextraktion %%
%Farbe identifizieren
dbstop in FARBERKENNUNG_V2
FARBE = FARBERKENNUNG_V2(ColorImage,BW);


Dies lässt das Programm beim Ausführen automatisch in die Funktion FARBERKENNUNG_V2 springen (mit Breakpoint). Sobald also nun ein farbiges Teil in der Box ist, wird das Programm an dieser Stelle anhalten. Nachdem dies geschehen ist, sollte der Benutzer folgende Variable beobachten:

FARBE(1,1) = (sum(sum(Farbmaske(:,:,1))))/Pixel_Flaeche;                    
FARBE(1,2) = (sum(sum(Farbmaske(:,:,2))))/Pixel_Flaeche;
FARBE(1,3) = (sum(sum(Farbmaske(:,:,3))))/Pixel_Flaeche;


Diese enthält die durchschnittliche R, G und B Anteile des hineingeworfenen Legoteils. Sollten diese (z.B. nach einem Umbau der Bildverarbeitungsbox) von den Werten in der hinterlegten Tabelle stark abweiche, müssen diese mit dem gemessenen Wert überschrieben werden:

%% Farbwerte-Tabelle mit normierten Lego-Farben
% %           R(1) G(1) B(1)  
Farbwerte=[   0.5273 0.5489 0.5362; %'weiss'          
              0.4138 0.3891 0.3115; %'beige'         
              0.3230 0.0622 0.0623; %'rot'           
              0.0087 0.1275 0.3309; %'blau'          
              0.5409 0.4596 0.2026; %'gelb'          
              0.0450 0.0664 0.0659; %'schwarz'       
              0.0509 0.1826 0.1287; %'gruen'         
              0.2182 0.2038 0.1518; %'hellbraun'          
              0.2709 0.3230 0.3345; %'hell-grau'        
              0.1391 0.1804 0.1878; %'dunkel-grau'   
%               0.0565 0.0629 0.0552; %'dunkelbraun'  
              ];



Geometrische Merkmale extrahieren:

Abbildung 15: geometrische Merkmalsextraktion

Die Funktion "Merkmalsberechnung_V3" erhält als Übergabeparameter ein Binärbild eines einzelnen Objektes (Legoteil). Aus diesem Objekt werden dann folgende Merkmale extrahiert, welche dann zurückgegeben werden:

  • Umfang --> Anzahl der Pixel, die sich am Rand des Objektes befinden
  • Fläche --> Anzahl der Pixel, die sich innerhalb des Objektes befinden (Löcher ausgeschlossen)
  • Flächenschwerpunkt --> Pixelkoordinaten {x/y}
  • Minimaler Abstand von Flächenschwerpunkt zu äußerem Rand des Objektes
  • Maximaler Abstand von Flächenschwerpunkt zu äußerem Rand des Objektes


Die Berechnung der Fläche erfolgt über die Summenbildung der Zeilen und Spalten des Binärbildes. Da so nur die weißen Pixel addiert werden, handelt es sich hierbei nur um die Pixel, die zum Objekt gehören.
Die Schwerpunktskoordinaten lassen sich mit der Matlab-Funktion Regionprops berechnen, welche als Übergabeparameter das Binärbild des Objektes und die Option 'centroid' erhält.
Mithilfe des Kantenbildes des Objektes (erzeugt mit der Matlab-Funktion bwperim), kann eine Liste mit allen Kantenkoordinaten erstellt werden (Matlab-Funktion: Regionprops(Kantenbild, 'Pixellist')). Aus der Differenz zwischen jedem einzelnen dieser Kantenpixel und dem Schwerpunkt bestimmt man nun die Abstände vom Schwerpunkt zum Rand, welche nach minimalen und maximalen Wert durchsucht werden. Anhand der Größe der Kantenpixelliste kann außerdem der Umfang des Objektes bestimmt werden.
Diese Merkmale dienen, zusätzlich zu der Farbe des Objektes und die Anzahl der Löcher im Objekt, als Indikatoren für den Abgleich zwischen aktuellen Legoteil in der Box und den hinterlegten Daten in der Datenbank (siehe Funktion: "Datenbankabgleich.m").
Sollten sich herausstellen, dass diese Merkmale nicht genügen, um alle Legoteile voneinander unterscheiden zu können, sind weitere Merkmalsberechnungen möglich (z.B. Die Seitenlängen einer um das Objekt aufgespannten Boundingbox).


Herauspusten der Legoteile:
Sobald alle Merkmale erfasst wurden, werden diese mit einer Datenbank abgeglichen und einer Legoteil-ID zugeordnet, anhand derer man die zugehörige Box (des Linearläufers) ermittelt und mitteilt (siehe Funktion: "BoxausID_SwitchCaseDB.m"). Danach erfolgt das Herauspusten des Legoteils aus der Kamerabox. Um herauszufinden, wann der Herauspusten beendet werden kann, wird das aktuelle Kamerabild (bei Auflichtverfahren) mit dem Kalibrierbild verglichen. Sollten hier keine großen unterschiede vorliegen, ist die Box leer und das Ventil der Druckluftdüse kann geschlossen werden.
[1] [2]

Teach In

Für das einteachen von Legoteilen sind folgende Schritte nötig:

  1. Vorraussetzungen:
    1. Maschine ist eingeschaltet
    2. USB-Verbindung zwischen PC und Arduino und PC und Webcam
    3. Arduino ist mit folgendem Programm geflasht: "Serielle_Kommunikation_Arduino_Matlab.ino"
    4. Druckluftversorgung der Ventilinsel
  2. Bildverarbeitungsprogramm öffnen: "Bildverarbeitung_Main_V1"
  3. Im Quellcode die Bereiche mit der Bezeichnung "Für Teach In:...." unkommentieren
  4. Nun gleiche Legoteile nacheinander in die BV_Box befördern, dabei werden die Merkmale gespeichert und bei Beendigung des Programms (Esc) gemittelt
  5. Öffnen der Excel_Liste: "Datenbank Teile-Kopie_fuer sql" und unter der jeweiligen Lego-ID die Mittelwerte der Merkmale eintragen (Achtung: Einige Teile müssen in mehreren Lagepositionen eingeteacht werden. Dazu einfach eine weitere Zeile mit derselben ID erstellen)
  6. Nachdem eintragen einiger Teile, schließen der Excel Liste und Ausführen des Programms: InventurlisteErstellen_SQL.m. Das führt dazu, dass die Inhalte der Excel-Liste in die SQL Datenbank eingetragen werden.
  7. Für die Zuordnung von IDs zu den einzelnen Sortierboxen existiert bisher nur ein Testprogramm: BoxausID_SwitchCaseDB.m". Eine Excel-Liste wäre hier jedoch besser geeignet.
  8. Zusatz: Die Toleranzen beim Abgleichen von Merkmalen können bei Bedarf in folgender Funktion geändert werden: "Datenbankabgleich.m". Dabei werden die Toleranzen für Fläche, Umfang und Max-Schwerpunkt relativ angegeben und die Toleranzen für Min-Schwerpunkt und Anzahl der Löcher absolut.


Zum Testen wurden bisher nur ein paar Legoteile in die Datenbank eingeteacht. Zur Vollständigkeit müsste dies mit den restlichen Legoteilen auch geschehen. Praktisch wäre hier eine extra Teach-In Funktion, welche die Werte automatisch ermittelt und in die Excel-Tabelle einträgt. Erste Implementierungen wurden schon durchgeführt, sind jedoch noch mit Fehlern versehen: "Teach_In.m"
[1] [2]

Teach In Programmierung

Das Ansteuern des Förderbandes über die GUI sowie die Bildaufnahme funktioniert jetzt flüssiger. Dafür wurden im Quellcode geringfügige Änderungen vorgenommen, die die Performance des Programmes verbessern. Beim Thema Teach In sind Probleme bei der Farberkennung aufgetreten. Farben, die ähnlich sind, werden nicht richtig erkannt.

Teach In Teile einpflegen

Zur Vervollständigung der Liste mit Teilen, die erkannt werden, müssen noch mehr Teile eingespeichert werden.

Ansteuerung über GUI

Die Teach In Funktion ist jetzt über die GUI aus der main-Funktion erreichbar.

  1. 1,0 1,1 1,2 1,3 1,4 Autor Kevin Penner
  2. 2,0 2,1 2,2 2,3 2,4 Autor Christo Tsibadze