PyTesseract: Reconocimiento 贸ptico de caracteres en Python

    Introducci贸n

    Los humanos pueden comprender el contenido de una imagen simplemente mirando. Percibimos el texto de la imagen como texto y podemos leerlo.

    Las computadoras no funcionan de la misma manera. Necesitan algo m谩s concreto, organizado de una manera que puedan entender.

    Aqu铆 es donde entra en juego el reconocimiento 贸ptico de caracteres (OCR). Ya sea que se trate del reconocimiento de placas de autom贸viles desde una c谩mara o de documentos escritos a mano que deben convertirse en una copia digital, esta t茅cnica es muy 煤til. Si bien no siempre es perfecto, es muy conveniente y hace que sea mucho m谩s f谩cil y r谩pido para algunas personas hacer su trabajo.

    En este art铆culo, profundizaremos en la profundidad del reconocimiento 贸ptico de caracteres y sus 谩reas de aplicaci贸n. Tambi茅n crearemos un script simple en Python que nos ayudar谩 a detectar personajes a partir de im谩genes y exponerlos a trav茅s de una aplicaci贸n Flask para un medio de interacci贸n m谩s conveniente.

    驴Qu茅 es el reconocimiento 贸ptico de caracteres?

    El reconocimiento 贸ptico de caracteres implica la detecci贸n de contenido de texto en im谩genes y la traducci贸n de las im谩genes a texto codificado que la computadora puede comprender f谩cilmente. Una imagen que contiene texto se escanea y analiza para identificar los caracteres en ella. Tras la identificaci贸n, el car谩cter se convierte en texto codificado por m谩quina.

    驴C贸mo se logra realmente? Para nosotros, el texto de una imagen es f谩cilmente discernible y podemos detectar caracteres y leer el texto, pero para una computadora, todo es una serie de puntos.

    Primero se escanea la imagen y los elementos de texto y gr谩ficos se convierten en un mapa de bits, que es esencialmente una matriz de puntos blancos y negros. Luego, la imagen se procesa previamente donde se ajustan el brillo y el contraste para mejorar la precisi贸n del proceso.

    La imagen ahora se divide en zonas que identifican las 谩reas de inter茅s, como d贸nde est谩n las im谩genes o el texto, y esto ayuda a iniciar el proceso de extracci贸n. Las 谩reas que contienen texto ahora se pueden dividir a煤n m谩s en l铆neas, palabras y caracteres, y ahora el software puede hacer coincidir los caracteres mediante la comparaci贸n y varios algoritmos de detecci贸n. El resultado final es el texto de la imagen que se nos da.

    Es posible que el proceso no sea 100% preciso y que necesite la intervenci贸n humana para corregir algunos elementos que no se escanearon correctamente. La correcci贸n de errores tambi茅n se puede lograr utilizando un diccionario o incluso el procesamiento del lenguaje natural (NLP).

    La salida ahora se puede convertir a otros medios, como documentos de Word, PDF o incluso contenido de audio a trav茅s de tecnolog铆as de conversi贸n de texto a voz.

    Usos de OCR

    Anteriormente, la digitalizaci贸n de documentos se lograba escribiendo manualmente el texto en la computadora. A trav茅s de OCR, este proceso se hace m谩s f谩cil ya que el documento se puede escanear, procesar y el texto se puede extraer y almacenar en una forma editable, como un documento de Word.

    Si tiene un esc谩ner de documentos en su tel茅fono, como Adobe Scan, probablemente haya encontrado tecnolog铆a OCR en uso.

    Los aeropuertos tambi茅n pueden utilizar OCR para automatizar el proceso de reconocimiento de pasaportes y extracci贸n de informaci贸n de ellos.

    Otros usos de OCR incluyen la automatizaci贸n de los procesos de entrada de datos, la detecci贸n y el reconocimiento de matr铆culas de autom贸viles.

    Que usaremos

    Para este proyecto de OCR, usaremos la biblioteca Python-Tesseract , o simplemente PyTesseract, que es un contenedor para el motor Tesseract-OCR de Google .

    Eleg铆 esto porque es completamente de c贸digo abierto y est谩 siendo desarrollado y mantenido por el gigante que es Google. Siga estas instrucciones para instalar Tesseract en su m谩quina, ya que PyTesseract depende de ello.

    Tambi茅n usaremos el marco web Flask para crear nuestro servidor OCR simple donde podemos tomar fotos a trav茅s de la c谩mara web o cargar fotos con fines de reconocimiento de personajes.

    Tambi茅n usaremos Pipenv, ya que tambi茅n maneja la configuraci贸n del entorno virtual y la gesti贸n de requisitos.

    Adem谩s de eso, tambi茅n usaremos la biblioteca Pillow , que es una bifurcaci贸n de la Biblioteca de im谩genes de Python (PIL) para manejar la apertura y manipulaci贸n de im谩genes en muchos formatos en Python.

    En esta publicaci贸n, nos concentraremos en PyTesseract, aunque hay otras bibliotecas de Python que pueden ayudarlo a extraer texto de im谩genes como:

    • Textract : que puede extraer datos de archivos PDF pero es un paquete pesado.
    • Pyocr : ofrece m谩s opciones de detecci贸n como frases, d铆gitos o palabras.

    Preparar

    Comience instalando Pipenv usando el siguiente comando a trav茅s de Pip (en caso de que necesite configurarlo, consulte esto ).

    $ pip install pipenv
    

    Cree el directorio del proyecto e inicie el proyecto ejecutando el siguiente comando:

    $ mkdir ocr_server && cd ocr_server && pipenv install --three
    

    Ahora podemos activar nuestro entorno virtual y empezar a instalar nuestras dependencias:

    $ pipenv shell
    $ pipenv install pytesseract Pillow 
    

    En caso de que no vaya a utilizar Pipenv, siempre puede utilizar el enfoque de Pip y entorno virtual. Siga la documentaci贸n oficial que lo ayudar谩 a comenzar con Pip y Virtual Environment :

    Nota : En ese caso, en lugar de pipenv install Pillow, el comando ser谩 pip install Pillow.

    Implementaci贸n

    Vamos a implementar este proyecto en 2 fases. En el primero, crearemos el script y en el siguiente crearemos una aplicaci贸n Flask para que act煤e como interfaz.

    Script de OCR

    Con la configuraci贸n completa, ahora podemos crear una funci贸n simple que toma una imagen y devuelve el texto detectado en la imagen; este ser谩 el n煤cleo de nuestro proyecto:

    try:
        from PIL import Image
    except ImportError:
        import Image
    import pytesseract
    
    def 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 text
    
    print(ocr_core('images/ocr_example_1.png'))
    

    La funci贸n es bastante sencilla, en las primeras 5 l铆neas importamos Imagede la Pillowbiblioteca y nuestra PyTesseractbiblioteca.

    Luego creamos una ocr_corefunci贸n que toma un nombre de archivo y devuelve el texto contenido en la imagen.

    Veamos c贸mo le va al script con una imagen simple que contiene algo de texto:

    Y al ejecutar el fragmento de c贸digo, somos recibidos con esto:

    隆Nuestro sencillo script OCR funciona! Obviamente, esto fue algo f谩cil ya que se trata de texto digital, perfecto y preciso, a diferencia de la escritura a mano. Hay mucho m谩s que podemos hacer con la biblioteca PyTesseract, pero m谩s sobre esto m谩s adelante en la publicaci贸n.

    Primero integremos este script en una aplicaci贸n Flask, para facilitar la carga de im谩genes y realizar operaciones de reconocimiento de caracteres.

    Interfaz web del matraz

    Nuestro script se puede utilizar a trav茅s de la l铆nea de comandos, pero una aplicaci贸n Flask lo har铆a m谩s f谩cil de usar y vers谩til. Por ejemplo, podemos cargar fotos a trav茅s del sitio web y hacer que el texto extra铆do se muestre en el sitio web o podemos capturar fotos a trav茅s de la c谩mara web y realizar el reconocimiento de caracteres en ellas.

    Si no est谩 familiarizado con el marco de Flask, este es un buen tutorial para ponerse al d铆a y ponerse en marcha.

    Comencemos instalando el paquete Flask:

    $ pipenv install Flask
    

    Ahora, definamos una ruta b谩sica:

    from flask import Flask
    app = Flask(__name__)
    
    @app.route("https://Pharos.sh.com/")
    def home_page():
        return "Hello World!"
    
    if __name__ == '__main__':
        app.run()
    

    Guarde el archivo y ejecute:

    $ python3 app.py
    

    Si abre su navegador y se dirige a 127.0.0.1:5000o localhost:5000deber铆a ver “隆Hola mundo!” en la pagina. Esto significa que nuestra aplicaci贸n Flask est谩 lista para los siguientes pasos.

    Ahora crearemos una templatescarpeta para alojar nuestros archivos HTML. Sigamos adelante y creemos un simple index.html:

    <!DOCTYPE html>
    <html>
      <head>
        <title>Index</title>
      </head>
      <body>
        Hello World.
      </body>
    </html>
    

    Tambi茅n modifiquemos nuestro app.pypara renderizar nuestra nueva plantilla:

    from flask import Flask, render_template
    app = Flask(__name__)
    
    @app.route("https://Pharos.sh.com/")
    def home_page():
        return render_template('index.html')
    
    if __name__ == '__main__':
        app.run()
    

    Observe que ahora lo hemos importado render_templatey usado para renderizar el archivo HTML. Si reinicia su aplicaci贸n Flask, a煤n deber铆a ver “隆Hola mundo!” en la p谩gina de inicio.

    Eso es suficiente en el curso intensivo de Flask, integremos ahora nuestro script OCR en la aplicaci贸n web.

    Primero, agregaremos funcionalidad para cargar im谩genes a nuestra aplicaci贸n Flask y las pasaremos a la ocr_corefunci贸n que escribimos anteriormente. Luego, renderizaremos la imagen junto al texto extra铆do en nuestra aplicaci贸n web como resultado:

    import os
    from flask import Flask, render_template, request
    
    # import our OCR function
    from ocr_core import ocr_core
    
    # define a folder to store and later serve the images
    UPLOAD_FOLDER = '/static/uploads/'
    
    # allow files of a specific type
    ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
    
    app = Flask(__name__)
    
    # function to check the file extension
    def allowed_file(filename):
        return '.' in filename and 
               filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
    
    # route and function to handle the home page
    @app.route("https://Pharos.sh.com/")
    def home_page():
        return render_template('index.html')
    
    # route and function to handle the upload page
    @app.route('/upload', methods=['GET', 'POST'])
    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['file']
            # 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()
    

    Como podemos ver en nuestra upload_page()funci贸n, recibiremos la imagen a trav茅s de POST y renderizaremos el HTML de carga si la solicitud es GET.

    Verificamos si el usuario realmente ha subido un archivo y usamos la funci贸n allowed_file()para verificar si el archivo es de un tipo aceptable.

    Tras verificar que la imagen es del tipo requerido, la pasamos al script de reconocimiento de caracteres que creamos anteriormente.

    La funci贸n detecta el texto en la imagen y lo devuelve. Finalmente, como respuesta a la carga de la imagen, renderizamos el texto detectado junto a la imagen para que el usuario vea los resultados.

    El upload.htmlarchivo manejar谩 la publicaci贸n de la imagen y la representaci贸n del resultado con la ayuda del motor de plantillas Jinja , que se env铆a con Flask por defecto:

    <!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>
    

    Las plantillas de Jinja nos permiten mostrar texto en escenarios espec铆ficos a trav茅s de las {% if %} {% endif %}etiquetas. Tambi茅n podemos pasar mensajes desde nuestra aplicaci贸n Flask para que se muestren en la p谩gina web dentro de las {{ }}etiquetas. Usamos un formulario para cargar la imagen en nuestra aplicaci贸n Flask.

    El resultado es:

    Ahora, si seguimos adelante y cargamos nuestra imagen de antes:

    隆Si! Nuestra aplicaci贸n Flask ha podido integrar la funcionalidad OCR y mostrar el texto en el navegador. Esto facilita el proceso de im谩genes en lugar de ejecutar comandos en la CLI cada vez que tenemos una nueva imagen para procesar.

    Adjuntemos algunas im谩genes m谩s para explorar m谩s a fondo los l铆mites de nuestro sencillo script OCR, ya que no funcionar谩 en todas las situaciones.

    Por ejemplo, intentemos extraer texto de la siguiente imagen y el resultado se ha resaltado en la imagen:

    Esta es una evidencia de que el OCR no siempre es 100% exacto y puede necesitar la intervenci贸n humana de vez en cuando.

    Tambi茅n prob茅 el script OCR con mi escritura a mano para ver c贸mo funcionar铆a, y este es el resultado:

    Como puede ver, no puede extraer texto de mi letra como lo hizo con otras im谩genes que hemos visto antes. Decid铆 darle otra oportunidad, esta vez con una imagen de esta fuente , y estos fueron los resultados:

    El reconocimiento de caracteres en esta imagen es mucho mejor que en el que us茅 mi propia letra. Como puede ver, las l铆neas en la imagen descargada son m谩s gruesas y hay un mejor contraste entre el texto y el fondo y esta podr铆a ser la raz贸n de la mala detecci贸n en mi letra.

    Esta es un 谩rea para explorar m谩s, puede obtener notas escritas a mano de amigos o colegas y ver qu茅 tan bien el gui贸n ser谩 capaz de detectar personajes. Incluso puede enviar carteles a eventos e intentar escanearlos en busca de texto, las posibilidades son muchas.

    Otras opciones de PyTesseract

    Python-Tesseract tiene m谩s opciones que puede explorar. Por ejemplo, puede especificar el idioma usando una langbandera:

    pytesseract.image_to_string(Image.open(filename), lang='fra')
    

    Este es el resultado de escanear una imagen sin la langbandera:

    Y ahora con la langbandera:

    El marco tambi茅n est谩 optimizado para detectar mejor los idiomas, como se ve en las capturas de pantalla. ( Fuente de la imagen ).

    Sin la langbandera, el gui贸n omiti贸 algunas palabras en franc茅s, pero despu茅s de introducir la bandera pudo detectar todo el contenido en franc茅s. La traducci贸n no es posible, pero sigue siendo impresionante. La documentaci贸n oficial de Tesseract incluye los idiomas admitidos en esta secci贸n.

    La orientaci贸n y la detecci贸n de secuencias de comandos tambi茅n se encuentran entre las capacidades de PyTesseract y esto ayuda a detectar las fuentes utilizadas y la orientaci贸n del texto en la imagen dada. Si podemos hacer referencia a la imagen manuscrita que descargamos anteriormente:

    print(pytesseract.image_to_osd(Image.open('downloaded_handwritten.png')))
    

    No hab铆a informaci贸n sobre el n煤mero de p谩gina en la imagen, por lo que no se detect贸. El motor Tesseract es capaz de extraer informaci贸n sobre la orientaci贸n del texto en la imagen y la rotaci贸n. La confianza de orientaci贸n es una cifra de la seguridad del motor sobre la orientaci贸n detectada para actuar como gu铆a y tambi茅n para mostrar que no siempre es 100% precisa. La secci贸n del gui贸n denota el sistema de escritura utilizado en el texto y tambi茅n va seguida del marcador de confianza.

    Si busc谩ramos los personajes reconocidos y sus l铆mites de caja, PyTesseract logra esto a trav茅s de pytesseract.image_to_boxes(Image.open('downloaded_handwritten.png')).

    Estas son algunas de las capacidades de PyTesseract, entre otras, como la conversi贸n del texto extra铆do en un PDF con capacidad de b煤squeda o una salida HOCR.

    Lo que no hemos hecho

    Hemos logrado mucho en esta publicaci贸n, pero a煤n queda mucho por hacer para refinar nuestro proyecto y prepararlo para el mundo real. Primero, podemos agregar estilo a nuestro sitio web y hacerlo m谩s atractivo para el usuario final usando CSS. Tambi茅n podemos agregar la opci贸n de cargar y escanear varias im谩genes a la vez y mostrar toda su salida a la vez. 驴No har铆a esto m谩s conveniente escanear varios documentos?

    El navegador nos permite acceder a la c谩mara de una m谩quina y capturar im谩genes, con el permiso del usuario, por supuesto. Esto puede ser de gran ayuda, especialmente en dispositivos m贸viles. En lugar de que el usuario tenga que capturar y guardar la imagen y luego cargarla en el sitio web, si agregamos la funcionalidad de la c谩mara, podemos permitir que el usuario realice las operaciones directamente desde la aplicaci贸n web Flask. Esto har谩 que el proceso de escaneo sea m谩s r谩pido.

    Suponga que una aplicaci贸n Flask no es lo que pretend铆a exponer su esc谩ner OCR, tambi茅n puede crear una herramienta CLI. La herramienta le permitir铆a ejecutar un comando que incluye la ubicaci贸n de la imagen y luego imprimir la salida del esc谩ner a su terminal o enviarla a una base de datos o API. Si elige esta ruta, Docopt es una herramienta fant谩stica para crear herramientas de l铆nea de comandos usando Python.

    Conclusi贸n

    A trav茅s de Tesseract y la biblioteca Python-Tesseract, hemos podido escanear im谩genes y extraer texto de ellas. Este es el reconocimiento 贸ptico de caracteres y puede ser de gran utilidad en muchas situaciones.

    Hemos construido un esc谩ner que toma una imagen y devuelve el texto contenido en la imagen y lo integramos en una aplicaci贸n Flask como interfaz. Esto nos permite exponer la funcionalidad en un medio m谩s familiar y de una manera que puede servir a varias personas simult谩neamente.

    El c贸digo fuente de este proyecto est谩 disponible aqu铆 en Github .

    .

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *