Kaltaisesi lukijat auttavat tukemaan MUO: ta. Kun teet ostoksen käyttämällä sivustollamme olevia linkkejä, voimme ansaita kumppanipalkkion. Lue lisää.

Haluat ehkä digitoida asiakirjan fyysisen tilan säästämiseksi tai luoda varmuuskopion. Joka tapauksessa ohjelman kirjoittaminen, joka voi muuntaa valokuvat paperitiedostoistasi vakiomuotoon, on tehtävä, jossa Python on erinomainen.

Käyttämällä sopivien kirjastojen yhdistelmää voit rakentaa pienen sovelluksen asiakirjojen digitointiin. Ohjelmasi ottaa kuvan fyysisestä asiakirjasta syötteeksi, käyttää siihen useita kuvankäsittelytekniikoita ja tulostaa syötteestä skannatun version.

Ympäristösi valmistelu

Jotta voit seurata tätä artikkelia, sinun tulee tuntea Pythonin perusteet. Sinulla on myös oltava ymmärrys kuinka työskennellä NumPy Python -kirjaston kanssa.

Avaa mikä tahansa Python IDE ja luo kaksi Python-tiedostoa. Nimeä yksi main.py ja toinen transform.py. Suorita sitten seuraava komento päätteessä asentaaksesi tarvittavat kirjastot.

pip asennus OpenCV-Python imutils scikit-image NumPy

Käytät OpenCV-Pythonia kuvan syöttämiseen ja kuvankäsittelyyn. Imutils muuttaa tulo- ja tulostuskuvien kokoa. scikit-image asettaaksesi kynnyksen kuvaan. NumPy auttaa sinua työskentelemään taulukoiden kanssa.

Odota, että asennus on valmis ja IDE päivittää projektirungot. Kun luurankopäivitys on valmis, olet valmis aloittamaan koodauksen. Täysi lähdekoodi on saatavilla a GitHub-arkisto.

Asennettujen kirjastojen tuonti

Avaa main.py-tiedosto ja tuo ympäristöön asentamasi kirjastot. Näin voit soittaa ja käyttää heidän toimintojaan tarvittaessa.

tuonti cv2
tuonti imutils
alkaen skimage.filters tuonti threshold_local
alkaen muuttaa tuonti perspektiivi_muunnos

Ohita perspektiivimuunnoksen aiheuttama virhe. Se katoaa, kun lopetat transform.py-tiedoston käsittelyn.

Syötteen ottaminen ja koon muuttaminen

Ota selkeä kuva asiakirjasta, jonka haluat skannata. Varmista, että asiakirjan neljä kulmaa ja sen sisältö ovat näkyvissä. Kopioi kuva samaan kansioon, johon tallennat ohjelmatiedostot.

Välitä syöttökuvan polku OpenCV: hen. Tee kopio alkuperäisestä kuvasta, koska tarvitset sitä perspektiivimuunnoksen aikana. Jaa alkuperäisen kuvan korkeus korkeudella, johon haluat muuttaa sen koon. Tämä säilyttää kuvasuhteen. Tulosta lopuksi muutettu kuva.

# Kuvapolun ohittaminen
alkuperäinen_img = cv2.imread("näyte.jpg")
kopioi = alkuperäinen_img.copy()

# Muutettu korkeus satoissa
suhde = alkuperäinen_kuva.muoto[0] / 500.0
img_resize = imutils.resize (alkuperäinen_kuva, korkeus=500)

# Näytetään tulos
cv2.imshow("Kuvan kokoa muutettu", img_resize)

# Odotetaan, että käyttäjä painaa mitä tahansa näppäintä
cv2.waitKey(0)

Yllä olevan koodin tulos on seuraava:

Olet nyt muuttanut alkuperäisen kuvan korkeuden 500 pikseliin.

Muunnetun kuvan kokoa harmaasävyiksi

Muunna muutettu RGB-kuva harmaasävyiksi. Useimmat kuvankäsittelykirjastot toimivat vain harmaasävykuvien kanssa, koska niitä on helpompi käsitellä.

gray_image = cv2.cvtColor (img_resize, cv2.COLOR_BGR2GRAY)
cv2.imshow("Harmaastunut kuva", harmaa_kuva)
cv2.waitKey(0)

Huomaa ero alkuperäisen kuvan ja harmaan kuvan välillä.

Värillinen pöytä on muuttunut mustavalkoiseksi.

Reunatunnistimen käyttäminen

Käytä Gaussin sumennussuodatinta harmaaseen kuvaan kohinan poistamiseksi. Kutsu sitten OpenCV canny -toiminto havaitaksesi kuvan reunat.

blurred_image = cv2.GaussianBlur (harmaa_kuva, (5, 5), 0)
edged_img = cv2.Canny (sumentunut_kuva, 75, 200)
cv2.imshow("Kuvan reunat", edged_img)
cv2.waitKey(0)

Reunat näkyvät tulosteessa.

Reunat, joita käytät, ovat asiakirjan reunat.

Suurimman ääriviivan löytäminen

Tunnista reunustetun kuvan ääriviivat. Lajittele ne laskevaan järjestykseen säilyttäen vain viisi suurinta ääriviivaa. Arvioi suurin nelisivuinen ääriviiva kiertämällä lajiteltujen ääriviivojen läpi.

cnts, _ = cv2.findContours (edged_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = lajiteltu (cnts, avain=cv2.contourArea, reverse=Totta)[:5]

varten c sisään cnts:
peri = cv2.arcLength (c, Totta)
likimäärä = cv2.approxPolyDP(c, 0.02 *peri, Totta)

jos len (noin) == 4:
doc = n
tauko

Nelisivuinen ääriviiva sisältää todennäköisesti asiakirjan.

Asiakirjan ääriviivan neljän kulman kiertäminen

Ympyröi tunnistetun asiakirjan ääriviivan kulmat. Tämä auttaa sinua määrittämään, pystyikö ohjelma tunnistamaan kuvassa olevan asiakirjan.

p = []

varten d sisään doc:
monikko_piste = monikko (d[0])
cv2.circle (img_resize, tuple_point, 3, (0, 0, 255), 4)
p.append (tuple_point)

cv2.imshow("Ympyröidyt kulmapisteet", img_resize)
cv2.waitKey(0)

Toteuta ympyröinti muutettuun RGB-kuvaan.

Kun olet löytänyt asiakirjan, sinun on nyt purettava asiakirja kuvasta.

Käytä Warp Perspectiveä halutun kuvan saamiseksi

Warp-perspektiivi on tietokonenäkötekniikka kuvan muuntamiseksi vääristymien korjaamiseksi. Se muuttaa kuvan eri tasolle, jolloin voit tarkastella kuvaa eri kulmasta.

warped_image = perspektiivi_muunnos (kopioi, doc.reshape(4, 2) * suhde)
vääntynyt_kuva = cv2.cvtColor (vääristynyt_kuva, cv2.COLOR_BGR2GRAY)
cv2.imshow("Kierretty kuva", imutils.resize (vääristynyt_kuva, korkeus=650))
cv2.waitKey(0)

Vääntyneen kuvan saamiseksi sinun on luoda yksinkertainen moduuli joka suorittaa perspektiivimuunnoksen.

Transformaatiomoduuli

Moduuli järjestää asiakirjan kulmien pisteet. Se myös muuttaa asiakirjan kuvan eri tasolle ja muuttaa kamerakulman yläkuvaksi.

Avaa aiemmin luomasi transform.py-tiedosto. Tuo OpenCV- ja NumPy-kirjastot.

tuonti nuhjuinen kuten np
tuonti cv2

Tämä moduuli sisältää kaksi toimintoa. Luo funktio, joka järjestää asiakirjan kulmapisteiden koordinaatit. Ensimmäinen koordinaatti on vasemman yläkulman koordinaatti, toinen on oikean yläkulman koordinaatti, kolmas on oikeasta alakulmasta ja neljäs koordinaatti on vasemman alakulman koordinaatti kulma.

deforder_points(pisteet):
# alustaa tilattavien koordinaattien luettelo
rect = np.zeros((4, 2), dtype = "float32")

s = pts.sum (akseli = 1)

# vasemmassa yläkulmassa on pienin summa
rect[0] = pts[np.argmin (s)]

# oikeassa alakulmassa on suurin summa
rect[2] = pts[np.argmax (s)]

pisteiden välisen eron laskeminen,
oikeassa yläkulmassa on pienin ero,
kun taas vasemmalla alakulmalla on suurin ero
ero = np.diff (pts, akseli = 1)
rect[1] = pts[np.argmin (diff)]
rect[3] = pts[np.argmax (diff)]

# palauttaa tilatut koordinaatit
palata rect

Luo toinen funktio, joka laskee uuden kuvan kulmakoordinaatit ja ottaa yläkuvan. Sitten se laskee perspektiivimuunnosmatriisin ja palauttaa vääntyneen kuvan.

defperspektiivi_muunnos(kuva, pisteet):
# pura tilatut koordinaatit yksitellen
rect = order_points (pts)
(tl, tr, br, bl) = suora

laskea uuden kuvan leveys, joka on
suurin etäisyys oikean alareunan välillä ja alhaalla vasemmalla
x-koordinaatit tai oikeassa yläkulmassa ja ylävasen x-koordinaatit
leveysA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
leveysB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max (int (widthA), int (widthB))

laskea uuden kuvan korkeus, joka on
suurin etäisyys vasemman yläkulman välillä ja alhaalla vasemmalla y-koordinaatit
korkeusA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
korkeusB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max (int (korkeusA), int (korkeusB))

rakentaa joukko määränpääpisteitä saadaksesi yleiskuvan
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, max Korkeus - 1],
[0, max Korkeus - 1]], dtype = "float32")

# laskea perspektiivimuunnosmatriisi
transform_matrix = cv2.getPerspectiveTransform (suora, dst)

# Käytä muunnosmatriisia
vääntynyt = cv2.warpPerspective (kuva, muunnosmatriisi, (maxWidth, maxHeight))

# palauttaa vääntyneen kuvan
palata vääntynyt

Olet nyt luonut muunnosmoduulin. Perspektiivin_muunnos-tuonnin virhe katoaa nyt.

Huomaa, että näytettävä kuva on otettu yläpuolelta.

Mukautuvan kynnyksen käyttäminen ja skannatun tulosteen tallentaminen

Käytä main.py-tiedostossa Gaussin kynnysarvoa vääntyneeseen kuvaan. Tämä antaa vääntyneelle kuvalle skannatun ilmeen. Tallenna skannattu kuva ohjelmatiedostot sisältävään kansioon.

T = threshold_local (vääristynyt_kuva, 11, offset=10, menetelmä="gaussilainen")
vääntynyt = (vääristynyt_kuva > T).astype("uint8") * 255
cv2.imwrite('./'+'skannata'+".png",vääntynyt)

Skannauksen tallentaminen PNG-muodossa säilyttää asiakirjan laadun.

Ulostulon näyttäminen

Tulosta skannatun asiakirjan kuva:

cv2.imshow("Lopullinen skannattu kuva", imutils.resize (vääristynyt, korkeus=650))
cv2.waitKey(0)
cv2.destroyAllWindows()

Seuraava kuva näyttää ohjelman tulosteen, skannatun asiakirjan yläkuvan.

Miten edistyä tietokonenäössä

Asiakirjaskannerin luominen kattaa joitain tietokonenäön ydinalueita, mikä on laaja ja monimutkainen ala. Edistyäksesi tietokonenäössä sinun tulee työskennellä mielenkiintoisten, mutta haastavien projektien parissa.

Sinun tulisi myös lukea lisää siitä, kuinka voit käyttää tietokonenäköä nykyisten tekniikoiden kanssa. Tämä pitää sinut ajan tasalla ja antaa sinulle uusia ideoita projekteihin.