camonet / README.md
Mattysmittttt's picture
Initial CamoNet release
ec97dbb verified
---
license: apache-2.0
language:
- en
tags:
- image-classification
- vision
- camouflage
- military
- osint
- dinov2
pipeline_tag: image-classification
library_name: transformers
base_model: facebook/dinov2-small
---
# CamoNet
A fine-grained military camouflage pattern classifier.
Given a photo of a uniform, vehicle, or fabric fragment, CamoNet predicts
which of **40 historical and contemporary military camouflage patterns** it
belongs to β€” along with country of origin, era, and visual family.
Built on a fine-tuned **DINOv2** backbone (`facebook/dinov2-small`), chosen
because its self-supervised ImageNet pre-training learns the kind of dense
texture features that camouflage classification depends on.
## Quick start
```python
from transformers import pipeline
clf = pipeline("image-classification", model="Mattysmittttt/camonet")
clf("path/to/uniform.jpg", top_k=3)
# [{'label': 'us_marpat_woodland', 'score': 0.91},
# {'label': 'ca_cadpat_tw', 'score': 0.04},
# {'label': 'us_aor2', 'score': 0.02}]
```
For richer output (origin, era, family) use the bundled `taxonomy.py`:
```python
from huggingface_hub import hf_hub_download
import importlib.util, sys
path = hf_hub_download("Mattysmittttt/camonet", "taxonomy.py")
spec = importlib.util.spec_from_file_location("camonet_tax", path)
tax = importlib.util.module_from_spec(spec); spec.loader.exec_module(tax)
print(tax.PATTERN_BY_ID["us_marpat_woodland"])
# Pattern(id='us_marpat_woodland', name='MARPAT Woodland',
# origin='USMC', era='2002-present', family='digital', notes=...)
```
## Pattern coverage (40 classes)
| Family | Count | Examples |
| ------------- | ----- | --------------------------------------------------------- |
| digital | 10 | MARPAT, CADPAT, UCP, EMR Digital Flora, Type 07, ROK Granite |
| blob | 8 | Flecktarn, AUSCAM, M90, TAZ 90, JGSDF, TTsKO, M75, Splittertarn |
| desert | 7 | Chocolate Chip, DCU 3-Color, AOR1, DPM Desert, Tropentarn |
| multi-terrain | 6 | MultiCam, OCP Scorpion W2, MTP, AMCU, Partizan, Kryptek Mandrake |
| woodland | 4 | M81 Woodland, ERDL, French CCE, Italian Vegetata |
| brushstroke | 4 | Tiger Stripe, DPM Woodland, KLMK, VSR-93 Flora |
| arid | 1 | A-TACS AU |
Full taxonomy with origin and era for each pattern lives in `taxonomy.py`.
## Intended uses
- **OSINT & journalism** β€” assist analysts in identifying camouflage patterns
in conflict imagery, photographs, and footage.
- **Museum & archival cataloguing** β€” auto-tag uniform collections.
- **Milsurp & collector tooling** β€” identify unknown patterns from photographs.
- **Airsoft, milsim, reenactment** β€” kit verification.
- **Educational / reference** β€” interactive teaching tool for military history.
## Limitations & out-of-scope use
- **Heavily worn, faded, or damaged fabric** drifts predictions toward visually
adjacent patterns. Treat low-confidence outputs as such.
- **Many real-world patterns share design DNA** (MARPAT ↔ AOR1/2 ↔ CADPAT).
A top-3 read is more honest than top-1 in those cases.
- **The model has not been trained on every pattern in existence** β€” it covers
~40 of the most widely-issued. Out-of-distribution patterns will be forced
into the closest learned class.
- **Not a person/face/identity classifier.** It looks at fabric, not faces.
- **Not a substitute for expert authentication** of historical garments.
## Training data
Composed from public web sources:
- eBay militaria listings (clean product photography, well-labeled)
- Reddit r/camo, r/Militariacollecting, r/milsurp (in-the-wild photos)
- Hand-curated reference plates per pattern
Actual scale used for this checkpoint: 3,080 labeled images across 40 patterns
(β‰ˆ77 per pattern average; min 14, max 137), stratified 85/15 train/val
(2,635 train / 445 val).
The dataset is **not redistributed** β€” only the trained weights are. The
scrape pipeline is included in the source repo so the dataset is reproducible.
## Training details
| Hyperparameter | Value |
| ---------------- | -------------------- |
| Backbone | `facebook/dinov2-small` (22M params) |
| Image size | 224Γ—224 |
| Optimizer | AdamW |
| Learning rate | 5e-5, cosine, 10% warmup |
| Weight decay | 0.05 |
| Batch size | 32 |
| Epochs | 8 (best checkpoint by top-1) |
| Augmentation | resize+crop, hflip, Β±10Β° rotation, light blur (no colour jitter β€” colour matters for camo) |
| Precision | fp32 (Apple Silicon MPS) |
## Evaluation
Reported on the held-out 15% validation split (445 images, 40 classes):
| Metric | Score |
| ------- | ------ |
| Top-1 | 0.7371 |
| Top-3 | 0.8652 |
Per-class confusion analysis is in `eval/confusion.png` once you run
`scripts/evaluate.py`.
## Bias, risks, ethical considerations
CamoNet identifies **fabric patterns**, not people, faces, vehicles as units,
or military formations. Its outputs are about textile design.
Camouflage classification is well-established public knowledge β€” pattern
catalogues like Camopedia have been freely available for over a decade, and
the patterns themselves are visible in countless public photographs, parades,
news coverage, and museum exhibits. The model does not provide capabilities
beyond what an attentive observer with reference material could already do.
That said, downstream use sits in the OSINT space, where claims based on a
single image carry real-world consequences. Users should:
- Treat predictions as **one signal among many**, not authoritative ID.
- Surface confidence scores, not just top-1 labels.
- Avoid using the model to make claims about individual identity, unit
attribution, or operational intent.
## Citation
```bibtex
@misc{camonet2026,
title = {CamoNet: Fine-Grained Military Camouflage Pattern Classification},
author = {Smith, Matt},
year = {2026},
url = {https://huggingface.co/Mattysmittttt/camonet}
}
```
## License
Apache-2.0 for the model weights and code.
Built on `facebook/dinov2-base` (Apache-2.0).