Lesere som deg er med på å støtte MUO. Når du foretar et kjøp ved å bruke lenker på nettstedet vårt, kan vi tjene en tilknyttet provisjon. Les mer.

Det kan være lurt å digitalisere et dokument for å spare fysisk plass eller lage en sikkerhetskopi. Uansett, å skrive et program som kan konvertere bilder av papirfilene dine til et standardformat er en oppgave Python utmerker seg med.

Ved å bruke en kombinasjon av passende biblioteker kan du bygge en liten app for å digitalisere dokumenter. Programmet ditt tar et bilde av et fysisk dokument som input, bruker flere bildebehandlingsteknikker på det, og sender ut en skannet versjon av input.

Forberede miljøet ditt

For å følge denne artikkelen bør du være kjent med grunnleggende om Python. Du må også ha forståelse for hvordan jobbe med NumPy Python-biblioteket.

Åpne hvilken som helst Python IDE, og lag to Python-filer. Nevn en main.py og den andre transform.py. Kjør deretter følgende kommando på terminalen for å installere de nødvendige bibliotekene.

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

Du vil bruke OpenCV-Python til å ta bildeinndata og utføre litt bildebehandling. Imutils for å endre størrelsen på inngangs- og utdatabildene. scikit-image for å bruke en terskel på bildet. NumPy vil hjelpe deg å jobbe med arrays.

Vent til installasjonen er ferdig og til IDE-en oppdaterer prosjektskjelettene. Etter at skjelettoppdateringen er fullført, er du klar til å begynne å kode. Den fullstendige kildekoden er tilgjengelig i en GitHub-depot.

Importere de installerte bibliotekene

Åpne main.py-filen, og importer bibliotekene du installerte i miljøet. Dette vil gjøre deg i stand til å ringe og bruke funksjonene deres der det er nødvendig.

import cv2
import imutils
fra skimage.filters import threshold_local
fra forvandle import perspektiv_transform

Ignorer feilen som ble kastet på perspective_transform. Den forsvinner når du er ferdig med å jobbe med transform.py-filen.

Ta og endre størrelse på input

Ta et klart bilde av dokumentet du vil skanne. Sørg for at de fire hjørnene av dokumentet og innholdet er synlige. Kopier bildet til samme mappe som du lagrer programfilene.

Send inngangsbildebanen til OpenCV. Lag en kopi av originalbildet ettersom du trenger det under perspektivtransformasjon. Del høyden på originalbildet med høyden du ønsker å endre størrelsen på det til. Dette vil opprettholde sideforholdet. Til slutt, skriv ut det endrede størrelsen på bildet.

# Passerer bildebanen
original_img = cv2.imread(«sample.jpg»)
kopi = original_img.copy()

# Den endrede høyden i hundrevis
ratio = original_img.shape[0] / 500.0
img_resize = imutils.resize (original_img, høyde=500)

# Viser utdata
cv2.imshow("Endre størrelse på bilde", img_resize)

# Venter på at brukeren skal trykke på en tast
cv2.waitKey(0)

Utgangen av koden ovenfor er som følger:

Du har nå endret størrelsen på originalbildet til 500 piksler.

Konvertering av endret størrelse på bildet til gråtoner

Konverter det endrede størrelsen på RGB-bildet til gråtoner. De fleste bildebehandlingsbiblioteker fungerer bare med bilder i gråtoner da de er lettere å behandle.

grey_image = cv2.cvtColor (img_resize, cv2.COLOR_BGR2GRAY)
cv2.imshow("Grået bilde", grått_bilde)
cv2.waitKey(0)

Legg merke til forskjellen mellom originalbildet og det grå.

Det fargede bordet har blitt svart og hvitt.

Bruk av en kantdetektor

Bruk et gaussisk uskarphet-filter på det gråtonede bildet for å fjerne støy. Deretter kaller du OpenCV canny-funksjonen for å oppdage kantene i bildet.

blurred_image = cv2.GaussianBlur (grå_bilde, (5, 5), 0)
edged_img = cv2.Canny (blurred_image, 75, 200)
cv2.imshow('Bildekanter', edged_img)
cv2.waitKey(0)

Kantene er synlige på utgangen.

Kantene du skal jobbe med er de av dokumentet.

Finne den største konturen

Oppdag konturene i det kantede bildet. Sorter dem i synkende rekkefølge med kun de fem største konturene. Tilnærmet den største konturen med fire sider ved å gå gjennom de sorterte konturene.

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

til c i cnts:
peri = cv2.arcLength (c, ekte)
ca = cv2.approxPolyDP(c, 0.02 *peri, ekte)

hvis len (ca) == 4:
doc = ca
gå i stykker

Konturen med fire sider vil sannsynligvis inneholde dokumentet.

Sirkle de fire hjørnene av dokumentkonturen

Sirkel rundt hjørnene på den oppdagede dokumentkonturen. Dette vil hjelpe deg å finne ut om programmet ditt var i stand til å oppdage dokumentet i bildet.

p = []

til d i dok:
tuppel_punkt = tuppel (d[0])
cv2.circle (img_resize, tuple_point, 3, (0, 0, 255), 4)
p.append (tuple_point)

cv2.imshow('Sirklede hjørnepunkter', img_resize)
cv2.waitKey(0)

Implementer sirkling på det endrede størrelsen på RGB-bildet.

Etter å ha oppdaget dokumentet, må du nå trekke ut dokumentet fra bildet.

Bruke Warp Perspective for å få det ønskede bildet

Warp-perspektiv er en datasynsteknikk for å transformere et bilde for å korrigere forvrengninger. Den forvandler et bilde til et annet plan slik at du kan se bildet fra en annen vinkel.

warped_image = perspektiv_transform (kopi, doc.reshape(4, 2) * forhold)
warped_image = cv2.cvtColor (warped_image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Skrudd bilde", imutils.resize (warped_image, height=650))
cv2.waitKey(0)

For å få et skjevt bilde, må du lage en enkel modul som vil utføre perspektivtransformasjonen.

Transformasjonsmodul

Modulen vil sortere punktene i dokumenthjørnene. Det vil også forvandle dokumentbildet til et annet plan og endre kameravinkelen til et overhead-bilde.

Åpne transform.py-filen du opprettet tidligere. Importer OpenCV- og NumPy-biblioteker.

import nusset som np
import cv2

Denne modulen vil inneholde to funksjoner. Lag en funksjon som vil sortere koordinatene til dokumentets hjørnepunkt. Den første koordinaten vil være den til øverste venstre hjørne, den andre vil være den til øverste høyre hjørne, den tredje vil være i nedre høyre hjørne, og den fjerde koordinaten vil være den nederst til venstre hjørne.

defordre_poeng(poeng):
# initialisering av listen over koordinater som skal bestilles
rect = np.zeros((4, 2), dtype = "float32")

s = pts.sum (akse = 1)

# punkt øverst til venstre vil ha den minste summen
rette[0] = poeng[np.argmin (s)]

# punkt nederst til høyre vil ha den største summen
rette[2] = poeng[np.argmax (s)]

beregne forskjellen mellom punktene
punktet øverst til høyre vil ha den minste forskjellen,
mens nederst til venstre vil ha størst forskjell
diff = np.diff (poeng, akse = 1)
rette[1] = poeng[np.argmin (diff)]
rette[3] = poeng[np.argmax (diff)]

# returnerer bestilte koordinater
komme tilbake rekt

Lag en annen funksjon som vil beregne hjørnekoordinatene til det nye bildet og få et overheadbilde. Den vil da beregne perspektivtransformasjonsmatrisen og returnere det forvrengte bildet.

defperspektiv_transform(bilde, poeng):
# pakk ut de bestilte koordinatene individuelt
rect = ordre_poeng (poeng)
(tl, st, br, bl) = rekt

beregne bredden på det nye bildet, som vil være
maksimal avstand mellom nede til høyre og nede til venstre
x-koordinater eller øverst til høyre og x-koordinater øverst til venstre
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max (int (widthA), int (widthB))

beregne høyden på det nye bildet, som vil være
maksimal avstand mellom øverst til venstre og y-koordinater nederst til venstre
høydeA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
høydeB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max (int (høydeA), int (høydeB))

konstruer settet med destinasjonspunkter for å få et overheadskudd
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, maks høyde - 1],
[0, maks høyde - 1]], dtype = "float32")

# beregne perspektivtransformasjonsmatrisen
transform_matrix = cv2.getPerspectiveTransform (rect, dst)

# Bruk transformasjonsmatrisen
warped = cv2.warpPerspective (image, transform_matrix, (maxWidth, maxHeight))

# returner det forvrengte bildet
komme tilbake forvrengt

Du har nå opprettet transformasjonsmodulen. Feilen på perspektiv_transform-importen vil nå forsvinne.

Legg merke til at bildet som vises har et overheadbilde.

Bruk av adaptiv terskel og lagring av skannede utdata

I main.py-filen bruker du den gaussiske terskelen på det forvrengte bildet. Dette vil gi det forvrengte bildet et skannet utseende. Lagre det skannede bildet i mappen som inneholder programfilene.

T = threshold_local (forvrengt_bilde, 11, offset=10, metode="gaussisk")
warped = (warped_image > T).astype("uint8") * 255
cv2.imwrite('./'+'skann'+'.png', skjev)

Lagring av skanningen i PNG-format opprettholder dokumentkvaliteten.

Viser utdata

Skriv ut bildet av det skannede dokumentet:

cv2.imshow("Endelig skannet bilde", imutils.resize (forvrengt, høyde=650))
cv2.waitKey(0)
cv2.destroyAllWindows()

Følgende bilde viser resultatet av programmet, et overheadbilde av det skannede dokumentet.

Hvordan komme videre i datasyn

Å lage en dokumentskanner dekker noen kjerneområder innen datasyn, som er et bredt og komplekst felt. For å komme videre i datasyn bør du jobbe med interessante, men utfordrende prosjekter.

Du bør også lese mer om hvordan du kan bruke datasyn med dagens teknologier. Dette vil holde deg informert og gi deg nye ideer til prosjekter du kan jobbe med.