detectarea zonelor care pot fi citite de mașină în imaginile pașaportului
postarea de astăzi pe blog nu ar fi posibilă fără membrul Pyimagesearch Gurus, Hans Boone. Hans lucrează la un proiect de viziune computerizată pentru a detecta automat zonele care pot fi citite de mașini (MRZ) în imaginile pașaportului-la fel ca regiunea detectată în imaginea de mai sus.
Regiunea MRZ în pașapoarte sau cărți de călătorie se încadrează în două clase: tipul 1 și tipul 3. MRZ-urile de tip 1 sunt trei linii, fiecare linie conținând 30 de caractere. Tipul 3 MRZ are doar două linii, dar fiecare linie conține 44 de caractere. În ambele cazuri, MRZ codifică informațiile de identificare ale unui cetățean dat, inclusiv tipul pașaportului, ID-ul pașaportului, țara emitentă, numele, naționalitatea, data expirării etc.
în cadrul cursului Pyimagesearch Gurus, Hans mi-a arătat progresul său în proiect și am devenit imediat interesat. Întotdeauna mi-am dorit să aplic algoritmi de viziune computerizată la imaginile pașaportului (în principal doar pentru distracție), dar nu aveam setul de date pentru a face acest lucru. Având în vedere informațiile personale de identificare pe care le conține un pașaport, evident că nu am putut scrie o postare pe blog pe această temă și să împărtășesc imaginile pe care le-am folosit pentru a dezvolta algoritmul.
din fericire, Hans a fost de acord să împărtășească câteva dintre imaginile de pașaport eșantion/specimen la care are acces — și am sărit la șansa de a mă juca cu aceste imagini.
acum, înainte de a ajunge departe, este important să rețineți că aceste pașapoarte nu sunt „reale” în sensul că pot fi legate de o ființă umană reală. Dar sunt pașapoarte autentice care au fost generate folosind nume false, adrese etc. pentru dezvoltatorii de a lucra cu.
s — ar putea să credeți că pentru a detecta Regiunea MRZ a unui pașaport aveți nevoie de un pic de învățare automată, probabil folosind cadrul liniar SVM + HOG pentru a construi un „detector MRZ” – dar asta ar fi excesiv.
în schimb, putem efectua detectarea MRZ folosind doar tehnici de bază de procesare a imaginii, cum ar fi pragurile, operațiile morfologice și proprietățile conturului. În restul acestui post pe blog, voi detalia propria mea abordare cu privire la modul de aplicare a acestor metode pentru a detecta Regiunea MRZ a unui pașaport.
Privind pentru codul sursă pentru acest post?
salt direct la secțiunea Descărcări
detectarea zonelor care pot fi citite de mașină în imaginile pașaportului
să mergem mai departe și să începem acest proiect. Deschideți un fișier nou, denumiți-l detect_mrz.py
și introduceți următorul cod:
# import the necessary packagesfrom imutils import pathsimport numpy as npimport argparseimport imutilsimport cv2# construct the argument parse and parse the argumentsap = argparse.ArgumentParser()ap.add_argument("-i", "--images", required=True, help="path to images directory")args = vars(ap.parse_args())# initialize a rectangular and square structuring kernelrectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (13, 5))sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 21))
liniile 2-6 importă pachetele noastre necesare. Presupun că aveți deja OpenCV instalat. De asemenea, veți avea nevoie de imutils, colecția mea de funcții de confort pentru a facilita operațiunile de procesare a imaginilor de bază cu OpenCV. Puteți instala imutils
folosind pip
:
$ pip install --upgrade imutils
de acolo, liniile 9-11 se ocupă de analizarea argumentului nostru din linia de comandă. Avem nevoie doar de un singur comutator aici, --images
, care este calea către directorul care conține imaginile pașaportului pe care urmează să le procesăm.
în cele din urmă, liniile 14 și 15 inițializează două nuclee pe care le vom folosi ulterior la aplicarea operațiilor morfologice, în special operația de închidere. Pentru moment, pur și simplu rețineți că primul nucleu este dreptunghiular cu o lățime de aproximativ 3x mai mare decât înălțimea. Al doilea nucleu este pătrat. Aceste nuclee ne vor permite să închidem decalajele dintre caracterele MRZ și deschiderile dintre liniile MRZ.
acum că argumentele noastre din linia de comandă sunt analizate, putem începe să buclăm fiecare dintre imaginile din setul nostru de date și să le procesăm:
# loop over the input image pathsfor imagePath in paths.list_images(args):# load the image, resize it, and convert it to grayscaleimage = cv2.imread(imagePath)image = imutils.resize(image, height=600)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# smooth the image using a 3x3 Gaussian, then apply the blackhat# morphological operator to find dark regions on a light backgroundgray = cv2.GaussianBlur(gray, (3, 3), 0)blackhat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, rectKernel)
liniile 20 și 21 încarcă imaginea noastră originală de pe disc și o redimensionează pentru a avea o înălțime maximă de 600 de pixeli. Puteți vedea mai jos un exemplu de imagine originală:
estomparea Gaussiană se aplică pe linia 26 pentru a reduce zgomotul de înaltă frecvență. Apoi aplicăm o operație morfologică blackhat pe imaginea neclară, în tonuri de gri, pe linia 27.
un operator blackhat este folosit pentru a dezvălui regiuni întunecate (adică text MRZ) pe fundaluri luminoase (adică fundalul pașaportului în sine). Deoarece textul pașaportului este întotdeauna negru pe un fundal deschis (cel puțin în ceea ce privește acest set de date), o operațiune blackhat este adecvată. Mai jos puteți vedea rezultatul aplicării operatorului blackhat:
următorul pas în detectarea MRZ este de a calcula reprezentarea magnitudinii gradientului imaginii blackhat folosind operatorul Scharr:
# compute the Scharr gradient of the blackhat image and scale the# result into the range gradX = cv2.Sobel(blackhat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)gradX = np.absolute(gradX)(minVal, maxVal) = (np.min(gradX), np.max(gradX))gradX = (255 * ((gradX - minVal) / (maxVal - minVal))).astype("uint8")
aici calculăm gradientul Scharr de-a lungul axei x a imaginii blackhat, dezvăluind regiuni ale imaginii care nu sunt doar întunecate pe un fundal deschis, ci conțin și modificări verticale ale gradientului, cum ar fi Regiunea textului MRZ. Apoi luăm această imagine de gradient și o scalăm înapoi în interval folosind scalarea min / max:
deși nu este în întregime evident de ce aplicăm acest pas, voi spune că este extrem de util în reducerea detectărilor MRZ fals pozitive. Fără aceasta, putem marca accidental regiunile înfrumusețate sau proiectate ale pașaportului ca MRZ. Vă voi lăsa acest lucru ca un exercițiu pentru a verifica dacă calculul gradientului imaginii blackhat poate îmbunătăți precizia detectării MRZ.
următorul pas este să încercați să detectați liniile reale ale MRZ:
# apply a closing operation using the rectangular kernel to close# gaps in between letters -- then apply Otsu's thresholding methodgradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
în primul rând, aplicăm o operație de închidere folosind nucleul nostru dreptunghiular. Această operațiune de închidere este menită să închidă golurile dintre caracterele MRZ. Apoi aplicăm thresholding folosind metoda Otsu pentru a prag automat imaginea:
după cum putem vedea din figura de mai sus, fiecare dintre liniile MRZ este prezentă în harta noastră de prag.
următorul pas este să închidem golurile dintre liniile reale, oferindu – ne o regiune dreptunghiulară mare care corespunde MRZ:
# perform another closing operation, this time using the square# kernel to close gaps between lines of the MRZ, then perform a# series of erosions to break apart connected componentsthresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)thresh = cv2.erode(thresh, None, iterations=4)
aici efectuăm o altă operație de închidere, de data aceasta folosind nucleul nostru pătrat. Acest kernel este folosit pentru a închide golurile dintre liniile individuale ale MRZ, oferindu-ne o regiune mare care corespunde MRZ. O serie de eroziuni sunt apoi efectuate pentru a rupe componentele conectate care ar fi putut fi unite în timpul operației de închidere. Aceste eroziuni sunt, de asemenea, utile în îndepărtarea petelor mici care sunt irelevante pentru MRZ.
pentru unele scanări de pașapoarte, este posibil ca granița pașaportului să fi fost atașată regiunii MRZ în timpul operațiunilor de închidere. Pentru a remedia acest lucru, setăm 5% din marginile stângi și drepte ale imaginii la zero (adică negru):
# during thresholding, it's possible that border pixels were# included in the thresholding, so let's set 5% of the left and# right borders to zerop = int(image.shape * 0.05)thresh = 0thresh - p:] = 0
puteți vedea mai jos rezultatul eliminării frontierei noastre.
comparativ cu figura 5 de mai sus, puteți vedea acum că granița a fost eliminată.
ultimul pas este să găsim contururile din imaginea noastră pragată și să folosim proprietățile conturului pentru a identifica MRZ:
# find contours in the thresholded image and sort them by their# sizecnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)cnts = sorted(cnts, key=cv2.contourArea, reverse=True)# loop over the contoursfor c in cnts:# compute the bounding box of the contour and use the contour to# compute the aspect ratio and coverage ratio of the bounding box# width to the width of the image(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)crWidth = w / float(gray.shape)# check to see if the aspect ratio and coverage width are within# acceptable criteriaif ar > 5 and crWidth > 0.75:# pad the bounding box since we applied erosions and now need# to re-grow itpX = int((x + w) * 0.03)pY = int((y + h) * 0.03)(x, y) = (x - pX, y - pY)(w, h) = (w + (pX * 2), h + (pY * 2))# extract the ROI from the image and draw a bounding box# surrounding the MRZroi = image.copy()cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)break# show the output imagescv2.imshow("Image", image)cv2.imshow("ROI", roi)cv2.waitKey(0)
pe linia 56-58 calculăm contururile (adică contururile) imaginii noastre pragate. Apoi luăm aceste contururi și le sortăm în funcție de dimensiunea lor în ordine descrescătoare pe linia 59 (ceea ce înseamnă că cele mai mari contururi sunt primele în listă).
pe linia 62 vom începe looping peste lista noastră sortate de contururi. Pentru fiecare dintre aceste contururi, vom calcula caseta de încadrare (linia 66) și o vom folosi pentru a calcula două proprietăți: raportul de aspect și raportul de acoperire. Raportul de aspect este pur și simplu lățimea cutiei de delimitare împărțită la înălțime. Raportul de acoperire este lățimea casetei de delimitare împărțită la lățimea imaginii reale.
folosind aceste două proprietăți putem face o verificare pe linia 72 pentru a vedea dacă examinăm Regiunea MRZ. MRZ este dreptunghiular, cu o lățime mult mai mare decât înălțimea. MRZ ar trebui să acopere, de asemenea, cel puțin 75% din imaginea de intrare.
cu condiția ca aceste două cazuri să se mențină, liniile 75-84 utilizează coordonatele (X, y) ale casetei de încadrare pentru a extrage MRZ și a desena caseta de încadrare pe imaginea noastră de intrare.
în cele din urmă, liniile 87-89 afișează rezultatele noastre.
rezultate
pentru a vedea detectorul nostru MRZ în acțiune, trebuie doar să executați următoarea comandă:
$ python detect_mrz.py --images examples
mai jos puteți vedea un exemplu de detectare MRZ reușită, cu MRZ conturat în verde:
Iată un alt exemplu de detectare a zonei care poate fi citită de mașină într-o imagine de pașaport folosind Python și OpenCV:
nu contează dacă Regiunea MRZ se află în partea de sus sau de jos a imaginii. Prin aplicarea operațiilor morfologice, extragerea contururilor și calcularea proprietăților conturului, suntem capabili să extragem MRZ fără probleme.
același lucru este valabil și pentru următoarea imagine:
să încercăm o altă imagine:
până acum am văzut doar MRZ-uri de tip 1 care conțin trei linii. Cu toate acestea, metoda noastră funcționează la fel de bine cu MRZ-urile de tip 3 care conțin doar două linii:
Iată un alt exemplu de detectare a unui MRZ de tip 3:
ce urmează? Recomand Universitatea PyImageSearch.
30 + total clase * 39H 44m video * Ultima actualizare: 12/2021
★★★★★ 4.84 (128 3.000 de studenți înscriși
cred cu tărie că, dacă ai avea profesorul potrivit, ai putea stăpâni viziunea computerizată și învățarea profundă.
credeți că învățarea viziunii computerizate și a învățării profunde trebuie să fie consumatoare de timp, copleșitoare și complicată? Sau trebuie să implice matematică și ecuații complexe? Sau necesită o diplomă în informatică?
nu este cazul.
tot ce ai nevoie pentru a stăpâni viziunea computerizată și învățarea profundă este ca cineva să-ți explice lucrurile în termeni simpli și intuitivi. Și exact asta fac. Misiunea mea este de a schimba educația și modul în care sunt predate subiecte complexe de inteligență artificială.
dacă sunteți serios în ceea ce privește învățarea viziunii pe computer, următoarea oprire ar trebui să fie PyImageSearch University, cea mai cuprinzătoare viziune pe computer, învățare profundă și curs OpenCV online astăzi. Aici veți învăța cum să aplicați cu succes și cu încredere viziunea computerizată asupra muncii, cercetării și proiectelor dvs. Alătură-te mie în computer vision mastery.
în cadrul Universității PyImageSearch veți găsi:
- &verifica; Peste 30 de cursuri pe teme esențiale de viziune computerizată, învățare profundă și OpenCV
- &verificați; peste 30 de certificate de finalizare
- &verificați; 39H 44m video la cerere
- &verificați; cursuri noi lansate în fiecare lună, asigurându-vă că puteți ține pasul cu tehnicile de ultimă oră
- &verificați; notebook-uri jupyter preconfigurate în Google colab
- &verificați; rulați toate exemplele de cod în browserul dvs. web-funcționează pe Windows, MacOS și Linux (nu este necesară configurarea mediului dev!)
- &verifica; Acces la repo-uri de cod centralizate pentru toate cele peste 500 de tutoriale despre PyImageSearch
- & verificați; descărcări ușoare cu un singur clic pentru cod, seturi de date, modele pre-instruite etc.
- &verificare; acces pe mobil, laptop, desktop etc.
Faceți clic aici pentru a vă alătura Universității PyImageSearch
rezumat
în această postare pe blog am învățat cum să detectăm zonele citibile de mașină (MRZ) în scanările de pașapoarte folosind doar tehnici de bază de procesare a imaginilor, și anume:
- prag.
- gradienți.
- operații morfologice (în special, închideri și eroziuni).
- proprietăți contur.
aceste operațiuni, deși simple, ne-au permis să detectăm regiunile MRZ în imagini fără a fi nevoie să ne bazăm pe metode mai avansate de extragere a caracteristicilor și de învățare automată, cum ar fi SVM liniar + HOG pentru detectarea obiectelor.
amintiți — vă, atunci când se confruntă cu o problemă provocatoare viziune calculator-întotdeauna ia în considerare problema și presupunerile tale! După cum demonstrează această postare pe blog, s-ar putea să fiți surprins de ce pot realiza funcțiile de bază de procesare a imaginilor utilizate în tandem.
încă o dată, un mare datorită Pyimagesearch Guru membru, Hans Boone, care ne-a furnizat cu aceste imagini exemplu pașaport! Mulțumesc Hans!