Views
No views yet
Superseded by NationalLibraryOfScotland/card-detector-retinanet, a newer detector trained on the same collection.
index_card| Metric | Value |
|---|---|
| mAP@50 | 99.3% |
| mAP@50-95 | 99.1% |
| Precision | 99.9% |
| Recall | 98.9% |
| Version | Images | mAP@50-95 | What happened |
|---|---|---|---|
| v1 | 100 | 94.4% | SAM3 bootstrap → manual correction → train |
| v2 | 297 | 95.5% | Run v1 on new images → correct outputs → retrain |
| v3 | 905 | 99.2% | Run v2 on more images → correct → retrain |
1from ultralytics import YOLO
2from huggingface_hub import hf_hub_download
3
4# Download and load model
5model = YOLO(hf_hub_download(
6 repo_id="NationalLibraryOfScotland/archival-index-card-detector",
7 filename="model.pt"
8))
9
10# Run inference
11results = model.predict("scan.jpg")
12
13# Get bounding boxes
14for result in results:
15 boxes = result.boxes
16 for box in boxes:
17 x1, y1, x2, y2 = box.xyxy[0].tolist()
18 confidence = box.conf[0].item()
19 print(f"Index card detected at ({x1:.0f}, {y1:.0f}, {x2:.0f}, {y2:.0f}) with confidence {confidence:.2f}")1from ultralytics import YOLO
2from PIL import Image
3
4model = YOLO(hf_hub_download(
5 repo_id="NationalLibraryOfScotland/archival-index-card-detector",
6 filename="model.pt"
7))
8image = Image.open("scan.jpg")
9results = model.predict(image)
10
11for i, box in enumerate(results[0].boxes):
12 x1, y1, x2, y2 = box.xyxy[0].tolist()
13 # Add padding (10%)
14 w, h = x2 - x1, y2 - y1
15 pad = 0.1
16 x1 = max(0, x1 - w * pad)
17 y1 = max(0, y1 - h * pad)
18 x2 = min(image.width, x2 + w * pad)
19 y2 = min(image.height, y2 + h * pad)
20
21 cropped = image.crop((x1, y1, x2, y2))
22 cropped.save(f"card_{i}.jpg")1@misc{vanstrien2026indexcard,
2 author = {van Strien, Daniel},
3 title = {Archival Index Card Detector},
4 year = {2026},
5 publisher = {Hugging Face},
6 url = {https://huggingface.co/davanstrien/archival-index-card-detector}
7}