
Te puedo asegurar que una de las cosas que más me saca de quicio es que alguien me pase una captura de pantalla en lugar del texto directamente. Todos lo hemos sufrido. Llega un mensaje al chat del trabajo, al grupo de Telegram o al correo, y en lugar de un texto que puedas copiar y pegar, te encuentras con una imagen. Y claro, tienes que ponerte a escribir manualmente todo lo que ves ahí, con el riesgo de equivocarte y el tiempo que se pierde.
Pero esto no es solo una cuestión de pereza ajena. También tiene que ver con nuestra propia productividad. A mí me pasó hace unas semanas, cuando empecé a hacer capturas de pantalla de los resultados de mis entrenamientos de running para pasárselas a mi agente Hermes. En lugar de dictarle todos los datos manualmente, que era un coñazo, hacía una captura rápida y se la pasaba. La cuestión es que él necesitaba el texto, no la imagen, así que me puse a buscar una solución que combinara lo mejor del OCR tradicional con la inteligencia artificial para conseguir buenos resultados.
Y de ahí nació todo esto que te voy a contar en el episodio de hoy. Una combinación de ImageMagick para preprocesar la imagen, Tesseract para el OCR y un modelo de lenguaje local, en este caso Llama 3.2, para corregir los errores y darle formato al resultado. He creado un script en Python que automatiza todo el proceso y que además es capaz de detectar el tipo de contenido al que se enfrenta. ¿Te parece interesante? Pues vamos allá.
El problema de las capturas de pantalla
¿Cuántas veces te ha pasado que recibes una imagen con información que necesitas digitalizar? Puede ser una captura de pantalla de una conversación, un PDF escaneado, un documento fotografiado con el móvil o incluso una tabla con datos de una web. En todas estas situaciones, el texto no es seleccionable, no se puede copiar y tienes que transcribirlo a mano.
Hasta ahora, mi postura era clara: si quieres que haga algo con tu información, dámela en texto. Pero la realidad es que la gente no va a cambiar sus hábitos, y cada vez es más común compartir información en formato imagen. Así que, en lugar de luchar contra ello, decidí buscar una solución tecnológica que me permitiera extraer ese texto de forma fiable.
La solución pasa por el OCR (Optical Character Recognition), una tecnología que lleva décadas entre nosotros pero que ha evolucionado muchísimo. En Linux tenemos herramientas potentes y, lo mejor de todo, gratuitas y de código abierto. El problema es que el OCR por sí solo no es perfecto, especialmente cuando las imágenes no están en condiciones óptimas. Y aquí es donde entra la inteligencia artificial para darle un empujón al resultado.
El pipeline completo: de la imagen al texto limpio
Antes de meterme en detalles técnicos, déjame explicarte el flujo completo que he diseñado. Es un proceso en cuatro fases:
- Captura o recepción de la imagen — haces una captura de pantalla o recibes un archivo de imagen
- Preprocesamiento con ImageMagick — preparas la imagen para que el OCR funcione mejor
- OCR con Tesseract — extraes el texto de la imagen
- Corrección con IA — pasas el texto por un modelo de lenguaje para limpiar errores y dar formato
Cada una de estas fases tiene su importancia, pero te diría que las dos que marcan la diferencia son el preprocesamiento y la corrección con IA. Sin ellas, el resultado es mediocre. Con ellas, el resultado es sorprendentemente bueno.
Captura de imagen en Linux
Lo primero es obtener la imagen. Si ya te la han pasado, no tienes que hacer nada. Pero si necesitas capturar tu propia pantalla, en Linux tienes varias opciones.
En mi caso, como estoy usando Wayland, he tenido que buscar alternativas a las herramientas clásicas de X11. Pero no te preocupes, porque tanto para Wayland como para X11 tienes opciones de sobra:
- ImageMagick (
import) — la herramienta clásica, funciona en X11 grim— el estándar en Wayland, ultrarrápido y sencilloslurp— para seleccionar regiones en Wayland, complementa a grimscrot— otra opción para X11, muy ligeramaim— más moderna, con opciones de retardo y selección
La cuestión es que da igual cuál uses. El pipeline que te voy a contar funciona con cualquier imagen que le pases, ya sea una captura de pantalla, una foto de un documento o un PDF escaneado.
Preprocesamiento con ImageMagick: el secreto del éxito
Y aquí llegamos al punto crítico. Si le pasas una imagen directamente a Tesseract, el resultado va a tener errores. Muchos errores. He llegado a medir tasas de error de hasta el 30% en capturas de pantalla sin procesar. ¿El motivo? Tesseract funciona mucho mejor con imágenes en blanco y negro de alto contraste, sin ruido y con el texto perfectamente alineado.
ImageMagick, en su versión 7 (que es la que uso ahora), se maneja con el comando magick. Ha sido un cambio importante respecto a la versión 6, donde se usaba convert. Si tienes Ubuntu 25.10 o una versión reciente, es muy probable que ya tengas ImageMagick 7 instalado. Si no, puedes instalarlo fácilmente con sudo apt install imagemagick o compilarlo desde fuente si necesitas las últimas funcionalidades.
Las operaciones de preprocesamiento que he encontrado más útiles son estas:
Colorspace Gray
Eliminar el color es el primer paso. El color es ruido para Tesseract. Con -colorspace gray conviertes la imagen a escala de grises, reduciendo la información a procesar y eliminando las distracciones cromáticas.
magick input.png -colorspace gray output.png
Normalize
Mejora el contraste de la imagen. Si tienes una captura con fondos degradados o iluminación desigual, -normalize ajusta los niveles de blanco y negro para que el texto destaque más.
magick input.png -colorspace gray -normalize output.png
Threshold
Convierte la imagen a blanco y negro puro. Es una operación brutal que elimina cualquier matiz de gris. El parámetro es el porcentaje de umbral. Un 50% suele funcionar bien para la mayoría de los casos, pero si el texto es muy claro o muy oscuro, puedes ajustarlo.
magick input.png -colorspace gray -normalize -threshold 50% output.png
Deskew
Endereza el texto. Si la imagen está ligeramente torcida, -deskew 40% la endereza automáticamente. Esto es especialmente útil para fotos de documentos hechas con el móvil.
magick input.png -deskew 40% -threshold 50% output.png
Sharpen
Afilia los bordes de las letras. Si el texto es borroso o tiene anti-aliasing (el suavizado de bordes típico de las capturas de pantalla modernas), -sharpen 0x1 ayuda a que los caracteres se distingan mejor.
magick input.png -sharpen 0x1 -threshold 50% output.png
La clave está en combinar estas operaciones en un pipeline que se ajuste al tipo de imagen que tengas. No es lo mismo una captura de pantalla de una terminal (texto blanco sobre fondo negro, nítido) que una foto de un documento impreso (fondo amarillento, texto borroso, posiblemente torcido).
Para capturas de pantalla de terminal, por ejemplo, mi pipeline es muy sencillo:
magick captura.png -colorspace gray -negate -threshold 40% output.png
El -negate invierte los colores, porque el texto blanco sobre fondo negro hay que pasarlo a texto negro sobre fondo blanco para que Tesseract lo procese bien.
Para fotos de documentos, el pipeline es más elaborado:
magick foto.jpg -colorspace gray -normalize -deskew 40% -sharpen 0x1 -threshold 55% output.png
La diferencia entre usar un pipeline adecuado y no hacerlo es abismal. Te lo digo por experiencia. He pasado de tasas de error del 30% a menos del 2% simplemente con un buen preprocesamiento.
Tesseract: el corazón del OCR
Tesseract es el motor de OCR de código abierto más conocido y utilizado. Originalmente fue desarrollado por Hewlett-Packard y luego pasó a ser mantenido por Google. La versión actual, Tesseract 5, incluye un motor de reconocimiento basado en redes neuronales LSTM que ofrece resultados muy superiores a las versiones anteriores.
La instalación es sencilla:
sudo apt install tesseract-ocr tesseract-ocr-spa
El paquete tesseract-ocr-spa incluye los datos de idioma para español. Si necesitas otros idiomas, puedes instalarlos con tesseract-ocr-{idioma}. Para catalán, por ejemplo, tesseract-ocr-cat.
El uso básico es tan simple como:
tesseract imagen.png stdout
Esto te devuelve el texto reconocido directamente en la terminal. Si quieres guardarlo en un archivo:
tesseract imagen.png salida
Y te creará salida.txt con el resultado.
Pero Tesseract tiene muchas opciones interesantes. Por ejemplo, puedes especificar el idioma con -l:
tesseract imagen.png stdout -l spa
O incluso combinar varios idiomas:
tesseract imagen.png stdout -l spa+eng
Y puedes limitar el conjunto de caracteres reconocidos con --psm (Page Segmentation Mode). Los modos más útiles son:
--psm 3— detección automática de página (el que usa por defecto)--psm 6— asume un bloque uniforme de texto--psm 7— trata la imagen como una sola línea de texto--psm 11— texto sin formato, con orientación variable
Para capturas de pantalla, el modo 6 o 7 suele dar mejores resultados que el automático.
Diccionarios personalizados
Una de las funcionalidades que más me gusta de Tesseract es la posibilidad de usar listas de palabras personalizadas. Si los textos que vas a escanear son siempre de un dominio concreto (facturas, logs de sistema, código fuente), puedes crear un archivo de palabras y pasárselo a Tesseract para que mejore el reconocimiento.
El archivo debe tener una palabra por línea y se pasa con el parámetro --user-words:
tesseract imagen.png stdout -l spa --user-words mis-palabras.txt
Esto es especialmente útil para términos técnicos, nombres propios o palabras en otros idiomas que Tesseract no tenga en su diccionario por defecto.
El salto a Python: ocr_ai.py
Con todas estas piezas sobre la mesa, me puse a escribir un script que unificara todo el proceso. Al principio lo hice en Fish, porque me resulta cómodo para prototipar rápido, pero pronto me di cuenta de que necesitaba algo más estructurado. Así que lo pasé a Python, y el resultado es ocr_ai.py.
El script hace exactamente lo que te he contado, pero con una capa adicional de inteligencia: es capaz de detectar automáticamente el tipo de contenido que está procesando y ajustar el pipeline en consecuencia.
Detección automática del tipo de contenido
¿Cómo sabe el script si lo que tiene delante es código, una tabla o texto normal? Pues con heurísticas bastante sencillas pero efectivas:
- Código: busca patrones como indentación, símbolos como
{,},=,->,=>, palabras clave comodef,class,if,for,fn,let,pub - Tablas: busca barras verticales
|, números alineados, patrones de repetición, múltiples columnas - Prosa: si no detecta lo anterior, asume que es texto normal
En función de lo que detecte, aplica un pipeline de preprocesamiento diferente y, lo que es más importante, un prompt distinto para la corrección con IA.
Pipelines optimizados por tipo
Para código, el preprocesamiento es más agresivo con el threshold y la nitidez, porque necesitas que cada carácter, cada espacio y cada indentación se reconozcan correctamente. El prompt de IA se centra en restaurar la sintaxis, la indentación y no cambiar nombres de variables ni añadir líneas que no estaban.
Para tablas, el preprocesamiento intenta preservar las líneas divisorias y los espacios. El prompt de IA se enfoca en corregir números mal reconocidos, preservar la estructura de filas y columnas y no rellenar celdas vacías.
Para prosa, el preprocesamiento es más suave, y el prompt simplemente corrige acentos, puntuación y caracteres mal reconocidos sin alterar el significado.
El script y cómo usarlo
El script se llama desde la terminal con:
python3 ocr_ai.py imagen.png
Y te devuelve el texto procesado. También puedes combinarlo con un capturador de pantalla para hacerlo todo en un solo paso:
grim -g "$(slurp)" - | python3 ocr_ai.py - | wl-copy
Este comando hace lo siguiente: captura una región de la pantalla con grim y slurp, la pasa directamente a ocr_ai.py (el guión indica que lea de la entrada estándar), y el resultado se copia al portapapeles con wl-copy. En X11, usarías import y xclip respectivamente.
El resultado es que con un solo atajo de teclado, seleccionas una región de la pantalla y el texto procesado ya está en tu portapapeles, listo para pegar donde quieras.
Corrección con Llama 3.2: el toque de la IA
Y aquí llegamos al elemento diferencial. El OCR con Tesseract, incluso con un buen preprocesamiento, va a tener errores. Puede confundir una letra «l» con un número «1», una «O» con un «0», o fallar con acentos y caracteres especiales.
Para solucionarlo, he añadido una fase de corrección con un modelo de lenguaje local. En mi caso uso Llama 3.2, que es el modelo que Meta lanzó y que puedes ejecutar localmente con herramientas como Ollama.
¿Por qué un modelo local y no uno en la nube? Principalmente por dos razones: privacidad y velocidad. No quiero enviar capturas de pantalla de mis datos a ningún servidor externo, y además, un modelo local como Llama 3.2 en su versión pequeña (3B parámetros) responde en milisegundos cuando se ejecuta en una CPU moderna o en una GPU modestas.
La instalación de Ollama es trivial:
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3.2:3b
Y ya tienes el modelo listo para usar. Desde Python, puedes llamarlo a través de la API que expone Ollama en http://localhost:11434/api/generate.
Los prompts que uso son diferentes según el tipo de contenido detectado:
Para código:
Corrige errores de OCR en código fuente. Restaura la indentación. No inventes líneas. No cambies nombres de variables. Devuelve solo el código corregido.
Para tablas:
Corrige números mal reconocidos en esta tabla. Preserva la estructura de filas y columnas. No rellenes celdas vacías. Devuelve la tabla formateada.
Para prosa:
Corrige caracteres mal reconocidos, acentos y puntuación. No cambies el significado del texto. Devuelve solo el texto corregido.
La diferencia entre usar un prompt genérico y uno específico para cada tipo de contenido es muy notable. Con el prompt adecuado, el modelo entiende el contexto y aplica las correcciones correctas.
OCRmyPDF: OCR para PDFs escaneados
Hasta ahora hemos hablado de imágenes sueltas, pero ¿qué pasa con los PDFs escaneados? Un PDF escaneado no es más que un conjunto de imágenes sin capa de texto. No puedes buscar palabras, no puedes seleccionar texto, no puedes copiar nada.
Para eso existe OCRmyPDF, una herramienta fantástica que utiliza Tesseract por debajo y añade una capa de texto invisible al PDF. El resultado es un PDF que sigue siendo idéntico visualmente al original, pero que ahora tiene texto seleccionable y buscable.
La instalación:
sudo apt install ocrmypdf
Y el uso:
ocrmypdf --language spa escaneado.pdf resultado.pdf
El resultado es un PDF con el mismo aspecto pero con una capa de texto que puedes buscar, seleccionar y copiar. Es una herramienta imprescindible si trabajas con documentos escaneados de forma habitual.
Automatización: monitorización de directorios
Una de las cosas que más me gusta hacer es automatizar procesos. Y este era un candidato perfecto. ¿Por qué no hacer que cualquier imagen que caiga en un directorio se procese automáticamente?
Con inotifywait (de la herramienta inotify-tools) puedes monitorizar un directorio y ejecutar un script cuando se cree un nuevo archivo:
inotifywait -m -e create --format '%f' /ruta/al/directorio | while read archivo; do
python3 ocr_ai.py "/ruta/al/directorio/$archivo" > "/ruta/al/directorio/$archivo.txt"
done
De esta manera, cada vez que arrastres una imagen a ese directorio, el script la procesa automáticamente y crea un archivo de texto con el resultado. Puedes incluso combinar esto con una carpeta compartida de Nextcloud, Syncthing o cualquier servicio de sincronización, y tener OCR automático desde el móvil.
Consejos prácticos y troubleshooting
Después de muchas pruebas, te dejo algunos consejos que te ahorrarán tiempo:
- Si el texto es borroso, ajusta el threshold. Prueba con valores entre 40% y 65%. Un valor más bajo hace que más píxeles se consideren negros
- Si hay ruido de fondo (puntos, manchas), aplica un filtro de morfología con
-morphology closeantes del threshold - Si el texto es muy pequeño, redimensiona la imagen antes de procesarla con
-resize 200%. Esto mejora mucho el reconocimiento - Si es una foto de un documento, añade
-median 3para reducir el ruido de la cámara antes de cualquier otra operación - Si los errores de OCR son persistentes, activa la corrección con IA. A veces merece la pena aunque el resultado del OCR sea aceptable
- Si trabajas siempre con el mismo tipo de documentos, crea un diccionario personalizado y un pipeline fijo. La especialización siempre gana
- Si el texto tiene fondo degradado, prueba a aplicar
-normalizevarias veces o combínalo con-equalizepara distribuir mejor los niveles de gris - Si el OCR devuelve caracteres extraños, verifica que tienes instalado el paquete de idioma correcto con
tesseract --list-langs
Más allá del OCR: una reflexión sobre automatización
Lo que más me gusta de todo esto no es solo el resultado final, sino el proceso de llegar a él. Porque al final, lo que hemos hecho es combinar herramientas clásicas (ImageMagick, Tesseract) con una tecnología moderna (modelos de lenguaje) para resolver un problema cotidiano de una manera elegante y eficiente.
Y esto es aplicable a muchísimas cosas. No se trata de usar IA por usar, sino de entender dónde puede aportar valor real y combinarla con las herramientas que ya funcionan bien. En este caso, el OCR tradicional hace el trabajo pesado de reconocer caracteres, y la IA se encarga de la parte semántica: entender el contexto, corregir errores ambiguos y dar formato al resultado.
El script ocr_ai.py lo subiré a un gist para que puedas trastear con él. Y si tienes ideas para mejorarlo, ya sabes dónde encontrarme. En el grupo de Telegram de atareao con Linux siempre estamos dándole vueltas a este tipo de cosas.
Espero que te haya gustado el episodio y que le saques tanto partido como yo. La vida son dos días y uno ya ha pasado, así que mejor automatizar lo que podamos y dedicar el tiempo a lo que realmente importa.
Y si te animas a probar el script, ya me contarás qué tal te va. Siempre se puede mejorar, y de hecho, cuanto más lo uses, más ideas te van a surgir para añadir nuevas funcionalidades. Yo ya estoy pensando en la siguiente iteración, pero eso será en otro episodio.
Más información
- Tesseract OCR – Documentación oficial — guía completa del motor de OCR
- ImageMagick v7 – Command-line Tools — referencia de todas las operaciones
- Ollama – Ejecuta modelos locales — la herramienta para ejecutar LLMs en local
- Llama 3.2 – Meta AI — el modelo de lenguaje que uso para corrección
- OCRmyPDF – Añade capa de texto a PDFs — herramienta imprescindible para PDFs escaneados
- inotify-tools – Monitorización de archivos — para automatizar el procesamiento de imágenes
- Grim – Captura de pantalla en Wayland — la herramienta que uso para capturar
- Slurp – Seleccionar regiones en Wayland — complemento de grim