← Volver al blog
TecnologíaScannerIA

Cómo funciona el scanner de binders: OCR, CLIP, Gemini y Scryfall

Cargar cartas a mano es el cuello de botella de cualquier app de trading. Si tenés 1000 cartas en una carpeta, no vas a sentarte a buscar una por una. Para poder usar el poder del algoritmo de matching de Natural Order, las cartas tienen que estar digitalizadas e indexadas correctamente. Existen conocidas apps de scan de cartas individuales como ManaBox, pero observamos que incluso con esta herramienta, la digitalización de una carpeta es muy tediosa. Era intuitivo que lo mejor sería sacarle todas las fotos a un binder (el formato más habitual en el que los coleccionistas / jugadores guardan su colección) y luego tirárselo a un proceso para que nos escupa la lista entera del contenido de la carpeta. Buscamos alternativas de scanners existentes y no encontramos nada útil. Así que lo construimos. Obviamente fue un desafío — tirarle la foto a una IA para que lo detecte en teoría funciona, pero es extremadamente lento y caro. Y queríamos disponibilizar esto de forma gratuita, sin gastar una fortuna.

El pipeline completo: de la foto al resultado

Cada foto de binder pasa por un pipeline de múltiples etapas. El diseño prioriza velocidad y precisión: las técnicas más baratas y rápidas se ejecutan primero, y los modelos más costosos solo intervienen cuando son estrictamente necesarios.

  1. Subida y grilla — El usuario sube fotos y configura la grilla sobre la imagen
  2. Detección de slots — La grilla adaptativa corta la imagen en celdas individuales
  3. Filtrado rápido — Slots vacíos y dorsos de cartas se descartan al instante
  4. OCR del nombre (EasyOCR) — Lee el texto del título de la carta
  5. Resolución contra Scryfall — 7 estrategias de búsqueda para encontrar la carta exacta
  6. OCR del collector number — Lee la información de la franja inferior para identificar la edición
  7. CLIP para edición exacta — Compara visualmente contra todas las impresiones posibles
  8. Gemini como fallback — Solo si los pasos anteriores no resolvieron la carta

La grilla adaptativa: la decisión que cambió todo

Antes de la grilla, el scanner intentaba detectar cartas individualmente usando detección de contornos — y era un desastre. Los bordes de los bolsillos del binder se confundían con bordes de cartas, las reflexiones generaban falsos positivos, y cartas oscuras contra fondos oscuros eran invisibles. La precisión era inaceptable.

La solución fue radicalmente simple: en vez de intentar "encontrar" cartas en la imagen, asumimos que la estructura de un binder es una grilla. El usuario ve un overlay interactivo sobre su foto y puede ajustar las líneas de la grilla para que coincidan con los bolsillos de su carpeta. Parece un detalle menor, pero fue el cambio que hizo viable todo el proyecto.

Además de la grilla base, el sistema aplica una refinación adaptativa con detección de bordes: usa filtros Sobel para detectar las transiciones reales entre carta y plástico, y ajusta las divisiones de la grilla hacia esos bordes. Si la señal de borde no es confiable, mantiene la división equitativa. Si las celdas resultantes son muy desiguales (ratio > 1.3x), descarta el ajuste y vuelve a la grilla base.

Interfaz de ajuste de grilla del scanner — el usuario arrastra las líneas para alinearlas con los bolsillos del binder

El usuario también puede marcar slots vacíos con una X roja, ahorrando procesamiento innecesario. Toda esta configuración se hace una sola vez por lote de fotos y las coordenadas se guardan normalizadas (0.0 a 1.0), así funcionan igual sin importar la resolución de la imagen.

Filtrado rápido: descartar antes de procesar

Antes de gastar recursos en OCR o modelos de IA, cada celda pasa por dos filtros ultra-rápidos:

  • Detección de vacíos — Si el slot está marcado como vacío por el usuario, se salta directamente
  • Detección de dorsos (card backs) — Un detector de dos etapas: primero analiza el histograma de color buscando las proporciones características de marrón y azul del dorso clásico de Magic (<1ms). Si pasa ese filtro, se confirma con una comparación CLIP contra un embedding de referencia del dorso (~50ms). Ambas etapas deben coincidir para evitar falsos positivos con artes que tengan colores similares

Estos filtros ahorran todo el pipeline de OCR + CLIP + VLM por cada slot vacío o dado vuelta. En un binder típico con algunas páginas incompletas, esto puede ser un 10-20% de ahorro en tiempo total.

OCR: leer el nombre de la carta

El corazón del scanner es EasyOCR, una librería de OCR en Python que soporta múltiples idiomas. Esto es importante: las cartas de Magic están impresas en inglés, español, japonés, coreano, portugués y más. EasyOCR tiene una limitación técnica con idiomas CJK (japonés/coreano) que son incompatibles con lectores de idiomas latinos, así que el scanner mantiene múltiples instancias de lectores y prueba con cada grupo.

La lectura del nombre no es trivial. La grilla puede cortar ligeramente el título de la carta, así que el sistema prueba recortes progresivamente más altos del slot (18%, 25%, 35% de la altura de la celda) e incluso extiende la lectura por encima del borde de la grilla para recuperar texto cortado. Antes de pasarle la imagen al OCR, se aplica conversión a escala de grises y CLAHE (Contrast Limited Adaptive Histogram Equalization) para mejorar el contraste del texto.

Además del nombre, el scanner lee una segunda zona: la franja inferior de la carta, donde están el collector number y el set code (ej: "183/249 MKM"). Esta información es clave para identificar la edición exacta. El parser usa regex para detectar patrones como "183/249" o dígitos concatenados, y aplica fuzzy matching (distancia de Levenshtein) contra collector numbers conocidos de la base de datos.

Resolución de nombres: 7 estrategias antes de rendirse

El texto que sale del OCR no es perfecto. Un "Lightning Bolt" puede salir como "Lightming Bolt" o "Lightn1ng Bolt". El sistema de resolución de nombres tiene 7 estrategias en cascada, ordenadas de la más barata a la más costosa:

  1. Match exacto local — Contra un índice de nombres en ChromaDB
  2. Match exacto case-insensitive — "lightning bolt" = "Lightning Bolt"
  3. Fuzzy matching local — Usando rapidfuzz con score ≥ 80
  4. Scryfall fuzzy API — El endpoint de búsqueda aproximada de Scryfall
  5. Scryfall por idioma específico — Si el OCR detectó que la carta es en español, busca en el catálogo en español
  6. Scryfall multilingüe — Búsqueda abierta en todos los idiomas
  7. Corrección con Gemini (texto) — Se le pasa el texto del OCR a Gemini como texto plano (sin imagen, costo mínimo) para que corrija errores de transcripción, y luego se reintentan los pasos 1-5

El sistema también detecta el idioma de la carta analizando caracteres distintivos en el texto del OCR: la ñ sugiere español, ã/õ portugués, è/ê francés, etc. Esto permite dirigir la búsqueda en Scryfall al idioma correcto en vez de buscar a ciegas.

Edición exacta: collector number + CLIP

Una vez que el nombre está resuelto, falta saber qué edición es. Un Lightning Bolt tiene más de 50 impresiones distintas, cada una con arte, precio y set diferente. El scanner combina dos señales:

  • Collector number — Si el OCR de la franja inferior leyó un collector number o set code válido, se filtra directamente. Si hay un solo match, se salta CLIP por completo (ahorro de ~100ms por carta)
  • CLIP visual matching — Se genera un embedding CLIP (ViT-B-32) de la imagen recortada y se compara contra embeddings pre-computados de todas las impresiones de esa carta en la base de datos. La impresión con mayor similitud coseno gana

Esto funciona bien para diferencias de arte (un Lightning Bolt de Alpha vs uno de Masters 25), pero es menos efectivo cuando el mismo arte se usa en múltiples sets. En esos casos, el collector number es lo que realmente marca la diferencia.

Gemini: el último recurso, no el primero

Una decisión de diseño fundamental: Gemini (Google's vision model) es el fallback, no el pipeline principal. Cada llamada a Gemini con imagen cuesta órdenes de magnitud más que una búsqueda local o una query a Scryfall. En un binder de 100 páginas con 9 cartas cada una, eso escala rápido.

Gemini solo entra cuando el OCR + las 7 estrategias de resolución no pudieron identificar la carta. Y cuando entra, lo hace de forma inteligente:

  • Recibe la imagen del recorte y un prompt que le pide transcribir, no identificar — queremos que lea el texto visible en la carta, no que adivine desde la imagen
  • Se le dan como contexto los 5 mejores candidatos de CLIP, para reducir alucinaciones
  • El resultado de Gemini pasa por una cadena de validación: se verifica que el nombre exista en la base de datos (ChromaDB), luego se busca en Scryfall. Si el nombre no se puede validar, se marca como alucinación y no se usa

En la práctica, menos del 5% de las cartas necesitan pasar por Gemini. El pipeline de OCR + Scryfall resuelve la enorme mayoría.

Infraestructura: Modal, ChromaDB y cold starts de 2 segundos

Todo el pipeline de Python corre en Modal, una plataforma de serverless computing que permite definir containers con dependencias pesadas (PyTorch, EasyOCR, CLIP) y mantenerlos "calientes" con snapshots. El cold start típico es de ~2 segundos en vez de los 30+ que tomaría levantar todo desde cero.

La base de datos de cartas es un índice ChromaDB con embeddings CLIP pre-computados de las ~90.000 impresiones de cartas en Scryfall. Este índice vive en un volumen persistente de Modal, así que no se reconstruye en cada ejecución.

Cada etapa del pipeline tiene timing instrumentado (OCR, resolve, bottom OCR, CLIP, VLM) almacenado en JSONB, lo que permite diagnosticar cuellos de botella y optimizar continuamente. El procesamiento de una página típica de 9 cartas toma ~40 segundos incluyendo todas las etapas.

Resultados y revisión

Después del procesamiento, el usuario ve cada carta identificada con su nombre, edición, imagen y un badge de confianza. Si algo está mal, puede buscar la carta correcta y reemplazarla antes de importar. Las cartas corregidas quedan marcadas para que podamos medir la tasa de error real y seguir mejorando.

Resultados del scanner mostrando las cartas identificadas con nombre, edición y badge de confianza

En la revisión, el usuario puede ver cada carta individual real de su binder y compararla con la carta identificada por el modelo. Además, cuenta con atajos de teclado para navegar y corregir rápidamente: derecha/izquierda para navegar entre cartas, arriba/abajo para cambiar edición, "F" para marcar foil, "E" para marcar vacío. Es la forma más ágil de comparar los resultados y ajustar lo que haga falta.

Vista de revisión comparando la foto real del binder con la carta identificada por el scanner

Una vez revisado, las cartas se importan directamente a la colección o a un lote. Sin CSV, sin copiar y pegar, sin búsquedas manuales. De la foto al trade en minutos.

El mejor scanner de binders del mercado. Y es gratis

No encontramos otro scanner que combine detección por grilla, OCR multilingüe, resolución en 7 pasos contra Scryfall, matching visual con CLIP, y validación con VLM. La mayoría de las apps de scanning escanean una carta a la vez. Nuestro scanner procesa páginas enteras.

Lo más importante: es gratis. No hay límites de fotos ni planes premium para desbloquear el scanner. Si tenés cartas de Magic en una carpeta, las podés escanear ahora mismo.

Y estamos mejorando constantemente. Cada corrección que hace un usuario nos da datos para afinar el pipeline. La precisión de hoy es mejor que la de la semana pasada, y la de la semana que viene va a ser mejor que la de hoy.

Escaneá tu carpeta ahora

Sacá una foto a tu binder y tené tus cartas cargadas en minutos. Gratis, sin límites.

Crear cuenta gratis