- Förutsättningar
- Steg involverade i erkännande av registreringsskylt med Raspberry Pi
- 1. Registrering av registreringsskylt
- 2. Karaktärsegmentering
- 3. Teckenigenkänning
- Misslyckade ärenden i erkännande av nummerplatta
- Andra framgångsrika exempel
Säkerhet har alltid varit ett stort bekymmer för mänskligheten. Idag har vi videoövervakningskameror i skolor, sjukhus och alla andra offentliga platser för att få oss att känna oss säkra. Enligt en undersökning av HIS uppskattas det att det fanns cirka 245 miljoner säkerhetskameror installerade och fungerade tillbaka 2014, vilket är som att ha en säkerhetskamera för varje 30 personer på denna planet. Med teknologins framsteg, särskilt inom bildbehandling och maskininlärning, är det möjligt att göra dessa kameror smartare genom att träna dem att bearbeta information från videoflöden.
Videoflöden från dessa kameror kan användas för att utföra ansiktsigenkänning, mönsteranalys, känsleanalys och mycket mer som verkligen skulle få det nära något som "Guds öga" som visas i FF7-filmen. Faktum är att övervakningsföretag som Hikvision och många andra redan har börjat implementera dessa funktioner i sina produkter. Vi använde tidigare MATLAB Bildbehandling för att läsa nummerskylten, idag lär vi oss i den här artikeln hur man känner igen och läser registreringsskyltnummer från bilar som använder Raspberry Pi och OpenCV. Vi använder några slumpmässiga fordonsbilder från Google och skriver ett program för att känna igen nummerskylten med hjälp av OpenCV Contour Detection och läser sedan numret från plattan med Tesseract OCR. Låter intressant rätt !, så låt oss komma igång.
Förutsättningar
Som tidigare sagt kommer vi att använda OpenCV-biblioteket för att upptäcka och känna igen ansikten. Så se till att installera OpenCV-biblioteket på Raspberry Pi innan du fortsätter med den här handledningen. Driv också din Pi med en 2A-adapter och anslut den till en bildskärm för enklare felsökning.
Denna handledning kommer inte att förklara hur exakt OpenCV fungerar, om du är intresserad av att lära dig bildbearbetning, kolla in de här grunderna i OpenCV och avancerade handledning för bildbehandling. Du kan också lära dig mer om konturer, upptäckt av fläckar osv. I denna bildsegmenteringshandledning med OpenCV. Vi kommer att göra något liknande detta för att upptäcka bilens registreringsskylt från bilden.
Steg involverade i erkännande av registreringsskylt med Raspberry Pi
License Plate Recognition eller LPR förkortar tre stora steg. Stegen är som följer
1. Registrering av registreringsskylt: Det första steget är att upptäcka registreringsskylten från bilen. Vi kommer att använda konturalternativet i OpenCV för att upptäcka för rektangulära objekt för att hitta nummerskylten. Noggrannheten kan förbättras om vi vet den exakta storleken, färgen och den ungefärliga platsen för nummerskylten. Normalt tränas detekteringsalgoritmen utifrån kamerans position och typ av typskylt som används i det aktuella landet. Detta blir svårare om bilden inte ens har en bil, i det här fallet kommer vi att göra ytterligare ett steg för att upptäcka bilen och sedan registreringsskylten.
2. Karaktärsegmentering: När vi har upptäckt registreringsskylten måste vi beskära den och spara den som en ny bild. Återigen kan detta göras enkelt med OpenCV.
3. Teckenigenkänning: Nu kommer den nya bilden som vi fick i föregående steg säkert att ha några tecken (siffror / alfabet) skrivna på den. Så vi kan utföra OCR (Optical Character Recognition) på den för att upptäcka numret. Vi har redan förklarat OCR (Optical Character Recognition) med Raspberry Pi.
1. Registrering av registreringsskylt
Det första steget i denna Raspberry Pi License Plate Reader är att upptäcka licensplattan. Låt oss ta en bild av en bil och börja med att upptäcka registreringsskylten på den bilen. Vi använder sedan samma bild för karaktärsegmentering och teckenigenkänning. Om du vill hoppa rakt in i koden utan förklaring kan du bläddra ner till botten av denna sida, där den fullständiga koden finns. Testbilden som jag använder för den här handledningen visas nedan.
Steg 1: Ändra storlek på bilden till önskad storlek och gråskala den sedan. Koden för detsamma ges nedan
img = cv2.resize (img, (620,480)) grå = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) #konvertera till gråskala
Ändra storlek vi hjälper oss att undvika problem med bilder med större upplösning, se till att nummerskylten fortfarande finns kvar i ramen efter att ha ändrat storlek. Gråskalning är vanligt i alla steg för bildbehandling. Detta påskyndar andra processprocesser efter vi behöver inte längre hantera färgdetaljerna när vi bearbetar en bild. Bilden skulle förvandlas ungefär så här när detta steg är klart
Steg 2: Varje bild kommer att ha användbar och värdelös information, i det här fallet är endast registreringsskylten den användbara informationen resten är ganska värdelösa för vårt program. Denna värdelösa information kallas buller. Normalt tar det oönskade informationen bort från en bild med hjälp av ett bilateralt filter (Bluring). Koden för detsamma är
grå = cv2.bilateralFilter (grå, 11, 17, 17)
Syntax är destination_image = cv2.bilateralFilter (källa_bild, pixeldiameter, sigmaColor, sigmaSpace). Du kan öka sigma-färgen och sigma-utrymmet från 17 till högre värden för att suddas ut mer bakgrundsinformation, men var försiktig så att den användbara delen inte blir suddig. Den utgående bilden visas nedan, eftersom du kan se bakgrundsdetaljer (träd och byggnad) är suddiga i den här bilden. På så sätt kan vi undvika att programmet koncentreras på dessa regioner senare.
Steg 3: Nästa steg är intressant där vi utför kantavkänning. Det finns många sätt att göra det, det enklaste och mest populära sättet är att använda canny edge-metoden från OpenCV. Raden för att göra detsamma visas nedan
kantad = cv2.Canny (grå, 30, 200) # Utför Edge-detektering
Syntaxen är destination_bild = cv2.Canny (källbild, tröskelvärde 1, tröskelvärde 2). Tröskelvärdet 1 och tröskelvärdet 2 är lägsta och högsta tröskelvärde. Endast kanterna som har en intensitetsgradient som är högre än det lägsta tröskelvärdet och mindre än det maximala tröskelvärdet visas. Den resulterande bilden visas nedan
Steg 4: Nu kan vi börja leta efter konturer på vår bild, vi har redan lärt oss hur man hittar konturer med OpenCV i vår tidigare handledning så vi fortsätter bara på samma sätt.
nts = cv2.findContours (edged.copy (), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours (cnts) cnts = sorted (cnts, key = cv2.contourArea, reverse = True) screenCnt = None
När räknarna har upptäckts sorterar vi dem från stora till små och anser bara att de första 10 resultaten ignorerar de andra. I vår bild kan räknaren vara vad som helst som har en sluten yta men av alla erhållna resultat kommer nummerskylten också att finnas där eftersom det också är en sluten yta.
För att filtrera registreringsskyltens bild bland de erhållna resultaten, kommer vi att slinga igenom alla resultat och kontrollera vilken som har en rektangelformad kontur med fyra sidor och sluten figur. Eftersom en registreringsskylt definitivt skulle vara en fyrkantig fyrkantig figur.
# loop över våra konturer för c i cnts: # ungefär konturen peri = cv2.arcLength (c, True) approx = cv2.approxPolyDP (c, 0,018 * peri, True) # om vår ungefärliga kontur har fyra punkter, då # vi kan anta att vi har hittat vår skärm om len (approx) == 4: screenCnt = approx break
Värdet 0,018 är ett experimentellt värde; du kan leka runt för att kontrollera vilka som fungerar bäst för dig. Eller ta det till nästa nivå genom att använda maskininlärning för att träna baserat på bilbilder och sedan använda rätt värde där. När vi har hittat rätt räknare sparar vi den i en variabel som heter screenCnt och ritar sedan en rektangelruta runt den för att se till att vi har upptäckt registreringsskylten korrekt.
Steg 5: Nu när vi vet var nummerskylten är är den återstående informationen ganska värdelös för oss. Så vi kan fortsätta med att maskera hela bilden förutom den plats där nummerskylten finns. Koden för att göra detsamma visas nedan
# Maskering av den andra delen än nummerplåtsmasken = np. nollor (grå. Form, np.uint8) new_image = cv2.drawContours (mask,, 0,255, -1,) new_image = cv2.bitwise_and (img, img, mask = mask)
Den maskerade nya bilden visas ungefär som nedan
2. Karaktärsegmentering
Nästa steg i Raspberry Pi Number Plate Recognition är att segmentera registreringsskylten ur bilden genom att beskära den och spara den som en ny bild. Vi kan sedan använda den här bilden för att upptäcka karaktären i den. Koden för att beskära roi-bilden (Region of interest) från huvudbilden visas nedan
# Beskär nu (x, y) = np.where (mask == 255) (topx, topy) = (np.min (x), np.min (y)) (bottomx, bottomy) = (np.max (x), np.max (y)) Beskuren = grå
Den resulterande bilden visas nedan. Normalt läggs till för att beskära bilden, vi kan också gråna den och kanta den vid behov. Detta görs för att förbättra karaktärsigenkänningen i nästa steg. Men jag tyckte att det fungerar bra även med originalbilden.
3. Teckenigenkänning
Det sista steget i detta Raspberry Pi Nummerplåtsigenkänning är att faktiskt läsa nummerplattainformationen från den segmenterade bilden. Vi kommer att använda paketet pytesseract för att läsa tecken från bilden, precis som vi gjorde i föregående handledning. Koden för detsamma ges nedan
#Läs nummerskylten text = pytesseract.image_to_string (Beskuren, config = '- psm 11') utskrift ("Detekterat nummer är:", text)
Vi har redan förklarat hur man konfigurerar en Tesseract-motor, så här igen om det behövs kan vi konfigurera Tesseract OCR för att få bättre resultat om det behövs. Det upptäckta tecknet skrivs sedan ut på konsolen. När det sammanställs visas resultatet enligt nedan
Som du kan se hade originalbilden numret “HR 25 BR9044” på och vårt program har upptäckt att det tryckt samma värde på skärmen.
Misslyckade ärenden i erkännande av nummerplatta
Den fullständiga projektfilen för denna Raspberry Pi License Plate Recognition kan hämtas härifrån, den innehåller programmet och testbilderna som vi använde för att kontrollera vårt program. Utan att sägas är det att komma ihåg att resultaten från denna metod inte kommer att vara korrekta . Noggrannheten beror på tydligheten i bilden, orientering, ljusexponering osv. För att få bättre resultat kan du försöka implementera maskininlärningsalgoritmer tillsammans med detta.
För att få en idé, låt oss titta på ett annat exempel där bilen inte vetter direkt mot kameran.
Som du kan se kunde vårt program upptäcka registreringsskylten korrekt och beskära den. Men Tesseract- biblioteket har inte lyckats känna igen karaktärerna ordentligt. I stället för själva ”TS 08 UE 3396” har OCR erkänt att det är ”1508 ye 3396”. Problem som detta kan korrigeras genom att antingen använda bilder med bättre orientering eller genom att konfigurera Tesseract- motorn.
Ett annat worst case-scenario är att konturen inte identifierar registreringsskylten korrekt. Bilden nedan har för mycket bakgrundsinformation och dålig belysning för att programmet till och med misslyckades med att identifiera registreringsskylten från numret. I det här fallet måste vi återigen förlita sig på maskininlärning eller förbättra bildens kvalitet.
Andra framgångsrika exempel
De flesta av tiderna för bildkvalitet och orientering är korrekt, programmet kunde identifiera registreringsskylten och läsa numret från den. Nedanstående snapshots visar några av de framgångsrika resultat som erhållits. Återigen kommer alla testbilder och koden som används här att finnas tillgängliga i ZIP-filen som tillhandahålls här.
Hoppas att du förstod Automatic Number Plate Recognition med Raspberry Pi och tyckte om att bygga något coolt på egen hand. Vad tror du mer kan göras med OpenCV och Tesseract ? Låt mig veta dina tankar i kommentarsektionen. Om du har några frågor angående den här artikeln är du välkommen att lämna dem i kommentarfältet nedan eller använd forumen för andra tekniska frågor.