Reading an Uno table from a single photo

Year
2026
Context
EPFL · In-class Kaggle competition
Team
Team project

TL;DR

Problem
From one overhead photo of a game, read the center card, whose turn it is and every player’s hand, even when cards overlap, rotate and hide each other.
What we built
A lightweight (12M parameter) customized ResNet-18 with CBAM attention, pre-trained through a synthetic data pipeline, then moved to real camera photos with multi-stage fine-tuning.
Result
75% accuracy on a Kaggle dataset.
Stack
Python, PyTorch, Torchvision, Albumentations, OpenCV

With few labeled photos and no pretrained weights allowed, the network first learned on tables that never existed.

  • 75% ACCURACY · 12M PARAMS
  • PyTorch
  • Synthetic data
  • Sim-to-real
  • Attention
Diagram: a table photo split into four rotated hand zones and a center pile, feeding synthetic pre-training, real fine-tuning and a table-state output

Full size diagram (opens in a new tab)

The approach

  1. Split the table. Each photo is cut into five zones, four hands and the center pile, and every hand is rotated upright.
  2. Detect by counting. A 56 × 6 output head predicts how many copies (0–5) of each card and turn-token class a zone holds, so real labels never need bounding boxes.
  3. Model. A customized ResNet-18 trained from scratch, with CBAM channel and spatial attention on its last feature map, inside a 12M-parameter budget.
  4. Synthetic data. Card cut-outs composited onto real table textures with aggressive augmentations (±180° rotation, perspective distortion, lighting jitter, noise and occlusion holes) so the network can’t memorize textures. Rare turn tokens are oversampled 3×, and nothing is flipped, because mirrored digits don’t exist.
  5. Multi-stage fine-tuning. Pre-train on synthetic composites, then fine-tune on real table crops at a 10× lower learning rate with early stopping.

What it achieved

  • 75% accuracy. Measured on a Kaggle dataset of real table photos.
  • Lightweight: 12M parameters. A ResNet-18 trunk with hand-written CBAM attention, trained without pretrained weights.
  • 200 synthetic composites per card class. Each has random rotation, perspective, lighting, noise and occlusion, to bridge the sim-to-real gap.
  • Two learning rates, two worlds: 1e-3 on synthetic data, then 1e-4 on real photos, starting from the synthetic weights.

Notes

This was a course competition. The table photos and labels belong to the course, so they are not shown here, and the code stays private.