Pokemon TCG Karten-Extraktor mit OCR

Einleitung

Als Pokemon TCG Pocket-Spieler fand ich mich jedes Mal dabei, meine Sammlung manuell zu durchsuchen, wenn ich wissen wollte, ob ich eine bestimmte Karte hatte. Das Spiel erlaubt dir, Karten zu erfassen, aber es gibt keinen einfachen Weg, deine Sammlung zu exportieren oder zu durchsuchen. Also habe ich einen gebaut.

Dieser Artikel dokumentiert, wie ich ein vollständiges Karten-Extraktionssystem mit OCR, Web-Scraping und SQLite gebaut habe. Ich führe dich durch die Architektur, die Herausforderungen, die ich gemeistert habe, und wie ich sie gelöst habe.


Das Problem

Karten manuell zu katalogisieren ist mühselig:

  • Screenshot einer Karte in der App
  • Kartenname in einer Datenbank nachschlagen
  • In einer Tabelle erfassen

Das wollte ich automatisieren: Screenshot → OCR → Datenbank in Sekunden, nicht Minuten.


Systemarchitektur

Das System hat fünf Hauptkomponenten:

Loading diagram...

Komponenten-Übersicht

| Komponente | Zweck | |-----------|---------| | vorverarbeitung/ | Bildzuschnitt, Kontrastverbesserung | | extraktion/ | Pokemon/Trainer/Energy-Karten erkennen | | ocr_engine/ | EasyOCR + Tesseract für Textextraktion | | api/local_lookup.py | Multi-Signal-Kartenabgleich | | database.py | SQLite-Sammlungsspeicher |


Datensammlung: Scraping von Pokewiki.de

Bevor ich Karten abgleichen konnte, brauchte ich eine Datenbank. Ich habe pokewiki.de (deutsches Pokemon-Wiki) nach Kartendaten gescraped.

Loading diagram...

Was ich gescraped habe

  • 2540 einzigartige Karten in 17 Sets (A1-B2a, PROMO-A, PROMO-B)
  • 124 einzigartige Fähigkeiten mit Effektbeschreibungen
  • 4509 Bild-URLs (inklusive Nachdrucke)
  • ~200 Angriffseffekte mit detailliertem Text

Scraping-Datenfluss

Loading diagram...

Karten-Erkennung: Pokemon vs Trainer vs Energy

Nicht alle Karten sind gleich. Pokemon-Karten haben KP, Angriffe und Fähigkeiten. Trainer-Karten haben völlig andere Felder. Ich musste zuerst den Kartentyp erkennen.

Loading diagram...

Die Erkennung nutzt deutsche Keywords, da das Spiel auf Deutsch angezeigt wird:


OCR-Extraktion: EasyOCR zur Rettung

Mit dem bekannten Kartentyp extrahierte ich Text mit EasyOCR mit deutschen und englischen Modellen.

Extraktions-Pipeline

Loading diagram...

Vollständiger End-to-End-Datenfluss

Loading diagram...

Bildvorverarbeitungs-Pipeline

Loading diagram...

OCR-Signal-Korrektur-Pipeline

Loading diagram...

Beispiel-Extraktion

Eingabe: Screenshot der Karte Igastarnish (Grass/Bug Pokemon)

Roh-OCR-Ausgabe:

Extrahierte Signale:


Herausforderungen & Lösungen

Herausforderung 1: OCR liest KP-Werte falsch

Problem: EasyOCR liest oft KP-Werte falsch. "502" bedeutet "50", "802" bedeutet "80". Die zusätzliche Ziffer ist Rauschen vom KP-Icon.

Lösung: Nachbearbeitung mit Regex, die nachfolgende Ziffern entfernt:

Herausforderung 2: Doppelte Karten in der Datenbank

Problem: Einige Karten erscheinen in mehreren Sets (Nachdrucke). Der Scraper erstellte doppelte Einträge mit verschiedenen Set-IDs, aber demselben Kartennamen.

Lösung: Deduplikationslogik hinzugefügt, die Einträge zusammenführt basierend auf:

  • Exaktem deutschen Namen
  • Gleicher KP-Wert
  • Gleicher Pokédex-Nummer

Herausforderung 3: Fehlende Kartenbilder

Problem: Erster Scrapevorgang erhielt nur 1483 Bilder. 1969 Karten hatten keine Bild-URLs.

Lösung: scrape_images.py ein zweites Mal mit aggressiverem Timeout-Handling und Retry-Logik ausgeführt:

Herausforderung 4: Besondere Illustration-Karten

Problem: Special Illustration (SAI)-Karten haben verschiedene Bild-URLs auf pokewiki - sie werden auf einem separaten CDN mit verschiedenen URL-Mustern gehostet.

Lösung: SAI-Karten anhand der Seltenheit ("4 Star" oder "Special Illustration") erkennen und ein anderes URL-Muster verwenden:

Herausforderung 5: Schwäche/Rückzug nicht extrahiert

Problem: Das Regex für Schwäche und Rückzug funktionierte nicht mit der OCR-Ausgabe. Das Schwäche-Symbol (Fire+20) erschien in einer separaten Zeile.

Lösung: Regex-Muster verbessert und gesamten OCR-Ausgabe-Kontext betrachtet:


Karten-Abgleich: Die Multi-Signal-Engine

Mit extrahierten Signalen und einer Datenbank brauchte ich einen Abgleichalgorithmus. Ich implementierte einen prioritätsbasierten Ansatz:

Loading diagram...

Konfidenz-Bewertung

| Strategie | Konfidenz | Wann verwendet | |-----------|----------|----------------| | Name + Set | 95% | Exakter deutscher Name + Set-ID | | Name + KP | 85% | Fuzzy-Name + KP-Übereinstimmung | | KP + Angriff + Set | 85% | KP + Angriffsname + Set-Kombination | | KP + Schwäche + Set | 80% | KP + Schwäche + Set-Kombination | | Nur KP | 60% | Notlösung - nur KP-Übereinstimmung |

Karten unter 60% Konfidenz gehen in failed_to_capture/ zur manuellen Überprüfung.


Datenbank-Design

Die Sammlung verwendet SQLite mit einem einfachen, aber effektiven Schema:

Loading diagram...

Wichtige Features:

  • Mengenverfolgung: Increment beim Hinzufügen von Duplikaten
  • Vollständige Kartendaten: Alle Felder für Filterung gespeichert
  • Schnelle Lookups: Indiziert auf name, set_id, KP

Python Core: Das Extraktions-Skript

Der Haupteinstiegspunkt ist extract_batch_v2.py. So funktioniert es:

Bildvorverarbeitung

Kartentyp-Erkennung


Python Core: Die Karten-Abgleich-Engine

Die Abgleichlogik in api/local_lookup.py implementiert Multi-Signal-Abgleich:


Python Core: Der Web-Scraper

Den Aufbau der Datenbank erforderte mehrere Scraper:


Ergebnisse

Nach Implementierung aller Komponenten:

  • Extraktionszeit: ~3-5 Sekunden pro Karte
  • Erfolgsrate: ~85% der Karten werden mit 60%+ Konfidenz zugeordnet
  • Sammlungsgröße: Begonnen mit 1 Karte (Ledyba, natürlich)
  • Datenabdeckung: Alle 2540 deutschen Karten mit Bildern

Gelernte Lektionen

  1. Nachbearbeitung ist essentiell: OCR ist nie perfekt. Baue robuste Korrekturlogik für häufige Fehlermodi.

  2. Scraping ist iterativ: Erster Durchgang holt selten alles. Plane mehrere Durchgänge, um Lücken zu füllen.

  3. Konfidenz-Bewertung ist subjektiv: 60% Schwellenwert funktioniert, aber einige Fehlpositive rutschen durch. Erwäge Feedback-Schleife.

  4. Deutscher Text ist knifflig: Sonderzeichen (ü, ö, ä) und zusammengesetzte Wörter verursachen Abgleichprobleme. Normalisieren vor dem Vergleichen.


Zukünftige Arbeit

  • Bildbasiertes Zuordnen mit Karten-Art hinzufügen
  • Mobile App für Kamera-Erfassung implementieren
  • Duplikaterkennung aus verschiedenen Sets hinzufügen
  • Web-Interface für Sammlungs-Durchsuchung bauen

Fazit

Den Bau dieses Karten-Extraktors hat mir viel über OCR-Pipelines, Web-Scraping im großen Maßstab und Multi-Signal-Abgleichalgorithmen beigebracht. Die wichtigste Erkenntnis: Beginne einfach, iteriere bei Fehlern.

Der vollständige Quellcode ist im Projekt-Repository verfügbar. Viel Spaß beim Sammeln!


Erstellt mit Python, EasyOCR, SQLite und jeder Menge deutscher Kartendaten.

Created:
4/9/2026
Last Updated:
5/21/2026