DEV Community

Carlos m. Ruiz
Carlos m. Ruiz

Posted on

Surya OCR vs Tesseract en CPU con Python

En los últimos años han surgido motores de OCR basados en deep learning que ofrecen mejoras en precisión, análisis de layout y soporte multilingüe. Entre ellos se encuentra Surya OCR. En paralelo, Tesseract OCR continúa siendo una solución ampliamente utilizada en producción, especialmente en entornos con recursos limitados.

El objetivo de este artículo es responder a la siguiente pregunta:

¿Es viable utilizar Surya OCR en CPU cuando no se dispone de GPU?

Para ello, se realizaron experimentos reproducibles en Python, comparando Surya OCR y Tesseract bajo las mismas condiciones de entrada.

Entorno del experimento

  • Ejecución en CPU (sin GPU)
  • Python 3.11.2
  • surya-ocr==0.2.0
  • Imagen real de documento escaneado
  • Mismo input para ambos motores

El objetivo no es evaluar la precisión teórica, sino la viabilidad operativa en producción en entornos CPU, como VPS sin aceleración por hardware.

Experimento 1: Surya OCR (primera ejecución)

Se mide el tiempo total (carga del modelo + OCR) y el tiempo de inferencia OCR.

import time
from PIL import Image
from surya_ocr import SuryBaseOCR

IMAGE_PATH = "img/cap.png"
image = Image.open(IMAGE_PATH)

start_total = time.perf_counter()
surya_ocr = SuryBaseOCR()

start_ocr = time.perf_counter()
preds = surya_ocr.ocr_image(image)
end_ocr = time.perf_counter()
end_total = time.perf_counter()

print("Tiempo total:", end_total - start_total)
print("Tiempo OCR:", end_ocr - start_ocr)
Enter fullscreen mode Exit fullscreen mode

Resultados observados

  • Tiempo total: ~107 segundos
  • Tiempo de inferencia OCR: ~98 segundos

La carga del modelo representa menos del 10% del tiempo total.

Experimento 2: Surya OCR con el modelo ya cargado

start = time.perf_counter()
preds2 = surya_ocr.ocr_image(image)
end = time.perf_counter()

print("Tiempo OCR (modelo ya cargado):", end - start)
Enter fullscreen mode Exit fullscreen mode

Resultado

  • Tiempo OCR: ~98 segundos

Mantener el modelo cargado no reduce el tiempo de inferencia. El cuello de botella es la ejecución del modelo en CPU.

Arquitectura interna de Surya OCR

Surya OCR utiliza una arquitectura en dos etapas:

  1. Detección de texto
  2. Reconocimiento del texto detectado

Cada etapa carga su propio modelo y processor.

from surya.model.detection.segformer import (
    load_model as load_det_model,
    load_processor as load_det_processor,
)

from surya.model.recognition.model import load_model as load_rec_model
from surya.model.recognition.processor import load_processor as load_rec_processor
Enter fullscreen mode Exit fullscreen mode

Los métodos load_* son helpers que cargan en memoria los pesos del modelo y los processors asociados (normalización, tokenización, escalado).

Componentes cargados en memoria

  • det_processor: processor para el modelo de detección
  • det_model: modelo de detección (localiza regiones de texto)
  • rec_model: modelo de reconocimiento (interpreta el texto)
  • rec_processor: processor del modelo de reconocimiento
class SuryBaseOCR:
    def __init__(self):
        (
            self.det_processor,
            self.det_model,
            self.rec_model,
            self.rec_processor,
        ) = self._load_surya_models()

    def _load_surya_models(self):
        det_processor, det_model = load_det_processor(), load_det_model()
        rec_model, rec_processor = load_rec_model(), load_rec_processor()
        return det_processor, det_model, rec_model, rec_processor

    def ocr_image(self, image, langs=["es"]):
        from surya.ocr import run_ocr

        preds = run_ocr(
            [image],
            [langs],
            self.det_model,
            self.det_processor,
            self.rec_model,
            self.rec_processor,
        )
        return preds
Enter fullscreen mode Exit fullscreen mode

Implicaciones en CPU

  • La detección y el reconocimiento son dos inferencias profundas consecutivas
  • Ambas están optimizadas para GPU
  • En CPU, el coste computacional es acumulativo
  • El tiempo de inferencia domina completamente la ejecución

Esto explica por qué reutilizar el modelo no reduce el tiempo total.

Experimento 3: Tesseract OCR en CPU

import pytesseract
from PIL import Image
import time

image = Image.open("img/cap.png")

start = time.perf_counter()
text = pytesseract.image_to_string(image, lang="spa")
end = time.perf_counter()

print("Tiempo Tesseract:", end - start)
Enter fullscreen mode Exit fullscreen mode

Resultados observados

  • Tiempo: ~2 a 5 segundos

Calidad de salida de Tesseract sin preprocesamiento

Sin aplicar filtros a la imagen, los resultados no fueron satisfactorios:

1- ¿Qué soncel diseño y la arquitectura?
¿la meta?.......
¿Qué ha ido mai?.
Enter fullscreen mode Exit fullscreen mode

Errores frecuentes:

  • Palabras mal segmentadas
  • Ruido tipográfico
  • Pérdida de acentos
  • Detección deficiente de encabezados

Necesidad de preprocesamiento de imágenes

Para obtener resultados aceptables con Tesseract, es necesario aplicar:

  • Escala de grises
  • Binarización adaptativa
  • Eliminación de ruido
  • Corrección de inclinación
  • Normalización de contraste y DPI

Sin esta etapa, la velocidad de Tesseract no compensa la baja calidad del texto generado.

Ejemplo de documento procesado

A continuación se muestra el tipo de documento utilizado en los experimentos. Se trata de un índice de contenidos escaneado, con texto en español, múltiples niveles de jerarquía y numeración de páginas:


Este tipo de documento representa un caso de uso común en producción: documentos administrativos, libros técnicos o informes con estructura compleja.

Comparación directa

Motor Tiempo CPU Viabilidad VPS Precisión
Surya OCR ~98 s No Alta
Tesseract ~3 s Media–Alta (con filtros)

Cuándo utilizar cada motor OCR

Utilizar Tesseract OCR cuando

  • Infraestructura limitada: VPS sin GPU o entornos con recursos CPU limitados
  • Procesamiento batch: Cientos o miles de documentos diarios
  • Latencia crítica: Aplicaciones web que requieren respuesta inmediata
  • Documentos estándar: Facturas, recibos, formularios con texto limpio
  • Presupuesto reducido: No se justifica el coste de infraestructura GPU
  • Documentos escaneados de calidad media-alta: Cuando se puede garantizar preprocesamiento adecuado

Utilizar Surya OCR cuando

  • GPU disponible: Infraestructura con aceleración por hardware
  • Precisión crítica: Documentos legales, médicos o académicos donde cada error tiene coste
  • Documentos complejos: Layouts irregulares, tablas anidadas, múltiples columnas
  • Multilingüe avanzado: Documentos con mezcla de idiomas o scripts no latinos
  • Baja calidad de origen: Documentos antiguos, deteriorados o con resolución muy baja
  • Procesamiento offline: Trabajos nocturnos o batch donde el tiempo no es limitante

Arquitectura híbrida recomendada

Para entornos de producción en CPU, se recomienda un enfoque estratificado:

Entrada de documento
   ↓
Preprocesamiento (obligatorio)
   ↓
Tesseract OCR (motor principal)
   ↓
Validación de confianza
   ↓
¿Confianza > umbral? → SÍ → Salida
   ↓ NO
Surya OCR (fallback excepcional)
   ↓
Salida
Enter fullscreen mode Exit fullscreen mode

Esta arquitectura permite:

  • Procesar el 90-95% de documentos con latencia baja
  • Reservar Surya OCR para casos excepcionales
  • Mantener costes operativos bajo control
  • Garantizar alta precisión cuando sea necesario

Arquitectura recomendada en CPU

Preprocesamiento de imagen
   ↓
Tesseract OCR
   ↓
Evaluación de calidad
   ↓
Surya OCR (fallback)
Enter fullscreen mode Exit fullscreen mode

Conclusión

Surya OCR ofrece una arquitectura moderna y alta precisión, pero su coste computacional en CPU lo hace inviable como motor OCR principal en entornos sin GPU. Tesseract, combinado con un preprocesamiento adecuado, sigue siendo la opción más eficiente y escalable en VPS.

Surya OCR debe utilizarse únicamente como motor de respaldo para documentos complejos, no como reemplazo directo en entornos CPU. La decisión entre ambos motores debe basarse en el análisis de los recursos disponibles, el volumen de procesamiento y los requisitos de precisión del caso de uso específico.

Top comments (0)