- Eerste vereisten
- Stappen voor kentekenherkenning met Raspberry Pi
- 1. Kentekenplaat detectie
- 2. Tekensegmentatie
- 3. Karakterherkenning
- Mislukkingen bij nummerplaatherkenning
- Andere succesvolle voorbeelden
Veiligheid is altijd een grote zorg voor de mensheid geweest. Tegenwoordig hebben we videobewakingscamera's in scholen, ziekenhuizen en elke andere openbare plaats om ons een veilig gevoel te geven. Volgens een onderzoek van HIS wordt geschat dat er in 2014 ongeveer 245 miljoen beveiligingscamera's waren geïnstalleerd en functioneerden, wat lijkt op het hebben van één beveiligingscamera voor elke 30 mensen op deze planeet. Met de technologische vooruitgang, met name in beeldverwerking en machine learning, is het mogelijk om deze camera's slimmer te maken door ze te trainen om informatie uit de videofeed te verwerken.
De videofeed van deze camera's kan worden gebruikt om gezichtsherkenning, patroonanalyse, emotieanalyse en nog veel meer uit te voeren, waardoor het echt in de buurt komt van zoiets als het "God's Eye" dat in de FF7-film wordt getoond. Surveillancebedrijven zoals Hikvision en vele anderen zijn zelfs al begonnen met het implementeren van deze functies in hun producten. We gebruikten eerder MATLAB-beeldverwerking om de nummerplaat te lezen, vandaag zullen we in dit artikel leren hoe we het kenteken van auto's kunnen herkennen en lezen met Raspberry Pi en OpenCV. We zullen enkele willekeurige voertuigafbeeldingen van Google gebruiken en een programma schrijven om de kentekenplaat te herkennen met OpenCV Contour Detection en vervolgens het nummer van de plaat lezen met behulp van Tesseract OCR. Klinkt interessant toch!, Dus laten we beginnen.
Eerste vereisten
Zoals eerder verteld, zullen we de OpenCV-bibliotheek gebruiken om gezichten te detecteren en te herkennen. Zorg er dus voor dat u OpenCV Library op Raspberry Pi installeert voordat u doorgaat met deze tutorial. Voorzie uw Pi ook van stroom met een 2A-adapter en sluit hem aan op een beeldscherm voor eenvoudiger debuggen.
Deze tutorial zal niet uitleggen hoe OpenCV precies werkt, als je geïnteresseerd bent in het leren van beeldverwerking, bekijk dan deze OpenCV basics en geavanceerde tutorials over beeldverwerking. U kunt ook leren over contouren, Blob-detectie enz. In deze zelfstudie over beeldsegmentatie met OpenCV. We zullen iets soortgelijks doen om de kentekenplaat van de auto op de afbeelding te detecteren.
Stappen voor kentekenherkenning met Raspberry Pi
Kentekenherkenning of afgekort LPR omvat drie grote stappen. De stappen zijn als volgt
1. Kentekenplaat detectie: De eerste stap is om de kentekenplaat van de auto te detecteren. We zullen de contouroptie in OpenCV gebruiken om rechthoekige objecten te detecteren om de nummerplaat te vinden. De nauwkeurigheid kan worden verbeterd als we de exacte grootte, kleur en geschatte locatie van de nummerplaat weten. Normaal gesproken wordt het detectie-algoritme getraind op basis van de positie van de camera en het type nummerplaat dat in dat specifieke land wordt gebruikt. Dit wordt lastiger als de afbeelding niet eens een auto heeft, in dit geval doen we een extra stap om de auto te detecteren en dan de kentekenplaat.
2. Tekensegmentatie: zodra we de kentekenplaat hebben gedetecteerd, moeten we deze bijsnijden en opslaan als een nieuwe afbeelding. Nogmaals, dit kan eenvoudig worden gedaan met OpenCV.
3. Tekenherkenning: Nu, de nieuwe afbeelding die we in de vorige stap hebben verkregen, zal zeker een aantal tekens (cijfers / alfabetten) bevatten. We kunnen er dus OCR (Optical Character Recognition) op uitvoeren om het nummer te detecteren. We hebben Optical Character Recognition (OCR) al uitgelegd met Raspberry Pi.
1. Kentekenplaat detectie
De eerste stap bij deze Raspberry Pi-kentekenlezer is het detecteren van de kentekenplaat. Laten we een voorbeeldfoto van een auto nemen en beginnen met het detecteren van de kentekenplaat op die auto. We zullen dan dezelfde afbeelding ook gebruiken voor tekensegmentatie en tekenherkenning. Als je zonder uitleg direct in de code wilt springen, kun je naar de onderkant van deze pagina scrollen, waar de volledige code staat. De testafbeelding die ik voor deze tutorial gebruik, wordt hieronder weergegeven.
Stap 1: pas het formaat van de afbeelding aan tot het gewenste formaat en schaal deze vervolgens in grijstinten. De code voor hetzelfde wordt hieronder gegeven
img = cv2.resize (img, (620,480)) grey = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) #converteren naar grijsschaal
Formaat wijzigen helpen we problemen met afbeeldingen met een grotere resolutie te voorkomen, zorg ervoor dat de nummerplaat na het wijzigen van het formaat nog steeds in het frame blijft. Grijsschaal is gebruikelijk in alle beeldverwerkingsstappen. Dit versnelt andere vervolgprocessen omdat we bij het verwerken van een afbeelding niet meer met de kleurdetails te maken hebben. De afbeelding zou zoiets als deze worden getransformeerd wanneer deze stap is voltooid
Stap 2: Elke afbeelding zal nuttige en nutteloze informatie bevatten, in dit geval is voor ons alleen het kenteken de nuttige informatie, de rest is vrijwel nutteloos voor ons programma. Deze nutteloze informatie wordt ruis genoemd. Normaal gesproken zal het gebruik van een bilateraal filter (vervaging) de ongewenste details uit een afbeelding verwijderen. De code voor hetzelfde is
grey = cv2.bilateralFilter (grijs, 11, 17, 17)
Syntaxis is destination_image = cv2.bilateralFilter (source_image, diameter van pixel, sigmaColor, sigmaSpace). U kunt de sigma-kleur en sigma-ruimte verhogen van 17 naar hogere waarden om meer achtergrondinformatie te vervagen, maar pas op dat het nuttige deel niet wazig wordt. De uitvoerafbeelding wordt hieronder weergegeven, zoals u kunt zien, zijn de achtergronddetails (boom en gebouw) wazig in deze afbeelding. Op deze manier kunnen we voorkomen dat het programma zich later op deze regio's concentreert.
Stap 3: De volgende stap is interessant waar we randdetectie uitvoeren. Er zijn veel manieren om dit te doen, de meest gemakkelijke en populaire manier is om de canny edge-methode van OpenCV te gebruiken. De regel om hetzelfde te doen, wordt hieronder weergegeven
edged = cv2.Canny (grijs, 30, 200) #Perform Edge detectie
De syntaxis is destination_image = cv2.Canny (source_image, thresholdValue 1, thresholdValue 2). De drempelwaarde 1 en de drempelwaarde 2 zijn de minimale en maximale drempelwaarden. Alleen de randen met een intensiteitsgradiënt groter dan de minimale drempelwaarde en kleiner dan de maximale drempelwaarde worden weergegeven. De resulterende afbeelding wordt hieronder weergegeven
Stap 4: Nu kunnen we beginnen met het zoeken naar contouren op onze afbeelding, we hebben al geleerd hoe we contouren kunnen vinden met OpenCV in onze vorige tutorial, dus we gaan gewoon door op dezelfde manier.
nts = cv2.findContours (edged.copy (), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours (cnts) cnts = gesorteerd (cnts, key = cv2.contourArea, reverse = True) screenCnt = Geen
Zodra de tellers zijn gedetecteerd, sorteren we ze van groot naar klein en beschouwen we alleen de eerste 10 resultaten en negeren we de andere. In onze afbeelding kan de teller alles zijn dat een gesloten oppervlak heeft, maar van alle verkregen resultaten zal het kenteken ook aanwezig zijn omdat het ook een gesloten oppervlak is.
Om de afbeelding van de kentekenplaat uit de verkregen resultaten te filteren, zullen we alle resultaten doorlopen en controleren welke een rechthoekige contour met vier zijden en een gesloten figuur heeft. Aangezien een kentekenplaat beslist een rechthoekige vierzijdige figuur zou zijn.
# loop over onze contouren voor c in cnts: # benader de contour peri = cv2.arcLength (c, True) approx = cv2.approxPolyDP (c, 0,018 * peri, True) # als onze geschatte contour vier punten heeft, dan # we kunnen aannemen dat we ons scherm hebben gevonden als len (circa) == 4: screenCnt = circa pauze
De waarde 0,018 is een experimentele waarde; je kunt er omheen spelen om te zien welke het beste bij je past. Of breng het naar een hoger niveau door machine learning te gebruiken om te trainen op basis van auto-afbeeldingen en daar vervolgens de juiste waarde te gebruiken. Zodra we de juiste teller hebben gevonden, slaan we deze op in een variabele genaamd screenCnt en tekenen we er een rechthoek omheen om er zeker van te zijn dat we de nummerplaat correct hebben gedetecteerd.
Stap 5: Nu we weten waar de nummerplaat is, is de resterende informatie voor ons vrijwel nutteloos. We kunnen dus doorgaan met het maskeren van de hele foto, behalve de plaats waar de kentekenplaat zit. De code om hetzelfde te doen, wordt hieronder weergegeven
# Maskeren van het andere deel dan het nummerplaatmasker = np.zeros (grey.shape, np.uint8) new_image = cv2.drawContours (mask,, 0,255, -1,) new_image = cv2.bitwise_and (img, img, mask = masker)
De gemaskeerde nieuwe afbeelding zal er ongeveer zo uitzien als hieronder
2. Tekensegmentatie
De volgende stap in Raspberry Pi-nummerplaatherkenning is om de kentekenplaat uit de afbeelding te segmenteren door deze bij te snijden en op te slaan als een nieuwe afbeelding. We kunnen deze afbeelding vervolgens gebruiken om het personage erin te detecteren. De code om de ROI-afbeelding (Region of interest) bij te snijden uit de hoofdafbeelding, wordt hieronder weergegeven
# Nu bijsnijden (x, y) = np.where (mask == 255) (topx, topy) = (np.min (x), np.min (y)) (bottomx, bottomy) = (np.max (x), np.max (y)) Cropped = grijs
De resulterende afbeelding wordt hieronder weergegeven. Normaal gesproken toegevoegd aan het bijsnijden van de afbeelding, kunnen we deze ook grijs maken en indien nodig een rand maken. Dit wordt gedaan om de karakterherkenning in de volgende stap te verbeteren. Ik ontdekte echter dat het prima werkt, zelfs met de originele afbeelding.
3. Karakterherkenning
De laatste stap in deze Raspberry Pi-nummerplaatherkenning is om de nummerplaatinformatie daadwerkelijk uit de gesegmenteerde afbeelding te lezen. We zullen het pytesseract- pakket gebruiken om tekens uit de afbeelding te lezen, net als in de vorige tutorial. De code voor hetzelfde wordt hieronder gegeven
#Read the number plate text = pytesseract.image_to_string (Cropped, config = '- psm 11') print ("Detected Number is:", text)
We hebben al uitgelegd hoe je een Tesseract-engine configureert, dus ook hier kunnen we indien nodig de Tesseract OCR configureren om indien nodig betere resultaten te verkrijgen. Het gedetecteerde teken wordt vervolgens op de console afgedrukt. Bij het samenstellen wordt het resultaat getoond zoals hieronder
Zoals u kunt zien, had de originele afbeelding het nummer “HR 25 BR9044” erop en ons programma heeft gedetecteerd dat dezelfde waarde op het scherm werd afgedrukt.
Mislukkingen bij nummerplaatherkenning
Het complete projectbestand van deze Raspberry Pi Kentekenplaatherkenning kan hier worden gedownload, het bevat het programma en de testafbeeldingen die we hebben gebruikt om ons programma te controleren. Zonder gezegd te worden, moet worden bedacht dat de resultaten van deze methode niet nauwkeurig zullen zijn . De nauwkeurigheid hangt af van de helderheid van het beeld, oriëntatie, belichting enz. Om betere resultaten te krijgen, kunt u proberen om hierbij machine learning-algoritmen te implementeren.
Laten we, om een idee te krijgen, naar een ander voorbeeld kijken waarbij de auto niet rechtstreeks naar de camera is gericht.
Zoals u kunt zien, was ons programma in staat om de kentekenplaat correct te detecteren en bij te snijden. Maar de Tesseract- bibliotheek heeft de karakters niet goed herkend. In plaats van de eigenlijke "TS 08 UE 3396" heeft de OCR erkend dat het "1508 ye 3396" is. Dergelijke problemen kunnen worden gecorrigeerd door ofwel betere oriëntatiebeelden te gebruiken of door de Tesseract- engine te configureren.
Een ander worstcasescenario is wanneer de contour de kentekenplaat niet correct detecteert. De onderstaande afbeelding bevat te veel achtergrondinformatie en slechte verlichting waardoor het programma de kentekenplaat niet eens heeft kunnen identificeren van het nummer. In dit geval moeten we opnieuw vertrouwen op Machine learning of de kwaliteit van de foto verbeteren.
Andere succesvolle voorbeelden
Meestal is de beeldkwaliteit en oriëntatie correct, het programma was in staat om de kentekenplaat te identificeren en het nummer ervan af te lezen. De onderstaande snapshots tonen enkele van de behaalde succesvolle resultaten. Opnieuw zullen alle testafbeeldingen en de code die hier wordt gebruikt, beschikbaar zijn in het ZIP-bestand dat hier wordt verstrekt.
Ik hoop dat je automatische kentekenherkenning met Raspberry Pi hebt begrepen en ervan genoten hebt om zelf iets cools te bouwen. Wat denk je dat er nog meer kan worden gedaan met OpenCV en Tesseract ? Laat me je mening weten in het commentaargedeelte. Als u vragen heeft over dit artikel, kunt u deze achterlaten in de commentaarsectie hieronder of de forums gebruiken voor andere technische vragen.