Skip to content

Tesseract OCR su AWS Lambda tramite virtualenv

I nostri sviluppatori stellari hanno esaurito le loro riserve di caffè, cercando giorno e notte la risposta, finché Sofia non ha trovato la soluzione su GitHub, quindi oggi la condivide con noi.

Soluzione:

Il motivo per cui non funziona è che questi pacchetti python sono solo dei wrapper per tesseract. È necessario compilare tesseract utilizzando un'istanza AWS Linux e copiare i binari e le librerie nel file zip della funzione lambda.

1) Avviare un'istanza EC2 con Amazon Linux a 64 bit;

2) Installare le dipendenze:

sudo yum install gcc gcc-c++ make
sudo yum install autoconf aclocal automake
sudo yum install libtool
sudo yum install libjpeg-devel libpng-devel libpng-devel libtiff-devel zlib-devel

3) Compilare e installare leptonica:

cd ~
mkdir leptonica
cd leptonica
wget http://www.leptonica.com/source/leptonica-1.73.tar.gz
tar -zxvf leptonica-1.73.tar.gz
cd leptonica-1.73
./configure
make
sudo make install

4) Compilare e installare tesseract

cd ~
mkdir tesseract
cd tesseract
wget https://github.com/tesseract-ocr/tesseract/archive/3.04.01.tar.gz
tar -zxvf 3.04.01.tar.gz
cd tesseract-3.04.01
./autogen.sh
./configure
make
sudo make install

5) Scaricare i dati addestrati alla lingua in tessdata

cd /usr/local/share/tessdata
wget https://github.com/tesseract-ocr/tessdata/raw/3.04.00/eng.traineddata
export TESSDATA_PREFIX=/usr/local/share/

A questo punto si dovrebbe essere in grado di utilizzare tesseract su questa istanza EC2. Per copiare i binari di tesseract e utilizzarlo in una funzione lambda, è necessario copiare alcuni file da questa istanza al file zip da caricare su lambda. Pubblicherò tutti i comandi per ottenere un file zip con tutti i file necessari.

6) Copiare tutto il materiale necessario per eseguire tesseract su lambda

cd ~
mkdir tesseract-lambda
cd tesseract-lambda
cp /usr/local/bin/tesseract .
mkdir lib
cd lib
cp /usr/local/lib/libtesseract.so.3 .
cp /usr/local/lib/liblept.so.5 .
cp /usr/lib64/libpng12.so.0 .
cd ..

mkdir tessdata
cd tessdata
cp /usr/local/share/tessdata/eng.traineddata .
cd ..

cd ..
zip -r tesseract-lambda.zip tesseract-lambda

Il file tesseract-lambda.zip contiene tutto ciò di cui lambda ha bisogno per eseguire tesseract. L'ultima cosa da fare è aggiungere la funzione lambda alla radice del file zip e caricarla su lambda. Ecco un esempio che non ho testato, ma che dovrebbe funzionare.

7) Creare un file chiamato main.py, scrivere una funzione lambda come quella sopra e aggiungerla alla radice di tesseract-lambda.zip:

from __future__ import print_function

import urllib
import boto3
import os
import subprocess

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
LIB_DIR = os.path.join(SCRIPT_DIR, 'lib')

s3 = boto3.client('s3')

def lambda_handler(event, context):

    # Get the bucket and object from the event
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')

    try:
        print("Bucket: " + bucket)
        print("Key: " + key)

        imgfilepath = '/tmp/image.png'
        jsonfilepath = '/tmp/result.txt'
        exportfile = key + '.txt'

        print("Export: " + exportfile)

        s3.download_file(bucket, key, imgfilepath)

        command = 'LD_LIBRARY_PATH={} TESSDATA_PREFIX={} {}/tesseract {} {}'.format(
            LIB_DIR,
            SCRIPT_DIR,
            SCRIPT_DIR,
            imgfilepath,
            jsonfilepath,
        )

        try:
            output = subprocess.check_output(command, shell=True)
            print(output)
            s3.upload_file(jsonfilepath, bucket, exportfile)
        except subprocess.CalledProcessError as e:
            print(e.output)

    except Exception as e:
        print(e)
        print('Error processing object {} from bucket {}.'.format(key, bucket))
        raise e

Quando si crea la funzione AWS Lambda sulla console AWS, caricare il file zip e impostare l'Hanlder su main.lambda_handler. Questo indicherà ad AWS Lambda di cercare il file main.py all'interno dello zip e di chiamare la funzione lambda_handler.

IMPORTANTE

Di tanto in tanto le cose cambiano nell'ambiente di AWS Lambda. Ad esempio, l'immagine corrente per l'ambiente lambda è amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2 (potrebbe non essere questa quando si legge questa risposta). Se tesseract inizia a restituire un errore di segmentazione, eseguire "ldd tesseract" sulla funzione Lambda e vedere l'output per le librerie necessarie (attualmente libtesseract.so.3 liblept.so.5 libpng12.so.0).

Grazie per il commento, SergioArcos.

Adattamenti per tesseract 4:

Tesseract offre molti miglioramenti nella versione 4, grazie a una rete neurale. L'ho provato con alcune scansioni e i miglioramenti sono abbastanza sostanziali. Inoltre, nel mio caso, l'intero pacchetto è stato ridotto del 25%. La data di rilascio prevista per la versione 4 è la prima metà del 2018.

I passaggi di compilazione sono simili a quelli di tesseract 3 con alcune modifiche, per questo ho voluto condividerli per intero. Ho anche creato un repo su github con i file binari già pronti (la maggior parte di essi si basa sul post di Jose qui sopra, che è stato molto utile), oltre a un post sul blog su come usarlo come fase di elaborazione dopo una fase di scansione alimentata da raspberrypi3.

Per compilare i binari di tesseract4, eseguire questi passaggi su un'istanza AWS AIM a 64 bit:

Compilare leptonica

cd ~
sudo yum install clang -y
sudo yum install libpng-devel libtiff-devel zlib-devel libwebp-devel libjpeg-turbo-devel -y
wget https://github.com/DanBloomberg/leptonica/releases/download/1.75.1/leptonica-1.75.1.tar.gz
tar -xzvf leptonica-1.75.1.tar.gz
cd leptonica-1.75.1
./configure && make && sudo make install

Compilare autoconf-archive

Sfortunatamente, da qualche settimana tesseract ha bisogno di autoconf-archive, che non è disponibile per gli AIM di Amazon, quindi è necessario compilarlo da soli:

cd ~
wget http://mirror.switch.ch/ftp/mirror/gnu/autoconf-archive/autoconf-archive-2017.09.28.tar.xz
tar -xvf autoconf-archive-2017.09.28.tar.xz
cd autoconf-archive-2017.09.28
./configure && make && sudo make install
sudo cp m4/* /usr/share/aclocal/

Compilare tesseract

cd ~
sudo yum install git-core libtool pkgconfig -y
git clone --depth 1  https://github.com/tesseract-ocr/tesseract.git tesseract-ocr
cd tesseract-ocr
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
./autogen.sh
./configure
make
sudo make install

Ottenere tutti i file necessari e comprimere

cd ~
mkdir tesseract-standalone
cd tesseract-standalone
cp /usr/local/bin/tesseract .
mkdir lib
cp /usr/local/lib/libtesseract.so.4 lib/
cp /usr/local/lib/liblept.so.5 lib/
cp /usr/lib64/libjpeg.so.62 lib/
cp /usr/lib64/libwebp.so.4 lib/
cp /usr/lib64/libstdc++.so.6 lib/
mkdir tessdata
cd tessdata
wget https://github.com/tesseract-ocr/tessdata_fast/raw/master/osd.traineddata
wget https://github.com/tesseract-ocr/tessdata_fast/raw/master/eng.traineddata
# additionally any other language you want to use, e.g. `deu` for Deutsch
mkdir configs
cp /usr/local/share/tessdata/configs/pdf configs/
cp /usr/local/share/tessdata/pdf.ttf .
cd ..
zip -r ~/tesseract-standalone.zip *

Generare file zip usando script di shell per compilare il codice Tesseract 4 per Python 3.7

Ho lottato con questo problema per alcuni giorni cercando di far funzionare Tesseract 4 su una funzione Lambda di Python 3.7. Alla fine ho trovato questo articolo e GitHub che descrive come generare file zip per tesseract, pytesseract, opencv e pillow usando script di shell che generano i file .zip necessari usando immagini Docker su EC2! Questo processo richiede meno di 20 minuti utilizzando questi passaggi ed è riproducibile in modo affidabile.

Passi riassunti:

Avviare un'istanza Amazon Linux EC2 (t2 micro va benissimo)

sudo yum update
sudo yum install git-core -y
sudo yum install docker -y
sudo service docker start
sudo usermod -a -G docker ec2-user #allows ec2-user to call docker

Dopo aver eseguito il 5° comando, è necessario effettuare il logout e il login per rendere effettiva la modifica.

git clone https://github.com/amtam0/lambda-tesseract-api.git
cd lambda-tesseract-api/
bash build_tesseract4.sh #takes a few minutes
bash build_py37_pkgs.sh

Questo genererà file .zip per tesseract, pytesseract, pillow e opencv. Per poterli usare con lambda è necessario completare altri due passaggi.

  1. Creare livelli Lambda, uno per ogni file zip, e allegare i livelli alla funzione Lambda.
  2. Creare una variabile d'ambiente. Chiave: PYTHONPATH e valore: /opt/.

(Nota: probabilmente sarà necessario aumentare l'allocazione della memoria e il timeout).

A questo punto siete pronti per caricare il vostro codice e iniziare a usare Tesseract su AWS Lambda! Fate riferimento all'articolo di Medium per uno script di test.

Ricordati di diffondere questa notizia se ti è stata utile.



Utilizzate il nostro motore di ricerca

Ricerca
Generic filters

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.