File size: 2,413 Bytes
c2d9c4d
2251fda
e9b0006
c2d9c4d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2251fda
 
c2d9c4d
 
 
 
2251fda
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2d9c4d
 
 
2251fda
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
---
license: agpl-3.0
library_name: collectorvision
tags:
- onnx
- object-detection
- card-detection
- mobilevit
base_model: apple/mobilevit-xx-small
---

# Cornelius — CCG Card Corner Detector

MobileViT-XXS backbone with a SimCC coordinate classification head, trained to locate the four corners of a CCG card (Magic: The Gathering, Pokémon, etc.) in a photograph or video frame.

## Model details

| Property | Value |
|---|---|
| Architecture | MobileViT-XXS + SimCC head |
| Input | 384×384 RGB, ImageNet-normalised |
| Outputs | corners (8 floats, normalised [0,1]), presence logit, sharpness scalar |
| Parameters | ~1.82M |
| File size | 8.6 MB (fp32 ONNX) |
| Codename | cornelius |
| Version | 1.0.0 (epoch 45) |

## Outputs

- **corners** — 8 floats `[x0,y0, x1,y1, x2,y2, x3,y3]` in TL→TR→BR→BL order, normalised [0,1]
- **presence** — raw logit; unreliable on blank images, prefer the sharpness gate
- **sharpness** — mean peak of the 8 SimCC softmax distributions; blank frames ≈ 0.008, valid cards ≈ 0.03–0.07

## Usage

The easiest way to use Cornelius is through the [CollectorVision](https://github.com/HanClinto/CollectorVision) library, which wires it into a full detect → dewarp → embed → identify pipeline:

```python
import collector_vision as cvg

cvid = cvg.Identifier(cvg.HFD("HanClinto/milo", "scryfall-mtg"))
result = cvid.identify("photo.jpg")
print(result.ids)  # {"scryfall_id": "..."}
```

### Direct ONNX usage

```python
import onnxruntime as ort
import numpy as np
from PIL import Image

session = ort.InferenceSession("model.onnx")

# Preprocess: resize to 384×384, ImageNet normalise, NCHW float32
img = Image.open("photo.jpg").convert("RGB").resize((384, 384))
x = np.array(img, dtype=np.float32) / 255.0
x = (x - [0.485, 0.456, 0.406]) / [0.229, 0.224, 0.225]
x = x.transpose(2, 0, 1)[None]  # (1, 3, 384, 384)

corners, presence, sharpness = session.run(None, {"pixel_values": x})
# corners: (1, 8) — x0,y0,x1,y1,x2,y2,x3,y3 normalised [0,1], TL→TR→BR→BL
# presence: (1, 1) — raw logit
# sharpness: (1, 1) — use > 0.02 as a card-present gate

if sharpness[0, 0] > 0.02:
    pts = corners[0].reshape(4, 2)  # (4, 2) normalised corners
```

## Part of CollectorVision

Used together with [HanClinto/milo](https://huggingface.co/HanClinto/milo) in the [CollectorVision](https://github.com/HanClinto/CollectorVision) inference library.