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 dem OCR-Output. Das Schwäche-Symbol (Fire+20) erschien in einer separaten Zeile.

Lösung: Regex-Muster verbessert und gesamten OCR-Output-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:

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 matchen mit 60%+ Konfidenz
  • Sammlungsgröße: Begonnen mit 1 Karte (Ledyba, natürlich)
  • Datenabdeckung: Alle 2540 deutschen Karten mit Bildern

#Datensammlung: Datenfluss

Dieses Dokument zeigt den Datenfluss durch das Pokemon TCG Pocket Karten-Extraktionssystem.

Loading diagram...

#Datenbank-Quellen

Loading diagram...

#Karten-Abgleich-Priorität

Loading diagram...

#Datenschema

Eingabe: Screenshot

Nach OCR: Signale

Datenbank-Abgleich: Kartendaten

Sammlungs-Speicher

#Datei-Transformationen

Loading diagram...

#Sammlungs-Statistiken Flow

Loading diagram...

#Scraping-Workflow

Loading diagram...

#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 Matching 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:
4/9/2026