Čitatelji poput vas podržavaju MUO. Kada kupite putem poveznica na našoj stranici, možemo zaraditi partnersku proviziju. Čitaj više.

Možda želite digitalizirati dokument kako biste uštedjeli fizički prostor ili izraditi sigurnosnu kopiju za spremanje. U svakom slučaju, pisanje programa koji može pretvoriti fotografije vaših papirnatih datoteka u standardni format zadatak je u kojem Python briljira.

Koristeći kombinaciju odgovarajućih biblioteka, možete izgraditi malu aplikaciju za digitalizaciju dokumenata. Vaš program će uzeti sliku fizičkog dokumenta kao ulaz, primijeniti nekoliko tehnika obrade slike na nju i ispisati skeniranu verziju ulaza.

Priprema vaše okoline

Da biste pratili ovaj članak, trebali biste biti upoznati s osnove Pythona. Također morate imati razumijevanja za kako raditi s NumPy Python bibliotekom.

Otvorite bilo koji Python IDE i izradite dvije Python datoteke. Imenujte jedan main.py, a drugi transform.py. Zatim pokrenite sljedeću naredbu na terminalu da biste instalirali potrebne biblioteke.

instagram viewer
pip instalirajte OpenCV-Python imutils scikit-image NumPy

Koristit ćete OpenCV-Python za unos slike i izvođenje određene obrade slike. Imutils za promjenu veličine ulaznih i izlaznih slika. scikit-image za primjenu praga na sliku. NumPy će vam pomoći u radu s nizovima.

Pričekajte da instalacija završi i da IDE ažurira kosture projekta. Nakon dovršetka ažuriranja kostura, spremni ste za početak kodiranja. Puni izvorni kod dostupan je u a GitHub spremište.

Uvoz instaliranih biblioteka

Otvorite datoteku main.py i uvezite biblioteke koje ste instalirali u okruženju. To će vam omogućiti pozivanje i korištenje njihovih funkcija gdje je to potrebno.

uvoz cv2
uvoz imutils
iz skimage.filteri uvoz prag_lokalni
iz transformirati uvoz perspektivna_transformacija

Ignorirajte pogrešku koja se javlja na perspective_transform. Nestat će kada završite s radom na datoteci transform.py.

Uzimanje i promjena veličine unosa

Snimite jasnu sliku dokumenta koji želite skenirati. Uvjerite se da su četiri kuta dokumenta i njegov sadržaj vidljivi. Kopirajte sliku u istu mapu u kojoj spremate programske datoteke.

Proslijedite put ulazne slike u OpenCV. Napravite kopiju izvorne slike jer će vam trebati tijekom transformacije perspektive. Podijelite visinu izvorne slike s visinom na koju želite promijeniti veličinu. Ovo će zadržati omjer slike. Na kraju ispišite sliku promijenjene veličine.

# Prolazak putanje slike
original_img = cv2.imread('uzorak.jpg')
kopija = original_img.copy()

# Promijenjena veličina visine u stotinama
omjer = original_img.shape[0] / 500.0
img_resize = imutils.resize (originalna_img, visina=500)

# Prikaz izlaza
cv2.imshow('Promijenjena veličina slike', img_resize)

# Čeka se da korisnik pritisne bilo koju tipku
cv2.waitKey(0)

Izlaz gornjeg koda je sljedeći:

Sada ste promijenili veličinu izvorne slike na 500 piksela.

Pretvaranje slike promijenjene veličine u sive tonove

Pretvorite RGB sliku promijenjene veličine u sive nijanse. Većina biblioteka za obradu slika radi samo sa slikama u sivim tonovima jer ih je lakše obraditi.

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

Primijetite razliku između izvorne slike i one zasivljene.

Tablica u boji postala je crno-bijela.

Primjena detektora rubova

Primijenite filtar Gaussovog zamućenja na sivu sliku kako biste uklonili šum. Zatim pozovite funkciju OpenCV canny da otkrijete rubove prisutne na slici.

zamućena_slika = cv2.GaussianBlur (siva_slika, (5, 5), 0)
edged_img = cv2.Canny (mutna_slika, 75, 200)
cv2.imshow('Rubovi slike', edged_img)
cv2.waitKey(0)

Rubovi su vidljivi na izlazu.

Rubovi s kojima ćete raditi su rubovi dokumenta.

Pronalaženje najveće konture

Otkrijte konture prisutne na rubnoj slici. Razvrstajte ih silaznim redoslijedom zadržavajući samo pet najvećih kontura. Približno odredite najveću konturu s četiri strane tako što ćete proći kroz sortirane konture.

cnts, _ = cv2.findContours (edged_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = sortirano (cnts, key=cv2.contourArea, reverse=Pravi)[:5]

za c u cnts:
peri = cv2.arcLength (c, Pravi)
approx = cv2.approxPolyDP(c, 0.02 * peri, Pravi)

ako dužina (približno) == 4:
doc = cca
pauza

Kontura s četiri strane vjerojatno će sadržavati dokument.

Zaokruživanje četiri ugla konture dokumenta

Zaokružite kutove detektirane konture dokumenta. To će vam pomoći utvrditi je li vaš program uspio otkriti dokument na slici.

p = []

za d u dokument:
tuple_point = tuple (d[0])
cv2.krug (img_resize, tuple_point, 3, (0, 0, 255), 4)
p.dodaj (torka_točka)

cv2.imshow('Zaokružene kutne točke', img_resize)
cv2.waitKey(0)

Implementirajte zaokruživanje na RGB slici promijenjene veličine.

Nakon što ste otkrili dokument, sada morate izdvojiti dokument sa slike.

Korištenje Warp perspektive za dobivanje željene slike

Warp perspektiva je tehnika računalnog vida za transformaciju slike radi ispravljanja izobličenja. Transformira sliku u drugu ravninu omogućujući vam da sliku vidite iz drugog kuta.

iskrivljena_slika = transformacija_perspektive (kopija, doc.reshape(4, 2) * omjer)
iskrivljena_slika = cv2.cvtColor (iskrivljena_slika, cv2.COLOR_BGR2SIVA)
cv2.imshow("Iskrivljena slika", imutils.resize (iskrivljena_slika, visina=650))
cv2.waitKey(0)

Da biste dobili iskrivljenu sliku, trebate stvoriti jednostavan modul koji će izvršiti transformaciju perspektive.

Modul transformacije

Modul će poredati točke uglova dokumenta. Također će transformirati sliku dokumenta u drugu ravninu i promijeniti kut kamere u snimak iznad glave.

Otvorite datoteku transform.py koju ste ranije stvorili. Uvezite biblioteke OpenCV i NumPy.

uvoz numpy kao np
uvoz cv2

Ovaj modul će sadržavati dvije funkcije. Napravite funkciju koja će poredati koordinate kutnih točaka dokumenta. Prva koordinata će biti ona gornjeg lijevog kuta, druga će biti ona gornjeg desnog kuta, treća će biti u donjem desnom kutu, a četvrta koordinata bit će u donjem lijevom kutu kutak.

defbodovi_narudžbe(bodovi):
# inicijaliziranje popisa koordinata koje treba naručiti
rect = np.nule((4, 2), dtip = "float32")

s = pts.sum (os = 1)

# gornja lijeva točka imat će najmanji zbroj
pravougaonik [0] = bodovi[np.argmin (s)]

# donja desna točka imat će najveći zbroj
pravougaonik [2] = bodovi[np.argmax (s)]

izračunavanje razlike između bodova,
gornja desna točka će imati najmanju razliku,
dok će donji lijevi dio imati najveću razliku
diff = np.diff (bodovi, os = 1)
pravougaonik [1] = bodovi[np.argmin (diff)]
pravougaonik [3] = bodovi[np.argmax (diff)]

# vraća poredane koordinate
povratak ispravan

Napravite drugu funkciju koja će izračunati kutne koordinate nove slike i dobiti snimak iznad glave. Zatim će izračunati matricu transformacije perspektive i vratiti iskrivljenu sliku.

defperspektivna_transformacija(slika, bodovi):
# raspakirajte pojedinačno naručene koordinate
rect = order_bodovi (bodovi)
(tl, tr, br, bl) = prav

izračunajte širinu nove slike, koja će biti
najveća udaljenost između dolje desno i Dolje lijevo
x-koordinate ili gornji desni i gornje lijeve 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 visinu nove slike, koja će biti
najveća udaljenost između gornjeg i lijevog i donje lijeve y-koordinate
visinaA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
visinaB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max (int (visinaA), int (visinaB))

konstruirajte skup odredišnih točaka kako biste dobili snimak iznad glave
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, maksimalna visina - 1],
[0, maksimalna visina - 1]], dtype = "float32")

# izračunajte matricu transformacije perspektive
transform_matrix = cv2.getPerspectiveTransform (rect, dst)

# Primijenite matricu transformacije
iskrivljen = cv2.warpPerspective (slika, transform_matrix, (maxWidth, maxHeight))

# vratiti iskrivljenu sliku
povratak iskrivljena

Sada ste izradili transformacijski modul. Pogreška na uvozu perspective_transform sada će nestati.

Primijetite da prikazana slika ima snimak iznad glave.

Primjena prilagodljivog praga i spremanje skeniranog izlaza

U datoteci main.py primijenite Gaussov prag na iskrivljenu sliku. Ovo će iskrivljenoj slici dati skenirani izgled. Spremite izlaz skenirane slike u mapu koja sadrži programske datoteke.

T = threshold_local (iskrivljena_slika, 11, pomak=10, metoda="gausov")
iskrivljen = (iskrivljena_slika > T).astype("uint8") * 255
cv2.imwrite('./'+'skenirati'+'.png',iskrivljen)

Spremanje skenirane slike u PNG formatu održava kvalitetu dokumenta.

Prikaz izlaza

Ispišite sliku skeniranog dokumenta:

cv2.imshow("Konačna skenirana slika", imutils.resize (iskrivljeno, visina=650))
cv2.waitKey(0)
cv2.destroyAllWindows()

Sljedeća slika prikazuje izlaz programa, snimak skeniranog dokumenta odozgo.

Kako napredovati u računalnom vidu

Izrada skenera dokumenata pokriva neka ključna područja računalnog vida, što je široko i složeno područje. Da biste napredovali u računalnom vidu, trebali biste raditi na zanimljivim, ali izazovnim projektima.

Također biste trebali pročitati više o tome kako možete koristiti računalni vid s trenutačnim tehnologijama. To će vas informirati i dati vam nove ideje za projekte na kojima možete raditi.