Instructions to use sroot/lgd-cards-gen4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- ultralytics
How to use sroot/lgd-cards-gen4 with ultralytics:
from ultralytics import YOLOvv11 model = YOLOvv11.from_pretrained("sroot/lgd-cards-gen4") source = 'http://images.cocodataset.org/val2017/000000039769.jpg' model.predict(source=source, save=True) - Notebooks
- Google Colab
- Kaggle
| license: agpl-3.0 | |
| tags: | |
| - object-detection | |
| - yolov11 | |
| - playing-cards | |
| - ultralytics | |
| - onnx | |
| library_name: ultralytics | |
| pipeline_tag: object-detection | |
| # lgd-cards-gen4 β playing-card corner-pip detector (spread-recall fine-tune) | |
| **4th-generation** card detector for [Live Game Defender](https://live-game-defender.cz), an on-prem | |
| computer-vision integrity monitor for live casino table games. Detects the **52 rank+suit corner | |
| index pips** (`AS`, `10H`, `KD`, β¦) on an overhead table camera β one card shows up to two pip | |
| boxes; whole-card assembly happens downstream in the tracker, not here. | |
| > **License / provenance.** AGPL-3.0. This is a fine-tune of **Ultralytics YOLO11s** (COCO | |
| > pre-trained), so the weights are a YOLO derivative β **not "ours"**. Downstream use inherits AGPL. | |
| > **β οΈ Not casino accuracy.** All numbers below are on our **own PoC / Czech Croupier Academy** | |
| > footage with **LLM-verified labels**, not human casino ground truth. Treat as PoC metrics only. | |
| ## Status: spread specialist β NOT the production model | |
| gen4 was activated on 2026-07-20 and **reverted the same day**: its gameplay-precision trade broke | |
| the ante-integrity pillar on gameplay footage. Two measured issues (KAS-35 E2E, | |
| `uth_player3_ante_paid.mp4`): **(a)** hot nested double-reads β it read a 7H pip's bare rank digit | |
| as "7C" at 73% confidence, minting a phantom board pair that faked "dealer qualifies"; **(b)** it | |
| missed two players' hole cards outright. **[`lgd-cards-gen3`](https://huggingface.co/sroot/lgd-cards-gen3) | |
| is the production/served model.** gen4 remains the best deck-spread specialist (45/52 live deck | |
| check vs fewer under gen3); the planned gen5 warm-starts from gen3's weights + this model's spread | |
| data and must beat both the spread gate and the gameplay E2E. | |
| ## Why gen4 | |
| gen4 targets the one thing prior gens were weak at: **recall on a fully spread deck** (the dealer | |
| fanning all 52 cards face-up β the KAS-52 "cards missing / only 1 card" report, and the input to the | |
| KAS-36 deck-completeness check). It is the same recipe as gen3 with one added dataset: **day-3 | |
| deck-spread video** (`lgd-cards-video-day3`). | |
| ## Metrics (frozen held-out real video, `eval_real.py`, serve-style 6Γ4 tiling @ 4K, threshold 50) | |
| Scored against the previous served model (**gen3** = day-2) in one run, both on the **same expanded | |
| 318-frame holdout** (225 prior frames + 93 newly-held-out deck-spread frames β never trained on): | |
| | | Recall (cards found) | Precision-proxy | | |
| |---|---|---| | |
| | **gen4 (this model)** | **0.786** | 0.752 | | |
| | gen3 (day-2, prior served) | 0.750 | 0.774 | | |
| On the **93 deck-spread-only** frames β the target scenario: | |
| | | Recall | count-of-52 unique codes (mean) | best frame | | |
| |---|---|---|---| | |
| | **gen4** | **0.665** | **26.2 / 52** | **32 / 52** | | |
| | gen3 | 0.574 | 23.0 / 52 | 24 / 52 | | |
| **+9 points of spread recall.** Normal-gameplay recall is held (~0.848 β 0.853). gen4 does **not** | |
| reach a full 52, and its precision-**proxy** dips β partly a genuine trade (it detects more | |
| aggressively) and partly an artifact: the LLM-made holdout GT is not exhaustive, so real cards gen4 | |
| recovers that the GT lacks score as false positives. It **fails the strict "beat the previous model | |
| on both axes" gate**; it was activated for the recall win on 2026-07-20 and reverted the same | |
| day (see Status above). Full numbers in `metrics.json`. | |
| > Numbering note: gen3's headline figure elsewhere (0.85) was on an older 225-frame holdout; on the | |
| > **same 318-frame** holdout used here gen3 scores 0.750, which is the fair comparison. Naming was | |
| > **unified 2026-07-20**: `genN` means the same model on HF, in the project's `generations/genN-*` | |
| > archive (this one: `generations/gen4-spread`) and in every doc. | |
| ## Files | |
| - `model.onnx` β deployable ONNX (dynamic batch) β the exact export served during its brief | |
| 2026-07-20 activation (not currently deployed; see Status). | |
| - `model.classes.json` β the 52 class names, in model output order. | |
| - `best.pt` β Ultralytics checkpoint (for resuming / re-export). | |
| - `metrics.json` β full eval incl. per-label recall and the reference-model comparison. | |
| ## Usage (onnxruntime, no Ultralytics at runtime) | |
| ```python | |
| import onnxruntime as ort, numpy as np, json | |
| sess = ort.InferenceSession("model.onnx", providers=["CUDAExecutionProvider", "CPUExecutionProvider"]) | |
| names = json.load(open("model.classes.json")) | |
| # letterbox your BGR frame to 640Γ640, NCHW float32 /255; run sess.run(None, {input: x}); | |
| # decode YOLO11 output [1,56,8400] -> boxes+52 class scores, NMS. For 4K, tile (serve uses 6Γ4). | |
| ``` | |
| The engine runs this tiled (full frame + a 6Γ4 overlap grid at 4K) at a confidence threshold of 50. | |
| ## Training | |
| YOLO11s (COCO) β fine-tuned 40 epochs (patience 15, batch 16, imgsz 640, seed 7) on the Roboflow | |
| `ow27d` base set (oversampled, not redistributed here β get it from | |
| [Roboflow Universe](https://universe.roboflow.com/augmented-startups/playing-cards-ow27d)) mixed with | |
| `lgd-cards-video-day1` + `-day2` + **`-day3`** (the new deck-spread tiles). Labels are | |
| detector-proposed, OpenAI-`gpt-5-mini`-verified against the closed 52-code vocabulary. | |
| ## Family | |
| Cards: [gen1](https://huggingface.co/sroot/lgd-cards-gen1) Β· [gen2](https://huggingface.co/sroot/lgd-cards-gen2) Β· [gen3](https://huggingface.co/sroot/lgd-cards-gen3) Β· **gen4 (this)** Β· Chips: [gen1](https://huggingface.co/sroot/lgd-chips-gen1) Β· [gen2](https://huggingface.co/sroot/lgd-chips-gen2) | |