introduktion
människor kan förstå innehållet i en bild helt enkelt genom att titta. Vi uppfattar texten på bilden som text och kan läsa den.
datorer fungerar inte på samma sätt. De behöver något mer konkret, organiserat på ett sätt de kan förstå.
det är här optisk teckenigenkänning (OCR) sparkar in. Oavsett om det är erkännande av bilplattor från en kamera eller handskrivna dokument som ska omvandlas till en digital kopia, är denna teknik mycket användbar. Även om det inte alltid är perfekt, är det väldigt bekvämt och gör det mycket enklare och snabbare för vissa människor att göra sina jobb.
i den här artikeln kommer vi att dyka in i djupet av optiskt teckenigenkänning och dess applikationsområden. Vi kommer också att bygga ett enkelt skript i Python som hjälper oss att upptäcka tecken från bilder och avslöja detta genom en Kolvapplikation för ett bekvämare interaktionsmedium.
Vad är optisk teckenigenkänning?
optisk teckenigenkänning innebär detektering av textinnehåll på bilder och översättning av bilderna till kodad text som datorn lätt kan förstå. En bild som innehåller text skannas och analyseras för att identifiera tecknen i den. Vid identifiering konverteras tecknet till maskinkodad text.
hur uppnås det egentligen? För oss är text på en bild lätt urskiljbar och vi kan upptäcka tecken och läsa texten, men till en dator är det allt en serie prickar.
bilden skannas först och text-och grafikelementen omvandlas till en bitmapp, som i huvudsak är en matris med svarta och vita prickar. Bilden förbehandlas sedan där ljusstyrkan och kontrasten justeras för att förbättra processens noggrannhet.
bilden är nu uppdelad i zoner som identifierar intresseområden som var bilderna eller texten är och detta hjälper till att starta extraktionsprocessen. Områdena som innehåller text kan nu delas upp ytterligare i rader och ord och tecken och nu kan programvaran matcha karaktärerna genom jämförelse och olika detekteringsalgoritmer. Slutresultatet är texten i bilden som vi får.
processen kanske inte är 100% korrekt och kan behöva mänsklig intervention för att korrigera vissa element som inte skannades korrekt. Felkorrigering kan också uppnås med hjälp av en ordbok eller till och med naturlig språkbehandling (NLP).
utgången kan nu konverteras till andra medier som word-dokument, PDF-filer eller till och med ljudinnehåll genom text-till-tal-teknik.
användning av OCR
tidigare uppnåddes digitalisering av dokument genom att manuellt skriva texten på datorn. Genom OCR underlättas denna process eftersom dokumentet kan skannas, bearbetas och texten extraheras och lagras i en redigerbar form som ett word-dokument.
Om du har en dokumentskanner på din telefon, till exempel Adobe Scan, har du förmodligen stött på OCR-teknik som används.
flygplatser kan också använda OCR för att automatisera processen för pass erkännande och utvinning av information från dem.
andra användningar av OCR inkluderar automatisering av datainmatningsprocesser, detektering och igenkänning av bilnummerskyltar.
vad vi ska använda
För detta OCR-projekt använder vi Python-Tesseract, eller helt enkelt PyTesseract, biblioteket som är ett omslag för Googles Tesseract-OCR-motor.
Jag valde detta eftersom det är helt öppen källkod och utvecklas och underhålls av jätten som är Google. Följ dessa instruktioner för att installera Tesseract på din maskin, eftersom PyTesseract beror på den.
Vi kommer också att använda Flask web framework för att skapa vår enkla OCR-server där vi kan ta bilder via webbkameran eller ladda upp foton för teckenigenkänningsändamål.
Vi kommer också att använda Pipenv eftersom det också hanterar installation och kravhantering för virtuell miljö.
förutom dem använder vi också Pillow library som är en gaffel i Python Imaging Library (PIL) för att hantera öppning och manipulation av bilder i många format i Python.
i det här inlägget koncentrerar vi oss på PyTesseract även om det finns andra Python-bibliotek som kan hjälpa dig att extrahera text från bilder som:
- Textract: som kan extrahera data från PDF-filer men är ett tungt paket.
- Pyocr: erbjuder fler detekteringsalternativ som meningar, siffror eller ord.
Setup
börja med att installera Pipenv med följande kommando via Pip (om du behöver ställa in det, se detta).
$ pip install pipenv
skapa projektkatalogen och initiera projektet genom att köra följande kommando:
$ mkdir ocr_server && cd ocr_server && pipenv install --three
Vi kan nu aktivera vår virtuella miljö och börja installera våra beroenden:
$ pipenv shell$ pipenv install pytesseract Pillow
om du inte använder Pipenv kan du alltid använda PIP och virtuell miljö. Följ den officiella dokumentationen för att hjälpa dig att komma igång med Pip och virtuell miljö:
Obs: i så fall, istället för pipenv install Pillow
, kommer kommandot att vara pip install Pillow
.
genomförande
Vi kommer att genomföra detta projekt i 2 faser. I det första skapar vi skriptet, och i nästa bygger vi en Flask-applikation för att fungera som ett gränssnitt.
OCR Script
När installationen är klar kan vi nu skapa en enkel funktion som tar en bild och returnerar texten som upptäckts i bilden – detta kommer att vara kärnan i vårt projekt:
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'))
funktionen är ganska enkel, i de första 5 raderna importerar viImage
frånPillow
bibliotek och vårtPyTesseract
bibliotek.
Vi skapar sedan och ocr_core
funktion som tar in ett filnamn och returnerar texten i bilden.
Låt oss se hur skriptet kostar med en enkel bild som innehåller lite text:
och när vi kör kodstycket hälsas vi med detta:
vårt enkla OCR-skript fungerar! Självklart var detta något enkelt eftersom det här är digital text, perfekt och exakt, till skillnad från handskrift. Det finns mycket mer vi kan göra med PyTesseract-biblioteket, men mer om detta senare i inlägget.
låt oss integrera detta skript i en Flask-applikation först för att göra det lättare att ladda upp bilder och utföra teckenigenkänningsoperationer.
Flask webbgränssnitt
vårt skript kan användas via kommandoraden, men en Flask-applikation skulle göra den mer användarvänlig och mångsidig. Till exempel kan vi ladda upp foton via webbplatsen och få den extraherade texten som visas på webbplatsen eller så kan vi ta bilder via webbkameran och utföra teckenigenkänning på dem.
Om du inte känner till Kolvramen är det här en bra handledning för att få dig igång och gå.
låt oss börja med att installera Kolvpaketet:
$ pipenv install Flask
låt oss nu definiera en grundläggande rutt:
from flask import Flaskapp = Flask(__name__)@app.route('/')def home_page(): return "Hello World!"if __name__ == '__main__': app.run()
spara filen och kör:
$ python3 app.py
Om du öppnar din webbläsare och gå vidare till 127.0.0.1:5000
eller localhost:5000
du borde se ”Hej världen!”på sidan. Det betyder att vår Flask-app är redo för nästa steg.
Vi skapar nu entemplates
mapp för att vara värd för våra HTML-filer. Låt oss gå vidare och skapa en enkel index.html
:
<!DOCTYPE html><html> <head> <title>Index</title> </head> <body> Hello World. </body></html>
Låt oss också justera vår app.py
för att göra vår nya Mall:
from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')def home_page(): return render_template('index.html')if __name__ == '__main__': app.run()
meddelande Vi har nu importerad render_template
och använde den för att göra html-filen. Om du startar om din Flask-app bör du fortfarande se ” Hej världen!”på hemsidan.
det räcker på Flask crash course, låt oss nu integrera vårt OCR-skript på webbapplikationen.
först lägger vi till funktionalitet för att ladda upp bilder till vår Flask-app och skicka dem till ocr_core
– funktionen som vi skrev ovan. Vi kommer då att göra bilden bredvid den extraherade texten på vår webbapp som ett resultat:
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()
som vi kan se i vårupload_page()
funktion, kommer vi att få bilden via POST och göra uppladdningen HTML om begäran är GET.
Vi kontrollerar om användaren verkligen har laddat upp en fil och använder funktionen allowed_file()
för att kontrollera om filen är av en acceptabel typ.
När vi verifierar att bilden är av önskad typ skickar vi den sedan till teckenigenkänningsskriptet vi skapade tidigare.
funktionen upptäcker texten i bilden och returnerar den. Slutligen, som ett svar på bilduppladdningen, gör vi den upptäckta texten tillsammans med bilden för att användaren ska se resultaten.
upload.html
– filen hanterar utstationering av bilden och rendering av resultatet med hjälp av Jinja-mallmotorn, som skickas med kolv som standard:
<!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 tillåter oss att visa text i specifika scenarier genom{% if %} {% endif %}
taggar. Vi kan också skicka meddelanden från vår Flask app som ska visas på webbsidan inom {{ }}
taggar. Vi använder ett formulär för att ladda upp bilden till vår Flask app.
resultatet är:
Nu, om vi fortsätter och laddar upp vår bild från tidigare:
Ja! Vår Flask-applikation har kunnat integrera OCR-funktionaliteten och visa texten i webbläsaren. Detta gör det lättare att bearbeta bilder istället för att köra kommandon på CLI varje gång vi har en ny bild att bearbeta.
låt oss bifoga några fler bilder för att ytterligare utforska gränserna för vårt enkla OCR-skript eftersom det inte fungerar i alla situationer.
Låt oss till exempel försöka extrahera text från följande bild och resultatet har markerats på bilden:
detta är bevis på att OCR inte alltid är 100% korrekt och kan behöva mänsklig intervention då och då.
Jag testade också OCR-skriptet mot min handskrift för att se hur det skulle fungera, och detta är resultatet:
som du kan se kan det inte riktigt extrahera text från min handskrift som det gjorde med andra bilder vi har sett tidigare. Jag bestämde mig för att ge det ett nytt försök, den här gången med en bild från den här källan, och det var resultaten:
teckenigenkänningen på den här bilden är mycket bättre än den där jag använde min egen handskrift. Som du kan se är linjerna i den nedladdade bilden tjockare och det finns bättre kontrast mellan texten och bakgrunden och det kan vara orsaken till den dåliga upptäckten på min handskrift.
detta är ett område att utforska vidare, Du kan få handskrivna anteckningar från vänner eller kollegor och se hur bra skriptet kommer att kunna upptäcka tecken. Du kan till och med få affischer till evenemang och försöka skanna dem efter text, möjligheterna är många.
andra PyTesseract alternativ
Python-Tesseract har fler alternativ du kan utforska. Du kan till exempel ange språket genom att använda en lang
flagga:
pytesseract.image_to_string(Image.open(filename), lang='fra')
detta är resultatet av att skanna en bild utan lang
flagga:
och nu med lang
flagga:
ramverket är också optimerat för att upptäcka språk bättre som det ses i skärmdumparna. (Bildkälla).
utan flagganlang
missade skriptet några franska ord, men efter att ha introducerat flaggan kunde det upptäcka allt franskt innehåll. Översättning är inte möjlig men det är fortfarande imponerande. Tesseracts officiella dokumentation innehåller de språk som stöds i det här avsnittet.
orientering och skriptdetektering är också bland funktionerna i PyTesseract och detta hjälper till att upptäcka de använda teckensnitten och orienteringen av texten på den givna bilden. Om vi kan hänvisa till den handskrivna bilden som vi laddade ner tidigare:
print(pytesseract.image_to_osd(Image.open('downloaded_handwritten.png')))
det fanns ingen sidnummerinformation på bilden så det upptäcktes inte. Tesseract-motorn kan extrahera information om textens orientering i bilden och rotationen. Orienteringsförtroendet är en siffra på motorns säkerhet om orienteringen som upptäckts för att fungera som en guide och för att också visa att den inte alltid är 100% korrekt. Skriptavsnittet betecknar skrivsystemet som används i texten och detta följs också av konfidensmarkören.
Om vi var efter de igenkända tecknen och deras boxgränser uppnår PyTesseract detta genompytesseract.image_to_boxes(Image.open('downloaded_handwritten.png'))
.
det här är några av funktionerna i PyTesseract bland annat som konvertering av den extraherade texten till en sökbar PDF-eller HOCR-utgång.
vad vi inte har gjort
Vi har åstadkommit mycket i det här inlägget, men det finns fortfarande mer att göra för att förfina vårt projekt och förbereda det för den verkliga världen. Först kan vi lägga till stil på vår webbplats och göra det mer tilltalande för slutanvändaren genom att använda CSS. Vi kan också lägga till alternativet att ladda upp och skanna flera bilder samtidigt och visa all sin produktion på en gång. Skulle det inte göra det bekvämare att skanna flera dokument?
webbläsaren tillåter oss att utnyttja en maskin kamera och ta bilder, med tillstånd från användaren, naturligtvis. Detta kan vara till stor hjälp, särskilt på mobila enheter. Istället för att användaren måste fånga och spara bilden och sedan ladda upp den på webbplatsen, om vi lägger till kamerans funktionalitet, kan vi tillåta användaren att utföra operationerna direkt från Flask-webbapplikationen. Detta gör skanningsprocessen snabbare.
anta att en Flask-applikation inte är vad du tänkte exponera din OCR-skanner, du kan också skapa ett CLI-verktyg. Verktyget låter dig köra ett kommando inklusive platsen för bilden och sedan skriva ut skannerns utgång till din terminal eller skicka den till en databas eller API. Om du väljer den här sökvägen är Docopt ett fantastiskt verktyg för att bygga kommandoradsverktyg med Python.
slutsats
genom Tesseract och Python-Tesseract-biblioteket har vi kunnat skanna bilder och extrahera text från dem. Detta är optiskt teckenigenkänning och det kan vara till stor nytta i många situationer.
Vi har byggt en skanner som tar en bild och returnerar texten i bilden och integrerat den i en Flask-applikation som gränssnitt. Detta gör att vi kan avslöja funktionaliteten på ett mer bekant medium och på ett sätt som kan tjäna flera personer samtidigt.