¿Cómo usar Tesseract en una aplicación de Android? ¿Hay buenos tutoriales?

El reconocimiento óptico de caracteres, generalmente abreviado a OCR , es la traducción mecánica o electrónica de imágenes escaneadas de texto escrito a mano, mecanografiado o impreso en texto codificado por máquina.
Image Deskew es el proceso de eliminar el sesgo de las imágenes (especialmente los mapas de bits creados con un escáner). La inclinación es un artefacto que puede ocurrir en las imágenes escaneadas debido a que la cámara está desalineada, imperfecciones en el escaneo o la superficie, o simplemente porque el papel no se colocó completamente plano cuando se escaneó.

Ahora, la mayor parte de la entrada u origen de datos ocurre en la Web, donde también se ha trasladado la mayor parte del procesamiento de formularios, es decir, OCR no ha estado de moda durante bastante tiempo. Sin embargo, la popularidad de los teléfonos inteligentes, combinada con cámaras incorporadas de alta calidad ha creado una nueva categoría de aplicaciones móviles, que se ha beneficiado enormemente de OCR. Tome Word-Lens (Quest Visual – Google Quest Visual) como ejemplo: una aplicación de traducción de realidad aumentada que intenta descubrir cuáles son las letras en una imagen y luego se ve en un diccionario, para eventualmente dibujar las palabras nuevamente en la pantalla en traducción.

¿En el dispositivo o en la nube?

Antes de decidirse por una biblioteca de OCR, uno debe decidir dónde debe llevarse a cabo el proceso de OCR: en el teléfono inteligente o en la nube. Cada enfoque tiene sus ventajas.
En el dispositivo, el OCR se puede realizar sin necesidad de una conexión a Internet y, en lugar de enviar una foto, que puede ser enorme (muchos teléfonos tienen ahora 8 o 12 cámaras Mega-Pixel), el texto es reconocido por un motor OCR integrado.
Sin embargo, las bibliotecas de OCR tienden a ser grandes, es decir, la aplicación móvil tendrá un tamaño considerable. Dependiendo de la cantidad de texto que necesita ser reconocido y la velocidad de transferencia de datos disponible, un servicio en la nube puede proporcionar el resultado más rápido. Un servicio en la nube se puede actualizar más fácilmente, pero la optimización individual (capacitación) de un motor de OCR puede funcionar mejor cuando se realiza localmente en el dispositivo.
¿Qué biblioteca de OCR elegir?

  • Wikipedia tiene una comparación “no exhaustiva” pero aún muy amplia del software de reconocimiento óptico de caracteres aquí: http: //en.wikipedia.org/wiki/ List_of_optical_character_recognition_software
  • Puede encontrar una comparación de algunos de los motores OCR más populares aquí: http://www.freewaregenius.com/2011/11/01/how-to-extract-text-from-images-a- compare-of- herramientas-ocr libres /
  • Comparación de software Linux OCR con un fuerte enfoque en la precisión: http://www.splitbrain.org/blog/2010-06/15-linux_ocr_software_comparison

Después de observar más de cerca todas las comparaciones, Tesseract se destaca. Proporciona una buena precisión, es de código abierto y con licencia de Apache, y tiene un amplio soporte de idiomas. Fue creado por HP y ahora lo desarrolla Google.

Además, dado que Tesseract es de código abierto y con licencia de Apache, podemos tomar el código fuente y transferirlo a la plataforma Android, o ponerlo en un servidor web para ejecutar nuestro propio servicio en la nube.

Un Tesseract es un objeto de cuatro dimensiones, al igual que un cubo es un objeto tridimensional. Un cuadrado tiene dos dimensiones. Puedes hacer un cubo de seis cuadrados. Un cubo tiene tres dimensiones. El tesseract se realiza de la misma manera, pero en cuatro dimensiones.

1. Tesseract

El motor Tesseract OCR fue desarrollado en Hewlett Packard Labs y actualmente está patrocinado por Google. Fue uno de los tres principales motores OCR en términos de precisión de caracteres en 1995. tesseract-ocr: un motor OCR que se desarrolló en HP Labs entre 1985 y 1995 … y ahora en Google. – Alojamiento de proyectos de Google
1.1. Ejecutar Tesseract localmente en una Mac
Al igual que con otras herramientas Unix y Linux, Homebrew (Redirigir …) es la forma más fácil y flexible de instalar las herramientas UNIX que Apple no incluyó con OS X. Una vez que se instala Homebrew (Homebrew / homebrew), se puede instalar Tesseract en OS X tan fácil como:
$ brew instalar tesseract
Una vez instalado,
$ brew info tesseract devolverá algo como esto:

tesseract 3.00
tesseract-ocr: un motor de OCR que se desarrolló en HP Labs entre 1985 y 1995 … y ahora en Google. – Alojamiento de proyectos de Google
Depende de: libtiff
/usr/local/Cellar/tesseract/3.00 (316 archivos, 11M)
Tesseract es un motor de reconocimiento óptico de caracteres (OCR).
La forma más fácil de usarlo es convertir la fuente a un tiff en escala de grises:
`convert source.png -type Grayscale terre_input.tif`
luego ejecute tesseract:
`tesseract terre_input.tif output`
Página en github.com

Tesseract no viene con una GUI y en su lugar se ejecuta desde una interfaz de línea de comandos. Para OCR una imagen codificada TIFF ubicada en su escritorio, haría algo como esto:
$ tesseract ~ / Desktop / cox.tiff ~ / Desktop / cox
Usando la imagen de abajo, Tesseract escribió con perfecta precisión el texto resultante en
~ / Desktop / cox.txt
Hay al menos dos proyectos, que proporcionan una interfaz gráfica de usuario para Tesseract en OS X

  1. TesseractGUI, un cliente nativo de OSX: Tesseract GUI para Mac OS X
  2. VietOCR, un cliente Java: VietOCR

TesseractGUI, un cliente OSX nativo para Tesseract
VietOCR, un cliente Java para Tesseract
1.2. Ejecutar Tesseract como un servicio podría en un servidor Linux
Una de las formas más rápidas y fáciles de implementar Tesseract como un servicio web, utiliza Tornado (servidor web Tornado – documentación de Tornado 4.0.2), un servidor web sin bloqueo Python de código abierto (con licencia de Apache). Dado que Tesseract acepta imágenes codificadas en TIFF, pero nuestro servicio en la nube debería funcionar con el formato de imagen JPEG más popular, también necesitamos implementar la biblioteca gratuita de imágenes de Python (Python Imaging Library (PIL)), los términos de la licencia están aquí: Licencia de software
La implementación en el servidor Ubuntu 11.10 de 64 bits se parece a esto:
sudo apt-get install python-tornado sudo apt-get install python-imaging sudo apt-get install tesseract-ocr1.2.1. El HTTP Server-Script para el puerto 8080

#! / usr / bin / env python
importar tornado.httpserver
importar tornado.ioloop
importar tornado.web
importar pprint
importar imagen
desde tesseract import image_to_string
importar StringIO
importar os.path
uuid de importación

clase MainHandler (tornado.web.RequestHandler):
def get (self):
self.write (‘


 ') 

publicación de def (auto):
self.set_header ("Content-Type", "text / html")
self.write ("") # crea un archivo de identificación único
tempname = str (uuid.uuid4 ()) + ".jpg"
myimg = Image.open (StringIO.StringIO (self.request.files.items () [0] [1] [0 ['body']))
myfilename = os.path.join (os.path.dirname (__ file __), "static", tempname);

# guardar imagen en archivo como JPEG
myimg.save (myfilename)

# hacer OCR, imprimir resultado
self.write (image_to_string (myimg))
self.write ("")

configuración = {
"static_path": os.path.join (os.path.dirname (__ file__), "static"),
}

application = tornado.web.Application ([
(r "/", MainHandler),
], ** ajustes)

if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer (aplicación)
http_server.listen (8080)
tornado.ioloop.IOLoop.instance (). start ()
El servidor recibe un archivo de imagen JPEG y lo almacena localmente en el directorio ./static, antes de llamar a image_to_string, que se define en el script de Python a continuación:
1.2.2. implementación de la función image_to_string

#! / usr / bin / env python

tesseract_cmd = 'tesseract'

importar imagen
importar StringIO
subproceso de importación
sistema de importación
importar os

__all__ = ['image_to_string']

def run_tesseract (input_filename, output_filename_base, lang = None, boxes = False):
'' '
ejecuta el comando:
`tesseract_cmd`` input_filename` `output_filename_base`

devuelve el estado de salida de tesseract, así como la salida stderr de tesseract

'' '

comando = [tesseract_cmd, input_filename, output_filename_base]

si lang no es Ninguno:
comando + = ['-l', lang]

si cajas:
comando + = ['batch.nochop', 'makebox']

proc = subprocess.Popen (comando,
stderr = subproceso.PIPE)
return (proc.wait (), proc.stderr.read ())

limpieza de def (nombre de archivo):
'' 'intenta eliminar el nombre de archivo dado. Ignora archivos inexistentes '' '
tratar:
os.remove (nombre de archivo)
excepto OSError:
pasar

def get_errors (cadena_error):
'' '
devuelve todas las líneas en la cadena_error que comienzan con la cadena "error"

'' '

líneas = error_string.splitlines ()
error_lines = tupla (línea por línea en líneas si line.find ('Error')> = 0)
if len (error_lines)> 0:
return '\ n'.join (líneas_error)
más:
return error_string.strip ()

def tempnam ():
'' 'devuelve un nombre de archivo temporal' ''

# evita que os.tmpname imprima un error ...
stderr = sys.stderr
tratar:
sys.stderr = StringIO.StringIO ()
return os.tempnam (Ninguno, 'tess_')
finalmente:
sys.stderr = stderr

clase TesseractError (Excepción):
def __init __ (self, estado, mensaje):
self.status = estado
self.message = mensaje
self.args = (estado, mensaje)

def image_to_string (image, lang = None, boxes = False):
'' '
Ejecuta tesseract en la imagen especificada. Primero, la imagen se escribe en el disco,
y luego se ejecuta el comando tesseract en la imagen. El resultado de Resseract es
leer, y los archivos temporales se borran.

'' '

input_file_name = '% s.bmp'% tempnam ()
output_file_name_base = tempnam ()
si no cajas:
output_file_name = '% s.txt'% output_file_name_base
más:
output_file_name = '% s.box'% output_file_name_base
tratar:
image.save (input_file_name)
status, error_string = run_tesseract (input_file_name,
output_file_name_base,
lang = lang,
cajas = cajas)
si estado:
errores = get_errors (cadena_error)
elevar TesseractError (estado, errores)
f = archivo (nombre_archivo_salida)
tratar:
return f.read (). strip ()
finalmente:
f.close ()
finalmente:
limpieza (input_file_name)
limpieza (nombre_archivo_salida)

if __name__ == '__main__':
si len (sys.argv) == 2:
filename = sys.argv [1]
tratar:
image = Image.open (nombre de archivo)
excepto IOError:
sys.stderr.write ('ERROR: No se pudo abrir el archivo "% s" \ n'% nombrearchivo)
salida (1)
print image_to_string (imagen)
elif len (sys.argv) == 4 y sys.argv [1] == '-l':
lang = sys.argv [2]
filename = sys.argv [3]
tratar:
image = Image.open (nombre de archivo)
excepto IOError:
sys.stderr.write ('ERROR: No se pudo abrir el archivo "% s" \ n'% nombrearchivo)
salida (1)
print image_to_string (image, lang = lang)
más:
sys.stderr.write ('Uso: python tesseract.py [-l idioma] input_file \ n')
salida (2)
1.2.3 El servicio desplegar / iniciar script

descripción "OCR WebService"

comenzar en el nivel de ejecución [2345]
detenerse en el nivel de ejecución [! 2345]

guión preinicio
mkdir / tmp / ocr

mkdir / tmp / ocr / static

cp /usr/share/ocr/*.py / tmp / ocr

fin de guión
exec /tmp/ocr/tesserver.py
Una vez iniciado el servicio, se puede acceder a él a través de un navegador web como se muestra aquí: Página en techcasita.com:8080 Actualmente estoy ejecutando tesseract 3.01 en Ubuntu Linux 11.10 de 64 bits, tenga cuidado, se ejecuta en un Intel Atom CPU 330 @ 1.60GHz, 4 núcleos (normalmente se encuentra en netbooks) El resultado codificado en HTML se parece a esto:

Contáctenos
www. Cox Communications: el sitio web oficial
Servicio al cliente 760-788-9000
Reparación 76O - 788 ~ 71O0
Teléfono de Cox 888-222-7743
1.3 Acceso al servicio en la nube de Tesseract desde Android
OCRTaskActivity a continuación utiliza AsyncTask incorporado en Android , así como la biblioteca HttpComponent de Apache Software Foundation, HttpClient 4.1.2, disponible aquí: Descripción general del cliente HttpClient OCRTaskActivity espera que la imagen pase como Intent Extra "ByteArray" de tipo ByteArray. El resultado de OCR se devuelve a la Actividad de llamada como OCR_TEXT, como se muestra aquí:
setResult (Activity.RESULT_OK, getIntent (). putExtra ("OCR_TEXT", resultado));

importar android.app.Activity;
importar android.graphics.BitmapFactory;
importar android.os.AsyncTask;
importar android.os.Bundle;
importar android.util.Log;
importar android.view.View;
importar android.widget.ImageView;
importar android.widget.ProgressBar;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.BufferedReader;
import java.io.InputStreamReader;

OCRTaskActivity de clase pública extiende la actividad {
Cadena estática privada LOG_TAG = OCRAsyncTaskActivity.class.getSimpleName ();
Cadena estática privada [] URL_STRINGS = {"Página en techcasita.com:8080"};

byte privado [] mBA;
ProgressBar privado mProgressBar;

@Anular
public void onCreate (paquete final salvadoInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.ocr);
mBA = getIntent (). getExtras (). getByteArray ("ByteArray");
ImageView iv = (ImageView) findViewById (Página en r.id.ImageView);
iv.setImageBitmap (BitmapFactory.decodeByteArray (mBA, 0, mBA.length));
mProgressBar = (ProgressBar) findViewById (Página en r.id.progressBar);
OCRTask task = new OCRTask ();
task.execute (URL_STRINGS);
}

clase privada OCRTask extiende AsyncTask {
@Anular
String protegido doInBackground (cadena final ... urls) {
Respuesta de cadena = "";
for (String url: urls) {
tratar {
respuesta = executeMultipartPost (url, mBA);
Log.v (LOG_TAG, "Respuesta:" + respuesta);
descanso;
} catch (Throwable ex) {
Log.e (LOG_TAG, "error:" + ex.getMessage ());
}
}
respuesta de retorno;
}

@Anular
Void protegido en PostExecute (resultado final de la cadena) {
mProgressBar.setVisibility (View.GONE);
setResult (Activity.RESULT_OK, getIntent (). putExtra ("OCR_TEXT", resultado));
terminar();
}
}

La cadena privada executeMultipartPost (cadena final stringUrl, byte final [] bm) arroja la excepción {
HttpClient httpClient = new DefaultHttpClient ();
HttpPost postRequest = new HttpPost (stringUrl);
ByteArrayBody bab = nuevo ByteArrayBody (bm, "the_image.jpg");
MultipartEntity reqEntity = new MultipartEntity (HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart ("subido", bab);
reqEntity.addPart ("nombre", nuevo StringBody ("el_archivo"));
postRequest.setEntity (reqEntity);
Respuesta de HttpResponse = httpClient.execute (postRequest);
BufferedReader reader = new BufferedReader (nuevo InputStreamReader (response.getEntity (). GetContent (), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder ();

while ((sResponse = reader.readLine ())! = null) {
s = s.append (sResponse) .append ('\ n');
}
int i = s.indexOf ("cuerpo");
int j = s.lastIndexOf ("cuerpo");
devuelve la subcadena (i + 5, j - 2);
}
}
Esta aplicación de Android de muestra tiene una Actividad que envía una pequeña imagen JPEG al Servicio en la Nube, que ejecuta el motor Tesseract OCR.
1.4. Creación de una biblioteca de Android nativa de Tesseract para que se incluya con una aplicación de Android
Este enfoque permite que una aplicación de Android realice OCR incluso sin una conexión de red. Es decir, el motor OCR está a bordo. Actualmente hay dos bases de origen para comenzar, el proyecto Tesseract original aquí:

  1. Tesseract Tools para Android es un conjunto de API de Android y archivos de compilación para las bibliotecas de procesamiento de imágenes Tesseract OCR y Leptonica: svn checkout tesseract-android-tools - Revisión 6: / trunk tesseract-android-tools
  2. Una bifurcación de Tesseract Tools para Android (tesseract-android-tools) que agrega algunas funciones adicionales: git clone git: //github.com/rmtheis/tess-two.git

... Fui con la opción 2.
1.4.1. Construyendo la lib nativa
Cada proyecto se puede compilar con los mismos pasos de compilación (ver más abajo) y ninguno funciona con NDK r7 de Android. Sin embargo, volver a NDK r6b resolvió ese problema. Aquí están los pasos de compilación. Lleva un tiempo, incluso en una máquina rápida.

cd / tess-two
export TESSERACT_PATH = $ {PWD} /external/tesseract-3.01
exportar LEPTONICA_PATH = $ {PWD} /external/leptonica-1.68
exportar LIBJPEG_PATH = $ {PWD} / external / libjpeg
ndk-build
proyecto de actualización de Android –path.
liberación de hormigas
Los pasos de compilación crean las bibliotecas nativas en los directorios libs / armabi y libs / armabi-v7a .
El proyecto tess-two ahora se puede incluir como un proyecto de biblioteca en un proyecto de Android y con la capa JNI en su lugar, llamar a la biblioteca nativa de OCR ahora se ve así:
JNI y bibliotecas nativas
1.4.2. Desarrollar una aplicación de Android simple con capacidades OCR incorporadas

TessBaseAPI baseApi = new TessBaseAPI ();
baseApi.init (DATA_PATH, LANG);
baseApi.setImage (mapa de bits);
Cadena reconocidaTexto = baseApi.getUTF8Text ();
baseApi.end ();
...
1.4.2.1. Bibliotecas / Datos entrenados / Tamaño de la aplicación
Las bibliotecas nativas tienen aproximadamente 3 MBytes de tamaño. Además, se necesita un idioma y una fuente dependiendo de los archivos de recursos de capacitación.
El archivo eng.traineddata (por ejemplo, disponible con la versión de escritorio de Tesseract) se coloca en la carpeta principal assers / tessdata de Android y se implementa con la aplicación, agregando otros 2 MBytes a la aplicación. Sin embargo, debido a la compresión, la aplicación de Android descargable real es "solo" aproximadamente 4,1 MBytes.
Durante el primer inicio de la aplicación, el archivo de recursos eng.traineddata se copia en la tarjeta SD del teléfono.
El método ocr () para la aplicación de muestra puede verse así:

vacío protegido ocr () {

Opciones de BitmapFactory.Options = new BitmapFactory.Options ();
opciones.inSampleSize = 2;
Mapa de bits mapa de bits = BitmapFactory.decodeFile (IMAGE_PATH, opciones);

tratar {
ExifInterface exif = new ExifInterface (IMAGE_PATH);
int exifOrientation = exif.getAttributeInt (ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

Log.v (LOG_TAG, "Oriente:" + exifOrientation);

int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotar = 90;
descanso;
caso ExifInterface.ORIENTATION_ROTATE_180:
rotar = 180;
descanso;
caso ExifInterface.ORIENTATION_ROTATE_270:
rotar = 270;
descanso;
}

Log.v (LOG_TAG, "Rotación:" + rotar);

if (rotar! = 0) {

// Obtención de ancho y alto de la imagen dada.
int w = bitmap.getWidth ();
int h = bitmap.getHeight ();

// Configuración pre rotación
Matrix mtx = nueva matriz ();
mtx.preRotate (rotar);

// Mapa de bits giratorio
mapa de bits = Bitmap.createBitmap (mapa de bits, 0, 0, w, h, mtx, falso);
// tesseract req. ARGB_8888
bitmap = bitmap.copy (Bitmap.Config.ARGB_8888, verdadero);
}

} catch (IOException e) {
Log.e (LOG_TAG, "Falló la rotación o la cobertura:" + e.toString ());
}

ImageView iv = (ImageView) findViewById (Página en r.id.image);
iv.setImageBitmap (mapa de bits);
iv.setVisibility (View.VISIBLE);

Log.v (LOG_TAG, "Antes de baseApi");

TessBaseAPI baseApi = new TessBaseAPI ();
baseApi.setDebug (verdadero);
baseApi.init (DATA_PATH, LANG);
baseApi.setImage (mapa de bits);
Cadena reconocidaTexto = baseApi.getUTF8Text ();
baseApi.end ();

Log.v (LOG_TAG, "Resultado OCR:" + RecognText);

// limpiar y mostrar
if (LANG.equalsIgnoreCase ("eng")) {
RecognText = RecognText.replaceAll ("[^ a-zA-Z0-9] +", "");
}
if (RecognizeText.length ()! = 0) {
((TextView) findViewById (Página en r.id.field)). SetText (shownText.trim ());
}
}
OCR en Android
La popularidad de los teléfonos inteligentes, combinada con cámaras incorporadas de alta calidad ha creado una nueva categoría de aplicaciones móviles, que se ha beneficiado enormemente de OCR.
OCR es una tecnología muy madura con una amplia gama de bibliotecas disponibles para elegir. Existen soluciones de Apache y BSD con licencia, rápidas y precisas disponibles de la comunidad de código abierto. He echado un vistazo más de cerca a Tesseract, desarrollado por HP y Google.
Tesseract se puede utilizar para crear una aplicación de escritorio, un servicio en la nube e incluso integrarse en una aplicación móvil de Android, realizando un OCR integrado. Las tres variaciones de OCR con la biblioteca Tesseract se han demostrado anteriormente.
Sin embargo, al centrarnos en las aplicaciones móviles, quedó muy claro que incluso en teléfonos con una cámara de 5MP, la precisión de los resultados todavía varía mucho, dependiendo de las condiciones de iluminación, la fuente y los tamaños de fuente, así como el artefacto circundante.
Al igual que con la aplicación TeleForm, incluso los mejores motores de OCR funcionan puramente, si la imagen de entrada no se ha preparado correctamente. Para que el OCR funcione en un dispositivo móvil, no importa si el OCR eventualmente se ejecutará a bordo o en la nube, se necesita mucho tiempo de desarrollo para entrenar el motor, pero aún más importante, para seleccionar y preparar las áreas de imagen que se proporcionará como entrada para el motor de OCR: se tratará del preprocesamiento.
Esto muestra mi aplicación Capture OCR de Android-OCR de muestra (con el motor Tesseract OCR incorporado), después de que realizó el OCR en una foto recién tomada de la portada de un libro.

¿Cómo uso Tesseract en una aplicación de Android? ¿Hay buenos tutoriales?

Después de la frustración y la pérdida de tiempo, finalmente logré usar el código provisto en este tutorial: Aplicación simple de Android OCR con el tutorial de Tesseract. Aquí puede encontrar una buena guía paso a paso para usar tesseract.

Hay un pequeño paso para mi aplicación, pero uno enorme para mí;

Buena suerte para ti también.

Creación de la aplicación OCR de Android usando Tesseract en el tutorial de Android Studio

Tesseract con andoird y gradle (Ejemplo)

Tutorial Tesseract OCR (opcional)

O puedes usar esto también
http://www.kaustubhraghavan.com/