dgenerate-ultralytics-headless 8.3.248__py3-none-any.whl → 8.3.250__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dgenerate-ultralytics-headless
3
- Version: 8.3.248
3
+ Version: 8.3.250
4
4
  Summary: Automatically built Ultralytics package with python-opencv-headless dependency instead of python-opencv
5
5
  Author-email: Glenn Jocher <glenn.jocher@ultralytics.com>, Jing Qiu <jing.qiu@ultralytics.com>
6
6
  Maintainer-email: Ultralytics <hello@ultralytics.com>
@@ -1,4 +1,4 @@
1
- dgenerate_ultralytics_headless-8.3.248.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
1
+ dgenerate_ultralytics_headless-8.3.250.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
2
2
  tests/__init__.py,sha256=bCox_hLdGRFYGLb2kd722VdNP2zEXNYNuLLYtqZSrbw,804
3
3
  tests/conftest.py,sha256=mOy9lGpNp7lk1hHl6_pVE0f9cU-72gnkoSm4TO-CNZU,2318
4
4
  tests/test_cli.py,sha256=GhIFHi-_WIJpDgoGNRi0DnjbfwP1wHbklBMnkCM-P_4,5464
@@ -8,11 +8,11 @@ tests/test_exports.py,sha256=5G5EgDmars6d-N7TVnJdDFWId0IJs-yw03DvdQIjrNU,14246
8
8
  tests/test_integrations.py,sha256=6QgSh9n0J04RdUYz08VeVOnKmf4S5MDEQ0chzS7jo_c,6220
9
9
  tests/test_python.py,sha256=viMvRajIbDZdm64hRRg9i8qZ1sU9frwB69e56mxwEXk,29266
10
10
  tests/test_solutions.py,sha256=CIaphpmOXgz9AE9xcm1RWODKrwGfZLCc84IggGXArNM,14122
11
- ultralytics/__init__.py,sha256=3s1nuBps-pxOoh0FBkRcxTAWjSIgHPexA-U-3STiLm8,1302
11
+ ultralytics/__init__.py,sha256=v-hVhlejM2hHyVyOWQ59-HPirtK5Go1IZS0C8EMKfKY,1302
12
12
  ultralytics/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
13
13
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
14
14
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
15
- ultralytics/cfg/__init__.py,sha256=msy7NE7le831rv5-eRdLFkHRkf8o7m07HRkY4810n9s,40208
15
+ ultralytics/cfg/__init__.py,sha256=T5bv7NdySatnqEvtOW4_qojIC3pmAbp0GlCwyk0RazU,40368
16
16
  ultralytics/cfg/default.yaml,sha256=KKENSHolDSto1HJVGjBvTXvz9ae-XMcYRzKrjU3QfZc,8912
17
17
  ultralytics/cfg/datasets/Argoverse.yaml,sha256=QGpdh3Hj5dFrvbsaE_8rAVj9BO4XpKTB7uhXaTTnE-o,3364
18
18
  ultralytics/cfg/datasets/DOTAv1.5.yaml,sha256=KE7VC-ZMDSei1pLPm-pdk_ZAMRU_gLwGgtIQNbwp6dA,1212
@@ -22,6 +22,7 @@ ultralytics/cfg/datasets/HomeObjects-3K.yaml,sha256=xEtSqEad-rtfGuIrERjjhdISggmP
22
22
  ultralytics/cfg/datasets/ImageNet.yaml,sha256=N9NHhIgnlNIBqZZbzQZAW3aCnz6RSXQABnopaDs5BmE,42529
23
23
  ultralytics/cfg/datasets/Objects365.yaml,sha256=8Bl-NAm0mlMW8EfMsz39JZo-HCvmp0ejJXaMeoHTpqw,9649
24
24
  ultralytics/cfg/datasets/SKU-110K.yaml,sha256=xvRkq3SdDOwBA91U85bln7HTXkod5MvFX6pt1PxTjJE,2609
25
+ ultralytics/cfg/datasets/TT100K.yaml,sha256=me7mEq3qDeL9_DpQBRS9jCVxsuByKuDBOwB0ePX0_LE,7369
25
26
  ultralytics/cfg/datasets/VOC.yaml,sha256=XpaegRHjp7xZnenOuA9zgg2lQURSL-o7mLQwzIKKuqM,3803
26
27
  ultralytics/cfg/datasets/VisDrone.yaml,sha256=PfudojW5av_5q-dC9VsG_xhvuv9cTGEpRp4loXCJ4Ng,3397
27
28
  ultralytics/cfg/datasets/african-wildlife.yaml,sha256=6UfO_gnwJEDVq05p72IMJfkTIKZlXKNLSeKru-JyTrQ,915
@@ -127,7 +128,7 @@ ultralytics/engine/exporter.py,sha256=Ncf5GK5xAqSu0DH-6z5V53qZB7LstDJFTMF5a-7VQf
127
128
  ultralytics/engine/model.py,sha256=61ea1rB0wmL0CCaEr8p5gzneH0eL55OOMaTcFt8fR80,53079
128
129
  ultralytics/engine/predictor.py,sha256=neYmNDX27Vv3ggk9xqaKlH6XzB2vlFIghU5o7ZC0zFo,22838
129
130
  ultralytics/engine/results.py,sha256=DomI01voqR_i7v8LhDGb6jWCprWB4H6I436GSO2NMBY,68030
130
- ultralytics/engine/trainer.py,sha256=mqVrhL8xnJwwKJVjxDEiiwu0WH48Ne5dB4SXxlxyHh4,45479
131
+ ultralytics/engine/trainer.py,sha256=UQfxbcT983v9bXYNYH5MvzZmuega0ZUW-KqUoq4vxjE,45798
131
132
  ultralytics/engine/tuner.py,sha256=qiozSxYC-Hk1TQgyftrYTKkqLrrwFzjjkT6mOYR3Vjc,21460
132
133
  ultralytics/engine/validator.py,sha256=2rqdVt4hB9ruMJq-L7PbaCNFwuERS7ZHdVSg91RM3wk,17761
133
134
  ultralytics/hub/__init__.py,sha256=Z0K_E00jzQh90b18q3IDChwVmTvyIYp6C00sCV-n2F8,6709
@@ -228,7 +229,7 @@ ultralytics/solutions/distance_calculation.py,sha256=RcpRDodEHAJUug9tobtQKt5_byS
228
229
  ultralytics/solutions/heatmap.py,sha256=DUyV5UFsOwZ8ArN4BtW8Vm3ps8_VZXc6VP0uiKyGDWY,5481
229
230
  ultralytics/solutions/instance_segmentation.py,sha256=eggk1uWCZ-6cp0YfxCGVUwnKS6xqJua946oxafjAXGk,3778
230
231
  ultralytics/solutions/object_blurrer.py,sha256=EZrv3oU68kEaahAxlhk9cF5ZKFtoVaW8bDB4Css9xe0,3981
231
- ultralytics/solutions/object_counter.py,sha256=nguTJebkCi_sCsP1cz2jABfi0kPOg2DdNZeS2xG-CeE,9354
232
+ ultralytics/solutions/object_counter.py,sha256=OpMSLlenDK-cLvCgCOoKbqMXIZrngyqP8DP6ZeEnWL8,9355
232
233
  ultralytics/solutions/object_cropper.py,sha256=WRbrfXAR5aD6PQBqJ-BvcVaiaqta_9YeTlXN2dY274s,3510
233
234
  ultralytics/solutions/parking_management.py,sha256=FQKeLEiwnTmRcXqsNOlOt9GTFPjkyvnE5pwwKnneJa4,13770
234
235
  ultralytics/solutions/queue_management.py,sha256=NlVX6PMEaffjoZjfQrVyayaDUdtc0JF8GzTQrZFjpCg,4371
@@ -254,7 +255,7 @@ ultralytics/utils/__init__.py,sha256=JfvODTB4mG_JOhTeCiPtq0iCEgiCh14hJf195rnOhLQ
254
255
  ultralytics/utils/autobatch.py,sha256=jiE4m_--H9UkXFDm_FqzcZk_hSTCGpS72XdVEKgZwAo,5114
255
256
  ultralytics/utils/autodevice.py,sha256=rXlPuo-iX-vZ4BabmMGEGh9Uxpau4R7Zlt1KCo9Xfyc,8892
256
257
  ultralytics/utils/benchmarks.py,sha256=S_W4S4pe2ktSRdSuWb6m09UEFQmZhmjl943bbo67hOI,32277
257
- ultralytics/utils/checks.py,sha256=QAy9nCtgBCCcweJhB4Wa_5SE25g5PF07lXJOhQOBssM,38312
258
+ ultralytics/utils/checks.py,sha256=NFtryEVFsmY35OsTDS-iEFKmU7nT9TVf_5qkUOF6f1U,38997
258
259
  ultralytics/utils/cpu.py,sha256=OksKOlX93AsbSsFuoYvLXRXgpkOibrZSwQyW6lipt4Q,3493
259
260
  ultralytics/utils/dist.py,sha256=hOuY1-unhQAY-uWiZw3LWw36d1mqJuYK75NdlwB4oKE,4131
260
261
  ultralytics/utils/downloads.py,sha256=IyiGjjXqOyf1B0qLMk7vE6sSQ8s232OhKS8aj9XbTgs,22883
@@ -265,7 +266,7 @@ ultralytics/utils/git.py,sha256=UdqeIiiEzg1qkerAZrg5YtTYPuJYwrpxW9N_6Pq6s8U,5501
265
266
  ultralytics/utils/instance.py,sha256=11mhefvTI9ftMqSirXuiViAi0Fxlo6v84qvNxfRNUoE,18862
266
267
  ultralytics/utils/logger.py,sha256=T5iaNnaqbCvx_FZf1dhVkr5FVxyxb4vO17t4SJfCIhg,19132
267
268
  ultralytics/utils/loss.py,sha256=t-z7qkvqF8OtuRHrj2wmvClZV2CCumIRi9jnqkc9i_A,39573
268
- ultralytics/utils/metrics.py,sha256=dpS9jSPf3dqozcrkiraKhYBI03U2t-_lt8pWNCijGww,69152
269
+ ultralytics/utils/metrics.py,sha256=SpyMGnuRwwmorJqSdUsDQquVpGmgfj1X3PNDiw_ZZWM,69152
269
270
  ultralytics/utils/nms.py,sha256=zv1rOzMF6WU8Kdk41VzNf1H1EMt_vZHcbDFbg3mnN2o,14248
270
271
  ultralytics/utils/ops.py,sha256=nWvTLJSBeW_XrxCy5Ytxl7sZJHp2sRqyCv4mm8QwYnw,25797
271
272
  ultralytics/utils/patches.py,sha256=mD3slAMAhcezzP42_fOWmacNMU6zXB68Br4_EBCyIjs,7117
@@ -283,7 +284,7 @@ ultralytics/utils/callbacks/dvc.py,sha256=YT0Sa5P8Huj8Fn9jM2P6MYzUY3PIVxsa5BInVi
283
284
  ultralytics/utils/callbacks/hub.py,sha256=fVLqqr3ZM6hoYFlVMEeejfq1MWDrkWCskPFOG3HGILQ,4159
284
285
  ultralytics/utils/callbacks/mlflow.py,sha256=wCXjQgdufp9LYujqMzLZOmIOur6kvrApHNeo9dA7t_g,5323
285
286
  ultralytics/utils/callbacks/neptune.py,sha256=_vt3cMwDHCR-LyT3KtRikGpj6AG11oQ-skUUUUdZ74o,4391
286
- ultralytics/utils/callbacks/platform.py,sha256=L7P5ttko-QVkig2y3r-D8YxfOWb7lNAan4iuMXxQ_u4,11682
287
+ ultralytics/utils/callbacks/platform.py,sha256=R9KcdNQUKs-mS_oOxXeKK51uYWlGhVkvQnarKO6qmOk,14804
287
288
  ultralytics/utils/callbacks/raytune.py,sha256=Y0dFyNZVRuFovSh7nkgUIHTQL3xIXOACElgHuYbg_5I,1278
288
289
  ultralytics/utils/callbacks/tensorboard.py,sha256=PTJYvD2gqRUN8xw5VoTjvKnu2adukLfvhMlDgTnTiFU,4952
289
290
  ultralytics/utils/callbacks/wb.py,sha256=ghmL3gigOa-z_F54-TzMraKw9MAaYX-Wk4H8dLoRvX8,7705
@@ -291,8 +292,8 @@ ultralytics/utils/export/__init__.py,sha256=Cfh-PwVfTF_lwPp-Ss4wiX4z8Sm1XRPklsqd
291
292
  ultralytics/utils/export/engine.py,sha256=23-lC6dNsmz5vprSJzaN7UGNXrFlVedNcqhlOH_IXes,9956
292
293
  ultralytics/utils/export/imx.py,sha256=2_mcNzqRIk5LB92JofqNYLN0kkQke1UgKT2jWmEy_l4,13300
293
294
  ultralytics/utils/export/tensorflow.py,sha256=igYzwbdblb9YgfV4Jgl5lMvynuVRcF51dAzI7j-BBI0,9966
294
- dgenerate_ultralytics_headless-8.3.248.dist-info/METADATA,sha256=qyUIMMG9J2dBqH73RFEcAizFoag0j0t3iGhnz-_ZTDA,38799
295
- dgenerate_ultralytics_headless-8.3.248.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
296
- dgenerate_ultralytics_headless-8.3.248.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
297
- dgenerate_ultralytics_headless-8.3.248.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
298
- dgenerate_ultralytics_headless-8.3.248.dist-info/RECORD,,
295
+ dgenerate_ultralytics_headless-8.3.250.dist-info/METADATA,sha256=iK_C4dYeMXmNoXQZhkhEq_uxDjF4SDef5-gWVXAZEgc,38799
296
+ dgenerate_ultralytics_headless-8.3.250.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
297
+ dgenerate_ultralytics_headless-8.3.250.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
298
+ dgenerate_ultralytics_headless-8.3.250.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
299
+ dgenerate_ultralytics_headless-8.3.250.dist-info/RECORD,,
ultralytics/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- __version__ = "8.3.248"
3
+ __version__ = "8.3.250"
4
4
 
5
5
  import importlib
6
6
  import os
@@ -410,7 +410,9 @@ def get_save_dir(args: SimpleNamespace, name: str | None = None) -> Path:
410
410
  else:
411
411
  from ultralytics.utils.files import increment_path
412
412
 
413
- project = args.project or (ROOT.parent / "tests/tmp/runs" if TESTS_RUNNING else RUNS_DIR) / args.task
413
+ runs = (ROOT.parent / "tests/tmp/runs" if TESTS_RUNNING else RUNS_DIR) / args.task
414
+ nested = args.project and len(Path(args.project).parts) > 1 # e.g. "user/project" or "org\repo"
415
+ project = runs / args.project if nested else args.project or runs
414
416
  name = name or args.name or f"{args.mode}"
415
417
  save_dir = increment_path(Path(project) / name, exist_ok=args.exist_ok if RANK in {-1, 0} else True)
416
418
 
@@ -0,0 +1,356 @@
1
+ # Ultralytics YOLO 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
+ # Tsinghua-Tencent 100K Traffic Sign Detection Dataset
3
+ # Dataset: https://cg.cs.tsinghua.edu.cn/traffic-sign/
4
+ # Paper: Traffic-Sign Detection and Classification in the Wild (CVPR 2016)
5
+ # Documentation: 100,000 images with 30,000+ traffic sign annotations
6
+ # Example usage: yolo train data=TT100K.yaml
7
+ # parent
8
+ # ├── ultralytics
9
+ # └── datasets
10
+ # └── TT100K ← downloads here (~30 GB with images)
11
+
12
+ # Train/val/test sets
13
+ path: TT100K # dataset root dir
14
+ train: images/train # train images (relative to 'path')
15
+ val: images/val # val images (relative to 'path')
16
+ test: images/test # test images (relative to 'path')
17
+
18
+ # Classes
19
+ nc: 221
20
+ names:
21
+ 0: pl5
22
+ 1: pl10
23
+ 2: pl15
24
+ 3: pl20
25
+ 4: pl25
26
+ 5: pl30
27
+ 6: pl40
28
+ 7: pl50
29
+ 8: pl60
30
+ 9: pl70
31
+ 10: pl80
32
+ 11: pl90
33
+ 12: pl100
34
+ 13: pl110
35
+ 14: pl120
36
+ 15: pm5
37
+ 16: pm10
38
+ 17: pm13
39
+ 18: pm15
40
+ 19: pm20
41
+ 20: pm25
42
+ 21: pm30
43
+ 22: pm35
44
+ 23: pm40
45
+ 24: pm46
46
+ 25: pm50
47
+ 26: pm55
48
+ 27: pm8
49
+ 28: pn
50
+ 29: pne
51
+ 30: ph4
52
+ 31: ph4.5
53
+ 32: ph5
54
+ 33: ps
55
+ 34: pg
56
+ 35: ph1.5
57
+ 36: ph2
58
+ 37: ph2.1
59
+ 38: ph2.2
60
+ 39: ph2.4
61
+ 40: ph2.5
62
+ 41: ph2.8
63
+ 42: ph2.9
64
+ 43: ph3
65
+ 44: ph3.2
66
+ 45: ph3.5
67
+ 46: ph3.8
68
+ 47: ph4.2
69
+ 48: ph4.3
70
+ 49: ph4.8
71
+ 50: ph5.3
72
+ 51: ph5.5
73
+ 52: pb
74
+ 53: pr10
75
+ 54: pr100
76
+ 55: pr20
77
+ 56: pr30
78
+ 57: pr40
79
+ 58: pr45
80
+ 59: pr50
81
+ 60: pr60
82
+ 61: pr70
83
+ 62: pr80
84
+ 63: pr90
85
+ 64: p1
86
+ 65: p2
87
+ 66: p3
88
+ 67: p4
89
+ 68: p5
90
+ 69: p6
91
+ 70: p7
92
+ 71: p8
93
+ 72: p9
94
+ 73: p10
95
+ 74: p11
96
+ 75: p12
97
+ 76: p13
98
+ 77: p14
99
+ 78: p15
100
+ 79: p16
101
+ 80: p17
102
+ 81: p18
103
+ 82: p19
104
+ 83: p20
105
+ 84: p21
106
+ 85: p22
107
+ 86: p23
108
+ 87: p24
109
+ 88: p25
110
+ 89: p26
111
+ 90: p27
112
+ 91: p28
113
+ 92: pa8
114
+ 93: pa10
115
+ 94: pa12
116
+ 95: pa13
117
+ 96: pa14
118
+ 97: pb5
119
+ 98: pc
120
+ 99: pg
121
+ 100: ph1
122
+ 101: ph1.3
123
+ 102: ph1.5
124
+ 103: ph2
125
+ 104: ph3
126
+ 105: ph4
127
+ 106: ph5
128
+ 107: pi
129
+ 108: pl0
130
+ 109: pl4
131
+ 110: pl5
132
+ 111: pl8
133
+ 112: pl10
134
+ 113: pl15
135
+ 114: pl20
136
+ 115: pl25
137
+ 116: pl30
138
+ 117: pl35
139
+ 118: pl40
140
+ 119: pl50
141
+ 120: pl60
142
+ 121: pl65
143
+ 122: pl70
144
+ 123: pl80
145
+ 124: pl90
146
+ 125: pl100
147
+ 126: pl110
148
+ 127: pl120
149
+ 128: pm2
150
+ 129: pm8
151
+ 130: pm10
152
+ 131: pm13
153
+ 132: pm15
154
+ 133: pm20
155
+ 134: pm25
156
+ 135: pm30
157
+ 136: pm35
158
+ 137: pm40
159
+ 138: pm46
160
+ 139: pm50
161
+ 140: pm55
162
+ 141: pn
163
+ 142: pne
164
+ 143: po
165
+ 144: pr10
166
+ 145: pr100
167
+ 146: pr20
168
+ 147: pr30
169
+ 148: pr40
170
+ 149: pr45
171
+ 150: pr50
172
+ 151: pr60
173
+ 152: pr70
174
+ 153: pr80
175
+ 154: ps
176
+ 155: w1
177
+ 156: w2
178
+ 157: w3
179
+ 158: w5
180
+ 159: w8
181
+ 160: w10
182
+ 161: w12
183
+ 162: w13
184
+ 163: w16
185
+ 164: w18
186
+ 165: w20
187
+ 166: w21
188
+ 167: w22
189
+ 168: w24
190
+ 169: w28
191
+ 170: w30
192
+ 171: w31
193
+ 172: w32
194
+ 173: w34
195
+ 174: w35
196
+ 175: w37
197
+ 176: w38
198
+ 177: w41
199
+ 178: w42
200
+ 179: w43
201
+ 180: w44
202
+ 181: w45
203
+ 182: w46
204
+ 183: w47
205
+ 184: w48
206
+ 185: w49
207
+ 186: w50
208
+ 187: w51
209
+ 188: w52
210
+ 189: w53
211
+ 190: w54
212
+ 191: w55
213
+ 192: w56
214
+ 193: w57
215
+ 194: w58
216
+ 195: w59
217
+ 196: w60
218
+ 197: w62
219
+ 198: w63
220
+ 199: w66
221
+ 200: i1
222
+ 201: i2
223
+ 202: i3
224
+ 203: i4
225
+ 204: i5
226
+ 205: i6
227
+ 206: i7
228
+ 207: i8
229
+ 208: i9
230
+ 209: i10
231
+ 210: i11
232
+ 211: i12
233
+ 212: i13
234
+ 213: i14
235
+ 214: i15
236
+ 215: il60
237
+ 216: il80
238
+ 217: il100
239
+ 218: il110
240
+ 219: io
241
+ 220: ip
242
+
243
+ # Download script/URL (optional) ---------------------------------------------------------------------------------------
244
+ download: |
245
+ import os
246
+ import json
247
+ import shutil
248
+ from pathlib import Path
249
+ from ultralytics.utils.downloads import download
250
+ from ultralytics.utils import TQDM
251
+
252
+ def tt100k2yolo(dir):
253
+ """Convert TT100K annotations to YOLO format."""
254
+ from PIL import Image
255
+
256
+ data_dir = dir / "data"
257
+ anno_file = data_dir / "annotations.json"
258
+
259
+ print("Loading annotations...")
260
+ with open(anno_file, 'r', encoding='utf-8') as f:
261
+ data = json.load(f)
262
+
263
+ # Get all unique classes
264
+ classes = set()
265
+ for img_id, img_data in data['imgs'].items():
266
+ for obj in img_data.get('objects', []):
267
+ classes.add(obj['category'])
268
+ class_to_idx = {cls: idx for idx, cls in enumerate(yaml["names"]) if cls in classes}
269
+ class_to_idx = {cls: idx for idx, cls in enumerate(classes)}
270
+
271
+ print(f"Found {len(classes)} traffic sign classes")
272
+
273
+ # Create directories
274
+ for split in ['train', 'val', 'test']:
275
+ (dir / 'images' / split).mkdir(parents=True, exist_ok=True)
276
+ (dir / 'labels' / split).mkdir(parents=True, exist_ok=True)
277
+
278
+ print("Converting annotations to YOLO format...")
279
+ for img_id, img_data in TQDM(data['imgs'].items(), desc="Processing"):
280
+ img_path_str = img_data['path']
281
+ if 'train' in img_path_str:
282
+ split = 'train'
283
+ elif 'test' in img_path_str:
284
+ split = 'test'
285
+ else:
286
+ split = 'val'
287
+
288
+ # Source and destination paths
289
+ src_img = data_dir / img_path_str
290
+ if not src_img.exists():
291
+ continue
292
+
293
+ img_name = src_img.name
294
+ dst_img = dir / 'images' / split / img_name
295
+
296
+ # Get image dimensions
297
+ try:
298
+ with Image.open(src_img) as img:
299
+ img_width, img_height = img.size
300
+ except Exception as e:
301
+ print(f"Error reading {src_img}: {e}")
302
+ continue
303
+ shutil.copy2(src_img, dst_img)
304
+ label_file = dir / 'labels' / split / f"{src_img.stem}.txt"
305
+ lines = []
306
+
307
+ for obj in img_data.get('objects', []):
308
+ category = obj['category']
309
+ if category not in class_to_idx:
310
+ continue
311
+
312
+ bbox = obj['bbox']
313
+ xmin, ymin = bbox['xmin'], bbox['ymin']
314
+ xmax, ymax = bbox['xmax'], bbox['ymax']
315
+
316
+ # Convert to YOLO format (normalized center coordinates and dimensions)
317
+ x_center = ((xmin + xmax) / 2.0) / img_width
318
+ y_center = ((ymin + ymax) / 2.0) / img_height
319
+ width = (xmax - xmin) / img_width
320
+ height = (ymax - ymin) / img_height
321
+
322
+ # Ensure valid coordinates
323
+ x_center = max(0, min(1, x_center))
324
+ y_center = max(0, min(1, y_center))
325
+ width = max(0, min(1, width))
326
+ height = max(0, min(1, height))
327
+
328
+ cls_idx = class_to_idx[category]
329
+ lines.append(f"{cls_idx} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")
330
+
331
+ # Write label file
332
+ if lines:
333
+ label_file.write_text("".join(lines), encoding="utf-8")
334
+
335
+ print(f"Conversion complete!")
336
+ print(f"Found {len(classes)} classes: {classes[:10]}..." if len(classes) > 10 else f"Classes: {classes}")
337
+
338
+ return classes
339
+
340
+ # Download dataset
341
+ dir = Path(yaml['path']) # dataset root dir
342
+
343
+ # TT100K dataset URLs
344
+ urls = [
345
+ 'https://cg.cs.tsinghua.edu.cn/traffic-sign/data_model_code/data.zip', # Main dataset with annotations
346
+ ]
347
+
348
+ print("Downloading TT100K dataset...")
349
+ print("Note: This dataset is large (~30GB). Download may take some time.")
350
+ print("Dataset is under CC-BY-NC license for non-commercial use only.")
351
+
352
+ # Download and extract
353
+ download(urls, dir=dir, unzip=True, delete=False, curl=False, threads=1)
354
+
355
+ # Convert dataset in YOLO format
356
+ classes = tt100k2yolo(dir)
@@ -631,13 +631,17 @@ class BaseTrainer:
631
631
  try:
632
632
  if self.args.task == "classify":
633
633
  data = check_cls_dataset(self.args.data)
634
- elif str(self.args.data).rsplit(".", 1)[-1] == "ndjson":
635
- # Convert NDJSON to YOLO format
634
+ elif str(self.args.data).rsplit(".", 1)[-1] == "ndjson" or (
635
+ str(self.args.data).startswith("ul://") and "/datasets/" in str(self.args.data)
636
+ ):
637
+ # Convert NDJSON to YOLO format (including ul:// platform dataset URIs)
636
638
  import asyncio
637
639
 
638
640
  from ultralytics.data.converter import convert_ndjson_to_yolo
641
+ from ultralytics.utils.checks import check_file
639
642
 
640
- yaml_path = asyncio.run(convert_ndjson_to_yolo(self.args.data))
643
+ ndjson_file = check_file(self.args.data) # Resolve ul:// or URL to local .ndjson file
644
+ yaml_path = asyncio.run(convert_ndjson_to_yolo(ndjson_file))
641
645
  self.args.data = str(yaml_path)
642
646
  data = check_det_dataset(self.args.data)
643
647
  elif str(self.args.data).rsplit(".", 1)[-1] in {"yaml", "yml"} or self.args.task in {
@@ -129,7 +129,7 @@ class ObjectCounter(BaseSolution):
129
129
  str.capitalize(key): f"{'IN ' + str(value['IN']) if self.show_in else ''} "
130
130
  f"{'OUT ' + str(value['OUT']) if self.show_out else ''}".strip()
131
131
  for key, value in self.classwise_count.items()
132
- if value["IN"] != 0 or (value["OUT"] != 0 and (self.show_in or self.show_out))
132
+ if (value["IN"] != 0 and self.show_in) or (value["OUT"] != 0 and self.show_out)
133
133
  }
134
134
  if labels_dict:
135
135
  self.annotator.display_analytics(plot_im, labels_dict, (104, 31, 17), (255, 255, 255), self.margin)
@@ -32,6 +32,85 @@ except (AssertionError, ImportError):
32
32
  _api_key = None
33
33
 
34
34
 
35
+ def resolve_platform_uri(uri, hard=True):
36
+ """Resolve ul:// URIs to signed URLs by authenticating with Ultralytics Platform.
37
+
38
+ Formats:
39
+ ul://username/datasets/slug -> Returns signed URL to NDJSON file
40
+ ul://username/project/model -> Returns signed URL to .pt file
41
+
42
+ Args:
43
+ uri (str): Platform URI starting with "ul://".
44
+ hard (bool): Whether to raise an error if resolution fails (FileNotFoundError only).
45
+
46
+ Returns:
47
+ (str | None): Signed URL on success, None if not found and hard=False.
48
+
49
+ Raises:
50
+ ValueError: If API key is missing/invalid or URI format is wrong.
51
+ PermissionError: If access is denied.
52
+ RuntimeError: If resource is not ready (e.g., dataset still processing).
53
+ FileNotFoundError: If resource not found and hard=True.
54
+ ConnectionError: If network request fails and hard=True.
55
+ """
56
+ import requests
57
+
58
+ path = uri[5:] # Remove "ul://"
59
+ parts = path.split("/")
60
+
61
+ api_key = os.getenv("ULTRALYTICS_API_KEY") or SETTINGS.get("api_key")
62
+ if not api_key:
63
+ raise ValueError(f"ULTRALYTICS_API_KEY required for '{uri}'. Get key at https://alpha.ultralytics.com/settings")
64
+
65
+ base = "https://alpha.ultralytics.com/api/webhooks"
66
+ headers = {"Authorization": f"Bearer {api_key}"}
67
+
68
+ # ul://username/datasets/slug
69
+ if len(parts) == 3 and parts[1] == "datasets":
70
+ username, _, slug = parts
71
+ url = f"{base}/datasets/{username}/{slug}/export"
72
+
73
+ # ul://username/project/model
74
+ elif len(parts) == 3:
75
+ username, project, model = parts
76
+ url = f"{base}/models/{username}/{project}/{model}/download"
77
+
78
+ else:
79
+ raise ValueError(f"Invalid platform URI: {uri}. Use ul://user/datasets/name or ul://user/project/model")
80
+
81
+ LOGGER.info(f"Resolving {uri} from Ultralytics Platform...")
82
+
83
+ try:
84
+ r = requests.head(url, headers=headers, allow_redirects=False, timeout=30)
85
+
86
+ # Handle redirect responses (301, 302, 303, 307, 308)
87
+ if 300 <= r.status_code < 400 and "location" in r.headers:
88
+ return r.headers["location"] # Return signed URL
89
+
90
+ # Handle error responses
91
+ if r.status_code == 401:
92
+ raise ValueError(f"Invalid ULTRALYTICS_API_KEY for '{uri}'")
93
+ if r.status_code == 403:
94
+ raise PermissionError(f"Access denied for '{uri}'. Check dataset/model visibility settings.")
95
+ if r.status_code == 404:
96
+ if hard:
97
+ raise FileNotFoundError(f"Not found on platform: {uri}")
98
+ LOGGER.warning(f"Not found on platform: {uri}")
99
+ return None
100
+ if r.status_code == 409:
101
+ raise RuntimeError(f"Resource not ready: {uri}. Dataset may still be processing.")
102
+
103
+ # Unexpected response
104
+ r.raise_for_status()
105
+ raise RuntimeError(f"Unexpected response from platform for '{uri}': {r.status_code}")
106
+
107
+ except requests.exceptions.RequestException as e:
108
+ if hard:
109
+ raise ConnectionError(f"Failed to resolve {uri}: {e}") from e
110
+ LOGGER.warning(f"Failed to resolve {uri}: {e}")
111
+ return None
112
+
113
+
35
114
  def _interp_plot(plot, n=101):
36
115
  """Interpolate plot curve data from 1000 to n points to reduce storage size."""
37
116
  import numpy as np
@@ -592,7 +592,7 @@ def check_file(file, suffix="", download=True, download_dir=".", hard=True):
592
592
  """Search/download file (if necessary), check suffix (if provided), and return path.
593
593
 
594
594
  Args:
595
- file (str): File name or path.
595
+ file (str): File name or path, or platform URI (ul://username/datasets/name).
596
596
  suffix (str | tuple): Acceptable suffix or tuple of suffixes to validate against the file.
597
597
  download (bool): Whether to download the file if it doesn't exist locally.
598
598
  download_dir (str): Directory to download the file to.
@@ -610,6 +610,18 @@ def check_file(file, suffix="", download=True, download_dir=".", hard=True):
610
610
  or file.lower().startswith("grpc://")
611
611
  ): # file exists or gRPC Triton images
612
612
  return file
613
+ elif download and file.lower().startswith("ul://"): # Ultralytics Platform URI
614
+ from ultralytics.utils.callbacks.platform import resolve_platform_uri
615
+
616
+ url = resolve_platform_uri(file, hard=hard) # Convert to signed HTTPS URL
617
+ if url is None:
618
+ return [] # Not found, soft fail (consistent with file search behavior)
619
+ local_file = Path(download_dir) / url2file(url)
620
+ if local_file.exists():
621
+ LOGGER.info(f"Found {clean_url(url)} locally at {local_file}")
622
+ else:
623
+ downloads.safe_download(url=url, file=local_file, unzip=False)
624
+ return str(local_file)
613
625
  elif download and file.lower().startswith(("https://", "http://", "rtsp://", "rtmp://", "tcp://")): # download
614
626
  url = file # warning: Pathlib turns :// -> :/
615
627
  file = Path(download_dir) / url2file(file) # '%2F' to '/', split https://url.com/file.txt?auth
@@ -315,7 +315,7 @@ class ConfusionMatrix(DataExportMixin):
315
315
  matches (dict): Contains the indices of ground truths and predictions categorized into TP, FP and FN.
316
316
  """
317
317
 
318
- def __init__(self, names: dict[int, str] = [], task: str = "detect", save_matches: bool = False):
318
+ def __init__(self, names: dict[int, str] = {}, task: str = "detect", save_matches: bool = False):
319
319
  """Initialize a ConfusionMatrix instance.
320
320
 
321
321
  Args: