Buscador de sets LEGO
El usuario fotografía las piezas distintivas de un montón: figuras, animales, ladrillos impresos, vehículos, formas extrañas. Cada pieza se recorta de las fotos, se identifica mediante Brickognize (un servicio gratuito de reconocimiento de imágenes) y se busca sin conexión en el catálogo público de Rebrickable. Los sets se clasifican según cuántas piezas distintivas independientes apuntan a ellos. Los ladrillos y placas lisos no distinguen bien entre sets, por lo que quedan fuera de las fotos y de la evidencia.
Todos los comandos son un solo script. Cada paso lee y escribe archivos en una carpeta de ejecución (RUN abajo, por ejemplo ./lego-run):
python3 ${CLAUDE_SKILL_DIR}/scripts/lsf.py <paso> RUN ...
Abajo, lsf.py representa ese comando completo. lsf.py <paso> -h lista todas las opciones. Si no se encuentra python3 (a menudo en Windows, que no está probado), use py en su lugar. Los formatos de archivo, la puntuación y las soluciones para problemas comunes están en reference.md; léalo cuando un paso salga mal o antes de editar un archivo manualmente.
1. Acordar el trabajo con el usuario
Pregunte, en un solo mensaje:
- ¿Duplo o LEGO regular? (Esta habilidad se probó solo en Duplo. Dígalo si responden LEGO.)
- ¿Dónde están las fotos? Si aún no hay, déles los consejos de foto a continuación.
- ¿Puede la habilidad enviar una imagen recortada de cada pieza individual a Brickognize, un servicio gratuito de reconocimiento de terceros? Solo esos recortes salen del ordenador, nunca las fotos completas, y no llevan metadatos (sin datos de cámara, hora ni ubicación). Los términos de Brickognize le otorgan una licencia permanente y libre de regalías para usar las imágenes subidas, incluido para entrenar modelos de aprendizaje automático; el usuario puede pedirle a Brickognize que las elimine. Sin un sí, deténgase aquí.
- ¿Algún set que ya sospechen (cajas, manuales, historial de pedidos)? Esto ayuda a verificar el resultado, nunca reemplaza la evidencia.
Consejos para las fotos (délos tal como están escritos):
- Saque solo las piezas distintivas: figuras, animales, ladrillos impresos, vehículos, formas extrañas. Los ladrillos y placas lisos son inútiles para distinguir sets.
- Extienda tantas como quepan sobre una sábana blanca lisa grande con unos 2 cm de espacio alrededor de cada pieza, con el lado impreso hacia arriba. El espacio importa más que la cantidad: las piezas que se tocan se recortan como una sola. Tome tantas fotos como el montón necesite; la habilidad pregunta antes de pasar de unas 300 piezas en una ejecución. Las piezas blancas, grises y transparentes se ven mejor sobre una sábana oscura.
- Dispare desde arriba, con buena luz y con toda la sábana en el encuadre.
- Para LEGO regular (piezas más pequeñas), ponga menos en cada foto y dispare más cerca.
- Las minifiguras y las piezas impresas llevan la mayor parte de la evidencia.
- Las fotos JPEG o PNG funcionan tal cual. Las fotos HEIC (iPhone) necesitan el paquete pillow-heif, o expórtelas como JPEG.
Terminado cuando sepa el tipo de piezas, los archivos de foto y tenga el sí para Brickognize.
2. Verificación de instalación y catálogo
lsf.py selftest # sin conexión, unos segundos; debe terminar con "0 failed"
lsf.py data --info # exit 0: catálogo instalado, vaya al paso 3
Si falta Pillow, el script dice cómo instalarlo.
El usuario descarga el catálogo de Rebrickable manualmente, una vez: los términos de Rebrickable prohíben las descargas automatizadas, así que nunca obtenga estos archivos usted mismo, con ninguna herramienta. Ejecute lsf.py data: imprime la página de descarga y los archivos exactos (sale con exit 1 a propósito). Dele esa lista al usuario, dígale que guarde los archivos en una carpeta (Descargas está bien) y espere hasta que diga que está listo. Luego:
lsf.py data --from ~/Descargas # o la carpeta que usaron; nombra cualquier archivo que aún falte
Terminado cuando lsf.py data --info sale con exit 0. Las descargas son unos 17 MB; el índice ocupa unos 115 MB en ~/.cache/lego-set-finder (o $LEGO_SET_FINDER_DATA). Para actualizarlo más tarde, el usuario descarga los archivos nuevamente y usted ejecuta data --from otra vez.
3. Encontrar las piezas
lsf.py detect RUN <fotos o carpeta>
Escribe RUN/overview/<foto>.jpg: la foto con cuadros numerados y una cuadrícula etiquetada cada 100 píxeles. Abra cada vista general y juzgue cada cuadro:
- mantenga un cuadro que contenga exactamente una pieza distintiva;
- descarte cuadros sobre ladrillos y placas lisos, fondo, sombras, el borde de la sábana y fragmentos de una pieza;
- reemplace un cuadro que contenga dos piezas que se tocan con un cuadro por pieza;
- añada un cuadro para cada pieza distintiva que no tenga ninguno (las piezas pálidas sobre un suelo pálido a menudo se pasan por alto).
lsf.py boxes RUN <foto> --only 3,7,12 # mantener estos cuadros automáticos, descartar el resto
lsf.py boxes RUN <foto> --drop 9 --add 405,225,515,385:figure --add 395,380,500,500
Las coordenadas son píxeles de la vista general (x0,y0,x1,y1), leídos de la cuadrícula. Cada llamada redibuja la vista general con solo los cuadros mantenidos: los automáticos en magenta, los suyos en cian. Mire de nuevo después de cada corrección. Cuando las piezas son pequeñas o están muy juntas, lsf.py zoom RUN <foto> x0,y0,x1,y1 muestra esa región al doble de tamaño con las mismas coordenadas y una cuadrícula cada 50 px; lea las esquinas del cuadro en el zoom.
Terminado cuando, en cada vista general, cada pieza distintiva está exactamente en un cuadro mantenido y cada cuadro mantenido contiene solo esa pieza.
4. Recortar y verificar los recortes
lsf.py crop RUN
Abra cada RUN/sheets/crops_<foto>.jpg. Cada recorte debe mostrar una pieza completa. Corrija los cuadros con lsf.py boxes y recorte de nuevo hasta que eso se cumpla para todos.
5. Identificar
lsf.py identify RUN
Envía cada recorte a Brickognize, de 3 en 3 por defecto (--workers, máximo 4). Las respuestas se almacenan en caché por imagen y endpoint, por lo que una reejecución no cuesta nada para los recortes ya enviados a ese endpoint. Se detiene en 300 llamadas nuevas (código de salida 2): pregunte al usuario antes de reejecutar con un --max-calls más alto.
Se enumeran los recortes sin respuesta. Brickognize a menudo no encuentra nada en piezas grandes o blandas (carrocerías de vehículos, vagones, tela). Intente una vez con --endpoint predict/parts/ --only <recortes>. Para lo que aún falla, usted mismo nombra la pieza en el paso 6.
6. Mapear y revisar cada pieza
lsf.py match RUN --kind duplo # o --kind lego
Esto escribe RUN/pieces.tsv, una fila por recorte: la respuesta de Brickognize, la pieza o figura de Rebrickable a la que se mapea (rb, varias cuando no está seguro), el color y una confianza. Primero imprime las filas para revisar, entre ellas todas las figuras: los emparejamientos de figuras mantienen los subcampeones cercanos que pueden ser claramente incorrectos (una niña por un niño). Abra cada RUN/sheets/review_<foto>.jpg (recorte, confianza, nombre de Brickognize, número y color de Rebrickable) y compare cada recorte con su leyenda.
Corrija lo que está mal con los ayudantes del catálogo:
lsf.py lookup yellow truck flatbed grille --duplo --colour Yellow # buscar por nombre o número de pieza
lsf.py fix RUN p10-m1 --rb 15454pr0006 --colour Yellow
lsf.py fix RUN p08-27 --colour "Neon Yellow" # su ojo supera a Brickognize en color
lsf.py fix RUN p08-m3 --use n # no se puede identificar: déjelo fuera
lsf.py set 10931 # las piezas de un set, para comprobar una corazonada
lsf.py sets-of 14094 --colour "Medium Azure" # qué sets tienen una pieza en un color
Nombre una pieza que Brickognize no haya visto, luego lookup ella; elija el candidato cuyo nombre y colores encajen. Cuando dos o tres candidatos encajan igual, délos todos (--rb a;b;c): la clasificación maneja eso mejor que una suposición incorrecta. Una pila de Duplo respondida con una pieza que no es de Duplo suele ser incorrecta.
Terminado cuando cada fila con use = y tiene un rb y un color que usted cree del recorte, y cada fila que no puede garantizar tiene use = n.
7. Clasificar los sets
lsf.py rank RUN
Lea RUN/sets.md. Para cada set muestra el nivel (probable, posible, débil), la puntuación de clasificación, cuántas piezas apuntan a él, cuántas de esas ningún otro set tiene, la proporción de los propios artículos distintivos del set vistos en las fotos y la evidencia pieza por pieza.
Presente los sets probables al usuario como una tabla (número de set, nombre, año, piezas, piezas solo aquí, proporción vista), luego los posibles en una línea cada uno. Señale:
- sets listados bajo "Comparte evidencia con": compiten por las mismas piezas, así que pregunte al usuario cuál tiene;
- sets grandes que puntúan alto en muchas piezas compartidas pero muestran pocas propias (baja proporción vista): estos son los falsos positivos habituales;
- piezas distintivas que ningún set listado explica: puede que haya otro set en el montón.
Pregunte al usuario qué sets reconoce o quiere en la lista de verificación. El enlace de Rebrickable en la lista de verificación muestra la imagen de la caja de cada set.
8. Construir la página de lista de verificación
lsf.py page RUN --sets 10906,10931,10963 [--confirmed] [--title "Nuestro Duplo"]
Sin --sets toma el nivel probable. --confirmed etiqueta cada set como confirmado (úsalo después de que el usuario los haya revisado). El resultado es RUN/checklist.html, un archivo que funciona al abrirlo desde el disco. Dígale al usuario cómo usarlo: elija un set o cambie a "Por montón de colores", toque el conteo de una pieza mientras cada pieza va a su montón, "Ocultar encontrado" para ver lo que queda, "Lista de piezas faltantes" para copiar lo que aún falta, "Guardar o restablecer marcas" para guardar las marcas en un archivo. Las marcas se guardan solo en ese navegador. Las imágenes de las piezas se cargan desde el servidor de imágenes de Rebrickable, por lo que necesitan conexión.
9. Decir lo que falta
Antes de que el usuario ordene, dígale qué artículos distintivos de cada set elegido no aparecieron en las fotos:
lsf.py missing RUN --sets 10906,10931
Diga claramente que "no está en las fotos" no es "falta": solo se fotografiaron las piezas distintivas. Cuando nombre un recorte que dejó fuera (use = n) que encaja con una pieza faltante, mire ese recorte de nuevo y restáurelo con lsf.py fix RUN <recorte> --use y si encaja; luego clasifique de nuevo. Después de ordenar, tome la lista que copia la página o el archivo de marcas que guarda la página (lsf.py missing RUN --sets ... --ticks <archivo>) y dé las piezas faltantes por set.
Límites para decirle al usuario
- Probado en una colección mixta de Duplo (12 sets), en macOS. LEGO regular y Windows no están probados.
- Brickognize es un servicio gratuito de terceros; los recortes de piezas se suben a él y puede conservarlos y usarlos (paso 1). Sus endpoints predict están marcados como "legacy" en su descripción de API, por lo que pueden cambiar o dejar de funcionar.
- El catálogo de Rebrickable es una descarga única manual (11 archivos, unos 17 MB; el índice ocupa unos 115 MB) y se queda obsoleto lentamente; para actualizarlo, descargue los archivos de nuevo y ejecute
lsf.py data --fromotra vez. - Rebrickable y BrickLink numeran algunas piezas de manera diferente, sobre todo las figuras de Duplo. Las figuras e impresiones mapeadas llevan una confianza; verifique las dudosas a simple vista.