¿Software para OCR por lotes de múltiples archivos de imagen a múltiples archivos de texto usando Tesseract?

Actualmente estoy usando tesseract para OCR algunos archivos jpeg a archivos txt (Ubuntu 16.04). Por lo general, esto es ~ 500 archivos en un directorio.

Sé que puedo hacer esto creando un archivo de texto con todos los nombres de archivo (savedlist.txt), y luego hago:

tesseract savedlist.txt output.txt

sin embargo, output.txt es un solo archivo con todos los resultados de OCR.

Lo que necesito es poder guardar los resultados de ocr en archivos txt individuales con el mismo nombre de archivo que el archivo de imagen original. Por ejemplo:

archivo de entrada: image456.jpeg
archivo de salida: image456.txt

Me doy cuenta de que las versiones más recientes de ABBYY FineReader pueden hacer esto, pero esto es para un proyecto gratuito, por lo que estoy buscando una solución gratuita o económica (menos de $ 20).

Lo que estoy buscando es un front-end de software o una GUI que use tesseract que pueda procesar por lotes o como este, todo en una sola operación por lotes.

Una solución de línea de comando para hacer esto también estaría bien. Si está fuera de tema aquí, puedo preguntar esto en otro sitio, pero no quería publicar en dos sitios al mismo tiempo.

@Izzy En caso de que haya una solución de programación en lugar de una de software, ¿habría algún problema para publicar también esta pregunta en otro sitio? ¿Alguna recomendación (SuperUser u otra)?
Si por programación te refieres a secuencias de comandos, SU podría encajar. La programación normalmente se encuentra en SO. Si se asegura de que la pregunta tenga un enfoque diferente (por lo que, de hecho, es una pregunta diferente; por ejemplo, aquí se solicita software existente, allí se solicitan soluciones de secuencias de comandos), no debería haber ningún problema.

Respuestas (4)

En bash:

for file in FILES ; do tesseract "$file" "${file%%.*}" ; done

donde en lugar de FILES, debe escribir una serie de nombres de archivo como image456.jpeg image457.jpeg image458.jpeg, o un patrón global como *.jpeg, o cualquier combinación de este tipo.

Ya veo, pero ¿cómo manejar el cambio de extensión? Los archivos de salida deben tener la extensión .txt. ARCHIVOS será una lista de nombres de archivos.
@ user3169 Tesseract agrega la extensión ".txt" automáticamente, la última vez que lo verifiqué. Si dices tesseract img.jpg foo.txt, entonces realmente obtienes foo.txt.txt. Por lo general, es molesto, pero aquí es conveniente.
Intenté esto e hizo bien el procesamiento de tesseract, pero los resultados aún estaban todos en un archivo de texto (FILES.txt). Su ejemplo no parece cambiar el hecho de que Tesseract solo admite una salida de archivo único, a menos que me esté perdiendo algo.
@ user3169 Creo que puede haber entendido mal mi ejemplo. Los caracteres literales FILESno deberían aparecer en su comando. ¿Qué comando usaste, exactamente?
No, simplemente nombré mi lista "ARCHIVOS" para seguir tu ejemplo. Mi comando: para archivo en ARCHIVOS; hacer tesseract "$archivo" "$archivo" ; hecho. Supongo que "$archivo" es el nombre del archivo de imagen extraído de ARCHIVO, ya que se realizó la función ocr. Pero entonces, ¿dónde está el archivo de texto de salida individual? Todo lo que obtuve fue un ARCHIVO.txt con todos los resultados.
@user3169 No use un archivo de texto que contenga nombres de archivo. Proporcione los nombres de archivo en la línea de comando en su lugar. Entonces, en lugar de los caracteres literales FILES, escriba algo como image456.jpeg image457.jpeg image458.jpego *.jpeg, para que el comando final se vea como for file in *.jpeg ; do tesseract "$file" "$file" ; done.
Veo. Estaba tratando de seguir el método original usando la lista de archivos. Probé su último ejemplo en el directorio mismo, y ahora obtengo un archivo de salida para cada archivo de entrada. Gracias. El único problema ahora es que los archivos de salida son .jpeg.txt mientras que necesito que sean solo .txt. Dado que dicho directorio puede tener más de 500 archivos de salida, ¿hay alguna forma (ya sea en Windows o Ubuntu) donde pueda cambiar todo el nombre de archivo.jpeg.txt a nombre de archivo.txt?
Olvídate de mi última pregunta. El comando de cambio de nombre de DOS debería funcionar bien. Mañana pruebo todo el proceso.
Gracias por quedarte conmigo en esto. Finalmente tuve éxito, aunque tuve que usar pyrename para cambiar las extensiones. Creo que su respuesta está bien si explica un poco que los archivos están en un directorio y no los nombres de los archivos en una lista. También hice esta pregunta en stackoverflow: cómo procesar lotes de múltiples archivos de imagen OCR en múltiples archivos de texto usando Tesseract . Dado que se trataba de una solución de secuencias de comandos, sería más apropiado responder allí. Elija cualquiera de los dos, luego aceptaré su respuesta.
@ user3169 Aquí probablemente esté bien. También agregué un poco de vudú de expansión de parámetros para cortar automáticamente la extensión del archivo de entrada.
Parece ser mejor usar -jla opción y dividir la cantidad de subprocesos de la CPU entre tres, la cantidad de subprocesos utilizados por tesseract. Por ejemplo, supongamos que la máquina tiene 40 núcleos de CPU, entonces puede ejecutar el comando anterior contesseract -j 13 ...
¿Por qué usas "${file%%.*}"? Para mí no funcionó (seguía sobrescribiendo en un solo archivo). Quitar uno de los %letreros ayudó.
@sup Supongo que estás usando un shell diferente. En Bash, x=foo.jpg; echo "${x%%.*}"imprime foo, según lo previsto.
Windows (dentro de un archivo por lotes):for %%d in (*.jpg) do "C:\...\tesseract.exe" %%d %%d

Hay otra solución, que requiere un poco más de análisis.

Necesitaba manejar una buena cantidad de archivos y tomar para cada uno el nivel de confianza de cada palabra encontrada; el manejo de archivos uno por uno fue muy lento.

Su publicación me dio la ruta correcta: use un archivo que contenga su lista y envíe el resultado a otro archivo, pero no use el archivo TSV o TXt; no están divididos ni ordenados por archivo.

Utilice HOCR en su lugar; es HTML simple en el que puede navegar programáticamente:

lista.txt:

SAMPLE-000.png
SAMPLE-001.png
SAMPLE-002.png

Línea de comando :

tesseract list.txt list hocr

Salida de muestra (parte de, para facilitar la lectura); lista.hocr :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title></title>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  <meta name='ocr-system' content='tesseract 4.1.0' />
  <meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
 </head>
 <body>
  <div class='ocr_page' id='page_1' title='image "SAMPLE-000.png"; bbox 0 0 3508 2592; ppageno 0'>
   <div class='ocr_carea' id='block_1_1' title="bbox 3283 1170 3313 1477">
    <p class='ocr_par' id='par_1_1' lang='eng' title="bbox 3283 1170 3313 1477">
     <span class='ocr_caption' id='line_1_1' title="bbox 3283 1170 3313 1477; baseline -307 0; x_size 39.714287; x_descenders 9.9285717; x_ascenders 9.9285717">
      <span class='ocrx_word' id='word_1_1' title='bbox 3284 1170 3313 1220; x_wconf 94'>EP</span>
      ( ... )
     </span>
    </p>
    ( ... ) 
   </div>
  </div>
  <div class='ocr_page' id='page_2' title='image "SAMPLE-001.png"; bbox 0 0 2592 3508; ppageno 1'>
   <div class='ocr_carea' id='block_2_1' title="bbox 792 194 1861 225">
    <p class='ocr_par' id='par_2_1' lang='eng' title="bbox 792 194 1861 225">
     <span class='ocr_header' id='line_2_1' title="bbox 792 194 1861 225; baseline 0.006 -4; x_size 39.866665; x_descenders 9.9666662; x_ascenders 9.9666662">
      <span class='ocrx_word' id='word_2_1' title='bbox 792 194 828 221; x_wconf 96'>17</span>
      ( ... ) 
     </span>
    </p>
   </div>
   ( ... )    
  </div>
 </body>
</html>

Puede notar algunos atributos interesantes en el marcado:

  • title='imagen "MUESTRA-000.png"; bbox 0 0 3508 2592; página 0'
  • x_wconf que parece representar confianza

etc. "Solo" tiene que analizarlo con su herramienta favorita.

Es un poco tarde para usted, pero tengo el mismo problema y noté que, si bien tesseract solo genera un archivo de texto, cada salida está separada por un carácter de alimentación de formulario (0x0C).

Puede agregar el argumento -c page_separator=''que debería encargarse de eso.
gracias, pero eso no fue un problema, estaba respondiendo a su pregunta. Puede dividir el archivo en múltiplos buscando el separador de alimentación de formulario.

Es más fácil de lo que se describe aquí. Piense en una situación más difícil en la que solo tiene los archivos en una carpeta y desea extraer los textos y guardarlos en una salida de archivo csv.

Simplemente visite mi repositorio de github en https://github.com/aneendo/Image_to_Text y ejecute el archivo main.py