jueves, 13 de marzo de 2014

Extracción de texto desde una imagen utilizando tesseract-ocr engine

Tesseract es probablemente el motor de OCR de fuente abierta más exacto disponible. En combinación con la Biblioteca de procesamiento Imagen Leptonica, puede leer una amplia variedad de formatos de imagen y los convierte a texto en más de 60 idiomas. Fue uno de los 3 mejores motores en el test de precisión de UNLV  en 1995. Entre 1995 y 2006 tuvo poco trabajo hecho en él, pero desde entonces se ha mejorado ampliamente por Google. Es liberado bajo la licencia Apache 2.0.

Fuente: https://github.com/tesseract-ocr/tesseract

A continuación, mediante una simple aplicación consola de java les mostrare paso a paso como hacer uso de este poderoso motor.

Contenido:

  1. Descargar la libreria.
  2. Estructura del proyecto en eclipse
  3. Escanear una imagen y definicion de la region a realizar la extraccion del texto.
  4. Desarrollo de la aplicacion.
  5. Ejecucion y verificacion de los resultados.

2. Estructura del proyecto en eclipse. Ver imagen a continuacion de como se debería ver tu proyecto.

3. Para mi ejemplo he escaneado el documento de identidad en mi país y he definido manualmente la región de extracción donde se encuentra el numero identificador. La región encerrada con el recuadro rojo, es la región a obtener mediante el motor tesseract.

4. Solo cree un archivo donde tengo un metodo principal y alli defino el lenguaje a utilizar, en mi caso español, creo un objeto Rectangle con las coordenadas de la región a realizar la extracción e imprimo por consola el texto procesado.

public class TesseractUtil {

 /**
  * Region
  */
 private static Rectangle DEFAULT_RECTANGLE_NUMERO_CEDULA_SIZE = new Rectangle(
   340, 118, 300, 60);

 private static String TYPE_DEFAULT_IMAGE = "jpg";

 private static String DEFAULT_LANGUAJE = "spa";

 public static void main(String[] args) throws IOException,
   TesseractException {
  File file = new File("C:\\Users\\usuario\\Pictures\\williams.jpg");
  System.out.println("Identificador: " + getIdentificadorCedula(file));
 }

 public static String getIdentificadorCedula(File imageFile)
   throws IOException, TesseractException {
  Tesseract1 instance = new Tesseract1(); // JNA Direct Mapping
  instance.setLanguage(DEFAULT_LANGUAJE);
  BufferedImage image = bufferedImage(imageFile);
  makeGray(image);
  String result = instance.doOCR(image,
    DEFAULT_RECTANGLE_NUMERO_CEDULA_SIZE);
  result = cleanIdentificadorCedula(result);
  return result;
 }

 public static BufferedImage bufferedImage(File file) throws IOException {
  return ImageIO.read(file);
 }

 public static String cleanIdentificadorCedula(String identificadorCedula) {
  String finalString = StringUtils.deleteWhitespace(identificadorCedula)
    .trim().toUpperCase();
  return finalString.replaceAll("[^\\d]", "");
 }

 public static BufferedImage cropImage(BufferedImage src, Rectangle rect) {
  BufferedImage dest = src.getSubimage(rect.x, rect.y, rect.width,
    rect.height);
  return dest;
 }

 public static void saveImage(String outputFolder, String filename,
   BufferedImage image, String type) throws IOException {
  File folder = new File(outputFolder);
  if (!folder.exists()) {
   folder.mkdir();
  }
  folder = new File(outputFolder);
  File save_path = new File(folder.getPath() + "\\" + filename + "."
    + TYPE_DEFAULT_IMAGE);
  ImageIO.write(image, type, save_path);
 }

 public static void makeGray(BufferedImage img) {
  for (int x = 0; x < img.getWidth(); ++x)
   for (int y = 0; y < img.getHeight(); ++y) {
    int rgb = img.getRGB(x, y);
    int r = (rgb >> 16) & 0xFF;
    int g = (rgb >> 8) & 0xFF;
    int b = (rgb & 0xFF);
    int gray = (r + g + b) / 3;
    img.setRGB(x, y, gray);
   }
 }

}

5. Salida por la consola:
Identificador: 55555555

37 comentarios:

  1. que tal tengo un problema con el codigo me podrias decir de donde sacaste esta metodo StringUtils.deleteWhitespace(identificadorCedula)

    ResponderEliminar
  2. Hola,

    podrías ocmpratir tu proyecto de eclipse, es que no logro configurar todos los paquetes del OCR en el proyecto que tengo. Mi correo es jesquerraferruzo@gmail.com

    ResponderEliminar
  3. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  4. Amigo disculpa pero solo reconoce numeros? intento con letras y no me retorna nada

    ResponderEliminar
  5. olvidalo ya logre hacer que me extrajera letras gracias por el ejemploe esta bastante bueno

    ResponderEliminar
    Respuestas
    1. que bueno amigo, influye también el lenguaje seleccionado; ingles, español... Saludos.

      Eliminar
  6. hola disculpa me ayudarías con tu aplicacion en eclipse estoy intentando desarrollar una apk y deseo saber como funciona esa libreria... gracias de antemano mi correo es carbel1990@gmail.com

    ResponderEliminar
  7. Buenas tardes. Podrías por favor enviarme el proyecto a mi correo. No logro descargar ni configurar la dll. Si me explicas mas detallado también me serviría.
    Muchas gracias. Este es mi correo: johan.bustos92@gmail.com

    ResponderEliminar
  8. Buenas tardes. Podrías por favor enviarme el proyecto a mi correo. No logro descargar ni configurar la dll. Si me explicas mas detallado también me serviría.
    Muchas gracias. Este es mi correo: johan.bustos92@gmail.com

    ResponderEliminar
  9. podrias facilitar el proyecto completo joseluis01011990@gmail.com

    ResponderEliminar
  10. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  11. Hola, disculpa la molestia, pero podrías ayudarme a añadir la librería Tesseract OCR, te lo agradecería bastante. O facilitándome tu proyecto, de cualquier forma gracias por el aporte.
    Mi correo es ricardomaciel117@gmail.com

    ResponderEliminar
  12. Me podrias ayudar con tu proyecto mi correo es aldogeova@•gmail.com por cierto muy buen aporte

    ResponderEliminar
  13. Hola amigo me podrías compartir el proyecto bernamc23@hotmail.com

    ResponderEliminar
  14. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  15. Hola buenos días, me podrias informar como la configuro en eclipse. gracias, este es mi correo castro_alonso@hotmail.com

    ResponderEliminar
  16. hola, buen aporte, pero podrias facilitarme tu proyecto para tomarlo de ejemplo gracias de antemano. yduque@uci.cu

    ResponderEliminar
  17. Muy buen aporte.
    Podrías compartir tu proyecto?
    El paquete actual no tiene los mismos archivos que tu proyecto.
    wtd000@hotmail.com

    ResponderEliminar
  18. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  19. Gracias por contestar.
    Te cuento que el proyecto que esta en github no coincide con el código y la foto que tienes aquí.

    Podriar decirme como hacer para que trabaje con letras pequeñas (como nuemero 11 - 12)? me funciona de 1000 pero con letras grandes solamente.

    ResponderEliminar
    Respuestas
    1. hola wtd000, el enlace que les coloque es un fork de un proyecto en github con las nuevas versiones de la librería; solamente modifique la versión de la dependencia que hace referencia a la librería y modifique el método para detectar el texto en un área de la imagen tal cual como explique en este articulo, puedes ver los cambios en este commit:

      https://github.com/ghwrivas/BasicTesseractExample/commit/fecdea2c3be8dc6e3b4112cc4c5c7cdbbcdb83ff .

      Este post es del año 2014 y hay nuevas versiones de la librería, por eso coloque el enlace al nuevo repositorio de github y puedan fijarse de ese proyecto.

      Con respecto a lo de las letras pequeñas no tengo idea, puede que se tenga que leer sobre la documentación del api.

      Eliminar
  20. Necesitas el lenguaje correcto de acuerdo a tu version del tess4j el mio es 3.05 te dejo el link https://github.com/tesseract-ocr/tesseract/wiki/Data-Files#data-files-for-version-304305

    ResponderEliminar
  21. Hola, gracias por el ejemplo
    Me da el siguiente error Exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.bridge.SLF4JBridgeHandler.removeHandlersForRootLogger()V
    at net.sourceforge.tess4j.util.LoggerConfig.loadConfig(Unknown Source)
    at net.sourceforge.tess4j.util.LoggHelper.toString(Unknown Source)
    at net.sourceforge.tess4j.util.LoadLibs.(Unknown Source)
    at net.sourceforge.tess4j.TessAPI1.(Unknown Source)
    at pruebatesseract.TesseractUtil.getIdentificadorCedula(TesseractUtil.java:36)
    at pruebatesseract.TesseractUtil.main(TesseractUtil.java:30) puedes ayudarme?

    ResponderEliminar
  22. Hola quisiera que me compartieras tu proyecto completo para guiarme en un caso similar que tengo.
    Gracias

    ResponderEliminar
  23. Hola....solo una pregunta...como sabes las cordenadas del rectangulo que quieres leer??
    Gracias

    ResponderEliminar
  24. joder tio eres genial

    ResponderEliminar