Potresti voler digitalizzare un documento per risparmiare spazio fisico o creare un backup di salvataggio. Ad ogni modo, scrivere un programma in grado di convertire le foto dei tuoi file cartacei in un formato standard è un compito in cui Python eccelle.
Utilizzando una combinazione di librerie appropriate, puoi creare una piccola app per digitalizzare i documenti. Il tuo programma prenderà un'immagine di un documento fisico come input, applicherà ad esso diverse tecniche di elaborazione delle immagini e produrrà una versione digitalizzata dell'input.
Preparare il tuo ambiente
Per seguire questo articolo dovresti avere familiarità con il basi di Python. Devi anche avere una comprensione di come lavorare con la libreria NumPy Python.
Apri qualsiasi IDE Python e crea due file Python. Nomina uno main.py e l'altro transform.py. Quindi eseguire il seguente comando sul terminale per installare le librerie richieste.
pip installa OpenCV-Python imutils scikit-image NumPy
Utilizzerai OpenCV-Python per prendere l'input dell'immagine ed eseguire alcune elaborazioni dell'immagine. Imutils per ridimensionare le immagini di input e output. scikit-image per applicare una soglia all'immagine. NumPy ti aiuterà a lavorare con gli array.
Attendere il completamento dell'installazione e l'IDE per aggiornare le scheletri del progetto. Al termine dell'aggiornamento degli scheletri, sei pronto per iniziare a programmare. Il codice sorgente completo è disponibile in a Deposito GitHub.
Importazione delle librerie installate
Apri il file main.py e importa le librerie che hai installato nell'ambiente. Ciò ti consentirà di chiamare e utilizzare le loro funzioni ove necessario.
importare cv2
importare imutils
da skimage.filters importare soglia_locale
da trasformare importare prospettiva_trasformazione
Ignora l'errore generato su perspective_transform. Scomparirà quando avrai finito di lavorare sul file transform.py.
Prendere e ridimensionare l'input
Scatta un'immagine nitida del documento che desideri scansionare. Assicurarsi che i quattro angoli del documento e il suo contenuto siano visibili. Copia l'immagine nella stessa cartella in cui stai memorizzando i file del programma.
Passa il percorso dell'immagine di input a OpenCV. Crea una copia dell'immagine originale poiché ti servirà durante la trasformazione prospettica. Dividi l'altezza dell'immagine originale per l'altezza a cui desideri ridimensionarla. Ciò manterrà le proporzioni. Infine, emetti l'immagine ridimensionata.
# Passaggio del percorso dell'immagine
original_img = cv2.imread('campione.jpg')
copia = immagine_originale.copia()# L'altezza ridimensionata in centinaia
rapporto = img_originale.forma[0] / 500.0
img_resize = imutils.resize (original_img, altezza=500)# Visualizzazione dell'output
cv2.imshow('Immagine ridimensionata', img_resize)
# In attesa che l'utente prema un tasto qualsiasi
cv2.waitKey(0)
L'output del codice precedente è il seguente:
Ora hai ridimensionato l'altezza dell'immagine originale a 500 pixel.
Conversione dell'immagine ridimensionata in scala di grigi
Converti l'immagine RGB ridimensionata in scala di grigi. La maggior parte delle librerie di elaborazione delle immagini funziona solo con immagini in scala di grigi poiché sono più facili da elaborare.
gray_image = cv2.cvtColor (img_resize, cv2.COLOR_BGR2GRAY)
cv2.imshow('Immagine in grigio', gray_image)
cv2.waitKey(0)
Notare la differenza tra l'immagine originale e quella in grigio.
La tavola colorata si è trasformata in bianco e nero.
Applicazione di un rilevatore di bordi
Applicare un filtro di sfocatura gaussiana sull'immagine in grigio per rimuovere il rumore. Quindi chiama la funzione canny OpenCV per rilevare i bordi presenti nell'immagine.
immagine_sfocata = cv2.GaussianBlur (immagine_gray, (5, 5), 0)
edged_img = cv2.Canny (immagine_sfocata, 75, 200)
cv2.imshow('Bordi dell'immagine', edged_img)
cv2.waitKey(0)
I bordi sono visibili sull'output.
I bordi con cui lavorerai sono quelli del documento.
Trovare il contorno più grande
Rileva i contorni presenti nell'immagine bordata. Ordinali in ordine decrescente mantenendo solo i cinque contorni più grandi. Approssima il contorno più grande con quattro lati scorrendo i contorni ordinati.
cnts, _ = cv2.findContours (edged_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = ordinati (cnts, key=cv2.contourArea, reverse=VERO)[:5]per C In cnt:
peri = cv2.arcLength (c, VERO)
approx = cv2.circaPolyDP(c, 0.02 *peri, VERO)
Se len (circa) == 4:
doc = ca
rottura
È probabile che il contorno con quattro lati contenga il documento.
Cerchiare i quattro angoli del contorno del documento
Cerchia gli angoli del contorno del documento rilevato. Questo ti aiuterà a determinare se il tuo programma è stato in grado di rilevare il documento nell'immagine.
p = []
per D In dottore:
punto_tupla = tupla (d[0])
cv2.circle (img_resize, tuple_point, 3, (0, 0, 255), 4)
p.append (tuple_point)
cv2.imshow('Punti d'angolo cerchiati', img_resize)
cv2.waitKey(0)
Implementa il cerchiaggio sull'immagine RGB ridimensionata.
Dopo aver rilevato il documento, è ora necessario estrarre il documento dall'immagine.
Usando Warp Perspective per ottenere l'immagine desiderata
La prospettiva di curvatura è una tecnica di visione artificiale per trasformare un'immagine per correggere le distorsioni. Trasforma un'immagine in un piano diverso consentendo di visualizzare l'immagine da un'angolazione diversa.
immagine_distorta = trasformazione_prospettiva (copia, doc.reshape(4, 2) * rapporto)
warped_image = cv2.cvtColor (warped_image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Immagine deformata", imutils.resize (warped_image, height=650))
cv2.waitKey(0)
Per ottenere un'immagine deformata, è necessario creare un modulo semplice che eseguirà la trasformazione prospettica.
Modulo di trasformazione
Il modulo ordinerà i punti degli angoli del documento. Trasformerà anche l'immagine del documento in un piano diverso e cambierà l'angolazione della telecamera in una ripresa dall'alto.
Apri il file transform.py che hai creato in precedenza. Importa librerie OpenCV e NumPy.
importare intorpidito COME np
importare cv2
Questo modulo conterrà due funzioni. Crea una funzione che ordinerà le coordinate dei punti d'angolo del documento. La prima coordinata sarà quella dell'angolo in alto a sinistra, la seconda sarà quella dell'angolo in alto a destra, la terza sarà dell'angolo in basso a destra e la quarta coordinata sarà quella dell'angolo in basso a sinistra angolo.
defordine_punti(punti):
# inizializzando l'elenco delle coordinate da ordinare
rect = np.zeros((4, 2), dtipo = "galleggia32")s = pts.sum (asse = 1)
# punto in alto a sinistra avrà la somma più piccola
retto[0] = punti[np.argmin (s)]# punto in basso a destra avrà la somma maggiore
retto[2] = punti[np.argmax (s)]calcolando la differenza tra i punti, il
il punto in alto a destra avrà la differenza minima,
mentre l'angolo in basso a sinistra avrà la differenza maggiore
diff = np.diff (pts, axis = 1)
retto[1] = punti[np.argmin (diff)]
retto[3] = punti[np.argmax (diff)]
# restituisce le coordinate ordinate
ritorno retto
Crea una seconda funzione che calcolerà le coordinate degli angoli della nuova immagine e otterrà una ripresa dall'alto. Quindi calcolerà la matrice di trasformazione prospettica e restituirà l'immagine deformata.
defprospettiva_trasformazione(immagine, punti):
# decomprime le coordinate ordinate singolarmente
rect = order_points (punti)
(tl, tr, br, bl) = rectcalcola la larghezza della nuova immagine, che sarà il
distanza massima tra in basso a destra E in basso a sinistra
coordinate x O in alto a destra E coordinate x in alto a sinistra
larghezzaA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
larghezzaB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max (int (larghezzaA), int (larghezzaB))calcola l'altezza della nuova immagine, che sarà il
distanza massima tra la parte superiore sinistra E coordinate y in basso a sinistra
altezzaA = np.sqrt(((tr[0] - fratello[0]) ** 2) + ((tr[1] - fratello[1]) ** 2))
altezzaB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max (int (altezzaA), int (altezzaB))costruire l'insieme dei punti di destinazione per ottenere una ripresa dall'alto
dst = np.array([
[0, 0],
[larghezza massima - 1, 0],
[larghezza massima - 1, altezza massima - 1],
[0, altezza massima - 1]], dtipo = "galleggia32")# calcola la matrice di trasformazione prospettica
transform_matrix = cv2.getPerspectiveTransform (rect, dst)# Applica la matrice di trasformazione
deformato = cv2.warpPerspective (immagine, transform_matrix, (maxWidth, maxHeight))
# restituisce l'immagine deformata
ritorno deformato
Ora hai creato il modulo di trasformazione. L'errore sull'importazione di prospect_transform ora scomparirà.
Si noti che l'immagine visualizzata ha una ripresa dall'alto.
Applicazione della soglia adattiva e salvataggio dell'output digitalizzato
Nel file main.py, applica la soglia gaussiana all'immagine distorta. Ciò conferirà all'immagine deformata un aspetto scansionato. Salvare l'output dell'immagine acquisita nella cartella contenente i file del programma.
T = threshold_local (warped_image, 11, offset=10, metodo="gaussiano")
warped = (warped_image > T).astype("uint8") * 255
cv2.imwrite('./'+'scansione'+'.png', deformato)
Il salvataggio della scansione in formato PNG mantiene la qualità del documento.
Visualizzazione dell'output
Emetti l'immagine del documento scansionato:
cv2.imshow("Immagine digitalizzata finale", imutils.resize (deformato, altezza=650))
cv2.waitKey(0)
cv2.destroyAllWindows()
L'immagine seguente mostra l'output del programma, una ripresa dall'alto del documento scansionato.
Come avanzare nella visione artificiale
La creazione di uno scanner per documenti copre alcune aree fondamentali della visione artificiale, che è un campo ampio e complesso. Per avanzare nella visione artificiale dovresti lavorare su progetti interessanti ma stimolanti.
Dovresti anche leggere di più su come utilizzare la visione artificiale con le tecnologie attuali. Questo ti terrà informato e ti darà nuove idee per i progetti su cui lavorare.