- Wymagania wstępne
- Kroki związane z rozpoznawaniem tablic rejestracyjnych przy użyciu Raspberry Pi
- 1. Wykrywanie tablic rejestracyjnych
- 2. Segmentacja postaci
- 3. Rozpoznawanie postaci
- Przypadki niepowodzeń w rozpoznawaniu tablic rejestracyjnych
- Inne udane przykłady
Bezpieczeństwo zawsze było głównym zmartwieniem ludzkości. Dziś mamy kamery monitorujące w szkołach, szpitalach i każdym innym miejscu publicznym, aby czuć się bezpiecznie. Według sondażu przeprowadzonego przez HIS szacuje się, że w 2014 r. Zainstalowano i działało około 245 milionów kamer bezpieczeństwa, co jest jak jedna kamera bezpieczeństwa na 30 osób na tej planecie. Wraz z postępem technologicznym, zwłaszcza w przetwarzaniu obrazu i uczeniu maszynowym, można uczynić te kamery inteligentniejszymi, ucząc je przetwarzania informacji z źródła wideo.
Transmisja wideo z tych kamer może być wykorzystana do rozpoznawania twarzy, analizy wzorców, analizy emocji i wielu innych, co naprawdę zbliżyłoby to do czegoś takiego jak „Oko Boga” pokazane w filmie FF7. W rzeczywistości firmy monitorujące, takie jak Hikvision i wiele innych, już zaczęły wdrażać te funkcje w swoich produktach. Wcześniej używaliśmy przetwarzania obrazu MATLAB do odczytywania tablic rejestracyjnych, dziś w tym artykule nauczymy się rozpoznawać i odczytywać numery tablic rejestracyjnych z samochodów korzystających z Raspberry Pi i OpenCV. Wykorzystamy losowe obrazy pojazdów z Google i napiszemy program rozpoznający tablicę rejestracyjną za pomocą OpenCV Contour Detection, a następnie odczytamy numer z tablicy za pomocą Tesseract OCR. Brzmi interesująco, prawda !, więc zaczynajmy.
Wymagania wstępne
Jak powiedziano wcześniej, będziemy używać biblioteki OpenCV do wykrywania i rozpoznawania twarzy. Dlatego przed kontynuowaniem tego samouczka zainstaluj bibliotekę OpenCV na Raspberry Pi. Zasilaj również swoje Pi za pomocą adaptera 2A i podłącz go do monitora, aby ułatwić debugowanie.
Ten samouczek nie wyjaśnia, jak dokładnie działa OpenCV, jeśli jesteś zainteresowany nauką przetwarzania obrazu, zapoznaj się z podstawami OpenCV i zaawansowanymi samouczkami dotyczącymi przetwarzania obrazu. Możesz również dowiedzieć się o konturach, wykrywaniu plamek itp. W tym samouczku Segmentacja obrazu przy użyciu OpenCV. Będziemy robić coś podobnego, aby wykryć tablicę rejestracyjną samochodu na obrazie.
Kroki związane z rozpoznawaniem tablic rejestracyjnych przy użyciu Raspberry Pi
Rozpoznawanie tablic rejestracyjnych lub w skrócie LPR obejmuje trzy główne kroki. Kroki są następujące
1. Wykrywanie tablic rejestracyjnych: Pierwszym krokiem jest wykrycie tablicy rejestracyjnej z samochodu. Użyjemy opcji konturu w OpenCV, aby wykryć prostokątne obiekty w celu znalezienia tablicy rejestracyjnej. Dokładność można poprawić, znając dokładny rozmiar, kolor i przybliżone położenie tablicy rejestracyjnej. Zwykle algorytm wykrywania jest szkolony na podstawie położenia kamery i typu tablicy rejestracyjnej używanej w danym kraju. To staje się trudniejsze, jeśli na obrazie nie ma nawet samochodu, w tym przypadku zrobimy dodatkowy krok, aby wykryć samochód, a następnie tablicę rejestracyjną.
2. Segmentacja postaci: Po wykryciu tablicy rejestracyjnej musimy ją wyciąć i zapisać jako nowy obraz. Ponownie można to łatwo zrobić za pomocą OpenCV.
3. Rozpoznawanie znaków: Teraz nowy obraz, który uzyskaliśmy w poprzednim kroku, z pewnością będzie zawierał jakieś znaki (cyfry / alfabety). Możemy więc wykonać na nim OCR (optyczne rozpoznawanie znaków), aby wykryć liczbę. Wyjaśniliśmy już optyczne rozpoznawanie znaków (OCR) przy użyciu Raspberry Pi.
1. Wykrywanie tablic rejestracyjnych
Pierwszym krokiem w tym czytniku tablic rejestracyjnych Raspberry Pi jest wykrycie tablicy rejestracyjnej. Zróbmy przykładowe zdjęcie samochodu i zacznijmy od wykrycia tablicy rejestracyjnej w tym samochodzie. Następnie użyjemy tego samego obrazu do segmentacji znaków i rozpoznawania znaków. Jeśli chcesz przejść bezpośrednio do kodu bez wyjaśnienia, możesz przewinąć w dół do dołu tej strony, gdzie znajduje się pełny kod. Obraz testowy, którego używam w tym samouczku, jest pokazany poniżej.
Krok 1: Zmień rozmiar obrazu do wymaganego rozmiaru, a następnie przeskaluj go w skali szarości. Kod tego samego podano poniżej
img = cv2.resize (img, (620,480)) gray = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) # konwertuj na skalę szarości
Zmiana rozmiaru pomaga nam uniknąć problemów z obrazami o większej rozdzielczości, upewnij się, że tablica rejestracyjna nadal pozostaje w ramce po zmianie rozmiaru. Skalowanie szarości jest powszechne na wszystkich etapach przetwarzania obrazu. Przyspiesza to inne następujące procesy, nie musimy już zajmować się szczegółami kolorów podczas przetwarzania obrazu. Po wykonaniu tego kroku obraz zostałby przekształcony w podobny sposób
Krok 2: Każdy obraz będzie zawierał przydatne i bezużyteczne informacje, w tym przypadku dla nas tylko numer rejestracyjny jest użyteczną informacją, reszta jest prawie bezużyteczna dla naszego programu. Ta bezużyteczna informacja nazywa się szumem. Zwykle użycie filtra dwustronnego (Bluring) usuwa niechciane szczegóły z obrazu. Kod na to samo to
gray = cv2.bilateralFilter (gray, 11, 17, 17)
Składnia to obraz_docelowy = cv2.bilateralFilter (obraz_źródłowy, średnica piksela, sigmaColor, sigmaSpace). Możesz zwiększyć kolor sigma i przestrzeń sigma z 17 do wyższych wartości, aby zamazać więcej informacji tła, ale uważaj, aby użyteczna część nie została rozmazana. Obraz wyjściowy jest pokazany poniżej, ponieważ widać, że szczegóły tła (drzewo i budynek) są rozmyte na tym obrazie. W ten sposób możemy uniknąć późniejszej koncentracji programu na tych regionach.
Krok 3: Kolejny krok jest interesujący, w którym wykonujemy wykrywanie krawędzi. Sposobów na to jest wiele, z których najłatwiejszym i najbardziej popularnym jest użycie sprytnej metody brzegowej z OpenCV. Linia do zrobienia tego samego jest pokazana poniżej
edged = cv2.Canny (gray, 30, 200) # Wykonaj wykrywanie krawędzi
Składnia będzie wyglądać następująco: obraz_docelowy = cv2.Canny (obraz_źródłowy, wartość progowa 1, wartość progowa 2). Wartość progowa 1 i Wartość progowa 2 to minimalne i maksymalne wartości progowe. Zostaną wyświetlone tylko te krawędzie, których gradient intensywności jest większy niż minimalna wartość progu i mniejszy niż maksymalna wartość progu. Wynikowy obraz pokazano poniżej
Krok 4: Teraz możemy zacząć szukać konturów na naszym obrazie, dowiedzieliśmy się już, jak znaleźć kontury za pomocą OpenCV w naszym poprzednim samouczku, więc postępujemy tak samo.
nts = cv2.findContours (edged.copy (), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours (cnts) cnts = sortowane (cnts, key = cv2nt.contourArea, reverse = True) screenContour
Po wykryciu liczników sortujemy je od dużych do małych i uwzględniamy tylko pierwsze 10 wyników, ignorując pozostałe. Na naszym obrazie licznikiem może być wszystko, co ma zamkniętą powierzchnię, ale spośród wszystkich uzyskanych wyników numer rejestracyjny również będzie tam, ponieważ jest to również zamknięta powierzchnia.
Aby odfiltrować obraz tablicy rejestracyjnej wśród otrzymanych wyników, przejrzymy wszystkie wyniki i sprawdzimy, który ma kontur w kształcie prostokąta z czterema bokami i zamkniętą figurą. Ponieważ tablica rejestracyjna z pewnością byłaby prostokątną figurą z czterech stron.
# pętla nad naszymi konturami dla c w cnts: # przybliż kontur peri = cv2.arcLength (c, True) approx = cv2.approxPolyDP (c, 0,018 * peri, True) # jeśli nasz przybliżony kontur ma cztery punkty, to # my możemy założyć, że znaleźliśmy nasz ekran, jeśli len (w przybliżeniu) == 4: screenCnt = ok. przerwa
Wartość 0,018 jest wartością eksperymentalną; możesz to obejść, aby sprawdzić, który z nich działa najlepiej. Lub przenieś go na wyższy poziom, korzystając z uczenia maszynowego do trenowania na podstawie obrazów samochodów, a następnie wykorzystaj tam odpowiednią wartość. Po znalezieniu odpowiedniego licznika zapisujemy go w zmiennej o nazwie screenCnt, a następnie rysujemy wokół niego prostokątną ramkę, aby upewnić się, że prawidłowo wykryliśmy tablicę rejestracyjną.
Krok 5: Teraz, gdy wiemy, gdzie jest numer rejestracyjny, pozostałe informacje są dla nas prawie bezużyteczne. Możemy więc przystąpić do maskowania całego obrazu poza miejscem, w którym znajduje się tablica rejestracyjna. Kod umożliwiający to samo pokazano poniżej
# Maskowanie części innej niż maska tablicy rejestracyjnej = np.zeros (gray.shape, np.uint8) new_image = cv2.drawContours (mask,, 0,255, -1,) new_image = cv2.bitwise_and (img, img, mask = maska)
Zamaskowany nowy obraz będzie wyglądał jak poniżej
2. Segmentacja postaci
Następnym krokiem w rozpoznawaniu tablic rejestracyjnych Raspberry Pi jest segmentacja tablicy rejestracyjnej z obrazu poprzez przycięcie jej i zapisanie jako nowy obraz. Możemy następnie użyć tego obrazu, aby wykryć znajdujący się na nim znak. Kod służący do przycięcia obrazu ROI (regionu zainteresowania) z obrazu głównego jest pokazany poniżej
# Teraz kadrowanie (x, y) = np.where (maska == 255) (topx, topy) = (np.min (x), np.min (y)) (bottomx, bottomy) = (np.max (x), np.max (y)) Przycięte = szare
Wynikowy obraz pokazano poniżej. Zwykle dodawane do kadrowania obrazu, możemy go również wyszarzać i w razie potrzeby obramowywać. Ma to na celu poprawę rozpoznawania znaków w następnym kroku. Jednak stwierdziłem, że działa dobrze nawet z oryginalnym obrazem.
3. Rozpoznawanie postaci
Ostatnim krokiem w tym rozpoznawaniu tablic rejestracyjnych Raspberry Pi jest faktyczne odczytanie informacji o tablicy rejestracyjnej z posegmentowanego obrazu. Będziemy używać pakietu pytesseract do odczytywania znaków z obrazka, tak jak robiliśmy to w poprzednim tutorialu. Kod tego samego podano poniżej
# Przeczytaj tablicę rejestracyjną text = pytesseract.image_to_string (przycięte, config = '- psm 11') print ("Wykryty numer to:", tekst)
Wyjaśniliśmy już, jak skonfigurować silnik Tesseract, więc tutaj ponownie w razie potrzeby możemy skonfigurować Tesseract OCR, aby w razie potrzeby uzyskać lepsze wyniki. Wykryty znak jest następnie drukowany na konsoli. Po kompilacji wynik jest pokazany poniżej
Jak widać na oryginalnym obrazie widniał numer „HR 25 BR9044” i nasz program wykrył, że wydrukował tę samą wartość na ekranie.
Przypadki niepowodzeń w rozpoznawaniu tablic rejestracyjnych
Pełny plik projektu tego Rozpoznawania tablic rejestracyjnych Raspberry Pi można pobrać stąd, zawiera on program i obrazy testowe, których użyliśmy do sprawdzenia naszego programu. Nie trzeba mówić, że należy pamiętać, że wyniki uzyskane tą metodą nie będą dokładne . Dokładność zależy od wyrazistości obrazu, orientacji, ekspozycji na światło itp. Aby uzyskać lepsze wyniki, możesz spróbować zaimplementować wraz z tym algorytmy uczenia maszynowego.
Aby się zorientować, spójrzmy na inny przykład, w którym samochód nie jest skierowany bezpośrednio w stronę aparatu.
Jak widać, nasz program był w stanie poprawnie wykryć tablicę rejestracyjną i ją przyciąć. Ale biblioteka Tesseract nie rozpoznała poprawnie znaków. Zamiast rzeczywistego „TS 08 UE 3396”, OCR rozpoznał, że jest to „1508 ye 3396”. Takie problemy można rozwiązać, używając obrazów o lepszej orientacji lub konfigurując silnik Tesseract .
Innym najgorszym scenariuszem jest sytuacja, w której kontur nie wykrywa prawidłowo tablicy rejestracyjnej. Poniższy obraz ma zbyt dużo informacji w tle i złe oświetlenie, że program nawet nie zidentyfikował tablicy rejestracyjnej na podstawie numeru. W takim przypadku musimy ponownie polegać na uczeniu maszynowym lub poprawić jakość obrazu.
Inne udane przykłady
W większości przypadków jakość i orientacja obrazu jest poprawna, program był w stanie zidentyfikować tablicę rejestracyjną i odczytać z niej numer. Poniższe zdjęcia przedstawiają kilka udanych wyników. Ponownie wszystkie obrazy testowe i użyty tutaj kod będą dostępne w dostarczonym tutaj pliku ZIP.
Mam nadzieję, że rozumiesz Automatyczne rozpoznawanie tablic rejestracyjnych za pomocą Raspberry Pi i cieszysz się samodzielnym budowaniem czegoś fajnego. Jak myślisz, co jeszcze można zrobić z OpenCV i Tesseract ?, Daj mi znać, co myślisz w sekcji komentarzy. Jeśli masz jakiekolwiek pytania dotyczące tego artykułu, możesz je zostawić w sekcji komentarzy poniżej lub skorzystać z forów, aby uzyskać odpowiedzi na inne pytania techniczne.