File size: 7,654 Bytes
ec97dbb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"""
CamoNet pattern taxonomy.

Each pattern has:
  - id:       short slug used as the class label (stable, snake_case)
  - name:     human-readable display name
  - origin:   country / military of origin
  - era:      rough date range of issue
  - family:   visual family (woodland / desert / arid / digital / brushstroke / blob / multi-terrain)
  - notes:    short blurb for the model card

Keep this list curated, not exhaustive. ~40 patterns is the sweet spot:
big enough to be impressive, small enough to actually train with limited data.
"""

from dataclasses import dataclass
from typing import Literal

Family = Literal[
    "woodland", "desert", "arid", "digital", "brushstroke",
    "blob", "multi-terrain", "winter", "urban", "naval"
]


@dataclass(frozen=True)
class Pattern:
    id: str
    name: str
    origin: str
    era: str
    family: Family
    notes: str


PATTERNS: list[Pattern] = [
    # --- United States ---
    Pattern("us_erdl", "ERDL", "United States", "1948-1980s", "woodland",
            "Early US 4-color woodland pattern, used in Vietnam."),
    Pattern("us_m81_woodland", "M81 Woodland", "United States", "1981-2006", "woodland",
            "Iconic 4-color US woodland; the BDU pattern."),
    Pattern("us_dcu_chocolate_chip", "Chocolate Chip (DBDU)", "United States", "1981-1991", "desert",
            "6-color desert with pebble-like spots; Gulf War era."),
    Pattern("us_dcu_3color", "3-Color Desert (DCU)", "United States", "1990-2000s", "desert",
            "Coffee-stain pattern that replaced Chocolate Chip."),
    Pattern("us_marpat_woodland", "MARPAT Woodland", "USMC", "2002-present", "digital",
            "USMC digital woodland; first widely-issued pixelated camo."),
    Pattern("us_marpat_desert", "MARPAT Desert", "USMC", "2002-present", "digital",
            "USMC digital desert variant of MARPAT."),
    Pattern("us_ucp", "UCP (ACU)", "US Army", "2004-2019", "digital",
            "Universal Camo Pattern; grey-green digital, controversially ineffective."),
    Pattern("us_multicam", "MultiCam", "United States (Crye)", "2010-present", "multi-terrain",
            "Crye Precision blended multi-environment pattern; OEF-CP, OCP."),
    Pattern("us_ocp_scorpion", "OCP Scorpion W2", "US Army", "2015-present", "multi-terrain",
            "Army's MultiCam-derivative replacement for UCP."),
    Pattern("us_aor1", "AOR1", "US Navy/NSW", "2010-present", "desert",
            "NSW desert digital, MARPAT-derived."),
    Pattern("us_aor2", "AOR2", "US Navy/NSW", "2010-present", "digital",
            "NSW woodland digital, MARPAT-derived."),
    Pattern("us_tigerstripe", "Tiger Stripe", "South Vietnam / US SF", "1962-1975", "brushstroke",
            "Asymmetric horizontal-stripe pattern; many regional variants."),

    # --- United Kingdom ---
    Pattern("uk_dpm_woodland", "DPM Woodland", "United Kingdom", "1968-2011", "brushstroke",
            "British Disruptive Pattern Material; brush-stroke 4-color."),
    Pattern("uk_dpm_desert", "DPM Desert", "United Kingdom", "1990-2011", "desert",
            "2-color desert DPM."),
    Pattern("uk_mtp", "MTP (Multi-Terrain Pattern)", "United Kingdom", "2010-present", "multi-terrain",
            "British MultiCam-derivative with DPM brush-stroke shapes."),

    # --- Germany ---
    Pattern("de_flecktarn", "Flecktarn", "Germany (Bundeswehr)", "1990-present", "blob",
            "5-color blob pattern; one of the most effective in temperate forest."),
    Pattern("de_tropentarn", "Tropentarn", "Germany (Bundeswehr)", "1990s-present", "desert",
            "3-color arid Flecktarn variant."),
    Pattern("de_splittertarn", "Splittertarn", "Germany (Wehrmacht)", "1931-1945", "blob",
            "WW2-era angular splinter pattern."),

    # --- USSR / Russia ---
    Pattern("ru_klmk", "KLMK", "USSR", "1968-1990s", "brushstroke",
            "Soviet 'silver leaf' sun-ray 2-color oversuit pattern."),
    Pattern("ru_ttsko", "TTsKO (Butan)", "USSR", "1984-2000s", "blob",
            "Three-color Soviet computer-generated pattern."),
    Pattern("ru_vsr_93", "VSR-93 (Flora)", "Russia", "1993-2000s", "brushstroke",
            "Vertical brush-stroke 'Flora' pattern."),
    Pattern("ru_emr_digital_flora", "EMR (Digital Flora)", "Russia", "2008-present", "digital",
            "Russian Armed Forces digital pattern; pixelated greens."),
    Pattern("ru_surpat", "SURPAT", "Russia (Survival Corps)", "2010s-present", "digital",
            "Commercial Russian multi-terrain digital."),
    Pattern("ru_partizan", "Partizan / Spectre", "Russia (SSO)", "2000s-present", "multi-terrain",
            "SSO Tactical 'leaf' pattern; layered foliage shapes."),

    # --- Other NATO / Western ---
    Pattern("ca_cadpat_tw", "CADPAT TW", "Canada", "1997-present", "digital",
            "Canadian Disruptive Pattern; first issued digital camo (predates MARPAT)."),
    Pattern("ca_cadpat_ar", "CADPAT AR", "Canada", "2000s-present", "desert",
            "Arid CADPAT variant."),
    Pattern("fr_cce", "CCE F1", "France", "1991-2010s", "woodland",
            "Centre Europe; French M81-style woodland."),
    Pattern("fr_daguet", "Daguet", "France", "1991-2010s", "desert",
            "French desert pattern, Gulf War era."),
    Pattern("it_vegetata", "Vegetata", "Italy", "2004-present", "woodland",
            "Italian 4-color fractal-style woodland."),
    Pattern("au_auscam", "AUSCAM (DPCU)", "Australia", "1982-2014", "blob",
            "Australian 'hearts and bunnies' 5-color blob pattern."),
    Pattern("au_amcu", "AMCU", "Australia", "2014-present", "multi-terrain",
            "Australian MultiCam-derivative replacement for DPCU."),
    Pattern("se_m90", "M90", "Sweden", "1990-present", "blob",
            "Swedish angular 4-color splinter; very distinctive."),
    Pattern("ch_taz_90", "TAZ 90", "Switzerland", "1990-present", "blob",
            "Swiss 5-color leaf/blob pattern."),
    Pattern("no_m75", "M75", "Norway", "1975-2000s", "blob",
            "Norwegian 3-color blob pattern."),

    # --- Asia ---
    Pattern("cn_type07_universal", "Type 07 Universal", "China (PLA)", "2007-present", "digital",
            "Chinese Type 07 woodland-leaning digital."),
    Pattern("cn_type07_desert", "Type 07 Desert", "China (PLA)", "2007-present", "digital",
            "Type 07 arid variant."),
    Pattern("kr_granite", "ROK Granite", "South Korea", "2014-present", "digital",
            "Korean digital pattern with granite-like color blocks."),
    Pattern("jp_jgsdf", "JGSDF Type II", "Japan", "1991-present", "blob",
            "Japan Ground SDF pinkish-brown tinted blob pattern."),

    # --- Commercial / specialty ---
    Pattern("commercial_kryptek_mandrake", "Kryptek Mandrake", "United States (commercial)", "2012-present", "multi-terrain",
            "Commercial layered reptilian-scale pattern."),
    Pattern("commercial_atacs_au", "A-TACS AU", "United States (commercial)", "2009-present", "arid",
            "Commercial arid-urban 'pixelated organic' pattern."),
]


PATTERN_BY_ID: dict[str, Pattern] = {p.id: p for p in PATTERNS}
LABELS: list[str] = [p.id for p in PATTERNS]
LABEL2ID: dict[str, int] = {label: i for i, label in enumerate(LABELS)}
ID2LABEL: dict[int, str] = {i: label for i, label in enumerate(LABELS)}
NUM_LABELS: int = len(LABELS)


if __name__ == "__main__":
    print(f"CamoNet taxonomy: {NUM_LABELS} patterns across {len(set(p.family for p in PATTERNS))} families")
    for fam in sorted(set(p.family for p in PATTERNS)):
        members = [p for p in PATTERNS if p.family == fam]
        print(f"  {fam:15s} ({len(members):2d}): {', '.join(m.id for m in members)}")