Analice archivos PDF escaneados para RAG con EasyOCR: el OCR gratuito le proporciona palabras, no un documento

en Enterprise Document Intelligence, la serie que construye un sistema RAG empresarial a partir de cuatro ladrillos. El artículo 5 (análisis de documentos) creó el analizador con PyMuPDF (fitz), que devuelve vacío en una página escaneada sin capa de texto. Este compañero cambia el motor por EasyOCR, un paquete OCR gratuito que recupera ese texto. Es el único caso en esta familia donde el nuevo motor te da menos, no más: recupera el texto y nada a su alrededor, y esa brecha es la lección.

donde se encuentra este compañero: extiende el Artículo 5 (análisis de documentos), dentro de la Parte II (los cuatro ladrillos), con un motor de análisis diferente – Imagen del autor

Los archivos PDF escaneados no se resuelven “simplemente aplicándoles OCR”. El paso OCR recupera texto; eso es necesario pero no suficiente para una tubería RAG empresarial. Lo que la canalización también necesita es todo lo relacionado con el texto: dónde están los límites de la página, qué líneas son encabezados de sección, qué es una figura, qué es una fila de la tabla frente a un párrafo libre. El “OCR tradicional” (el término técnico para motores de detección y reconocimiento de texto como EasyOCR, Tesseract, PaddleOCR) le proporciona el texto. No te da nada más. El resto es el problema del diseño, y el problema del diseño es la mitad más difícil.

Este artículo analiza esa distinción de manera concreta. El motor de OCR tradicional es EasyOCR: la biblioteca de reconocimiento y detección de texto de JaidedAI más simple, rápida y gratuita (Apache 2.0, declarada en el archivo de LICENCIA del proyecto). El motor que tiene en cuenta el diseño es Docling (Artículo 5ter; licencia MIT, declarada en el archivo LICENCIA del proyecto). Ambos pueden realizar OCR en una página escaneada. Difieren en lo que hacen con el resultado. El artículo completo es una preparación para el cara a cara de un escaneo real de dominio público de 1974 en la sección 5.

EasyOCR es el piso de OCR: solo line_df, sin diseño. El resto de la familia añade estructura – Imagen del autor

1. Qué hace (y qué no hace) el “OCR tradicional”

El OCR tradicional lee píxeles y devuelve rectángulos de texto. Todo lo demás, secciones, tablas, figuras, orden de lectura, es un problema de diseño separado que el motor se niega a considerar. Los dos modelos detrás de esto son la detección de texto (busca regiones rectangulares de la imagen que contienen texto) y el reconocimiento de texto (lee los píxeles de cada región y devuelve caracteres con una puntuación de confianza). El resultado es una lista plana de (bbox, texto, confianza) por región detectada.

Eso es todo lo que hace EasyOCR (o Tesseract o PaddleOCR). El motor lee píxeles y devuelve rectángulos de texto. Una página de dos columnas aparece como una lista plana de cuadros de texto de izquierda y derecha entremezclados por la coordenada y; el motor no sabe que hay dos columnas. Una tabla aparece como una cuadrícula de celdas desconectadas que el motor no puede distinguir de los párrafos normales. El título de una figura es simplemente otro cuadro de texto. El encabezado de la página, el pie de página y los márgenes también aparecen como cuadros.

Cualquier cosa que necesite "este texto es un encabezado de sección" o "estos cuatro cuadros son una fila de la tabla" necesita un segundo modelo en la parte superior, un modelo de diseño. El modelo de diseño lee la salida de OCR más la imagen de la página y clasifica cada región (encabezado, párrafo, celda de tabla, figura, título, pie de página…) y las agrupa en un orden de lectura. Eso es lo que el Artículo 5bis (Azure DI), el Artículo 5ter (Docling) y el Artículo 5quater (vision LLM) agregan al paso OCR. Sin uno, tendrá una “salida OCR”, no “un documento analizado”.

2. EasyOCR: el OCR tradicional canónico

EasyOCR es la demostración más clara del "OCR tradicional" como clase. La biblioteca es pequeña (~150 MB de pesos de modelos almacenados en caché en la primera llamada), gratuita, solo CPU de forma predeterminada y local. La API de la biblioteca completa consta de dos llamadas: cree un lector para los idiomas que necesita y luego lea el texto de una imagen. Cada detección regresa como un triple: el polígono alrededor del texto, la cadena reconocida y la propia confianza del reconocedor.

importar easyocr importar fitz importar numpy como np lector = easyocr.Reader(["en"], gpu=False) # descargas de primera llamada ~150 MB # renderizar la página 1 de un PDF escaneado en una matriz numpy EasyOCR puede leer la página = fitz.open("data/contracts/scanned_amendment.pdf")[0]pix = page.get_pixmap(matrix=fitz.Matrix(2.0, 2.0)) # Zoom 2x = ~144 DPI img = np.frombuffer(pix.samples, dtype=np.uint8).reshape( pix.height, pix.width, pix.n, ) # el reconocedor: una imagen dentro, una triple por región de texto detectada fuera detecciones = lector.readtext(img) para quad, texto, conf en detecciones: # quad = [[x0,y0], [x1,y0], [x1,y1], [x0,y1]] en coordenadas de píxeles print(round(conf, 2), text)

parse_pdf_easyocr envuelve ese bucle. Recorre cada página del PDF, representa cada una en una matriz numerosa, llama a readtext, convierte los polígonos de espacio de píxeles nuevamente a coordenadas PDF y empaqueta las detecciones en el mismo contrato de dictado de tablas que los otros analizadores, el mismo line_df, el mismo parsing_summary, los mismos consumidores posteriores, excepto que solo esas dos claves transportan datos. Cada dos espacios (page_df, image_df, toc_df, span_df, object_registry, cross_ref_df) regresan como un DataFrame vacío. Ese no es un error de característica faltante; es exactamente lo que significa "OCR tradicional".

parsed = parse_pdf_easyocr( "data/contracts/scanned_amendment.pdf", language=("en",), # agregue "fr", "de", … para escaneos multilingües render_scale=2.0, # 2.0 = ~144 DPI; aumente para fuentes pequeñas gpu=False, # CPU-only de forma predeterminada; configure True si CUDA está disponibletrust_threshold=0.0, # filtro de baja confianza detecciones si es necesario) parsed["line_df"] # texto + bbox + confianza por detección parsed["parsing_summary"] # método, recuento de páginas, recuento de líneas, escala de representación # Cada dos claves (page_df, image_df, toc_df, span_df, object_registry, # cross_ref_df) es un DataFrame vacío; EasyOCR no tiene nada que poner ahí.

Los kwargs característicos son los únicos mandos:

Idiomas: tupla de códigos ISO-639-1 (en, fr, de, zh,…). Un corpus multilingüe carga un lector por conjunto de idiomas; @lru_cache en get_easyocr_reader mantiene algunos de estos en la memoria durante las llamadas. render_scale: cuántos píxeles por unidad de PDF al rasterizar cada página. 1.0 es nativo (~72 DPI, a menudo demasiado pequeño). 2.0 es el punto ideal para el cuerpo del texto. Aumente a 3.0 para fuentes pequeñas; más bajo si tienes problemas de memoria. gpu: La CPU es la predeterminada, por lo que el módulo funciona en cualquier máquina. CUDA ofrece una aceleración de 3 a 5 veces en páginas con mucho texto. umbral_confianza: elimina las detecciones de baja confianza. 0.0 mantiene todo (la columna se conserva para que el código posterior pueda filtrar), 0.3 corta la mayor parte del ruido en escaneos degradados.

3. Cómo se ve line_df

Filas de muestra de la portada de NIST FIPS 199 (trabajo del gobierno de EE. UU., dominio público en EE. UU., consulte la declaración de derechos de autor de NIST), una por región de texto detectada: la coordenada de la página, el texto OCR y la puntuación de confianza del propio reconocedor. Ese es todo el resultado.

La misma forma de columna que line_df de Fitz, más una columna de confianza que EasyOCR agrega gratis – Imagen del autor

La forma es deliberadamente pequeña:

texto + bbox: la carga útil del reconocedor, una fila por región de texto detectada. confianza: flota entre 0 y 1, la autopuntuación de EasyOCR. Útil tanto como filtro (cae por debajo de 0,3 en escaneos ruidosos) como como señal de retroalimentación (la generación del Artículo 8 puede señalar al usuario pasajes de baja confianza). caracter_count: mantenido por simetría con los otros analizadores; en EasyOCR es solo len(texto). Sin columna/columna de orden de lectura. Una página de dos columnas aparece como una lista plana, con cuadros de izquierda y derecha entremezclados por la coordenada y.

Cualquier otra clave en el dict devuelto (page_df, image_df, toc_df, span_df, object_registry, cross_ref_df) es un DataFrame vacío. Un consumidor que llama a parsed["image_df"] no falla; itera un marco vacío.

4. Lo que omite el OCR tradicional: la brecha en el diseño, elemento por elemento

Cinco artefactos estructurales que el proceso RAG necesita y que el OCR tradicional no puede producir, independientemente de cuán grande sea el modelo de reconocimiento. Cada uno interrumpe una operación posterior de la que depende el resto de la serie.

TOC/secciones. La resolución de referencias cruzadas (Artículo 11) y la recuperación de corpus de ámbito de sección (Artículo 17) se basan en toc_df. EasyOCR devuelve cero filas. El despachador no puede enviar preguntas de “respuesta en la Sección 3.2” porque la Sección 3.2 no tiene límites. Figuras individuales dentro de la página. Un contrato escaneado de 30 páginas puede contener seis capturas de pantalla de gráficos incrustadas en el cuerpo del texto. EasyOCR trata toda la página como una imagen y devuelve texto alrededor de las figuras; las figuras mismas nunca se convierten en filas. Una tubería descendente que necesita recuperar “el gráfico de la página 14” no tiene control. Orden de lectura en páginas de varias columnas/multizona. Una página de artículo científico de dos columnas aparece de arriba a abajo en ambas columnas mezcladas: línea 1 izquierda, línea 1 derecha, línea 2 izquierda, línea 2 derecha… Generación lee basura. Las barras laterales, las notas a pie de página y los márgenes se filtran al flujo principal. Celdas de la tabla. Una lista escaneada de cargos o una tabla de primas aparece como una lista plana de cuadros de texto desconectados (las etiquetas de las filas en una columna, los valores en otra, los encabezados de las unidades en otro lugar). Se pierde la relación “este valor pertenece a esta etiqueta”. El artículo 5 (análisis de documentos) comienza exactamente con este modo de falla (“el analizador recorrió la tabla celda por celda y las unió en una cadena plana”). Los motores que tienen en cuenta el diseño ejecutan un modelo de estilo TableFormer separado para reconstruir filas × columnas × encabezados. Señales de fuente/peso/tamaño. OCR recupera la forma de los caracteres, no su codificación tipográfica. “Esta línea está en negrita 18 puntos” es información que el motor de diseño lee en la representación de la página; EasyOCR lo descarta. Los títulos, énfasis y notas a pie de página pierden la clave que los habría clasificado.

Tome el tercero, el orden de lectura, porque es el que silenciosamente corrompe una respuesta. EasyOCR devuelve cuadros de texto ordenados por su coordenada y. En una página de dos columnas, las dos columnas se encuentran a la misma altura, por lo que los cuadros aparecen intercalados: primera línea de la columna de la izquierda, primera línea de la columna de la derecha, segunda línea de la izquierda, y así sucesivamente. La prosa se lee en zigzag y la generación cita el zigzag.

sin modelo de diseño, los cuadros vuelven ordenados por y, por lo que una página de dos columnas se entrelaza en zigzag – Imagen del autor

La frase única: el paso de OCR recupera el texto, el paso de diseño recupera lo que hace que el texto sea utilizable. El artículo 5ter (Docling) y el artículo 5bis (Azure DI) agregan el paso de diseño encima del mismo OCR. El artículo 5quater (vision LLM) reúne los dos en una sola convocatoria. EasyOCR se detiene en el paso de OCR.

5. EasyOCR vs Docling en un PDF escaneado real

En el mismo escaneo de 1974, Docling extrae más caracteres (5423 frente a 4952), los límites de la página, once entradas de TOC y cuatro regiones de figuras. EasyOCR extrae rectángulos de texto y se detiene. Los dos motores coinciden a nivel de caracteres, ambos OCR con la misma precisión de clase de reconocedor, pero el pase de diseño de Docling convierte la salida de OCR en un documento.

La comparación interesante no es con fitz (fitz devuelve cero en un escaneo) sino con el siguiente motor: Docling, el analizador local consciente del diseño del Artículo 5ter. La comparación es más clara de lo que parece: el backend de OCR predeterminado de Docling es el propio EasyOCR. Mismo reconocedor leyendo los mismos píxeles; la diferencia es todo lo que Docling construye a su alrededor.

El caso de prueba es un escaneo real de dominio público: páginas 1 a 5 de karg74.pdf, la Evaluación de seguridad MULTICS de la USAF de 1974 (Karger & Schell, ESD-TR-74-193 Vol. II). NIST lo aloja en su archivo Early Computer Security Papers; el trabajo es de dominio público como resultado de oficiales de la Fuerza Aérea de EE. UU. El PDF tiene incorporada la capa OCR “Paper Capture” de Adobe, pero la ignoramos, ambos motores re-OCR a partir de imágenes de páginas, que es el escenario realista cuando el OCR incrustado (cuando está presente) no es confiable.

La verdadera comparación. Ambos vuelven a realizar OCR las imágenes de la página; Docling agrega diseño – Imagen del autor

Las dos columnas cuentan historias diferentes.

EasyOCR (izquierda). Más rápido (59,7 s frente a 134,4 s, sin modelo de diseño para cargar y ejecutar), transmite la confianza del reconocedor como una columna (media 0,81 en este escaneo), produce más detecciones a nivel de fila (346 cuadros) porque cada región de texto en la página se convierte en una fila. Estructura cero: sin page_df, sin toc_df, sin image_df. La salida es texto en formato bbox, nada más.

Docling (derecha). Más lento (2,3 veces más cálculo), une las detecciones en 105 líneas/párrafos en lugar de 346 cuadros, sin columna de confianza. La ganancia estructural es real: 5 filas page_df, 11 entradas toc_df (el modelo de diseño de Docling clasifica los encabezados como secciones), 4 filas image_df (figuras detectadas dentro de la página como objetos separados). En un PDF con tablas, la brecha se amplía aún más: TableFormer de Docling reconoce filas × columnas × encabezados, lo que EasyOCR no puede hacer en absoluto. El artículo 5ter desarrolla íntegramente el caso del cuadro.

Ambos motores OCR con tasas de error a nivel de caracteres similares en este escaneo de 1974 (Karger → “Karger” de EasyOCR, “Karger” de Docling en la página más limpia; las regiones degradadas producen un ruido similar en ambos, “Laboralory”, “und” en lugar de “y”). El motor de OCR dentro de Docling (EasyOCR u OnnxTR dependiendo de la instalación) no es mágicamente más preciso que llamar directamente a EasyOCR. Lo que Docling agrega es cómo organiza la salida de OCR, no cómo realiza el OCR.

Para RAG empresarial, casi siempre la opción correcta es Docling. El cálculo 2,3× se paga una vez en el momento de la ingestión (la caché de análisis del Artículo 5 (análisis de documentos) reutiliza los resultados para siempre); la ganancia estructural (TOC, figuras, celdas de tabla, orden de lectura) se devuelve en cada consulta posterior. Lo único que Docling no incluye es la señal de confianza a nivel de fila de EasyOCR, que rara vez vale la pena renunciar a secciones, figuras y tablas.

6. Cuando el OCR tradicional todavía se mantiene

EasyOCR es el paquete de emergencia de la familia: menos visibilidad del documento, dependencias más simples, más rápido de implementar cuando la restricción es operativa en lugar de pedagógica. Cuatro cajas estrechas mantienen la puerta abierta.

Documentos de clase recibo. Una factura o recibo de 1 página sin encabezados, secciones, figuras ni tablas con celdas combinadas. El diseño es trivial; el reconocedor es todo el trabajo. Agregar la estructura de compras informáticas 2× de Docling que el documento no tiene. La confianza por región como señal de retroalimentación generacional. Generation (Artículo 8) puede leer la confianza de la fila del pasaje citado y advertir al usuario cuando la respuesta se basa en un bit de confianza de 0,3 de OCR. Docling no envía esa columna. Para tuberías donde esta señal soporta carga, EasyOCR (o ejecutar EasyOCR junto con Docling) es la respuesta. Escrituras no latinas a escala. EasyOCR envía modelos previamente entrenados para más de 80 idiomas, incluidos chino, japonés, coreano, árabe, hindi y cirílico. La pila de OCR de Docling es más limitada en cobertura no latina al momento de escribir este artículo. Restricciones operativas que bloquean Docling. La inspección Corp SSL interrumpe la descarga del modelo HuggingFace. Windows bloquea enlaces simbólicos sin el modo de desarrollador. La imagen de producción tiene un presupuesto de estricta dependencia. Implementación aislada sin forma de enviar 3 GB de pesos de diseño. En cada uno de estos, el modelo en caché de 150 MB de EasyOCR + la inferencia de CPU pasa por donde Docling no llega. Ves menos del documento, pero ves algo.

Fuera de estos casos: de forma predeterminada, Docling en escaneos, Azure DI en tiendas reguladas en la nube-OK, visión LLM cuando el documento tiene escritura a mano/firmas/una capa semántica no textual. El despachador de análisis adaptativo (Artículo 10) enruta automáticamente.

7. Conclusión

OCR recupera caracteres. El diseño recupera lo que hace útiles a los personajes, secciones, figuras, celdas de la tabla, orden de lectura. El motor predeterminado para escaneos es el que hace ambas cosas. La familia completa del Artículo 5 se alinea según el mismo eje:

EasyOCR se encuentra en el piso de OCR (solo line_df); Todos los demás motores de la familia añaden un paso de diseño en la parte superior – Imagen del autor

EasyOCR es el piso de OCR, lo que obtienes cuando te detienes en reconocer caracteres y nunca preguntas "¿y dónde están en la página?" La pregunta importa. "En qué parte de la página" marca la diferencia entre una lista de cuadros de texto y un documento analizado. El despachador del Artículo 10 (análisis adaptativo) elige el motor correcto por página; Este artículo existe para que el despachador sepa a qué renuncia cuando elige el más barato.

8. Fuentes y lecturas adicionales

EasyOCR es el motor de OCR tradicional más accesible en 2026; PaddleOCR (Baidu) y Tesseract (Google, con décadas de antigüedad) se encuentran junto a él en la misma familia. El paso de diseño superior es lo que separa el "OCR" del "análisis de documentos"; Docling (Artículo 5ter) y Azure DI (Artículo 5bis) lo agregan, en hardware local y en la nube respectivamente. La lectura cruzada correcta es la literatura sobre diseño (Smock et al. 2022 para la estructura de tablas, Auer et al. 2024 para la cascada de diseño completa) y los motores OCR alternativos para escrituras no latinas.

Misma dirección que el artículo:

JaidedAI, EasyOCR. La biblioteca que documenta este artículo, incluidos los más de 80 paquetes de modelos de idiomas. PaddleOCR (Baidu). Motor OCR tradicional de la misma clase; mejor cobertura china, ceguera de diseño similar. Teseracto OCR. La referencia de décadas de antigüedad, todavía ampliamente utilizada; Misma forma arquitectónica que EasyOCR (detección + reconocimiento, sin diseño).

Ángulo diferente, contexto diferente:

Auer et al., Informe técnico Docling, IBM Research 2024 (arXiv:2408.09869). La cascada de diseño que convierte la salida de OCR en un documento analizado; el punto de comparación en la sección 5 de este artículo. Smock, Pesala, Abraham, PubTables-1M / Table Transformer (TATR), CVPR 2022 (arXiv:2110.00061). El linaje de investigación detrás de la extracción de tablas a nivel de celda, la mayor capacidad de la que carece EasyOCR.

Al principio de la serie:

Document Intelligence: introducción a la serie. Qué construye la serie, ladrillo a ladrillo y en qué orden. Baseline Enterprise RAG, desde PDF hasta respuesta resaltada. El canal de cuatro ladrillos de un extremo a otro: PDF de entrada, respuesta resaltada de salida. Las incrustaciones no son mágicas: los modos de falla predecibles de la recuperación de RAG. Dónde gana la incorporación de similitud (sinónimos, errores tipográficos, paráfrasis), dónde predeciblemente se rompe (términos desconocidos, negación, relevancia de término versus respuesta) y cómo usarlo de todos modos. Los rerankers tampoco son mágicos: cuando la capa de codificador cruzado vale la pena. Lo que agrega un codificador cruzado sobre las incorporaciones de codificador doble, medido y cuándo vale la pena la latencia. RAG no es aprendizaje automático y el conjunto de herramientas de ML resuelve el problema equivocado. Por qué los barridos y ajustes de tamaño de fragmentos optimizan lo incorrecto; en su lugar, ruta por tipo de pregunta. De expresiones regulares a modelos de visión: qué técnica RAG se adapta a qué problema. Dos ejes, complejidad documental y control de preguntas, que seleccionan la técnica para cada caso. 10 errores comunes de RAG que seguimos viendo en producción. Diez errores de producción, organizados ladrillo por ladrillo, con la solución para cada uno. Más allá de extract_text: las dos capas de un PDF que impulsan la calidad RAG. La primera mitad del bloque de análisis: la naturaleza del documento, las señales y el resumen. Deje de devolver texto plano desde un PDF: la forma relacional que RAG necesita. La segunda mitad del bloque de análisis: las tablas relacionales que lee cada bloque posterior.