Bralci, kot ste vi, pomagajo podpirati MUO. Ko opravite nakup prek povezav na našem spletnem mestu, lahko zaslužimo partnersko provizijo. Preberi več.

Morda boste želeli digitalizirati dokument, da prihranite fizični prostor ali ustvariti varnostno kopijo. Kakor koli že, pisanje programa, ki lahko pretvori fotografije vaših papirnatih datotek v standardni format, je naloga, pri kateri Python blesti.

S kombinacijo ustreznih knjižnic lahko zgradite majhno aplikacijo za digitalizacijo dokumentov. Vaš program bo kot vhod vzel sliko fizičnega dokumenta, zanj uporabil več tehnik obdelave slik in izdal skenirano različico vhoda.

Priprava vašega okolja

Če želite slediti temu članku, morate poznati osnove Pythona. Prav tako morate razumeti kako delati s knjižnico NumPy Python.

Odprite kateri koli Python IDE in ustvarite dve datoteki Python. Poimenujte enega main.py in drugega transform.py. Nato zaženite naslednji ukaz na terminalu, da namestite zahtevane knjižnice.

pip namestite OpenCV-Python imutils scikit-image NumPy

Uporabili boste OpenCV-Python, da sprejmete vnos slike in izvedete nekaj obdelave slike. Imutils za spreminjanje velikosti vhodnih in izhodnih slik. scikit-image za uporabo praga na sliki. NumPy vam bo pomagal pri delu z nizi.

Počakajte, da se namestitev konča in da IDE posodobi okostja projekta. Ko je posodobitev okostja končana, ste pripravljeni na začetek kodiranja. Celotna izvorna koda je na voljo v a Repozitorij GitHub.

Uvoz nameščenih knjižnic

Odprite datoteko main.py in uvozite knjižnice, ki ste jih namestili v okolje. Tako boste lahko po potrebi poklicali in uporabljali njihove funkcije.

uvoz cv2
uvoz imutils
od skimage.filtri uvoz threshold_local
od transformirati uvoz perspective_transform

Ignorirajte napako, vrženo na perspective_transform. Izginil bo, ko boste končali z delom na datoteki transform.py.

Sprejem in spreminjanje velikosti vnosa

Posnemite jasno sliko dokumenta, ki ga želite skenirati. Prepričajte se, da so vidni štirje vogali dokumenta in njegova vsebina. Kopirajte sliko v isto mapo, v kateri shranjujete programske datoteke.

Prenesite pot vhodne slike v OpenCV. Naredite kopijo izvirne slike, saj jo boste potrebovali med transformacijo perspektive. Višino izvirne slike delite z višino, na katero jo želite spremeniti. To bo ohranilo razmerje stranic. Nazadnje izpišite spremenjeno sliko.

# Prehajanje poti slike
original_img = cv2.imread('vzorec.jpg')
kopija = original_img.copy()

# Spremenjena višina v stotinah
razmerje = original_img.shape[0] / 500.0
img_resize = imutils.resize (izvirna_img, višina=500)

# Prikaz izhoda
cv2.imshow('Spremenjena velikost slike', img_resize)

# Čakanje, da uporabnik pritisne katero koli tipko
cv2.waitKey(0)

Rezultat zgornje kode je naslednji:

Zdaj ste spremenili velikost izvirne slike na 500 slikovnih pik.

Pretvarjanje spremenjene velikosti slike v sivine

Spremenjeno velikost RGB slike pretvorite v sivine. Večina knjižnic za obdelavo slik deluje samo s slikami v sivinah, saj jih je lažje obdelati.

siva_slika = cv2.cvtColor (img_resize, cv2.COLOR_BGR2GRAY)
cv2.imshow('Siva slika', siva_slika)
cv2.waitKey(0)

Opazite razliko med izvirno sliko in sivo.

Barvna miza se je spremenila v črno-belo.

Uporaba detektorja robov

Na sivo sliko uporabite Gaussov filter za zameglitev, da odstranite šum. Nato pokličite funkcijo Canny OpenCV, da zazna robove na sliki.

zamegljena_slika = cv2.GaussianBlur (siva_slika, (5, 5), 0)
edged_img = cv2.Canny (zamegljena_slika, 75, 200)
cv2.imshow('Robovi slike', edged_img)
cv2.waitKey(0)

Robovi so vidni na izpisu.

Robovi, s katerimi boste delali, so robovi dokumenta.

Iskanje največje konture

Zaznajte obrise na sliki z robom. Razvrstite jih v padajočem vrstnem redu, tako da ohranite samo pet največjih kontur. Približajte največjo konturo s štirimi stranmi tako, da se pomikate po razvrščenih konturah.

cnts, _ = cv2.findContours (edged_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = razvrščeno (cnts, key=cv2.contourArea, reverse=Prav)[:5]

za c v cnts:
peri = cv2.arcLength (c, Prav)
približno = cv2.approxPolyDP(c, 0.02 * peri, Prav)

če len (približno) == 4:
doc = pribl
odmor

Kontura s štirimi stranicami bo verjetno vsebovala dokument.

Kroženje štirih vogalov konture dokumenta

Obkrožite vogale zaznane konture dokumenta. To vam bo pomagalo ugotoviti, ali je vaš program lahko zaznal dokument na sliki.

p = []

za d v dokument:
tuple_point = tuple (d[0])
cv2.krog (img_resize, tuple_point, 3, (0, 0, 255), 4)
p.append (torna_točka)

cv2.imshow('Obkrožene kotne točke', img_resize)
cv2.waitKey(0)

Izvedite kroženje na spremenjeni RGB sliki.

Ko ste zaznali dokument, ga morate zdaj izvleči iz slike.

Uporaba Warp perspektive za pridobitev želene slike

Warp perspektiva je tehnika računalniškega vida za preoblikovanje slike za popravljanje popačenj. Preoblikuje sliko v drugo ravnino, kar vam omogoča ogled slike iz drugega kota.

izkrivljena_slika = perspective_transform (kopiraj, doc.reshape(4, 2) * razmerje)
izkrivljena_slika = cv2.cvtColor (izkrivljena_slika, cv2.COLOR_BGR2SIVA)
cv2.imshow("Izkrivljena slika", imutils.resize (izkrivljena_slika, višina=650))
cv2.waitKey(0)

Če želite dobiti izkrivljeno sliko, morate ustvarite preprost modul ki bo izvedel perspektivno transformacijo.

Transformacijski modul

Modul bo uredil točke vogalov dokumenta. Prav tako bo spremenil sliko dokumenta v drugo ravnino in spremenil kot kamere v posnetek od zgoraj.

Odprite datoteko transform.py, ki ste jo ustvarili prej. Uvozite knjižnici OpenCV in NumPy.

uvoz numpy kot np
uvoz cv2

Ta modul bo vseboval dve funkciji. Ustvarite funkcijo, ki bo uredila koordinate kotnih točk dokumenta. Prva koordinata bo zgornji levi kot, druga pa zgornji desni kot, tretja bo v spodnjem desnem kotu, četrta koordinata pa bo v spodnjem levem kotu kotiček.

defnaročilo_točke(točke):
# inicializacija seznama koordinat za naročanje
rect = np.zeros((4, 2), dtype = "float32")

s = pts.sum (os = 1)

# zgornja leva točka bo imela najmanjšo vsoto
rect[0] = točke[np.argmin (s)]

# točka spodaj desno bo imela največjo vsoto
rect[2] = točke[np.argmax (s)]

izračunavanje razlike med točkami,
zgornja desna točka bo imela najmanjšo razliko,
medtem ko bo spodaj levo največja razlika
diff = np.diff (točke, os = 1)
rect[1] = pts[np.argmin (diff)]
rect[3] = pts[np.argmax (diff)]

# vrne urejene koordinate
vrnitev rect

Ustvarite drugo funkcijo, ki bo izračunala kotne koordinate nove slike in pridobila posnetek od zgoraj. Nato bo izračunal matriko perspektivne transformacije in vrnil izkrivljeno sliko.

defperspective_transform(slika, točke):
# razpakirajte naročene koordinate posebej
rect = order_points (točke)
(tl, tr, br, bl) = rekt

izračunajte širino nove slike, ki bo
največja razdalja med spodnjim desnim in spodaj levo
x-koordinate oz zgornji desni in zgornje leve x-koordinate
širinaA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
širinaB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max (int (widthA), int (widthB))

izračunajte višino nove slike, ki bo
največja razdalja med zgornjim levim in y-koordinate spodaj levo
višinaA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
višinaB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max (int (heightA), int (heightB))

sestavite nabor ciljnih točk, da dobite strel od zgoraj
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, največja višina - 1],
[0, največja višina - 1]], dtype = "float32")

# izračunajte matriko perspektivne transformacije
transform_matrix = cv2.getPerspectiveTransform (rect, dst)

# Uporabite transformacijsko matriko
deformiran = cv2.warpPerspective (slika, transform_matrix, (maxWidth, maxHeight))

# vrni izkrivljeno sliko
vrnitev zvit

Sedaj ste ustvarili transformacijski modul. Napaka pri uvozu perspective_transform bo zdaj izginila.

Upoštevajte, da ima prikazana slika posnetek od zgoraj.

Uporaba prilagodljivega praga in shranjevanje skeniranega izhoda

V datoteki main.py uporabite Gaussov prag za izkrivljeno sliko. To bo dalo izkrivljeni sliki optično prebran videz. Shranite optično prebrano sliko v mapo, ki vsebuje programske datoteke.

T = threshold_local (izkrivljena_slika, 11, odmik=10, metoda="gaussov")
izkrivljen = (izkrivljena_slika > T).astype("uint8") * 255
cv2.imwrite('./'+'skeniraj'+'.png',zvit)

Shranjevanje optično prebranega v formatu PNG ohranja kakovost dokumenta.

Prikaz izhoda

Izpišite sliko skeniranega dokumenta:

cv2.imshow("Končna skenirana slika", imutils.resize (zvit, višina=650))
cv2.waitKey(0)
cv2.destroyAllWindows()

Naslednja slika prikazuje rezultat programa, posnetek optično prebranega dokumenta od zgoraj.

Kako napredovati v računalniškem vidu

Ustvarjanje optičnega bralnika dokumentov pokriva nekaj ključnih področij računalniškega vida, ki je široko in zapleteno področje. Če želite napredovati v računalniškem vidu, morate delati na zanimivih, a zahtevnih projektih.

Preberite tudi več o tem, kako lahko uporabljate računalniški vid s trenutnimi tehnologijami. Tako boste obveščeni in vam dali nove ideje za projekte, na katerih bi lahko delali.