OCR en Android

¿Qué es OCR?

La sigla OCR (del inglés Optical Character recognition), en español ROC o reconocimiento óptico de caracteres, se refiere al proceso de identificar automáticamente a partir de una imagen símbolos o caracteres que pertenecen a un determinado alfabeto. En esta entrada nos centraremos en explicar como usar OCR en Android.

Una vez reconocidos los caracteres de la imagen, el texto resultante puede utilizarse para:

  • Almacenamiento en forma de datos.
  • Uso en programas de edición de texto o similar.
  • Traducción en tiempo real.

La popularidad de los dispositivos inteligentes combinada con la mejora de sus cámaras ha conllevado a un aumento en el uso de este tipo de técnicas de reconocimiento y a una nueva categoría de aplicaciones móviles

¿En el dispositivo o en la nube?

Antes de utilizar una librería OCR es necesario decidir donde va a tener lugar el proceso de reconocimiento de caracteres, en el smartphone o en la nube.

En función de los requisitos de cada aplicación, cada enfoque tiene sus ventajas y desventajas.

OCR en Android. Cloud or local.

Por ejemplo, si la app necesita realizar el reconocimiento de caracteres sin conexión a internet, el motor OCR se lanzará en el propio dispositivo. De esta forma, también se evita el envío de imágenes a un servidor, que con las cámaras que montan los dispositivos actuales pueden ocupar mucho espacio.

Por otro lado, las librerías OCR tienden a ocupar mucho espacio, siendo necesario descargar cada uno de los idiomas a reconocer, como explicaremos más adelante.

¿Qué librerías se pueden utilizar?

En el siguiente enlace existe una tabla comparativa con todas las librerías OCR, las plataformas compatibles, lenguajes en los que están escritas y otra información relevante.

Link: http://en.wikipedia.org/wiki/ List_of_optical_character_recognition_software

En esta entrada usaremos la librería Tesseract, que destaca por encima de las demás. Es de código abierto, cuenta con SDK, fue creada por HP y actualmente es desarrollada por Google.

OCR en Android usando la librería Tesseract

Aunque Tesseract puede ejecutarse en un servidor Linux como un servicio en la nube, en esta entrada implementaremos la librería Tesseract en una aplicación Android, lanzando el motor OCR en el propio dispositivo.

El proyecto original de Tesseract para Android se denomina Tesseract Android Tools y cuenta con una serie de APIs y ficheros de configuración para Android.

Link: https://github.com/rebbix/tesseract-android-tools/tree/master/tesseract-android-tools

En este caso, vamos a utilizar un fork de Tesseract Android Tools, que añade más funcionalidades.

Link: https://github.com/rmtheis/tess-two

Ejemplo de OCR en Android

Los pasos que necesitamos para realizar OCR en Android son:

  1. Crear un proyecto Android en Android Studio.
  2. Añadir la librería Tesseract al proyecto añadiendo en el fichero build.gradle las siguientes lineas:
    dependencies {
        compile 'com.rmtheis:tess-two:6.0.0'
    }
  3. Crear una clase a la que llamaremos TessOCR con el siguiente código:
    import android.content.Context;
    import android.graphics.Bitmap; 
    import com.googlecode.tesseract.android.TessBaseAPI; 
    
    public class TessOCR { 
        private final TessBaseAPI mTess; 
    
        public TessOCR(Context context, String language) { 
            mTess = new TessBaseAPI(); 
            String datapath = context.getFilesDir() + "/tesseract/"; mTess.init(datapath, language); 
        }
     
        public String getOCRResult(Bitmap bitmap) { 
            mTess.setImage(bitmap); return mTess.getUTF8Text(); 
        }
     
        public void onDestroy() { 
            if (mTess != null) mTess.end(); 
        } 
    }
    • El constructor necesita un contexto (en este caso nos vale el de la actividad principal o MainActivity) y el idioma a reconocer con el que se iniciará el motor OCR. Este idioma debe estar en formato ISO 639-2/B. Ejemplo: spa (español) , chi (chino).
    • Nota:
      • Para reconocer cada idioma es necesario descargar un fichero y guardarlo en el dispositivo. En nuestro caso se guardará en el directorio de datos de la aplicación seguido de /tesseract/.
      • Los ficheros que se deben almacenar de cada idioma a reconocer se encuentran en https://github.com/tesseract-ocr/tessdata.
    • El método getOCRResult devolverá el texto reconocido a partir de la imagen que le pasemos.
  4. Desde el MainActivity importar la clase del punto anterior y crear una nueva instancia de reconocimiento con la siguiente linea:
    mTessOCR = 

    new

    TessOCR(

    this

    , language);
  5. Crear en el MainActivity el método que realice el reconocimiento de caracteres.
    private void doOCR (final Bitmap bitmap) {
       	 if (mProgressDialog == null) {
            mProgressDialog = ProgressDialog.show(ocrView, "Processing",
                    "Doing OCR...", true);
       	 } else {
           	 mProgressDialog.show();
       	 }
       	 new Thread(new Runnable() {
            	public void run() {
                	final String srcText = mTessOCR.getOCRResult(bitmap);
                	ocrView.runOnUiThread(new Runnable() {
                   	 @Override
                  	  public void run() {
                        // TODO Auto-generated method stub
                        if (srcText != null && !srcText.equals("")) {
                            //srcText contiene el texto reconocido
                        }
                        mTessOCR.onDestroy();
                        mProgressDialog.dismiss();
                    }
                });
            }
        }).start();
    }
    • Este código primero inicia un diálogo de progreso que indica el estado del reconocimiento. Después, lanza un nuevo hilo de ejecución que realizará el reconocimiento llamando al método getOCRResult. Cuando el reconocimiento termina, se detiene el diálogo el progreso y el texto reconocido se encuentra en srcText si todo ha funcionado correctamente.
  6. LLamar al método del paso 5 para comenzar con el reconocimiento.
    doOCR(bitmap);

Consideraciones

  • La calidad del reconocimiento puede variar en función de las condiciones lumínicas de la imagen, la nitidez, la resolución de la cámara, el tipo de letra, su tamaño y otros…
  • Para conseguir la mayor calidad posible, es importante centrar el texto y enfocar la imagen correctamente.

Video demostrativo del uso de OCR en un app traductora

El siguiente video muestra parte de la app que estoy desarrollando para mi Trabajo fin de Grado, donde utilizo las técnicas OCR descritas.

Enlaces relacionados

Beacons en Android

  • Video para detectar beacons en Android con un ejemplo:

Informes en formato PDF en Android

ASO – Posiciona tu app en el App Store o Google Play

Librería Android Priority Job Queue para tus tareas en segundo plano

Detección de dispositivos Bluetooth en Android

16 comentarios en «OCR en Android»

  1. ¿PODRÍAN SER UN POCO MÁS ESPECÍFICOS EN LA PARTE QUE DICE: «El constructor necesita un contexto (en este caso nos vale el de la actividad principal o MainActivity) y el idioma a reconocer con el que se iniciará el motor OCR. Este idioma debe estar en formato ISO 639-2/B. Ejemplo: spa (español) , chi (chino).
    Nota:
    Para reconocer cada idioma es necesario descargar un fichero y guardarlo en el dispositivo. En nuestro caso se guardará en el directorio de datos de la aplicación seguido de /tesseract/.
    Los ficheros que se deben almacenar de cada idioma a reconocer se encuentran en https://github.com/tesseract-ocr/tessdata.
    El método getOCRResult devolverá el texto reconocido a partir de la imagen que le pasemos.»
    Y EL PASO 4 POR FAVOR?

    Responder
    • Hola Víctor, en la parte que dice “El constructor necesita un contexto (en este caso nos vale el de la actividad principal o MainActivity) y el idioma a reconocer con el que se iniciará el motor OCR. Este idioma debe estar en formato ISO 639-2/B. Ejemplo: spa (español) , chi (chino)», describo los parámetros que tienes que pasar a este constructor, que está justo encima del texto por el que preguntas:

      public TessOCR(Context context, String language) {
      mTess = new TessBaseAPI();
      String datapath = context.getFilesDir() + "/tesseract/"; mTess.init(datapath, language);
      }

      En el punto 4 tienes que importar en el MainActivity la clase TessOCR que has creado en el paso 3:

      import your-package-name.TessOCR

      Y ya podrías crear el objeto TessOCR usando el constructor:

      mTessOCR = new TessOCR(this, language);

      Responder
  2. Hola David, hay alguna manera que luego de reconocer el texto, también guardar la foto? o viceversa? En el caso de la aplicación que estoy realizando, necesito tomarle foto al documento de identidad de una persona luego de registrarla. Me gustaría poder cotejar los datos obtenidos del documento para así validar que los datos ingresados con fiables. No se si me explico.

    Saludos!

    Responder
  3. Hola David, mira la verdad que no tengo ni idea de programación y pretendo aprender pasito a paso pues tengo una idea que me ronda la cabeza, verás, llevo tiempo dándole vueltas como se podría hacer para que la cámara de mi smartphone se convirtiera en una aplicación en la cual los caracteres que reconoce se copien automáticamente en el buscador de Google por ejemplo. Sería posible? Muchas gracias.

    Responder
    • Hola Eliseo, ese archivo tendrías que guardarlo en el directorio de datos de la aplicación seguido de /tesseract/ y es un archivo pesado porque contiene todo lo necesario para reconocer español; esto lo detallo en la sección ¿En el dispositivo o en la nube? del post.

      Un saludo

      Responder
  4. Hola, buenas tardes, cuando analiza la imagen, me devuelve caracteres aleatorios, por ejemplo le saco una foto al número 5 y me devuelve «A s d:», hay mucha luz y la imagen es de alta calidad.
    ¿Que podría estar pasando?

    Saludos

    Responder
  5. Buenos días.

    Estoy probando y cuando le paso una foto, me devuelve caracteres aleatorios, no reconoce bien el texto.

    Por que puede ser?. He probado con números y tampoco. Tengo el archivo del idioma en su sitio pero no hay manera.

    Un saludo.

    Responder
  6. hola

    nesecito reconocer tres datos numericos que se encuentran en un display de un equipo digital, ejemplo : como tres datos en pila en una calculadora , y pasarlos a unas cajas de texto , solo numeros, donde puedo encontrar documentacion para esto???

    Gracias

    Responder
  7. Hola,
    Buen artículo, pero no está nada clara la frase:
    «Para reconocer cada idioma es necesario descargar un fichero y guardarlo en el dispositivo. En nuestro caso se guardará en el directorio de datos de la aplicación seguido de /tesseract/»

    – ¿Qué directorio es ese?
    – ¿Cómo se guarda el fichero en ese directorio?
    – ¿Copiándolo en la carpeta del smartphone?
    – ¿Cómo se hace en una App distribuible? No puedo decir a los usuarios «copiad ese fichero en tal carpeta».
    – ¿Como se hace en un App distribuible?
    – ¿No hay manera de que los ficheros «traineddata» puedan estar en los recursos «raw» de la App?

    Muchas gracias!

    Responder

Deja un comentario

¿Necesitas una estimación?

Calcula ahora