- Voraussetzungen
- Schritte zur Erkennung von Nummernschildern mit Raspberry Pi
- 1. Kennzeichenerkennung
- 2. Zeichensegmentierung
- 3. Zeichenerkennung
- Fehlerfälle bei der Nummernschilderkennung
- Andere erfolgreiche Beispiele
Sicherheit war schon immer ein wichtiges Anliegen der Menschheit. Heute haben wir Videoüberwachungskameras in Schulen, Krankenhäusern und an jedem anderen öffentlichen Ort, damit wir uns sicher fühlen. Laut einer Umfrage von HIS waren im Jahr 2014 schätzungsweise 245 Millionen Überwachungskameras installiert und funktionsfähig. Dies entspricht einer Überwachungskamera pro 30 Menschen auf diesem Planeten. Mit dem technologischen Fortschritt, insbesondere in der Bildverarbeitung und im maschinellen Lernen, ist es möglich, diese Kameras intelligenter zu machen, indem sie für die Verarbeitung von Informationen aus dem Video-Feed geschult werden.
Der Video-Feed dieser Kameras kann zur Gesichtserkennung, Musteranalyse, Emotionsanalyse und vielem mehr verwendet werden, um dem im FF7-Film gezeigten „God's Eye“ wirklich nahe zu kommen. Tatsächlich haben Überwachungsunternehmen wie Hikvision und viele andere bereits damit begonnen, diese Funktionen in ihre Produkte zu implementieren. Wir haben zuvor die MATLAB-Bildverarbeitung zum Lesen des Nummernschilds verwendet. In diesem Artikel erfahren Sie heute, wie Sie das Nummernschild von Automobilen mithilfe von Raspberry Pi und OpenCV erkennen und lesen. Wir werden einige zufällige Fahrzeugbilder von Google verwenden und ein Programm schreiben, um das Nummernschild mit OpenCV Contour Detection zu erkennen und dann das Nummernschild mit Tesseract OCR vom Schild zu lesen. Klingt interessant, oder? Also, fangen wir an.
Voraussetzungen
Wie bereits erwähnt, werden wir die OpenCV-Bibliothek verwenden, um Gesichter zu erkennen und zu erkennen. Stellen Sie daher sicher, dass Sie OpenCV Library auf Raspberry Pi installieren, bevor Sie mit diesem Tutorial fortfahren. Versorgen Sie Ihren Pi auch mit einem 2A-Adapter und schließen Sie ihn zum einfacheren Debuggen an einen Monitor an.
In diesem Tutorial wird nicht erklärt, wie genau OpenCV funktioniert. Wenn Sie die Bildverarbeitung erlernen möchten, lesen Sie die OpenCV-Grundlagen und die erweiterten Bildverarbeitungs-Tutorials. In diesem Tutorial zur Bildsegmentierung mit OpenCV erfahren Sie auch mehr über Konturen, Blob-Erkennung usw. Wir werden etwas Ähnliches tun, um das Nummernschild des Autos auf dem Bild zu erkennen.
Schritte zur Erkennung von Nummernschildern mit Raspberry Pi
Die Kennzeichenerkennung oder kurz LPR umfasst drei Hauptschritte. Die Schritte sind wie folgt
1. Kennzeichenerkennung: Der erste Schritt besteht darin, das Kennzeichen vom Auto aus zu erkennen. Wir werden die Konturoption in OpenCV verwenden, um nach rechteckigen Objekten zu suchen, um das Nummernschild zu finden. Die Genauigkeit kann verbessert werden, wenn wir die genaue Größe, Farbe und ungefähre Position des Nummernschilds kennen. Normalerweise wird der Erkennungsalgorithmus basierend auf der Position der Kamera und dem Typ des in diesem bestimmten Land verwendeten Nummernschilds trainiert. Dies wird schwieriger, wenn das Bild nicht einmal ein Auto enthält. In diesem Fall werden wir einen zusätzlichen Schritt ausführen, um das Auto und dann das Nummernschild zu erkennen.
2. Zeichensegmentierung: Sobald wir das Nummernschild erkannt haben, müssen wir es ausschneiden und als neues Bild speichern. Auch dies kann einfach mit OpenCV durchgeführt werden.
3. Zeichenerkennung: Auf dem neuen Bild, das wir im vorherigen Schritt erhalten haben, sind sicher einige Zeichen (Zahlen / Alphabete) geschrieben. Wir können also OCR (Optical Character Recognition) ausführen, um die Nummer zu ermitteln. Wir haben bereits die optische Zeichenerkennung (OCR) mit Raspberry Pi erklärt.
1. Kennzeichenerkennung
Der erste Schritt in diesem Raspberry Pi-Kennzeichenleser besteht darin, das Kennzeichen zu erkennen. Nehmen wir ein Beispielbild eines Autos und beginnen mit der Erkennung des Nummernschilds an diesem Auto. Wir werden dann dasselbe Bild auch für die Zeichensegmentierung und die Zeichenerkennung verwenden. Wenn Sie ohne Erklärung direkt in den Code springen möchten, können Sie zum Ende dieser Seite scrollen, wo der vollständige Code bereitgestellt wird. Das Testbild, das ich für dieses Tutorial verwende, ist unten dargestellt.
Schritt 1: Ändern Sie die Größe des Bildes auf die gewünschte Größe und skalieren Sie es anschließend in Graustufen. Der Code dafür ist unten angegeben
img = cv2.resize (img, (620,480)) grey = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) # in Graustufen konvertieren
Größenänderung Wir helfen uns, Probleme mit Bildern mit größerer Auflösung zu vermeiden. Stellen Sie sicher, dass das Nummernschild nach der Größenänderung noch im Rahmen bleibt. Graustufen sind in allen Bildverarbeitungsschritten gleich. Dies beschleunigt andere folgende Prozesssinusse, bei denen wir uns bei der Verarbeitung eines Bildes nicht mehr mit den Farbdetails befassen müssen. Das Bild würde ungefähr so transformiert, wenn dieser Schritt ausgeführt wird
Schritt 2: Jedes Bild enthält nützliche und nutzlose Informationen. In diesem Fall ist für uns nur das Nummernschild die nützliche Information, der Rest ist für unser Programm so gut wie nutzlos. Diese nutzlose Information wird als Rauschen bezeichnet. Normalerweise werden mit einem bilateralen Filter (Bluring) die unerwünschten Details aus einem Bild entfernt. Der Code dafür ist
grau = cv2.bilateralFilter (grau, 11, 17, 17)
Die Syntax lautet destination_image = cv2.bilateralFilter (Quellbild, Pixeldurchmesser, sigmaColor, sigmaSpace). Sie können die Sigma-Farbe und den Sigma-Raum von 17 auf höhere Werte erhöhen, um mehr Hintergrundinformationen zu verwischen. Achten Sie jedoch darauf, dass der nützliche Teil nicht unscharf wird. Das Ausgabebild wird unten angezeigt, da Sie sehen können, dass die Hintergrunddetails (Baum und Gebäude) in diesem Bild unscharf sind. Auf diese Weise können wir verhindern, dass sich das Programm später auf diese Regionen konzentriert.
Schritt 3: Der nächste Schritt ist interessant, wenn wir eine Kantenerkennung durchführen. Es gibt viele Möglichkeiten, dies zu tun. Die einfachste und beliebteste Möglichkeit ist die Verwendung der Canny Edge-Methode von OpenCV. Die entsprechende Zeile ist unten dargestellt
edged = cv2.Canny (grau, 30, 200) #Kantenerkennung durchführen
Die Syntax lautet destination_image = cv2.Canny (Quellbild, Schwellwert 1, Schwellwert 2). Der Schwellenwert 1 und der Schwellenwert 2 sind die minimalen und maximalen Schwellenwerte. Es werden nur die Kanten angezeigt, deren Intensitätsgradient über dem minimalen Schwellenwert und unter dem maximalen Schwellenwert liegt. Das resultierende Bild wird unten gezeigt
Schritt 4: Jetzt können wir nach Konturen in unserem Bild suchen. In unserem vorherigen Tutorial haben wir bereits gelernt, wie Sie mit OpenCV Konturen finden, sodass wir genauso vorgehen.
nts = cv2.findContours (edged.copy (), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours (cnts) cnts = sortiert (cnts, key = cv2.contourArea, reverse = True) screenCnt = Keine
Sobald die Zähler erkannt wurden, sortieren wir sie von groß nach klein und berücksichtigen nur die ersten 10 Ergebnisse, wobei die anderen ignoriert werden. In unserem Bild könnte der Zähler alles sein, was eine geschlossene Oberfläche hat, aber von allen erzielten Ergebnissen wird auch das Kennzeichen vorhanden sein, da es sich ebenfalls um eine geschlossene Oberfläche handelt.
Um das Kennzeichenbild unter den erhaltenen Ergebnissen zu filtern, werden wir alle Ergebnisse durchlaufen und prüfen, welche eine rechteckige Kontur mit vier Seiten und einer geschlossenen Figur aufweist. Da wäre ein Nummernschild definitiv eine rechteckige vierseitige Figur.
# Schleife über unsere Konturen für c in cnts: # ungefähr die Kontur peri = cv2.arcLength (c, True) approx = cv2.approxPolyDP (c, 0,018 * peri, True) # wenn unsere approximierte Kontur vier Punkte hat, dann # wir kann davon ausgehen, dass wir unseren Bildschirm gefunden haben, wenn len (approx) == 4: screenCnt = approx break
Der Wert 0,018 ist ein experimenteller Wert; Sie können herumspielen, um zu überprüfen, welche für Sie am besten geeignet ist. Oder bringen Sie es auf die nächste Stufe, indem Sie maschinelles Lernen verwenden, um anhand von Fahrzeugbildern zu trainieren, und dann dort den richtigen Wert verwenden. Sobald wir den richtigen Zähler gefunden haben, speichern wir ihn in einer Variablen namens screenCnt und zeichnen dann ein Rechteckfeld darum, um sicherzustellen, dass wir das Nummernschild korrekt erkannt haben.
Schritt 5: Jetzt, da wir wissen, wo sich das Nummernschild befindet, sind die verbleibenden Informationen für uns so gut wie nutzlos. So können wir mit der Maskierung des gesamten Bildes fortfahren, mit Ausnahme der Stelle, an der sich das Nummernschild befindet. Der Code, um dasselbe zu tun, ist unten gezeigt
# Maskieren des anderen Teils als des Kennzeichens mask = np.zeros (grey.shape, np.uint8) new_image = cv2.drawContours (mask,, 0,255, -1,) new_image = cv2.bitwise_and (img, img, mask = Maske)
Das maskierte neue Bild wird wie folgt angezeigt
2. Zeichensegmentierung
Der nächste Schritt bei der Erkennung von Himbeer-Pi- Nummernschildern besteht darin, das Nummernschild aus dem Bild zu segmentieren, indem Sie es zuschneiden und als neues Bild speichern. Wir können dieses Bild dann verwenden, um das Zeichen darin zu erkennen. Der Code zum Zuschneiden des Roi-Bilds (Region of Interest) aus dem Hauptbild ist unten dargestellt
# Jetzt beschneiden (x, y) = np.where (Maske == 255) (topx, topy) = (np.min (x), np.min (y)) (bottomx, bottomy) = (np.max (x), np.max (y)) Beschnitten = grau
Das resultierende Bild wird unten gezeigt. Normalerweise zum Zuschneiden des Bildes hinzugefügt, können wir es auch grau machen und bei Bedarf kanten. Dies geschieht, um die Zeichenerkennung im nächsten Schritt zu verbessern. Ich fand jedoch, dass es auch mit dem Originalbild gut funktioniert.
3. Zeichenerkennung
Der letzte Schritt bei dieser Raspberry Pi- Nummernschilderkennung besteht darin , die Nummernschildinformationen tatsächlich aus dem segmentierten Bild zu lesen. Wir werden das Pytesseract- Paket verwenden, um Zeichen aus dem Bild zu lesen, genau wie im vorherigen Tutorial. Der Code dafür ist unten angegeben
#Lesen Sie das Nummernschild text = pytesseract.image_to_string (Cropped, config = '- psm 11') print ("Erkannte Nummer ist:", Text)
Wir haben bereits erklärt, wie eine Tesseract-Engine konfiguriert wird. Daher können wir bei Bedarf auch hier die Tesseract-OCR konfigurieren, um bei Bedarf bessere Ergebnisse zu erzielen. Das erkannte Zeichen wird dann auf der Konsole gedruckt. Beim Kompilieren wird das Ergebnis wie folgt angezeigt
Wie Sie sehen können, hatte das Originalbild die Nummer „HR 25 BR9044“ und unser Programm hat festgestellt, dass es denselben Wert auf dem Bildschirm gedruckt hat.
Fehlerfälle bei der Nummernschilderkennung
Die vollständige Projektdatei dieser Raspberry Pi-Kennzeichenerkennung kann hier heruntergeladen werden. Sie enthält das Programm und die Testbilder, mit denen wir unser Programm überprüft haben. Ohne es zu sagen, ist zu beachten, dass die Ergebnisse dieser Methode nicht genau sind . Die Genauigkeit hängt von der Klarheit des Bildes, Orientierung, Lichtexposition etc. Um bessere Ergebnisse zu erzielen, können Sie versuchen, Algorithmen für maschinelles Lernen zu implementieren.
Um eine Vorstellung zu bekommen, schauen wir uns ein anderes Beispiel an, bei dem das Auto nicht direkt auf die Kamera zeigt.
Wie Sie sehen, konnte unser Programm das Nummernschild korrekt erkennen und zuschneiden. Die Tesseract- Bibliothek hat die Zeichen jedoch nicht richtig erkannt. Anstelle des tatsächlichen "TS 08 UE 3396" hat die OCR erkannt, dass es "1508 ye 3396" ist. Probleme wie diese können entweder durch Verwendung von Bildern mit besserer Ausrichtung oder durch Konfiguration der Tesseract- Engine behoben werden.
Ein weiteres Worst-Case-Szenario besteht darin, dass die Kontur das Nummernschild nicht richtig erkennt. Das folgende Bild enthält zu viele Hintergrundinformationen und schlechte Beleuchtung, als dass das Programm das Nummernschild anhand der Nummer nicht identifizieren konnte. In diesem Fall müssen wir uns wieder auf maschinelles Lernen verlassen oder die Bildqualität verbessern.
Andere erfolgreiche Beispiele
In den meisten Fällen ist die Bildqualität und -ausrichtung korrekt. Das Programm konnte das Nummernschild identifizieren und die Nummer daraus lesen. Die folgenden Schnappschüsse zeigen einige der erfolgreichen Ergebnisse. Auch hier sind alle hier verwendeten Testbilder und der Code in der hier bereitgestellten ZIP-Datei verfügbar.
Ich hoffe, Sie haben die automatische Nummernschilderkennung mit Raspberry Pi verstanden und es genossen, selbst etwas Cooles zu bauen. Was kann Ihrer Meinung nach noch mit OpenCV und Tesseract getan werden ? Lassen Sie mich Ihre Gedanken im Kommentarbereich wissen. Wenn Sie Fragen zu diesem Artikel haben, können Sie diese gerne im Kommentarbereich unten hinterlassen oder die Foren für andere technische Fragen verwenden.