registrering af maskinlæsbare områder i pasbilleder
dagens blogindlæg ville ikke være muligt uden PyImageSearch guruer medlem, Hans Boone. Hans arbejder på et computervisionsprojekt for automatisk at registrere maskinlæsbare områder i pasbilleder — ligesom det område, der er registreret i billedet ovenfor.
MR-regionen i pas eller rejsekort falder i to klasser: Type 1 og Type 3. Type 1 Mrs. er tre linjer, hvor hver linje indeholder 30 tegn. Type 3 MR har kun to linjer, men hver linje indeholder 44 tegn. I begge tilfælde koder Mrs. for at identificere oplysninger om en given borger, herunder typen af pas, pas-ID, udstedelsesland, navn, nationalitet, udløbsdato osv.
inde i PyImageSearch guruer kursus, Hans viste mig hans fremskridt på projektet, og jeg blev straks interesseret. Jeg har altid ønsket at anvende computersynsalgoritmer til pasbilleder (hovedsagelig bare for sjov), men manglede datasættet til at gøre det. I betragtning af de personlige identificerende oplysninger, som et pas indeholder, kunne jeg naturligvis ikke skrive et blogindlæg om emnet og dele de billeder, jeg brugte til at udvikle algoritmen.
heldigvis accepterede hans at dele nogle af de prøve — /prøvepasbilleder, han har adgang til-og jeg sprang på chancen for at lege med disse billeder.
nu, før vi kommer til langt, er det vigtigt at bemærke, at disse pas ikke er “rigtige” i den forstand, at de kan knyttes til et faktisk menneske. Men de er ægte pas, der blev genereret ved hjælp af falske navne, adresser osv. for udviklere at arbejde med.
du tror måske, at for at opdage MR — regionen i et pas, har du brug for en smule maskinindlæring, måske ved hjælp af den lineære SVM + HOG-ramme til at konstruere en “MR-detektor” – men det ville være overkill.
i stedet kan vi udføre MR-detektering ved kun at bruge grundlæggende billedbehandlingsteknikker som tærskelværdier, morfologiske operationer og konturegenskaber. I resten af dette blogindlæg beskriver jeg min egen opfattelse af, hvordan man anvender disse metoder til at opdage MR-regionen i et pas.
Leder du efter kildekoden til dette indlæg?
Spring til højre til afsnittet Overførsler
registrering af maskinlæsbare områder i pasbilleder
lad os gå videre og få dette projekt i gang. Åbn en ny fil, navngiv den detect_mrz.py
, og indsæt følgende kode:
# 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))
linjer 2-6 importerer vores nødvendige pakker. Jeg antager, at du allerede har OpenCV installeret. Du har også brug for imutils, min samling af bekvemmelighedsfunktioner for at gøre grundlæggende billedbehandlingsoperationer med OpenCV lettere. Du kan installere imutils
ved hjælp af pip
:
$ pip install --upgrade imutils
derfra håndterer linjer 9-11 parsing af vores kommandolinjeargument. Vi har kun brug for en enkelt kontakt her, --images
, som er stien til mappen, der indeholder de pasbilleder, vi skal behandle.
endelig initialiserer linjer 14 og 15 to kerner, som vi senere vil bruge, når vi anvender morfologiske operationer, specifikt lukningsoperationen. For øjeblikket skal du blot bemærke, at den første kerne er rektangulær med en bredde, der er cirka 3 gange større end højden. Den anden kerne er firkantet. Disse kerner giver os mulighed for at lukke huller mellem MR-tegn og åbninger mellem MR-linjer.
nu hvor vores kommandolinjeargumenter analyseres, kan vi begynde at løbe over hvert af billederne i vores datasæt og behandle dem:
# 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)
linjer 20 og 21 indlæser vores originale billede fra disken og ændrer størrelsen til at have en maksimal højde på 600 billedpunkter. Du kan se et eksempel på et originalt billede nedenfor:
Gaussisk sløring anvendes på linje 26 for at reducere højfrekvent støj. Vi anvender derefter en blackhat morfologisk operation på det slørede gråtonebillede på linje 27.
en blackhat-operatør bruges til at afsløre mørke områder (dvs. Da passteksten altid er sort på en lys baggrund (i det mindste med hensyn til dette datasæt), er en blackhat-operation passende. Nedenfor kan du se output fra at anvende blackhat-operatøren:
det næste trin i MR-detektering er at beregne gradientstørrelsesrepræsentationen af blackhat-billedet ved hjælp af Scharr-operatøren:
# 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")
her beregner vi Scharr-gradienten langs blackhat-billedets h-akse og afslører områder af billedet, der ikke kun er mørke mod en lys baggrund, men også indeholder lodrette ændringer i gradienten, f.eks. Vi tager derefter dette gradientbillede og skalerer det tilbage i området ved hjælp af min / maks skalering:
selvom det ikke er helt indlysende, hvorfor vi anvender dette trin, vil jeg sige, at det er yderst nyttigt at reducere falsk-positive MR-detektioner. Uden det kan vi ved et uheld markere udsmykkede eller designede regioner i passet som Mrs. Jeg vil overlade dette som en øvelse til dig for at kontrollere, at beregning af gradienten af blackhat-billedet kan forbedre MR-detekteringsnøjagtigheden.
det næste skridt er at forsøge at opdage de faktiske linjer i Mrs.:
# 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)
først anvender vi en lukkeoperation ved hjælp af vores rektangulære kerne. Denne lukningsoperation er beregnet til at lukke huller mellem MR-tegn. Vi anvender derefter tærskelværdi ved hjælp af otsus metode til automatisk tærskelværdi af billedet:
som vi kan se fra figuren ovenfor, er hver af MR-linjerne til stede i vores tærskelkort.
det næste trin er at lukke hullerne mellem de faktiske linjer, hvilket giver os et stort rektangulært område, der svarer til MR:
# 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)
her udfører vi en anden lukningsoperation, denne gang ved hjælp af vores firkantede kerne. Denne kerne bruges til at lukke huller mellem de enkelte linjer i Mrs., hvilket giver os en stor region, der svarer til MRS. En række erosioner udføres derefter for at bryde forbundne komponenter fra hinanden, der kan have været forbundet under lukningsoperationen. Disse erosioner er også nyttige til at fjerne små klatter, der er irrelevante for Mrs.
for nogle passcanninger kan pasets grænse være blevet knyttet til Mrs-regionen under de afsluttende operationer. For at afhjælpe dette indstiller vi 5% af billedets venstre og højre kant til nul (dvs. sort):
# 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
du kan se output fra vores fjernelse af grænser nedenfor.
sammenlignet med figur 5 ovenfor kan du nu se, at grænsen er fjernet.
det sidste trin er at finde konturerne i vores tærskelbillede og bruge konturegenskaber til at identificere MR:
# 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)
på linje 56-58 beregner vi konturerne (dvs.konturerne) af vores tærskelbillede. Vi tager derefter disse konturer og sorterer dem ud fra deres størrelse i faldende rækkefølge på linje 59 (hvilket antyder, at de største konturer er først på listen).
på linje 62 begynder vi at løbe over vores sorterede liste over konturer. For hver af disse konturer beregner vi afgrænsningsboksen (linje 66) og bruger den til at beregne to egenskaber: billedformatet og dækningsforholdet. Billedformatet er simpelthen bredden af afgrænsningsboksen divideret med højden. Dækningsforholdet er bredden af afgrænsningsboksen divideret med bredden af det faktiske billede.
ved hjælp af disse to egenskaber kan vi foretage en check på linje 72 for at se, om vi undersøger MR-regionen. MR er rektangulær, med en bredde, der er meget større end højden. MR-værdien skal også spænde over mindst 75% af inputbilledet.
forudsat at disse to tilfælde holder, bruger linjer 75-84 (h, y)-koordinaterne for afgrænsningsboksen til at udtrække Mrs. og tegne afgrænsningsboksen på vores inputbillede.
endelig viser linjer 87-89 vores resultater.
resultater
for at se vores MR-detektor i aktion skal du bare udføre følgende kommando:
$ python detect_mrz.py --images examples
nedenfor kan du se et eksempel på en vellykket Mrs-detektion med Mrs. skitseret i grønt:
her er et andet eksempel på at detektere det maskinlæsbare område i et pasbillede ved hjælp af Python og OpenCV:
det betyder ikke noget, om Mr-regionen er øverst eller nederst på billedet. Ved at anvende morfologiske operationer, ekstraktion af konturer og beregning af konturegenskaber er vi i stand til at udtrække MR uden problemer.
det samme gælder for følgende billede:
lad os prøve et andet billede:
indtil nu har vi kun set Type 1 Mrs, der indeholder tre linjer. Imidlertid, vores metode fungerer lige så godt med type 3 Mrs., der kun indeholder to linjer:
her er et andet eksempel på detektering af en type 3 MR:
hvad er det næste? Jeg anbefaler PyImageSearch University.
30 + samlede klasser • 39h 44m video * sidst opdateret: 12/2021
★★★★★ 4.84 (128 bedømmelser) * 3.000+ studerende tilmeldt
jeg er overbevist om, at hvis du havde den rigtige lærer, kunne du mestre computersyn og dyb læring.
tror du, at læring af computersyn og dyb læring skal være tidskrævende, overvældende og kompliceret? Eller skal involvere komplekse matematik og ligninger? Eller kræver en grad i datalogi?
det er ikke tilfældet.
alt hvad du behøver for at mestre computersyn og dyb læring er, at nogen forklarer ting for dig på enkle, intuitive vilkår. Og det er præcis, hvad jeg gør. Min mission er at ændre uddannelse og hvordan komplekse kunstige Intelligensemner undervises.
hvis du er seriøs om at lære computer vision, skal dit næste stop være PyImageSearch University, det mest omfattende computer vision, deep learning og OpenCV kursus online i dag. Her lærer du, hvordan du med succes og med sikkerhed anvender computersyn til dit arbejde, forskning og projekter. Deltag i Computer vision mastery.
inde i PyImageSearch University finder du:
- &tjek; 30+ kurser om essential computer vision, deep learning og OpenCV emner
- &kontrollere; 30+ Færdiggørelsescertifikater
- &kontrollere; 39h 44m on-demand video
- &kontrollere; helt nye kurser udgivet hver måned, hvilket sikrer, at du kan holde trit med state-of-the-art teknikker
- &kontroller; prækonfigurerede jupyter-notesbøger i Google colab
- &kontroller; kør alle kodeeksempler i din netsøgemaskine — fungerer på vinduer, MacOS og linou (ingen konfiguration af dev-miljø kræves!)
- &tjek; Adgang til centraliserede kode repos for alle 500 + tutorials på PyImageSearch
- & kontrollere; nemme et-klik overførsler til kode, datasæt, præ-uddannede modeller, etc.
- & kontrollere; adgang på mobil, bærbar computer, desktop osv.
Klik her for at blive medlem af PyImageSearch University
Resume
i dette blogindlæg lærte vi, hvordan man registrerer maskinlæsbare områder (MRSA) i passcanninger ved kun at bruge grundlæggende billedbehandlingsteknikker, nemlig:
- tærskelværdi.
- gradienter.
- morfologiske operationer (specifikt lukninger og erosioner).
- Konturegenskaber.
disse operationer, selvom de var enkle, gjorde det muligt for os at registrere MR-regionerne i billeder uden at skulle stole på mere avancerede funktionsekstraktions-og maskinindlæringsmetoder såsom lineær SVM + HOG til objektdetektering.
Husk, når du står over for et udfordrende computersynsproblem-overvej altid problemet og dine antagelser! Som dette blogindlæg viser, kan du blive overrasket over, hvilke grundlæggende billedbehandlingsfunktioner, der bruges i tandem, kan udføre.
endnu en gang en stor tak til PyImageSearch guruer medlem, Hans Boone, der leverede os med disse eksempel pas billeder! Tak Hans!