Introduzione
Gli esseri umani possono capire il contenuto di un’immagine semplicemente guardando. Percepiamo il testo sull’immagine come testo e possiamo leggerlo.
I computer non funzionano allo stesso modo. Hanno bisogno di qualcosa di più concreto, organizzato in un modo che possano capire.
Questo è dove il riconoscimento ottico dei caratteri (OCR) entra in gioco. Che si tratti di riconoscimento di targhe di auto da una macchina fotografica, o documenti scritti a mano che dovrebbero essere convertiti in una copia digitale, questa tecnica è molto utile. Anche se non è sempre perfetto, è molto conveniente e rende molto più facile e veloce per alcune persone a fare il loro lavoro.
In questo articolo, approfondiremo la profondità del riconoscimento ottico dei caratteri e le sue aree di applicazione. Costruiremo anche un semplice script in Python che ci aiuterà a rilevare i caratteri dalle immagini ed esporli attraverso un’applicazione Flask per un mezzo di interazione più conveniente.
Che cos’è il riconoscimento ottico dei caratteri?
Il riconoscimento ottico dei caratteri comporta il rilevamento del contenuto del testo sulle immagini e la traduzione delle immagini in testo codificato che il computer può facilmente comprendere. Un’immagine contenente testo viene scansionata e analizzata per identificare i caratteri in essa contenuti. Dopo l’identificazione, il carattere viene convertito in testo codificato dalla macchina.
Come si ottiene realmente? Per noi, il testo su un’immagine è facilmente distinguibile e siamo in grado di rilevare i caratteri e leggere il testo, ma per un computer, è tutto una serie di punti.
L’immagine viene prima scansionata e gli elementi di testo e grafica vengono convertiti in una bitmap, che è essenzialmente una matrice di punti bianchi e neri. L’immagine viene quindi pre-elaborata in cui la luminosità e il contrasto vengono regolati per migliorare la precisione del processo.
L’immagine è ora divisa in zone che identificano le aree di interesse, ad esempio dove sono le immagini o il testo, e questo aiuta a dare il via al processo di estrazione. Le aree contenenti testo possono ora essere suddivise ulteriormente in linee e parole e caratteri e ora il software è in grado di abbinare i caratteri attraverso il confronto e vari algoritmi di rilevamento. Il risultato finale è il testo nell’immagine che ci viene dato.
Il processo potrebbe non essere accurato al 100% e potrebbe essere necessario un intervento umano per correggere alcuni elementi che non sono stati scansionati correttamente. La correzione degli errori può anche essere ottenuta utilizzando un dizionario o anche Natural Language Processing (NLP).
L’output può ora essere convertito in altri mezzi come documenti Word, PDF o persino contenuti audio tramite tecnologie text-to-speech.
Usi di OCR
In precedenza, la digitalizzazione dei documenti veniva ottenuta digitando manualmente il testo sul computer. Attraverso l’OCR, questo processo è reso più semplice in quanto il documento può essere scansionato, elaborato e il testo estratto e memorizzato in una forma modificabile come un documento Word.
Se si dispone di uno scanner di documenti sul telefono, come Adobe Scan, probabilmente avete incontrato la tecnologia OCR in uso.
Gli aeroporti possono anche utilizzare OCR per automatizzare il processo di riconoscimento del passaporto e l’estrazione di informazioni da loro.
Altri usi dell’OCR includono l’automazione dei processi di immissione dei dati, il rilevamento e il riconoscimento delle targhe delle auto.
Cosa useremo
Per questo progetto OCR, useremo la libreria Python-Tesseract, o semplicemente PyTesseract, che è un wrapper per il motore Tesseract-OCR di Google.
Ho scelto questo perché è completamente open-source e in fase di sviluppo e manutenzione da parte del gigante che è Google. Segui queste istruzioni per installare Tesseract sulla tua macchina, poiché PyTesseract dipende da esso.
Useremo anche il framework web Flask per creare il nostro semplice server OCR dove possiamo scattare foto tramite la webcam o caricare foto per scopi di riconoscimento dei caratteri.
Useremo anche Pipenv poiché gestisce anche la configurazione dell’ambiente virtuale e la gestione dei requisiti.
Oltre a questi, useremo anche la libreria Pillow che è un fork della Python Imaging Library (PIL) per gestire l’apertura e la manipolazione di immagini in molti formati in Python.
In questo post, ci concentreremo su PyTesseract anche se ci sono altre librerie Python che possono aiutarti a estrarre testo da immagini come:
- Textract: che può estrarre dati da PDF ma è un pacchetto pesante.
- Pyocr: offre più opzioni di rilevamento come frasi, cifre o parole.
Setup
Inizia installando Pipenv usando il seguente comando tramite Pip (Nel caso in cui sia necessario configurarlo, fare riferimento a questo).
$ pip install pipenv
Creare la directory del progetto e avviare il progetto eseguendo il seguente comando:
$ mkdir ocr_server && cd ocr_server && pipenv install --three
Ora possiamo attivare il nostro ambiente virtuale e iniziare a installare le nostre dipendenze:
$ pipenv shell$ pipenv install pytesseract Pillow
Nel caso in cui non utilizzerai Pipenv, puoi sempre usare l’approccio Pip e Virtual Environment. Segui la documentazione ufficiale per aiutarti a iniziare con Pip e Ambiente virtuale:
Nota: in questo caso, invece dipipenv install Pillow
, il comando saràpip install Pillow
.
Implementazione
Implementeremo questo progetto in 2 fasi. Nel primo, creeremo lo script e nel prossimo costruiremo un’applicazione Flask per fungere da interfaccia.
OCR Script
Con il programma di installazione completo, ora siamo in grado di creare una semplice funzione che prende un’immagine e restituisce il testo riconosciuto nell’immagine – questo sarà il cuore del nostro progetto:
try: from PIL import Imageexcept ImportError: import Imageimport pytesseractdef ocr_core(filename): """ This function will handle the core OCR processing of images. """ text = pytesseract.image_to_string(Image.open(filename)) # We'll use Pillow's Image class to open the image and pytesseract to detect the string in the image return textprint(ocr_core('images/ocr_example_1.png'))
La funzione è abbastanza semplice, nei primi 5 linee importiamo Image
dal Pillow
la biblioteca e la nostra PyTesseract
libreria.
Abbiamo quindi creare eocr_core
funzione che prende in un nome di file e restituisce il testo contenuto nell’immagine.
Vediamo come lo script funziona con una semplice immagine contenente del testo:
E dopo aver eseguito il pezzo di codice, siamo accolti con questo:
Il nostro semplice script OCR funziona! Ovviamente, questo è stato un po ‘ facile dal momento che questo è il testo digitale, perfetto e preciso, a differenza della scrittura a mano. C’è molto di più che possiamo fare con la libreria PyTesseract, ma ne parleremo più avanti nel post.
Integriamo prima questo script in un’applicazione Flask, per semplificare il caricamento delle immagini ed eseguire operazioni di riconoscimento dei caratteri.
Interfaccia Web Flask
Il nostro script può essere utilizzato tramite la riga di comando, ma un’applicazione Flask lo renderebbe più user-friendly e versatile. Ad esempio, possiamo caricare foto tramite il sito Web e ottenere il testo estratto visualizzato sul sito Web o possiamo catturare foto tramite la webcam ed eseguire il riconoscimento dei caratteri su di esse.
Se non si ha familiarità con il quadro Flask, questo è un buon tutorial per arrivare fino a velocità e andare.
cominciamo con l’installazione di Pallone pacchetto:
$ pipenv install Flask
Ora, cerchiamo di definire un itinerario di base:
from flask import Flaskapp = Flask(__name__)@app.route('/')def home_page(): return "Hello World!"if __name__ == '__main__': app.run()
Salvare il file ed eseguire:
$ python3 app.py
Se si apre il browser e, di testa, su 127.0.0.1:5000
o localhost:5000
si dovrebbe vedere “Hello World!”sulla pagina. Ciò significa che la nostra applicazione Flask è pronto per i prossimi passi.
Ora creeremo una cartellatemplates
per ospitare i nostri file HTML. Andiamo avanti e creare un semplice index.html
:
<!DOCTYPE html><html> <head> <title>Index</title> </head> <body> Hello World. </body></html>
anche noi, che modifica le nostre app.py
per rendere il nostro nuovo modello:
from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')def home_page(): return render_template('index.html')if __name__ == '__main__': app.run()
si Noti ora abbiamo importato render_template
e usata per rendere il file HTML. Se si riavvia l’applicazione Flask, si dovrebbe ancora vedere ” Ciao mondo!”sulla home page.
Basta con il Flask crash course, ora integriamo il nostro script OCR sull’applicazione web.
Per prima cosa, aggiungeremo funzionalità per caricare le immagini nella nostra app Flask e passarle alla funzioneocr_core
che abbiamo scritto sopra. Quindi renderemo l’immagine accanto al testo estratto sulla nostra app web come risultato:
import osfrom flask import Flask, render_template, request# import our OCR functionfrom ocr_core import ocr_core# define a folder to store and later serve the imagesUPLOAD_FOLDER = '/static/uploads/'# allow files of a specific typeALLOWED_EXTENSIONS = set()app = Flask(__name__)# function to check the file extensiondef allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1).lower() in ALLOWED_EXTENSIONS# route and function to handle the home [email protected]('/')def home_page(): return render_template('index.html')# route and function to handle the upload [email protected]('/upload', methods=)def upload_page(): if request.method == 'POST': # check if there is a file in the request if 'file' not in request.files: return render_template('upload.html', msg='No file selected') file = request.files # if no file is selected if file.filename == '': return render_template('upload.html', msg='No file selected') if file and allowed_file(file.filename): # call the OCR function on it extracted_text = ocr_core(file) # extract the text and display it return render_template('upload.html', msg='Successfully processed', extracted_text=extracted_text, img_src=UPLOAD_FOLDER + file.filename) elif request.method == 'GET': return render_template('upload.html')if __name__ == '__main__': app.run()
Come possiamo vedere nella nostra funzione upload_page()
, riceveremo l’immagine tramite POST e renderemo l’upload HTML se la richiesta è GET.
Controlliamo se l’utente ha realmente caricato un file e usiamo la funzioneallowed_file()
per verificare se il file è di tipo accettabile.
Dopo aver verificato che l’immagine sia del tipo richiesto, la passiamo allo script di riconoscimento dei caratteri che abbiamo creato in precedenza.
La funzione rileva il testo nell’immagine e lo restituisce. Infine, come risposta al caricamento dell’immagine, rendiamo il testo rilevato accanto all’immagine per consentire all’utente di vedere i risultati.
Il file upload.html
gestirà la pubblicazione dell’immagine e il rendering del risultato con l’aiuto del motore di template Jinja, che viene fornito con Flask per impostazione predefinita:
<!DOCTYPE html><html> <head> <title>Upload Image</title> </head> <body> {% if msg %} <h1>{{ msg }}</h1> {% endif %} <h1>Upload new File</h1> <form method=post enctype=multipart/form-data> <p><input type=file name=file> <input type=submit value=Upload> </form> <h1>Result:</h1> {% if img_src %} <img src="{{ img_src }}"> {% endif %} {% if extracted_text %} <p> The extracted text from the image above is: <b> {{ extracted_text }} </b></p> {% else %} The extracted text will be displayed here {% endif %} </body></html>
Jinja templating ci permette di visualizzare il testo in scenari specifici attraverso i tag {% if %} {% endif %}
. Possiamo anche passare messaggi dalla nostra app Flask da visualizzare sulla pagina Web all’interno dei tag{{ }}
. Usiamo un modulo per caricare l’immagine sulla nostra app Flask.
Il risultato è:
Ora, se andiamo avanti e carichiamo la nostra immagine da prima:
Sì! La nostra applicazione Flask è stata in grado di integrare la funzionalità OCR e visualizzare il testo sul browser. Ciò rende più facile elaborare le immagini invece di eseguire comandi sulla CLI ogni volta che abbiamo una nuova immagine da elaborare.
Alleghiamo altre immagini per esplorare ulteriormente i limiti del nostro semplice script OCR poiché non funzionerà in tutte le situazioni.
Ad esempio, proviamo a estrarre il testo dall’immagine seguente e il risultato è stato evidenziato sull’immagine:
Questa è la prova che l’OCR non è sempre accurato al 100% e potrebbe richiedere l’intervento umano di volta in volta.
Ho anche testato lo script OCR contro la mia scrittura per vedere come avrebbe funzionato, e questo è il risultato:
Come puoi vedere, non può estrarre abbastanza testo dalla mia scrittura come ha fatto con altre immagini che abbiamo visto prima. Ho deciso di fare un altro tentativo, questa volta con un’immagine da questa fonte, e questi sono stati i risultati:
Il riconoscimento dei caratteri su questa immagine è molto meglio di quello in cui ho usato la mia grafia. Come puoi vedere le linee nell’immagine scaricata sono più spesse e c’è un contrasto migliore tra il testo e lo sfondo e questo potrebbe essere il motivo della scarsa rilevazione sulla mia calligrafia.
Questa è un’area da esplorare ulteriormente, è possibile ottenere note scritte a mano da amici o colleghi e vedere quanto bene lo script sarà in grado di rilevare i caratteri. Puoi persino ottenere poster per eventi e provare a scansionarli per il testo, le possibilità sono molte.
Altre opzioni PyTesseract
Python-Tesseract ha più opzioni che puoi esplorare. Ad esempio, è possibile specificare la lingua utilizzando un lang
bandiera:
pytesseract.image_to_string(Image.open(filename), lang='fra')
Questo è il risultato della scansione di un’immagine senza il lang
flag:
E ora con il lang
flag:
Il framework è anche ottimizzato per rilevare meglio le lingue come si vede negli screenshot. (Fonte immagine).
Senza il flaglang
, lo script ha perso alcune parole francesi, ma dopo aver introdotto il flag è stato in grado di rilevare tutto il contenuto francese. La traduzione non è possibile, ma questo è ancora impressionante. La documentazione ufficiale di Tesseract include le lingue supportate in questa sezione.
L’orientamento e il rilevamento degli script sono anche tra le funzionalità di PyTesseract e questo aiuta nel rilevamento dei font utilizzati e dell’orientamento del testo sull’immagine data. Se possiamo fare riferimento all’immagine scritta a mano che abbiamo scaricato in precedenza:
print(pytesseract.image_to_osd(Image.open('downloaded_handwritten.png')))
Non c’erano informazioni sul numero di pagina sull’immagine, quindi questo non è stato rilevato. Il motore Tesseract è in grado di estrarre informazioni sull’orientamento del testo nell’immagine e sulla rotazione. La fiducia orientamento è una figura della fideiussione del motore circa l’orientamento rilevato per agire come una guida e per dimostrare anche che non è sempre accurato al 100%. La sezione script indica il sistema di scrittura utilizzato nel testo e questo è seguito anche dal marcatore di confidenza.
Se cercassimo i caratteri riconosciuti e i loro limiti di casella, PyTesseract lo raggiunge attraversopytesseract.image_to_boxes(Image.open('downloaded_handwritten.png'))
.
Queste sono alcune delle funzionalità di PyTesseract, tra le altre, come la conversione del testo estratto in un PDF ricercabile o in un output HOCR.
Quello che non abbiamo fatto
Abbiamo realizzato molto in questo post, ma c’è ancora molto da fare per affinare il nostro progetto e prepararlo per il mondo reale. In primo luogo, possiamo aggiungere stile al nostro sito web e renderlo più attraente per l’utente finale utilizzando i CSS. Possiamo anche aggiungere l’opzione per caricare e scansionare più immagini contemporaneamente e visualizzare tutti i loro output contemporaneamente. Questo non renderebbe più conveniente la scansione di più documenti?
Il browser ci consente di attingere alla fotocamera di una macchina e catturare immagini, con il permesso dell’utente, ovviamente. Questo può essere di grande aiuto soprattutto sui dispositivi mobili. Invece di dover catturare e salvare l’immagine e caricarla sul sito web, se aggiungiamo la funzionalità della fotocamera, possiamo consentire all’utente di eseguire le operazioni direttamente dall’applicazione web Flask. Questo renderà il processo di scansione più veloce.
Supponiamo che un’applicazione Flask non sia ciò che intendevi esporre il tuo scanner OCR, puoi anche creare uno strumento CLI. Lo strumento consente di eseguire un comando che include la posizione dell’immagine e quindi stampare l’output dello scanner sul terminale o inviarlo a un database o API. Se hai scelto questo percorso Docopt è uno strumento fantastico per creare strumenti da riga di comando usando Python.
Conclusione
Attraverso Tesseract e la libreria Python-Tesseract, siamo stati in grado di scansionare le immagini ed estrarre il testo da esse. Questo è il riconoscimento ottico dei caratteri e può essere di grande utilità in molte situazioni.
Abbiamo costruito uno scanner che prende un’immagine e restituisce il testo contenuto nell’immagine e lo ha integrato in un’applicazione Flask come interfaccia. Questo ci permette di esporre la funzionalità in un mezzo più familiare e in un modo che può servire più persone contemporaneamente.