mtgscan

Convert an image containing Magic cards to decklist


Keywords
mtg, scan, OCR, magic, cards, computer, vision, card, computer-vision, deck, detect, magic-the-gathering, recognition, scanner, screenshot
License
MIT
Install
pip install mtgscan==1.0.8

Documentation

MTGScan

License: MIT CodeFactor

mtgscan

MTGScan uses OCR recognition to list Magic cards from an image.
After OCR, cards are looked up in a dictionnary provided by MTGJSON, using fuzzy search with SymSpell.

Try the Web App

  flowchart LR;
  subgraph "Browser"
    C1[Client];
    C2[Client];
    C3[Client];
  end
  subgraph "Frontend"
    F((Flask Server));
  end
  subgraph "Backend"
    W1[Celery Worker<br>using mtgscan];
    W2[Celery Worker<br>using mtgscan];
  end
  subgraph "Cloud"
    A[Azure Read OCR];
  end
  C1 <-->|Socket.IO| F;
  C2 <-->|Socket.IO| F;
  C3 <-->|Socket.IO| F;
  F <-->|RedisMQ| W1;
  F <-->|RedisMQ| W2;
  W1 <-->|API| A;
  W2 <-->|API| A;

Repository for the web app

Prerequisites

  • Python >= 3.7
  • Credentials for the required OCR (e.g Azure Computer Vision Read API)

Installation

... with Poetry

poetry install

... with requirements

pip install -r requirements.txt

... with pip

pip install mtgscan

OCR

Currently, only Azure OCR is supported. To add an OCR, inherit mtgscan.ocr.OCR.

Azure

API subscription key and endpoint must be stored in environment variables AZURE_VISION_KEY and AZURE_VISION_ENDPOINT respectively.
Steps:

Tests

Every test case is stored in a separated folder in tests/samples/ containing:

  • image.*: image of Magic cards
  • deck.txt: decklist of the cards on the image

To run every test:

poetry run python tests/test.py

This produces the following outputs, for each sample and OCR:

  • statistics about number of cards found, number of errors...
  • test.log: informations about the run
  • errors.txt: history of the number of errors made by the OCR
  • box_texts.txt: output of the OCR

Basic usage

Let's retrieve the decklist from the following screenshot: Screenshot

from mtgscan.text import MagicRecognition
from mtgscan.ocr.azure import Azure

azure = Azure()
rec = MagicRecognition(file_all_cards="all_cards.txt", file_keywords="Keywords.json")  # download card files from mtgjson if missing
box_texts = azure.image_to_box_texts("https://user-images.githubusercontent.com/49362475/105632710-fa07a180-5e54-11eb-91bb-c4710ef8168f.jpeg")
deck = rec.box_texts_to_deck(box_texts)
print(deck)

Output:

4 Ancient Tomb
4 Mishra's Factory
4 Mishra's Workshop
1 Strip Mine
1 Tolarian Academy
4 Wasteland
1 Sacrifice
1 Mox Ruby
1 Mox Emerald
1 Mox Jet
1 Mox Pearl
1 Mox Sapphire
1 Black Lotus
1 Mana Crypt
1 Sol Ring
4 Phyrexian Revoker
4 Arcbound Ravager
1 Thorn of Amethyst
4 Sphere of Resistance
4 Foundry Inspector
3 Chief of the Foundry
1 Trinisphere
1 Lodestone Golem
1 Mystic Forge
2 Fleetwheel Cruiser
1 Traxos, Scourge of Kroog
4 Walking Ballista
3 Stonecoil Serpent
1 Chalice of the Void

3 Mindbreak Trap
4 Leyline of the Void
2 Crucible of Worlds
4 Pithing Needle
2 Wurmcoil Engine

Task list

  • Tested on MTGO, Arena and IRL (simple) images
  • Handle sideboard (only on the right side)
  • Support for stacked cards
  • Add and compare OCR (GCP, AWS...)