Læsere som dig hjælper med at støtte MUO. Når du foretager et køb ved hjælp af links på vores websted, kan vi optjene en affiliate-kommission. Læs mere.

Du ønsker måske at digitalisere et dokument for at spare fysisk plads eller oprette en sikkerhedskopi. Uanset hvad, er det en opgave, som Python udmærker sig ved at skrive et program, der kan konvertere billeder af dine papirfiler til et standardformat.

Ved at bruge en kombination af passende biblioteker kan du bygge en lille app til at digitalisere dokumenter. Dit program tager et billede af et fysisk dokument som input, anvender flere billedbehandlingsteknikker på det og udsender en scannet version af inputtet.

Forbered dit miljø

For at følge denne artikel skal du være bekendt med det grundlæggende i Python. Du skal også have forståelse for hvordan man arbejder med NumPy Python-biblioteket.

Åbn enhver Python IDE, og opret to Python-filer. Navngiv den ene main.py og den anden transform.py. Kør derefter følgende kommando på terminalen for at installere de nødvendige biblioteker.

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

Du skal bruge OpenCV-Python til at tage billedinputtet og udføre noget billedbehandling. Imutils for at ændre størrelsen på input- og outputbillederne. scikit-image for at anvende en tærskelværdi på billedet. NumPy hjælper dig med at arbejde med arrays.

Vent på, at installationen er færdig, og til IDE'en opdaterer projektskeletterne. Når skeletteropdateringen er færdig, er du klar til at begynde at kode. Den fulde kildekode er tilgængelig i en GitHub-depot.

Import af de installerede biblioteker

Åbn filen main.py, og importer de biblioteker, du har installeret i miljøet. Dette vil give dig mulighed for at ringe og bruge deres funktioner, hvor det er nødvendigt.

importere cv2
importere imutils
fra skimage.filtre importere threshold_local
fra transformere importere perspektiv_transform

Ignorer fejlen kastet på perspective_transform. Den forsvinder, når du er færdig med at arbejde på filen transform.py.

Tage og ændre størrelse på input

Tag et klart billede af det dokument, du vil scanne. Sørg for, at de fire hjørner af dokumentet og dets indhold er synlige. Kopier billedet til den samme mappe, som du gemmer programfilerne.

Send input-billedstien til OpenCV. Lav en kopi af det originale billede, da du får brug for det under perspektivtransformation. Divider højden af ​​det originale billede med den højde, du ønsker at ændre størrelsen på det til. Dette vil bevare billedformatet. Til sidst skal du udskrive det ændrede størrelse billede.

# Passerer billedstien
original_img = cv2.imread('sample.jpg')
kopi = original_img.copy()

# Den ændrede størrelse i hundreder
ratio = original_img.shape[0] / 500.0
img_resize = imutils.resize (original_img, højde=500)

# Viser output
cv2.imshow('Ændret størrelse på billede', img_resize)

# Venter på, at brugeren trykker på en vilkårlig tast
cv2.waitKey(0)

Outputtet af ovenstående kode er som følger:

Du har nu ændret størrelsen på det originale billede til 500 pixels.

Konvertering af ændret størrelse billede til gråtoner

Konverter det ændrede RGB-billede til gråtoner. De fleste billedbehandlingsbiblioteker fungerer kun med gråtonebilleder, da de er nemmere at behandle.

grey_image = cv2.cvtColor (img_resize, cv2.COLOR_BGR2GRAY)
cv2.imshow('Grået billede', gråt_billede)
cv2.waitKey(0)

Bemærk forskellen mellem det originale billede og det grå.

Det farvede bord er blevet sort og hvidt.

Anvendelse af en kantdetektor

Anvend et Gaussisk sløringsfilter på det gråtonede billede for at fjerne støj. Kald derefter OpenCV canny-funktionen for at registrere kanterne i billedet.

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

Kanterne er synlige på udgangen.

De kanter, du vil arbejde med, er dem på dokumentet.

At finde den største kontur

Registrer konturerne i det kantede billede. Sorter dem i faldende rækkefølge med kun de fem største konturer. Tilnærme den største kontur med fire sider ved at sløjfe gennem de sorterede konturer.

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

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

hvis len (ca.) == 4:
doc = ca
pause

Konturen med fire sider indeholder sandsynligvis dokumentet.

Cirkel de fire hjørner af dokumentkonturen

Cirkel hjørnerne af den registrerede dokumentkontur. Dette vil hjælpe dig med at afgøre, om dit program var i stand til at registrere dokumentet på billedet.

p = []

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

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

Implementer cirkling på det ændrede RGB-billede.

Når du har fundet dokumentet, skal du nu udtrække dokumentet fra billedet.

Brug af Warp-perspektiv til at få det ønskede billede

Warp-perspektiv er en computervisionsteknik til at transformere et billede til at korrigere forvrængninger. Det forvandler et billede til et andet plan, så du kan se billedet fra en anden vinkel.

warped_image = perspektiv_transform (kopi, doc.reshape(4, 2) * forhold)
warped_image = cv2.cvtColor (forvrænget_image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Forvrænget billede", imutils.resize (warped_image, height=650))
cv2.waitKey(0)

For at få et skævt billede skal du oprette et simpelt modul der vil udføre perspektivtransformationen.

Transformationsmodul

Modulet vil sortere punkterne i dokumenthjørnerne. Det vil også omdanne dokumentbilledet til et andet plan og ændre kameravinklen til et overheadbillede.

Åbn filen transform.py, du oprettede tidligere. Importer OpenCV- og NumPy-biblioteker.

importere nusset som np
importere cv2

Dette modul vil indeholde to funktioner. Opret en funktion, der sorterer koordinaterne for dokumentets hjørnepunkter. Den første koordinat vil være den for det øverste venstre hjørne, den anden vil være den for det øverste højre hjørne, den tredje vil være i nederste højre hjørne, og den fjerde koordinat vil være den nederst til venstre hjørne.

defordre_point(pkt.):
# initialisering af listen over koordinater, der skal bestilles
rect = np.zeros((4, 2), dtype = "float32")

s = pts.sum (akse = 1)

# top-venstre punkt vil have den mindste sum
rekt[0] = pts[np.argmin (s)]

# punkt nederst til højre vil have den største sum
rekt[2] = pts[np.argmax (s)]

beregne forskellen mellem punkterne, den
punktet øverst til højre vil have den mindste forskel,
hvorimod nederst til venstre vil have den største forskel
diff = np.diff (pts, akse = 1)
rekt[1] = pts[np.argmin (diff)]
rekt[3] = pts[np.argmax (diff)]

# returnerer bestilte koordinater
Vend tilbage rekt

Opret en anden funktion, der vil beregne hjørnekoordinaterne for det nye billede og få et overheadbillede. Det vil derefter beregne perspektivtransformationsmatrixen og returnere det skæve billede.

defperspektiv_transform(billede, pts):
# pak de bestilte koordinater ud individuelt
rect = ordre_point (pts)
(tl, tr, br, bl) = rekt

beregne bredden af ​​det nye billede, som vil være
maksimal afstand mellem nederst til højre og nederst til venstre
x-koordinater eller øverst til højre 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øjden af ​​det nye billede, som vil være
maksimal afstand mellem øverst til venstre og y-koordinater nederst til venstre
højdeA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
højdeB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHøjde = max (int (højdeA), int (højdeB))

konstruer sættet af destinationspunkter for at opnå et overheadskud
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, maxHøjde - 1],
[0, maxHøjde - 1]], dtype = "float32")

# udregn perspektivtransformationsmatrixen
transform_matrix = cv2.getPerspectiveTransform (rect, dst)

# Anvend transformationsmatrixen
warped = cv2.warpPerspective (image, transform_matrix, (maxWidth, maxHeight))

# returner det skæve billede
Vend tilbage skævt

Du har nu oprettet transformationsmodulet. Fejlen på perspektiv_transform importen vil nu forsvinde.

Bemærk, at det viste billede har et overheadbillede.

Anvendelse af adaptiv tærskel og lagring af det scannede output

I main.py-filen skal du anvende den gaussiske tærskelværdi på det skæve billede. Dette vil give det skæve billede et scannet udseende. Gem det scannede billede i den mappe, der indeholder programfilerne.

T = threshold_local (forvrænget_billede, 11, offset=10, metode="gaussisk")
forvrænget = (forvrænget_billede > T).astype("uint8") * 255
cv2.imwrite('./'+'Scan'+'.png', skæv)

Lagring af scanningen i PNG-format bevarer dokumentkvaliteten.

Visning af output

Udskriv billedet af det scannede dokument:

cv2.imshow("Endelig scannet billede", imutils.resize (forvrænget, højde=650))
cv2.waitKey(0)
cv2.destroyAllWindows()

Følgende billede viser outputtet af programmet, et overheadbillede af det scannede dokument.

Sådan kommer du videre i computersyn

Oprettelse af en dokumentscanner dækker nogle kerneområder inden for computersyn, som er et bredt og komplekst felt. For at komme videre i computervision bør du arbejde på interessante, men udfordrende projekter.

Du bør også læse mere om, hvordan du kan bruge computersyn med de nuværende teknologier. Dette vil holde dig orienteret og give dig nye ideer til projekter at arbejde på.