detekce strojově čitelných zón v pasových obrázcích

mrz_output_04

dnešní blogový příspěvek by nebyl možný bez člena Guru Pyimagesearch, Hans Boone. Hans pracuje na projektu počítačového vidění, který automaticky detekuje strojově čitelné zóny (Mrz) v pasových obrázcích-podobně jako oblast detekovaná na obrázku výše.

Region MRZ v pasech nebo cestovních kartách spadá do dvou tříd: typ 1 a typ 3. Mrz typu 1 jsou tři řádky, přičemž každý řádek obsahuje 30 znaků. Typ 3 MRZ má pouze dva řádky, ale každý řádek obsahuje 44 znaků. V obou případech MRZ kóduje identifikační údaje daného občana, včetně typu pasu, průkazu totožnosti, vydávající země, jména, státní příslušnosti, data vypršení platnosti atd.

v rámci kurzu Guru PyImageSearch mi Hans ukázal svůj pokrok v projektu a okamžitě jsem se začal zajímat. Vždy jsem chtěl použít algoritmy počítačového vidění na pasové obrázky (hlavně jen pro zábavu), ale postrádal jsem k tomu datovou sadu. Vzhledem k osobním identifikačním údajům, které cestovní pas obsahuje, jsem zjevně nemohl napsat blogový příspěvek na toto téma a sdílet obrázky, které jsem použil k vývoji algoritmu.

naštěstí Hans souhlasil se sdílením některých vzorků / vzorků pasových obrázků, ke kterým má přístup — a já jsem skočil na šanci hrát si s těmito obrázky.

nyní, než se dostaneme daleko, je důležité si uvědomit, že tyto pasy nejsou „skutečné“ v tom smyslu, že mohou být spojeny se skutečnou lidskou bytostí. Jsou to však pravé pasy, které byly generovány pomocí falešných jmen, adres atd. pro vývojáře pracovat s.

možná si myslíte, že k detekci oblasti MRZ pasu potřebujete trochu strojového učení, možná pomocí lineárního SVM + HOG framework k vytvoření “ detektoru MRZ — – ale to by bylo přehnané.

místo toho můžeme MRZ detekovat pouze pomocí základních technik zpracování obrazu, jako je prahování, morfologické operace a vlastnosti obrysu. Ve zbývající části tohoto blogu, podrobně popíšu svůj vlastní pohled na to, jak tyto metody použít k detekci oblasti MRZ pasu.

hledáte zdrojový kód k tomuto příspěvku?

přejít přímo na sekci Ke stažení

detekce strojově čitelných zón v pasových obrázcích

pojďme do toho a začneme tento projekt. Otevřete nový soubor, pojmenujte jej detect_mrz.py a vložte následující kód:

# 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))

linky 2-6 dovážejí naše potřebné balíčky. Předpokládám, že už máte nainstalovaný OpenCV. Budete také potřebovat imutils, Moje sbírka pohodlných funkcí, aby se základní operace zpracování obrazu s OpenCV jednodušší. Můžete nainstalovat imutils pomocí pip :

$ pip install --upgrade imutils

odtud řádky 9-11 zpracovávají analýzu našeho argumentu příkazového řádku. Potřebujeme zde pouze jeden přepínač, --images, což je cesta k adresáři obsahujícímu pasové obrázky, které budeme zpracovávat.

konečně řádky 14 a 15 inicializují dvě jádra, která později použijeme při použití morfologických operací, konkrétně operace zavírání. Prozatím si jednoduše všimněte, že první jádro je obdélníkové s šířkou přibližně 3x větší než výška. Druhé jádro je čtvercové. Tato jádra nám umožní uzavřít mezery mezi znaky MRZ a otvory mezi řádky MRZ.

Nyní, když jsou analyzovány naše argumenty příkazového řádku, můžeme začít opakovat každý z obrázků v naší datové sadě a zpracovat je:

# 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)

řádky 20 a 21 načte náš původní obrázek z disku a změní jeho velikost tak, aby měla maximální výšku 600 pixelů. Můžete vidět příklad původního obrázku níže:

Obrázek 1: náš původní pasový obrázek, ve kterém se snažíme detekovat MRZ.
Obrázek 1: náš původní pasový obrázek, ve kterém se snažíme detekovat MRZ.

Gaussovo rozmazání se používá na lince 26 pro snížení vysokofrekvenčního šumu. Poté použijeme morfologickou operaci blackhat na rozmazaný obraz ve stupních šedi na řádku 27.

operátor blackhat se používá k odhalení tmavých oblastí (tj. textu MRZ) proti světlému pozadí (tj. pozadí samotného pasu). Protože text pasu je vždy černý na světlém pozadí (alespoň pokud jde o tento datový soubor), je vhodná operace blackhat. Níže vidíte výstup použití operátora blackhat:

Obrázek 2: Použití morfologického operátora blackhat odhalí černý text MRZ na pozadí světlého pasu.
Obrázek 2: Použití morfologického operátora blackhat odhalí černý text MRZ na pozadí světlého pasu.

dalším krokem v detekci MRZ je výpočet gradientní velikosti obrazu blackhat pomocí operátoru 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")

zde vypočítáme scharrův gradient podél osy x obrazu blackhat, odhalující oblasti obrazu, které jsou nejen tmavé na světlém pozadí, ale také obsahují vertikální změny gradientu, jako je například oblast textu MRZ. Poté vezmeme tento gradientní obrázek a změníme jej zpět do rozsahu pomocí měřítka min/max:

obrázek 3: Použití operátora Scharr na náš obrázek blackhat odhaluje oblasti, které obsahují silné vertikální změny gradientu.
obrázek 3: Použití operátora Scharr na náš obrázek blackhat odhaluje oblasti, které obsahují silné vertikální změny gradientu.

i když není zcela zřejmé, proč tento krok aplikujeme, řeknu, že je to velmi užitečné při snižování falešně pozitivních detekcí MRZ. Bez ní můžeme omylem označit ozdobené nebo navržené oblasti pasu jako MRZ. Nechám to jako cvičení pro vás, abyste ověřili, že výpočet gradientu obrazu blackhat může zlepšit přesnost detekce MRZ.

dalším krokem je pokusit se zjistit skutečné řádky 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)

nejprve použijeme uzavírací operaci pomocí našeho obdélníkového jádra. Tato uzavírací operace má za cíl uzavřít mezery mezi znaky MRZ. Poté použijeme prahování pomocí metody Otsu k automatickému prahu obrazu:

obrázek 4: Použití uzavírací operace pomocí pravoúhlého jádra (které je širší než vysoké) k uzavření mezer mezi znaky MRZ
obrázek 4: Použití uzavírací operace pomocí pravoúhlého jádra (které je širší než vysoké) k uzavření mezer mezi znaky MRZ

jak vidíme z obrázku výše, každá z řádků MRZ je přítomna v naší prahové mapě.

dalším krokem je uzavření mezer mezi skutečnými čarami, což nám dává jednu velkou obdélníkovou oblast, která odpovídá 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)

zde provádíme další uzavírací operaci, tentokrát pomocí našeho čtvercového jádra. Toto jádro se používá k uzavření mezer mezi jednotlivými liniemi MRZ, což nám dává jednu velkou oblast, která odpovídá MRZ. Poté se provede řada erozí, aby se oddělily připojené komponenty, které mohly být spojeny během uzavírací operace. Tyto eroze jsou také užitečné při odstraňování malých kuliček, které jsou pro MRZ irelevantní.

 obrázek 5: provede se druhá uzavírací operace, tentokrát pomocí čtvercového jádra k uzavření mezer mezi jednotlivými řádky MRZ.
obrázek 5: Provádí se druhá uzavírací operace, tentokrát pomocí čtvercového jádra k uzavření mezer mezi jednotlivými liniemi MRZ.

u některých pasových skenů může být hranice pasu připojena k oblasti MRZ během uzavíracích operací. Abychom to napravili, nastavili jsme 5% levého a pravého okraje obrázku na nulu (tj.):

# 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

níže vidíte výstup našeho odstranění hranic.

 obrázek 6: Nastavení 5% pixelů levého a pravého okraje na nulu, čímž se zajistí, že oblast MRZ nebude připojena k naskenovanému okraji pasu.
obrázek 6: Nastavení 5% pixelů levého a pravého okraje na nulu, čímž se zajistí, že oblast MRZ nebude připojena k naskenovanému okraji pasu.

ve srovnání s obrázkem 5 výše můžete nyní vidět, že hranice byla odstraněna.

posledním krokem je najít obrysy v našem prahovém obrázku a použít vlastnosti obrysu k identifikaci 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)

na řádku 56-58 vypočítáme obrysy (tj. obrysy) našeho prahového obrazu. Poté vezmeme tyto obrysy a třídíme je podle jejich velikosti v sestupném pořadí na řádku 59 (což znamená, že největší obrysy jsou první v seznamu).

na řádku 62 začneme opakovat náš tříděný seznam obrysů. Pro každý z těchto obrysů vypočítáme ohraničující rámeček (řádek 66) a použijeme jej k výpočtu dvou vlastností: poměru stran a poměru pokrytí. Poměr stran je jednoduše šířka ohraničující krabice dělená výškou. Poměr pokrytí je šířka ohraničujícího rámečku dělená šířkou skutečného obrazu.

pomocí těchto dvou vlastností můžeme provést kontrolu na řádku 72, abychom zjistili, zda zkoumáme oblast MRZ. MRZ je obdélníkový, se šířkou, která je mnohem větší než výška. MRZ by také mělo zahrnovat alespoň 75% vstupního obrazu.

za předpokladu, že tyto dva případy drží, řádky 75-84 používají (X, y)-souřadnice ohraničujícího pole k extrahování MRZ a nakreslení ohraničujícího pole na našem vstupním obrázku.

konečně řádky 87-89 zobrazují naše výsledky.

výsledky

Chcete-li vidět náš detektor MRZ v akci, stačí provést následující příkaz:

$ python detect_mrz.py --images examples

níže vidíte příklad úspěšné detekce MRZ, přičemž MRZ je uvedeno zeleně:

Obrázek 7: vlevo máme náš vstupní obrázek. A vpravo máme Region MRZ, který byl úspěšně detekován.
Obrázek 7: vlevo máme náš vstupní obrázek. A vpravo máme Region MRZ, který byl úspěšně detekován.

zde je další příklad detekce strojově čitelné zóny v pasovém obrázku pomocí Pythonu a OpenCV:

Obrázek 8: použití detekce MRZ na naskenovaný pas.
Obrázek 8: použití detekce MRZ na naskenovaný pas.

nezáleží na tom, zda je oblast MRZ v horní nebo dolní části obrázku. Použitím morfologických operací, extrakcí obrysů a výpočtem vlastností obrysů jsme schopni bez problémů extrahovat MRZ.

totéž platí pro následující obrázek:

obrázek 9: detekce strojově čitelných zón v obrazech pomocí počítačového vidění.
obrázek 9: detekce strojově čitelných zón v obrazech pomocí počítačového vidění.

zkusme další obrázek:

 obrázek 10: opět jsme schopni detekovat MRZ v pasovém skenování pomocí základních technik zpracování obrazu.
obrázek 10: opět jsme schopni detekovat MRZ v pasovém skenování pomocí základních technik zpracování obrazu.

až dosud jsme viděli pouze Mrz typu 1, které obsahují tři řádky. Naše metoda však funguje stejně dobře s Mrz typu 3, které obsahují pouze dva řádky:

obrázek 11: detekce MRZ v pasovém obrázku typu 3 pomocí Pythonu a OpenCV.
obrázek 11: Detekce MRZ v pasovém obrázku typu 3 pomocí Pythonu a OpenCV.

zde je další příklad detekce MRZ typu 3:

Obrázek 12: použití počítačového vidění a zpracování obrazu k detekci strojově čitelných zón v obrazech.
Obrázek 12: použití počítačového vidění a zpracování obrazu k detekci strojově čitelných zón v obrazech.

co bude dál? Doporučuji PyImageSearch University.

informace o kurzu:
30 + celkem tříd * 39h 44m video * Poslední aktualizace: 12/2021
★★★★★ 4.84 (128 hodnocení) * 3,000 + studenti zapsaní

pevně věřím, že pokud byste měli správného učitele, mohli byste zvládnout počítačové vidění a hluboké učení.

myslíte si, že učení počítačového vidění a hlubokého učení musí být časově náročné, ohromující a komplikované? Nebo musí zahrnovat komplexní matematiku a rovnice? Nebo vyžaduje titul v oboru informatiky?

tak tomu není.

vše, co potřebujete k zvládnutí počítačového vidění a hlubokého učení, je, aby vám někdo vysvětlil věci jednoduchým a intuitivním způsobem. A to je přesně to, co dělám. Mým posláním je změnit vzdělávání a to, jak složitá témata umělé inteligence jsou vyučována.

pokud jste vážně učení počítačového vidění, vaše další zastávka by měla být PyImageSearch University, nejkomplexnější počítačové vidění, hluboké učení a OpenCV kurz online dnes. Zde se naučíte, jak úspěšně a sebevědomě aplikovat počítačové vidění na svou práci, výzkum a projekty. Připojte se ke mně v Computer vision mastery.

uvnitř PyImageSearch University najdete:

  • &kontrola; 30 + kurzů o základních tématech počítačového vidění, hlubokého učení a OpenCV
  • &kontrola; 30+ osvědčení o absolvování
  • &kontrola; 39h 44m video na vyžádání
  • &kontrola; zcela nové kurzy vydané každý měsíc, které vám zajistí, že budete moci držet krok s nejmodernějšími technikami
  • &kontrola; předkonfigurované notebooky Jupyter v Google Colab
  • &zkontrolujte; spusťte všechny příklady kódu ve webovém prohlížeči-funguje na Windows, MacOS a Linux (není nutná konfigurace prostředí dev!)
  • &kontrola; Přístup k centralizovaným repozitářům kódu pro všech 500 + výukových programů na PyImageSearch
  • & kontrola; Snadné stahování jedním kliknutím pro kód, datové sady, předem vyškolené modely atd.
  • & kontrola; přístup na mobil, notebook, stolní počítač atd.

Klikněte zde a připojte se k Pyimagesearch University

shrnutí

v tomto blogu jsme se naučili, jak detekovat strojově čitelné zóny (Mrz) v pasových skenech pomocí pouze základních technik zpracování obrazu, a to:

  • prahování.
  • přechody.
  • morfologické operace (konkrétně uzavření a eroze).
  • vlastnosti obrysu.

tyto operace, i když jednoduché, nám umožnily detekovat oblasti MRZ v obrazech, aniž bychom se museli spoléhat na pokročilejší metody extrakce funkcí a strojového učení, jako je lineární SVM + HOG pro detekci objektů.

nezapomeňte, že když čelíte náročnému problému s počítačovým viděním – vždy zvažte problém a vaše předpoklady! Jak ukazuje tento blogový příspěvek, možná vás překvapí, jaké základní funkce zpracování obrazu používané v tandemu mohou dosáhnout.

ještě jednou, velké díky PyImageSearch Guru člen, Hans Boone, který nám dodal s těmito příklady pasových obrázků! Díky Hansi!

Leave a Reply

Vaše e-mailová adresa nebude zveřejněna.