dgenerate-ultralytics-headless 8.3.158__py3-none-any.whl → 8.3.160__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.
- {dgenerate_ultralytics_headless-8.3.158.dist-info → dgenerate_ultralytics_headless-8.3.160.dist-info}/METADATA +2 -2
- {dgenerate_ultralytics_headless-8.3.158.dist-info → dgenerate_ultralytics_headless-8.3.160.dist-info}/RECORD +28 -28
- ultralytics/__init__.py +1 -1
- ultralytics/cfg/__init__.py +0 -2
- ultralytics/data/augment.py +8 -8
- ultralytics/engine/exporter.py +4 -2
- ultralytics/engine/model.py +2 -0
- ultralytics/engine/results.py +0 -5
- ultralytics/models/yolo/detect/val.py +56 -20
- ultralytics/models/yolo/model.py +25 -24
- ultralytics/models/yolo/pose/val.py +3 -27
- ultralytics/models/yolo/segment/val.py +7 -42
- ultralytics/models/yolo/world/train.py +1 -1
- ultralytics/models/yolo/yoloe/train.py +1 -1
- ultralytics/nn/autobackend.py +5 -1
- ultralytics/nn/text_model.py +44 -11
- ultralytics/solutions/heatmap.py +1 -1
- ultralytics/solutions/object_counter.py +10 -10
- ultralytics/solutions/similarity_search.py +5 -14
- ultralytics/solutions/solutions.py +2 -2
- ultralytics/utils/__init__.py +1 -4
- ultralytics/utils/instance.py +2 -0
- ultralytics/utils/metrics.py +18 -30
- ultralytics/utils/plotting.py +1 -1
- {dgenerate_ultralytics_headless-8.3.158.dist-info → dgenerate_ultralytics_headless-8.3.160.dist-info}/WHEEL +0 -0
- {dgenerate_ultralytics_headless-8.3.158.dist-info → dgenerate_ultralytics_headless-8.3.160.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.158.dist-info → dgenerate_ultralytics_headless-8.3.160.dist-info}/licenses/LICENSE +0 -0
- {dgenerate_ultralytics_headless-8.3.158.dist-info → dgenerate_ultralytics_headless-8.3.160.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: dgenerate-ultralytics-headless
|
3
|
-
Version: 8.3.
|
3
|
+
Version: 8.3.160
|
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>
|
@@ -118,7 +118,7 @@ The workflow runs automatically every day at midnight UTC to check for new Ultra
|
|
118
118
|
<img width="100%" src="https://raw.githubusercontent.com/ultralytics/assets/main/yolov8/banner-yolov8.png" alt="Ultralytics YOLO banner"></a>
|
119
119
|
</p>
|
120
120
|
|
121
|
-
[中文](https://docs.ultralytics.com/zh) | [한국어](https://docs.ultralytics.com/ko) | [日本語](https://docs.ultralytics.com/ja) | [Русский](https://docs.ultralytics.com/ru) | [Deutsch](https://docs.ultralytics.com/de) | [Français](https://docs.ultralytics.com/fr) | [Español](https://docs.ultralytics.com/es) | [Português](https://docs.ultralytics.com/pt) | [Türkçe](https://docs.ultralytics.com/tr) | [Tiếng Việt](https://docs.ultralytics.com/vi) | [العربية](https://docs.ultralytics.com/ar) <br>
|
121
|
+
[中文](https://docs.ultralytics.com/zh/) | [한국어](https://docs.ultralytics.com/ko/) | [日本語](https://docs.ultralytics.com/ja/) | [Русский](https://docs.ultralytics.com/ru/) | [Deutsch](https://docs.ultralytics.com/de/) | [Français](https://docs.ultralytics.com/fr/) | [Español](https://docs.ultralytics.com/es) | [Português](https://docs.ultralytics.com/pt/) | [Türkçe](https://docs.ultralytics.com/tr/) | [Tiếng Việt](https://docs.ultralytics.com/vi/) | [العربية](https://docs.ultralytics.com/ar/) <br>
|
122
122
|
|
123
123
|
<div>
|
124
124
|
<a href="https://github.com/ultralytics/ultralytics/actions/workflows/ci.yml"><img src="https://github.com/ultralytics/ultralytics/actions/workflows/ci.yml/badge.svg" alt="Ultralytics CI"></a>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
dgenerate_ultralytics_headless-8.3.
|
1
|
+
dgenerate_ultralytics_headless-8.3.160.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
2
2
|
tests/__init__.py,sha256=b4KP5_q-2IO8Br8YHOSLYnn7IwZS81l_vfEF2YPa2lM,894
|
3
3
|
tests/conftest.py,sha256=JjgKSs36ZaGmmtqGmAapmFSoFF1YwyV3IZsOgqt2IVM,2593
|
4
4
|
tests/test_cli.py,sha256=Kpfxq_RlbKK1Z8xNScDUbre6GB7neZhXZAYGI1tiDS8,5660
|
@@ -8,10 +8,10 @@ tests/test_exports.py,sha256=HmMKOTCia9ZDC0VYc_EPmvBTM5LM5eeI1NF_pKjLpd8,9677
|
|
8
8
|
tests/test_integrations.py,sha256=kl_AKmE_Qs1GB0_91iVwbzNxofm_hFTt0zzU6JF-pg4,6323
|
9
9
|
tests/test_python.py,sha256=nOoaPDg-0j7ZPRz9-uGFny3uocxjUM1ze5wA3BpGxKQ,27865
|
10
10
|
tests/test_solutions.py,sha256=tuf6n_fsI8KvSdJrnc-cqP2qYdiYqCWuVrx0z9dOz3Q,13213
|
11
|
-
ultralytics/__init__.py,sha256=
|
11
|
+
ultralytics/__init__.py,sha256=dkOuwhLnRXwuh6b1GNUdg_IfIptuMf47ZGNgy9FdV-Y,730
|
12
12
|
ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
|
13
13
|
ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
|
14
|
-
ultralytics/cfg/__init__.py,sha256=
|
14
|
+
ultralytics/cfg/__init__.py,sha256=VIpPHImhjb0XLJquGZrG_LBGZchtOtBSXR7HYTYV2GU,39602
|
15
15
|
ultralytics/cfg/default.yaml,sha256=oFG6llJO-Py5H-cR9qs-7FieJamroDLwpbrkhmfROOM,8307
|
16
16
|
ultralytics/cfg/datasets/Argoverse.yaml,sha256=_xlEDIJ9XkUo0v_iNL7FW079BoSeZtKSuLteKTtGbA8,3275
|
17
17
|
ultralytics/cfg/datasets/DOTAv1.5.yaml,sha256=SHND_CFkojxw5iQD5Mcgju2kCZIl0gW2ajuzv1cqoL0,1224
|
@@ -106,7 +106,7 @@ ultralytics/cfg/trackers/botsort.yaml,sha256=TpRaK5kH_-QbjCQ7ekM4s_7j8I8ti3q8Hs7
|
|
106
106
|
ultralytics/cfg/trackers/bytetrack.yaml,sha256=6u-tiZlk16EqEwkNXaMrza6PAQmWj_ypgv26LGCtPDg,886
|
107
107
|
ultralytics/data/__init__.py,sha256=nAXaL1puCc7z_NjzQNlJnhbVhT9Fla2u7Dsqo7q1dAc,644
|
108
108
|
ultralytics/data/annotator.py,sha256=uAgd7K-yudxiwdNqHz0ubfFg5JsfNlae4cgxdvCMyuY,3030
|
109
|
-
ultralytics/data/augment.py,sha256=
|
109
|
+
ultralytics/data/augment.py,sha256=jyEXZ1TqJFIdz_oqecsDa4gKDCMC71RGiMJh3kQV9G0,129378
|
110
110
|
ultralytics/data/base.py,sha256=mRcuehK1thNuuzQGL6D1AaZkod71oHRdYTod_zdQZQg,19688
|
111
111
|
ultralytics/data/build.py,sha256=13gPxCJIZRjgcNh7zbzanCgtyK6_oZM0ho9KQhHcM6c,11153
|
112
112
|
ultralytics/data/converter.py,sha256=oKW8ODtvFOKBx9Un8n87xUUm3b5GStU4ViIBH5UDylM,27200
|
@@ -120,10 +120,10 @@ ultralytics/data/scripts/get_coco.sh,sha256=UuJpJeo3qQpTHVINeOpmP0NYmg8PhEFE3A8J
|
|
120
120
|
ultralytics/data/scripts/get_coco128.sh,sha256=qmRQl_hOKrsdHrTrnyQuFIH01oDz3lfaz138OgGfLt8,650
|
121
121
|
ultralytics/data/scripts/get_imagenet.sh,sha256=hr42H16bM47iT27rgS7MpEo-GeOZAYUQXgr0B2cwn48,1705
|
122
122
|
ultralytics/engine/__init__.py,sha256=lm6MckFYCPTbqIoX7w0s_daxdjNeBeKW6DXppv1-QUM,70
|
123
|
-
ultralytics/engine/exporter.py,sha256=
|
124
|
-
ultralytics/engine/model.py,sha256=
|
123
|
+
ultralytics/engine/exporter.py,sha256=MUgH9gEzeVjnhoZzHuZn958I6c9axE4PTIjJG9uBXuQ,73081
|
124
|
+
ultralytics/engine/model.py,sha256=FmLwiKuItVNgoyXhAvesUnD3UeHBzCVzGHDrqB8J4ms,53453
|
125
125
|
ultralytics/engine/predictor.py,sha256=88zrgZP91ehwdeGl8BM_cQ_caeuwKIPDy3OzxcRBjTU,22474
|
126
|
-
ultralytics/engine/results.py,sha256=
|
126
|
+
ultralytics/engine/results.py,sha256=CHTLuyzGdRyAZJDNajEjF_uOtrWrUUu3zqKdZVA-76M,71989
|
127
127
|
ultralytics/engine/trainer.py,sha256=28FeqASvQRxCaK96SXDM-BfPJjqy5KNiWhf8v6GXTug,39785
|
128
128
|
ultralytics/engine/tuner.py,sha256=4ue7JbMFQp7JcWhhwCAY-b-xZsjm5VKVlPFDUTyxt_8,12789
|
129
129
|
ultralytics/engine/validator.py,sha256=qftJUomb4A-6rSThtST3TccEbc_zTmzovCBBCSpYm3k,16671
|
@@ -165,7 +165,7 @@ ultralytics/models/utils/__init__.py,sha256=lm6MckFYCPTbqIoX7w0s_daxdjNeBeKW6DXp
|
|
165
165
|
ultralytics/models/utils/loss.py,sha256=E-61TfLPc04IdeL6IlFDityDoPju-ov0ouWV_cNY4Kg,21254
|
166
166
|
ultralytics/models/utils/ops.py,sha256=Pr77n8XW25SUEx4X3bBvXcVIbRdJPoaXJuG0KWWawRQ,15253
|
167
167
|
ultralytics/models/yolo/__init__.py,sha256=or0j5xvcM0usMlsFTYhNAOcQUri7reD0cD9JR5b7zDk,307
|
168
|
-
ultralytics/models/yolo/model.py,sha256=
|
168
|
+
ultralytics/models/yolo/model.py,sha256=xK-Te6D0PGY3vpWQg-HT3TwP0bzPs0XfUjd_L_tVXRs,18752
|
169
169
|
ultralytics/models/yolo/classify/__init__.py,sha256=9--HVaNOfI1K7rn_rRqclL8FUAnpfeBrRqEQIaQw2xM,383
|
170
170
|
ultralytics/models/yolo/classify/predict.py,sha256=FqAC2YXe25bRwedMZhF3Lw0waoY-a60xMKELhxApP9I,4149
|
171
171
|
ultralytics/models/yolo/classify/train.py,sha256=V-hevc6X7xemnpyru84OfTRA77eNnkVSMEz16_OUvo4,10244
|
@@ -173,7 +173,7 @@ ultralytics/models/yolo/classify/val.py,sha256=YakPxBVZCd85Kp4wFKx8KH6JJFiU7nkFS
|
|
173
173
|
ultralytics/models/yolo/detect/__init__.py,sha256=GIRsLYR-kT4JJx7lh4ZZAFGBZj0aebokuU0A7JbjDVA,257
|
174
174
|
ultralytics/models/yolo/detect/predict.py,sha256=ySUsdIf8dw00bzWhcxN1jZwLWKPRT2M7-N7TNL3o4zo,5387
|
175
175
|
ultralytics/models/yolo/detect/train.py,sha256=HlaCoHJ6Y2TpCXXWabMRZApAYqBvjuM_YQJUV5JYCvw,9907
|
176
|
-
ultralytics/models/yolo/detect/val.py,sha256=
|
176
|
+
ultralytics/models/yolo/detect/val.py,sha256=Yhs7SdS8O_4_61N_ZxzGaEfm4tnpEzIRV5XcMsrI-e4,20485
|
177
177
|
ultralytics/models/yolo/obb/__init__.py,sha256=tQmpG8wVHsajWkZdmD6cjGohJ4ki64iSXQT8JY_dydo,221
|
178
178
|
ultralytics/models/yolo/obb/predict.py,sha256=4r1eSld6TNJlk9JG56e-DX6oPL8uBBqiuztyBpxWlHE,2888
|
179
179
|
ultralytics/models/yolo/obb/train.py,sha256=bnYFAMur7Uvbw5Dc09-S2ge7B05iGX-t37Ksgc0ef6g,3921
|
@@ -181,23 +181,23 @@ ultralytics/models/yolo/obb/val.py,sha256=nT82lKXewUw3bgX45Ms045rzcYn2A1j8g3Dxig
|
|
181
181
|
ultralytics/models/yolo/pose/__init__.py,sha256=63xmuHZLNzV8I76HhVXAq4f2W0KTk8Oi9eL-Y204LyQ,227
|
182
182
|
ultralytics/models/yolo/pose/predict.py,sha256=M0C7ZfVXx4QXgv-szjnaXYEPas76ZLGAgDNNh1GG0vI,3743
|
183
183
|
ultralytics/models/yolo/pose/train.py,sha256=GyvNnDPJ3UFq_90HN8_FJ0dbwRkw3JJTVpkMFH0vC0o,5457
|
184
|
-
ultralytics/models/yolo/pose/val.py,sha256=
|
184
|
+
ultralytics/models/yolo/pose/val.py,sha256=abAll3lWT6IRwoHOFNsgAZyNQtTtPBXHq0Wszpu9p5E,13994
|
185
185
|
ultralytics/models/yolo/segment/__init__.py,sha256=3IThhZ1wlkY9FvmWm9cE-5-ZyE6F1FgzAtQ6jOOFzzw,275
|
186
186
|
ultralytics/models/yolo/segment/predict.py,sha256=qlprQCZn4_bpjpI08U0MU9Q9_1gpHrw_7MXwtXE1l1Y,5377
|
187
187
|
ultralytics/models/yolo/segment/train.py,sha256=XrPkXUiNu1Jvhn8iDew_RaLLjZA3un65rK-QH9mtNIw,3802
|
188
|
-
ultralytics/models/yolo/segment/val.py,sha256=
|
188
|
+
ultralytics/models/yolo/segment/val.py,sha256=AnvY0O7HhD5xZ2BE2artLTAVW4SNmHbVopBJsYRcmk8,12328
|
189
189
|
ultralytics/models/yolo/world/__init__.py,sha256=nlh8I6t8hMGz_vZg8QSlsUW1R-2eKvn9CGUoPPQEGhA,131
|
190
|
-
ultralytics/models/yolo/world/train.py,sha256=
|
190
|
+
ultralytics/models/yolo/world/train.py,sha256=karlbEdkfAh08ZzYj9nXOiqLsRq5grsbV-XDv3yl6GQ,7819
|
191
191
|
ultralytics/models/yolo/world/train_world.py,sha256=YJm37ZTgr0CoE_sYrjxN45w9mICr2RMWfWZrriiHqbM,9022
|
192
192
|
ultralytics/models/yolo/yoloe/__init__.py,sha256=6SLytdJtwu37qewf7CobG7C7Wl1m-xtNdvCXEasfPDE,760
|
193
193
|
ultralytics/models/yolo/yoloe/predict.py,sha256=TAcT6fiWbV-jOewu9hx_shGI10VLF_6oSPf7jfatBWo,7041
|
194
|
-
ultralytics/models/yolo/yoloe/train.py,sha256=
|
194
|
+
ultralytics/models/yolo/yoloe/train.py,sha256=H1Z5yzcYklyfIkT0xR35qq3f7CxmeG2jUhWhbVyE6RA,14060
|
195
195
|
ultralytics/models/yolo/yoloe/train_seg.py,sha256=aCV7M8oQOvODFnU4piZdJh3tIrBJYAzZfRVRx1vRgxo,4956
|
196
196
|
ultralytics/models/yolo/yoloe/val.py,sha256=yebPkxwKKt__cY05Zbh1YXg4_BKzzpcDc3Cv3FJ5SAA,9769
|
197
197
|
ultralytics/nn/__init__.py,sha256=rjociYD9lo_K-d-1s6TbdWklPLjTcEHk7OIlRDJstIE,615
|
198
|
-
ultralytics/nn/autobackend.py,sha256=
|
198
|
+
ultralytics/nn/autobackend.py,sha256=yk1IXPChI1D7rupJdH2TMvUqFv6PVmBU3tgfZOquQ_8,41358
|
199
199
|
ultralytics/nn/tasks.py,sha256=aCXYmWan2LTznH3i_-2OwMagG3ZwnVL1gjKtY-3oShM,72456
|
200
|
-
ultralytics/nn/text_model.py,sha256=
|
200
|
+
ultralytics/nn/text_model.py,sha256=cYwD-0el4VeToDBP4iPFOQGqyEQatJOBHrVyONL3K_s,15282
|
201
201
|
ultralytics/nn/modules/__init__.py,sha256=2nY0X69Z5DD5SWt6v3CUTZa5gXSzC9TQr3VTVqhyGho,3158
|
202
202
|
ultralytics/nn/modules/activation.py,sha256=75JcIMH2Cu9GTC2Uf55r_5YLpxcrXQDaVoeGQ0hlUAU,2233
|
203
203
|
ultralytics/nn/modules/block.py,sha256=JfOjWEgUNfwFCt-P2awhga4B7GXeDlkKVhLBp7oA-Es,70652
|
@@ -210,17 +210,17 @@ ultralytics/solutions/ai_gym.py,sha256=wwfTqX7G3mZXneMwiibEfYbVYaJF_JUX3SQdsdQUv
|
|
210
210
|
ultralytics/solutions/analytics.py,sha256=aHwKjSEW_3y47LrzugJbPB3VQGTDQCIb5goiPuxnmrc,12802
|
211
211
|
ultralytics/solutions/config.py,sha256=CevL8lzeSbiSAAA514CTiduCg2_Wh04P0RaB_kmwJa8,5404
|
212
212
|
ultralytics/solutions/distance_calculation.py,sha256=r05_ufxb2Mpw3EIX8X32PIWlh9rYMADypGhVIPoZYV4,5939
|
213
|
-
ultralytics/solutions/heatmap.py,sha256=
|
213
|
+
ultralytics/solutions/heatmap.py,sha256=hBJR_Z3Lu9JcvCaEwnd-uN_WEiXK14FDRXedgaI8oqU,5515
|
214
214
|
ultralytics/solutions/instance_segmentation.py,sha256=qsIQkvuR1Ur2bdEsCCJP2IEO1Hz2l0wfR2KUBo247xE,3795
|
215
215
|
ultralytics/solutions/object_blurrer.py,sha256=wHbfrudh6li_JADc-dTHGGMI8GU-MvesoTvVlX6YuYc,3998
|
216
|
-
ultralytics/solutions/object_counter.py,sha256=
|
216
|
+
ultralytics/solutions/object_counter.py,sha256=ccKuchrVkNE8AD4EvArtl6LCVf442jTOyc6_7tGua5o,9433
|
217
217
|
ultralytics/solutions/object_cropper.py,sha256=mS3iT_CgqfqG9ldM_AM5ptq5bfYFyTycPQY5DxxMlSA,3525
|
218
218
|
ultralytics/solutions/parking_management.py,sha256=IfPUn15aelxz6YZNo9WYkVEl5IOVSw8VD0OrpKtExPE,13613
|
219
219
|
ultralytics/solutions/queue_management.py,sha256=u0VFzRqa0OxIWY7xXItsXEm073CzkQGFhhXG-6VK3SI,4393
|
220
220
|
ultralytics/solutions/region_counter.py,sha256=j6f5VAaE1JWGdWOecZpWMFp6yF1GdCnHjftN6CRybjQ,5967
|
221
221
|
ultralytics/solutions/security_alarm.py,sha256=U6FTbg3cthKLfWeLunsFhOJvB6GGmwYDDxZ3K0GCx-Q,6351
|
222
|
-
ultralytics/solutions/similarity_search.py,sha256=
|
223
|
-
ultralytics/solutions/solutions.py,sha256=
|
222
|
+
ultralytics/solutions/similarity_search.py,sha256=ri8bf65tt6xyS6Xa-ikj2AgvfCsFOtaQk6IM_k7FhKg,9579
|
223
|
+
ultralytics/solutions/solutions.py,sha256=w9enbzZ02H9M00cGb7SqYsar6hKZfBU52ez-5G8cXJI,37554
|
224
224
|
ultralytics/solutions/speed_estimation.py,sha256=chg_tBuKFw3EnFiv_obNDaUXLAo-FypxC7gsDeB_VUI,5878
|
225
225
|
ultralytics/solutions/streamlit_inference.py,sha256=SqL-YxU3RCxCKscH2AYUTkmJknilV9jCCco6ufqsFk4,10501
|
226
226
|
ultralytics/solutions/trackzone.py,sha256=kIS94rNfL3yVPAtSbnW8F-aLMxXowQtsfKNB-jLezz8,3941
|
@@ -235,7 +235,7 @@ ultralytics/trackers/utils/__init__.py,sha256=lm6MckFYCPTbqIoX7w0s_daxdjNeBeKW6D
|
|
235
235
|
ultralytics/trackers/utils/gmc.py,sha256=9IvCf5MhBYY9ppVHykN02_oBWHmE98R8EaYFKaykdV0,14032
|
236
236
|
ultralytics/trackers/utils/kalman_filter.py,sha256=PPmM0lwBMdT_hGojvfLoUsBUFMBBMNRAxKbMcQa3wJ0,21619
|
237
237
|
ultralytics/trackers/utils/matching.py,sha256=uSYtywqi1lE_uNN1FwuBFPyISfDQXHMu8K5KH69nrRI,7160
|
238
|
-
ultralytics/utils/__init__.py,sha256=
|
238
|
+
ultralytics/utils/__init__.py,sha256=oJZ1o2L2R-EHepFbe_9bAzyiLi3Rd3Cv6gJmgO5jNfc,59437
|
239
239
|
ultralytics/utils/autobatch.py,sha256=33m8YgggLIhltDqMXZ5OE-FGs2QiHrl2-LfgY1mI4cw,5119
|
240
240
|
ultralytics/utils/autodevice.py,sha256=AvgXFt8c1Cg4icKh0Hbhhz8UmVQ2Wjyfdfkeb2C8zck,8855
|
241
241
|
ultralytics/utils/benchmarks.py,sha256=GlsR6SvD3qlus2hVj7SqSNErsejBlIxO0Y7hMc_cWHw,31041
|
@@ -245,12 +245,12 @@ ultralytics/utils/downloads.py,sha256=YB6rJkcRGQfklUjZqi9dOkTiZaDSqbkGyZEFcZLQkg
|
|
245
245
|
ultralytics/utils/errors.py,sha256=XT9Ru7ivoBgofK6PlnyigGoa7Fmf5nEhyHtnD-8TRXI,1584
|
246
246
|
ultralytics/utils/export.py,sha256=0gG_GZNRqHcORJbjQq_1MXEHc3UEfzPAdpOl2X5VoDc,10008
|
247
247
|
ultralytics/utils/files.py,sha256=ZCbLGleiF0f-PqYfaxMFAWop88w7U1hpreHXl8b2ko0,8238
|
248
|
-
ultralytics/utils/instance.py,sha256=
|
248
|
+
ultralytics/utils/instance.py,sha256=s97d-GXSSCluu-My2DFLAubdk_hf44BuVQ6OCROBrMc,18550
|
249
249
|
ultralytics/utils/loss.py,sha256=fbOWc3Iu0QOJiWbi-mXWA9-1otTYlehtmUsI7os7ydM,39799
|
250
|
-
ultralytics/utils/metrics.py,sha256=
|
250
|
+
ultralytics/utils/metrics.py,sha256=fSDA0YV3Bb3ALhmWv0Uy1s8acDwFUymd8Tj1MFNPYyU,62251
|
251
251
|
ultralytics/utils/ops.py,sha256=Jkh80ujyi0XDQwNqCUYyomH8NQ145AH9doMUS8Vt8GE,34545
|
252
252
|
ultralytics/utils/patches.py,sha256=P2uQy7S4RzSHBfwJEXJsjyuRUluaaUusiVU84lV3moQ,6577
|
253
|
-
ultralytics/utils/plotting.py,sha256=
|
253
|
+
ultralytics/utils/plotting.py,sha256=SCpG5DHZUPlFUsu72kNH3DYGpsjgkd3eIZ9-QTllY88,47171
|
254
254
|
ultralytics/utils/tal.py,sha256=aXawOnhn8ni65tJWIW-PYqWr_TRvltbHBjrTo7o6lDQ,20924
|
255
255
|
ultralytics/utils/torch_utils.py,sha256=iIAjf2g4hikzBeHvKN-EQK8QFlC_QtWWRuYQuBF2zIk,39184
|
256
256
|
ultralytics/utils/triton.py,sha256=M7qe4RztiADBJQEWQKaIQsp94ERFJ_8_DUHDR6TXEOM,5410
|
@@ -266,8 +266,8 @@ ultralytics/utils/callbacks/neptune.py,sha256=j8pecmlcsM8FGzLKWoBw5xUsi5t8E5HuxY
|
|
266
266
|
ultralytics/utils/callbacks/raytune.py,sha256=S6Bq16oQDQ8BQgnZzA0zJHGN_BBr8iAM_WtGoLiEcwg,1283
|
267
267
|
ultralytics/utils/callbacks/tensorboard.py,sha256=MDPBW7aDes-66OE6YqKXXvqA_EocjzEMHWGM-8z9vUQ,5281
|
268
268
|
ultralytics/utils/callbacks/wb.py,sha256=Tm_-aRr2CN32MJkY9tylpMBJkb007-MSRNSQ7rDJ5QU,7521
|
269
|
-
dgenerate_ultralytics_headless-8.3.
|
270
|
-
dgenerate_ultralytics_headless-8.3.
|
271
|
-
dgenerate_ultralytics_headless-8.3.
|
272
|
-
dgenerate_ultralytics_headless-8.3.
|
273
|
-
dgenerate_ultralytics_headless-8.3.
|
269
|
+
dgenerate_ultralytics_headless-8.3.160.dist-info/METADATA,sha256=UW5E8ePDgtefP25esNBr8NKHlkgTExMW8TWO4D6oFBY,38318
|
270
|
+
dgenerate_ultralytics_headless-8.3.160.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
271
|
+
dgenerate_ultralytics_headless-8.3.160.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
|
272
|
+
dgenerate_ultralytics_headless-8.3.160.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
|
273
|
+
dgenerate_ultralytics_headless-8.3.160.dist-info/RECORD,,
|
ultralytics/__init__.py
CHANGED
ultralytics/cfg/__init__.py
CHANGED
@@ -954,8 +954,6 @@ def entrypoint(debug: str = "") -> None:
|
|
954
954
|
from ultralytics import YOLO
|
955
955
|
|
956
956
|
model = YOLO(model, task=task)
|
957
|
-
if isinstance(overrides.get("pretrained"), str):
|
958
|
-
model.load(overrides["pretrained"])
|
959
957
|
|
960
958
|
# Task Update
|
961
959
|
if task != model.task:
|
ultralytics/data/augment.py
CHANGED
@@ -251,8 +251,7 @@ class Compose:
|
|
251
251
|
>>> multiple_transforms = compose[0:2] # Returns a Compose object with RandomFlip and RandomPerspective
|
252
252
|
"""
|
253
253
|
assert isinstance(index, (int, list)), f"The indices should be either list or int type but got {type(index)}"
|
254
|
-
|
255
|
-
return Compose([self.transforms[i] for i in index])
|
254
|
+
return Compose([self.transforms[i] for i in index]) if isinstance(index, list) else self.transforms[index]
|
256
255
|
|
257
256
|
def __setitem__(self, index: Union[list, int], value: Union[list, int]) -> None:
|
258
257
|
"""
|
@@ -1560,14 +1559,15 @@ class RandomFlip:
|
|
1560
1559
|
h = 1 if instances.normalized else h
|
1561
1560
|
w = 1 if instances.normalized else w
|
1562
1561
|
|
1563
|
-
#
|
1562
|
+
# WARNING: two separate if and calls to random.random() intentional for reproducibility with older versions
|
1564
1563
|
if self.direction == "vertical" and random.random() < self.p:
|
1565
1564
|
img = np.flipud(img)
|
1566
1565
|
instances.flipud(h)
|
1566
|
+
if self.flip_idx is not None and instances.keypoints is not None:
|
1567
|
+
instances.keypoints = np.ascontiguousarray(instances.keypoints[:, self.flip_idx, :])
|
1567
1568
|
if self.direction == "horizontal" and random.random() < self.p:
|
1568
1569
|
img = np.fliplr(img)
|
1569
1570
|
instances.fliplr(w)
|
1570
|
-
# For keypoints
|
1571
1571
|
if self.flip_idx is not None and instances.keypoints is not None:
|
1572
1572
|
instances.keypoints = np.ascontiguousarray(instances.keypoints[:, self.flip_idx, :])
|
1573
1573
|
labels["img"] = np.ascontiguousarray(img)
|
@@ -2533,9 +2533,9 @@ def v8_transforms(dataset, imgsz, hyp, stretch=False):
|
|
2533
2533
|
flip_idx = dataset.data.get("flip_idx", []) # for keypoints augmentation
|
2534
2534
|
if dataset.use_keypoints:
|
2535
2535
|
kpt_shape = dataset.data.get("kpt_shape", None)
|
2536
|
-
if len(flip_idx) == 0 and hyp.fliplr > 0.0:
|
2537
|
-
hyp.fliplr = 0.0
|
2538
|
-
LOGGER.warning("No 'flip_idx' array defined in data.yaml,
|
2536
|
+
if len(flip_idx) == 0 and (hyp.fliplr > 0.0 or hyp.flipud > 0.0):
|
2537
|
+
hyp.fliplr = hyp.flipud = 0.0 # both fliplr and flipud require flip_idx
|
2538
|
+
LOGGER.warning("No 'flip_idx' array defined in data.yaml, disabling 'fliplr' and 'flipud' augmentations.")
|
2539
2539
|
elif flip_idx and (len(flip_idx) != kpt_shape[0]):
|
2540
2540
|
raise ValueError(f"data.yaml flip_idx={flip_idx} length must be equal to kpt_shape[0]={kpt_shape[0]}")
|
2541
2541
|
|
@@ -2546,7 +2546,7 @@ def v8_transforms(dataset, imgsz, hyp, stretch=False):
|
|
2546
2546
|
CutMix(dataset, pre_transform=pre_transform, p=hyp.cutmix),
|
2547
2547
|
Albumentations(p=1.0),
|
2548
2548
|
RandomHSV(hgain=hyp.hsv_h, sgain=hyp.hsv_s, vgain=hyp.hsv_v),
|
2549
|
-
RandomFlip(direction="vertical", p=hyp.flipud),
|
2549
|
+
RandomFlip(direction="vertical", p=hyp.flipud, flip_idx=flip_idx),
|
2550
2550
|
RandomFlip(direction="horizontal", p=hyp.fliplr, flip_idx=flip_idx),
|
2551
2551
|
]
|
2552
2552
|
) # transforms
|
ultralytics/engine/exporter.py
CHANGED
@@ -1152,7 +1152,9 @@ class Exporter:
|
|
1152
1152
|
)
|
1153
1153
|
if getattr(self.model, "end2end", False):
|
1154
1154
|
raise ValueError("IMX export is not supported for end2end models.")
|
1155
|
-
check_requirements(
|
1155
|
+
check_requirements(
|
1156
|
+
("model-compression-toolkit>=2.3.0,<2.4.1", "sony-custom-layers>=0.3.0", "edge-mdt-tpc>=1.1.0")
|
1157
|
+
)
|
1156
1158
|
check_requirements("imx500-converter[pt]>=3.16.1") # Separate requirements for imx500-converter
|
1157
1159
|
|
1158
1160
|
import model_compression_toolkit as mct
|
@@ -1493,7 +1495,7 @@ class NMSModel(torch.nn.Module):
|
|
1493
1495
|
scores, classes = scores.max(dim=-1)
|
1494
1496
|
self.args.max_det = min(pred.shape[1], self.args.max_det) # in case num_anchors < max_det
|
1495
1497
|
# (N, max_det, 4 coords + 1 class score + 1 class label + extra_shape).
|
1496
|
-
out = torch.zeros(
|
1498
|
+
out = torch.zeros(pred.shape[0], self.args.max_det, boxes.shape[-1] + 2 + extra_shape, **kwargs)
|
1497
1499
|
for i in range(bs):
|
1498
1500
|
box, cls, score, extra = boxes[i], classes[i], scores[i], extras[i]
|
1499
1501
|
mask = score > self.args.conf
|
ultralytics/engine/model.py
CHANGED
@@ -777,6 +777,8 @@ class Model(torch.nn.Module):
|
|
777
777
|
|
778
778
|
checks.check_pip_update_available()
|
779
779
|
|
780
|
+
if isinstance(kwargs.get("pretrained", None), (str, Path)):
|
781
|
+
self.load(kwargs["pretrained"]) # load pretrained weights if provided
|
780
782
|
overrides = YAML.load(checks.check_yaml(kwargs["cfg"])) if kwargs.get("cfg") else self.overrides
|
781
783
|
custom = {
|
782
784
|
# NOTE: handle the case when 'cfg' includes 'data'.
|
ultralytics/engine/results.py
CHANGED
@@ -16,7 +16,6 @@ import torch
|
|
16
16
|
from ultralytics.data.augment import LetterBox
|
17
17
|
from ultralytics.utils import LOGGER, DataExportMixin, SimpleClass, ops
|
18
18
|
from ultralytics.utils.plotting import Annotator, colors, save_one_box
|
19
|
-
from ultralytics.utils.torch_utils import smart_inference_mode
|
20
19
|
|
21
20
|
|
22
21
|
class BaseTensor(SimpleClass):
|
@@ -1204,7 +1203,6 @@ class Keypoints(BaseTensor):
|
|
1204
1203
|
>>> keypoints_cpu = keypoints.cpu() # Move keypoints to CPU
|
1205
1204
|
"""
|
1206
1205
|
|
1207
|
-
@smart_inference_mode() # avoid keypoints < conf in-place error
|
1208
1206
|
def __init__(self, keypoints: Union[torch.Tensor, np.ndarray], orig_shape: Tuple[int, int]) -> None:
|
1209
1207
|
"""
|
1210
1208
|
Initialize the Keypoints object with detection keypoints and original image dimensions.
|
@@ -1225,9 +1223,6 @@ class Keypoints(BaseTensor):
|
|
1225
1223
|
"""
|
1226
1224
|
if keypoints.ndim == 2:
|
1227
1225
|
keypoints = keypoints[None, :]
|
1228
|
-
if keypoints.shape[2] == 3: # x, y, conf
|
1229
|
-
mask = keypoints[..., 2] < 0.5 # points with conf < 0.5 (not visible)
|
1230
|
-
keypoints[..., :2][mask] = 0
|
1231
1226
|
super().__init__(keypoints, orig_shape)
|
1232
1227
|
self.has_visible = self.data.shape[-1] == 3
|
1233
1228
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
import os
|
4
4
|
from pathlib import Path
|
5
|
-
from typing import Any, Dict, List, Optional, Tuple
|
5
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
6
6
|
|
7
7
|
import numpy as np
|
8
8
|
import torch
|
@@ -219,6 +219,7 @@ class DetectionValidator(BaseValidator):
|
|
219
219
|
self.confusion_matrix.plot(save_dir=self.save_dir, normalize=normalize, on_plot=self.on_plot)
|
220
220
|
self.metrics.speed = self.speed
|
221
221
|
self.metrics.confusion_matrix = self.confusion_matrix
|
222
|
+
self.metrics.save_dir = self.save_dir
|
222
223
|
|
223
224
|
def get_stats(self) -> Dict[str, Any]:
|
224
225
|
"""
|
@@ -392,38 +393,73 @@ class DetectionValidator(BaseValidator):
|
|
392
393
|
Returns:
|
393
394
|
(Dict[str, Any]): Updated statistics dictionary with COCO/LVIS evaluation results.
|
394
395
|
"""
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
396
|
+
pred_json = self.save_dir / "predictions.json" # predictions
|
397
|
+
anno_json = (
|
398
|
+
self.data["path"]
|
399
|
+
/ "annotations"
|
400
|
+
/ ("instances_val2017.json" if self.is_coco else f"lvis_v1_{self.args.split}.json")
|
401
|
+
) # annotations
|
402
|
+
return self.coco_evaluate(stats, pred_json, anno_json)
|
403
|
+
|
404
|
+
def coco_evaluate(
|
405
|
+
self,
|
406
|
+
stats: Dict[str, Any],
|
407
|
+
pred_json: str,
|
408
|
+
anno_json: str,
|
409
|
+
iou_types: Union[str, List[str]] = "bbox",
|
410
|
+
suffix: Union[str, List[str]] = "Box",
|
411
|
+
) -> Dict[str, Any]:
|
412
|
+
"""
|
413
|
+
Evaluate COCO/LVIS metrics using faster-coco-eval library.
|
414
|
+
|
415
|
+
Performs evaluation using the faster-coco-eval library to compute mAP metrics
|
416
|
+
for object detection. Updates the provided stats dictionary with computed metrics
|
417
|
+
including mAP50, mAP50-95, and LVIS-specific metrics if applicable.
|
418
|
+
|
419
|
+
Args:
|
420
|
+
stats (Dict[str, Any]): Dictionary to store computed metrics and statistics.
|
421
|
+
pred_json (str | Path]): Path to JSON file containing predictions in COCO format.
|
422
|
+
anno_json (str | Path]): Path to JSON file containing ground truth annotations in COCO format.
|
423
|
+
iou_types (str | List[str]]): IoU type(s) for evaluation. Can be single string or list of strings.
|
424
|
+
Common values include "bbox", "segm", "keypoints". Defaults to "bbox".
|
425
|
+
suffix (str | List[str]]): Suffix to append to metric names in stats dictionary. Should correspond
|
426
|
+
to iou_types if multiple types provided. Defaults to "Box".
|
402
427
|
|
428
|
+
Returns:
|
429
|
+
(Dict[str, Any]): Updated stats dictionary containing the computed COCO/LVIS evaluation metrics.
|
430
|
+
"""
|
431
|
+
if self.args.save_json and (self.is_coco or self.is_lvis) and len(self.jdict):
|
403
432
|
LOGGER.info(f"\nEvaluating faster-coco-eval mAP using {pred_json} and {anno_json}...")
|
404
433
|
try:
|
405
434
|
for x in pred_json, anno_json:
|
406
435
|
assert x.is_file(), f"{x} file not found"
|
436
|
+
iou_types = [iou_types] if isinstance(iou_types, str) else iou_types
|
437
|
+
suffix = [suffix] if isinstance(suffix, str) else suffix
|
407
438
|
check_requirements("faster-coco-eval>=1.6.7")
|
408
439
|
from faster_coco_eval import COCO, COCOeval_faster
|
409
440
|
|
410
441
|
anno = COCO(anno_json)
|
411
442
|
pred = anno.loadRes(pred_json)
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
443
|
+
for i, iou_type in enumerate(iou_types):
|
444
|
+
val = COCOeval_faster(
|
445
|
+
anno, pred, iouType=iou_type, lvis_style=self.is_lvis, print_function=LOGGER.info
|
446
|
+
)
|
447
|
+
val.params.imgIds = [int(Path(x).stem) for x in self.dataloader.dataset.im_files] # images to eval
|
448
|
+
val.evaluate()
|
449
|
+
val.accumulate()
|
450
|
+
val.summarize()
|
451
|
+
|
452
|
+
# update mAP50-95 and mAP50
|
453
|
+
stats[f"metrics/mAP50({suffix[i][0]})"] = val.stats_as_dict["AP_all"]
|
454
|
+
stats[f"metrics/mAP50-95({suffix[i][0]})"] = val.stats_as_dict["AP_50"]
|
417
455
|
|
418
|
-
|
419
|
-
|
420
|
-
|
456
|
+
if self.is_lvis:
|
457
|
+
stats[f"metrics/APr({suffix[i][0]})"] = val.stats_as_dict["APr"]
|
458
|
+
stats[f"metrics/APc({suffix[i][0]})"] = val.stats_as_dict["APc"]
|
459
|
+
stats[f"metrics/APf({suffix[i][0]})"] = val.stats_as_dict["APf"]
|
421
460
|
|
422
461
|
if self.is_lvis:
|
423
|
-
stats["metrics/
|
424
|
-
stats["metrics/APc(B)"] = val.stats_as_dict["APc"]
|
425
|
-
stats["metrics/APf(B)"] = val.stats_as_dict["APf"]
|
426
|
-
stats["fitness"] = val.stats_as_dict["AP_all"]
|
462
|
+
stats["fitness"] = stats["metrics/mAP50-95(B)"] # always use box mAP50-95 for fitness
|
427
463
|
except Exception as e:
|
428
464
|
LOGGER.warning(f"faster-coco-eval unable to run: {e}")
|
429
465
|
return stats
|
ultralytics/models/yolo/model.py
CHANGED
@@ -406,18 +406,18 @@ class YOLOE(Model):
|
|
406
406
|
f"Expected equal number of bounding boxes and classes, but got {len(visual_prompts['bboxes'])} and "
|
407
407
|
f"{len(visual_prompts['cls'])} respectively"
|
408
408
|
)
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
409
|
+
if not isinstance(self.predictor, yolo.yoloe.YOLOEVPDetectPredictor):
|
410
|
+
self.predictor = (predictor or yolo.yoloe.YOLOEVPDetectPredictor)(
|
411
|
+
overrides={
|
412
|
+
"task": self.model.task,
|
413
|
+
"mode": "predict",
|
414
|
+
"save": False,
|
415
|
+
"verbose": refer_image is None,
|
416
|
+
"batch": 1,
|
417
|
+
},
|
418
|
+
_callbacks=self.callbacks,
|
419
|
+
)
|
419
420
|
|
420
|
-
if len(visual_prompts):
|
421
421
|
num_cls = (
|
422
422
|
max(len(set(c)) for c in visual_prompts["cls"])
|
423
423
|
if isinstance(source, list) and refer_image is None # means multiple images
|
@@ -426,18 +426,19 @@ class YOLOE(Model):
|
|
426
426
|
self.model.model[-1].nc = num_cls
|
427
427
|
self.model.names = [f"object{i}" for i in range(num_cls)]
|
428
428
|
self.predictor.set_prompts(visual_prompts.copy())
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
429
|
+
self.predictor.setup_model(model=self.model)
|
430
|
+
|
431
|
+
if refer_image is None and source is not None:
|
432
|
+
dataset = load_inference_source(source)
|
433
|
+
if dataset.mode in {"video", "stream"}:
|
434
|
+
# NOTE: set the first frame as refer image for videos/streams inference
|
435
|
+
refer_image = next(iter(dataset))[1][0]
|
436
|
+
if refer_image is not None:
|
437
|
+
vpe = self.predictor.get_vpe(refer_image)
|
438
|
+
self.model.set_classes(self.model.names, vpe)
|
439
|
+
self.task = "segment" if isinstance(self.predictor, yolo.segment.SegmentationPredictor) else "detect"
|
440
|
+
self.predictor = None # reset predictor
|
441
|
+
elif isinstance(self.predictor, yolo.yoloe.YOLOEVPDetectPredictor):
|
442
|
+
self.predictor = None # reset predictor if no visual prompts
|
442
443
|
|
443
444
|
return super().predict(source, stream, **kwargs)
|
@@ -8,7 +8,6 @@ import torch
|
|
8
8
|
|
9
9
|
from ultralytics.models.yolo.detect import DetectionValidator
|
10
10
|
from ultralytics.utils import LOGGER, ops
|
11
|
-
from ultralytics.utils.checks import check_requirements
|
12
11
|
from ultralytics.utils.metrics import OKS_SIGMA, PoseMetrics, kpt_iou
|
13
12
|
|
14
13
|
|
@@ -289,29 +288,6 @@ class PoseValidator(DetectionValidator):
|
|
289
288
|
|
290
289
|
def eval_json(self, stats: Dict[str, Any]) -> Dict[str, Any]:
|
291
290
|
"""Evaluate object detection model using COCO JSON format."""
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
LOGGER.info(f"\nEvaluating faster-coco-eval mAP using {pred_json} and {anno_json}...")
|
296
|
-
try:
|
297
|
-
check_requirements("faster-coco-eval>=1.6.7")
|
298
|
-
from faster_coco_eval import COCO, COCOeval_faster
|
299
|
-
|
300
|
-
for x in anno_json, pred_json:
|
301
|
-
assert x.is_file(), f"{x} file not found"
|
302
|
-
anno = COCO(anno_json) # init annotations api
|
303
|
-
pred = anno.loadRes(pred_json) # init predictions api (must pass string, not Path)
|
304
|
-
kwargs = dict(cocoGt=anno, cocoDt=pred, print_function=LOGGER.info)
|
305
|
-
for i, eval in enumerate(
|
306
|
-
[COCOeval_faster(iouType="bbox", **kwargs), COCOeval_faster(iouType="keypoints", **kwargs)]
|
307
|
-
):
|
308
|
-
eval.params.imgIds = [int(Path(x).stem) for x in self.dataloader.dataset.im_files] # im to eval
|
309
|
-
eval.evaluate()
|
310
|
-
eval.accumulate()
|
311
|
-
eval.summarize()
|
312
|
-
idx = i * 4 + 2
|
313
|
-
# update mAP50-95 and mAP50
|
314
|
-
stats[self.metrics.keys[idx + 1]], stats[self.metrics.keys[idx]] = eval.stats[:2]
|
315
|
-
except Exception as e:
|
316
|
-
LOGGER.warning(f"faster-coco-eval unable to run: {e}")
|
317
|
-
return stats
|
291
|
+
anno_json = self.data["path"] / "annotations/person_keypoints_val2017.json" # annotations
|
292
|
+
pred_json = self.save_dir / "predictions.json" # predictions
|
293
|
+
return super().coco_evaluate(stats, pred_json, anno_json, ["bbox", "keypoints"], suffix=["Box", "Pose"])
|
@@ -272,45 +272,10 @@ class SegmentationValidator(DetectionValidator):
|
|
272
272
|
|
273
273
|
def eval_json(self, stats: Dict[str, Any]) -> Dict[str, Any]:
|
274
274
|
"""Return COCO-style instance segmentation evaluation metrics."""
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
LOGGER.info(f"\nEvaluating faster-coco-eval mAP using {pred_json} and {anno_json}...")
|
284
|
-
try:
|
285
|
-
for x in anno_json, pred_json:
|
286
|
-
assert x.is_file(), f"{x} file not found"
|
287
|
-
check_requirements("faster-coco-eval>=1.6.7")
|
288
|
-
from faster_coco_eval import COCO, COCOeval_faster
|
289
|
-
|
290
|
-
anno = COCO(anno_json) # init annotations api
|
291
|
-
pred = anno.loadRes(pred_json) # init predictions api (must pass string, not Path)
|
292
|
-
kwargs = dict(cocoGt=anno, cocoDt=pred, lvis_style=self.is_lvis, print_function=LOGGER.info)
|
293
|
-
for i, eval in enumerate(
|
294
|
-
[COCOeval_faster(iouType="bbox", **kwargs), COCOeval_faster(iouType="segm", **kwargs)]
|
295
|
-
):
|
296
|
-
eval.params.imgIds = [int(Path(x).stem) for x in self.dataloader.dataset.im_files] # im to eval
|
297
|
-
eval.evaluate()
|
298
|
-
eval.accumulate()
|
299
|
-
eval.summarize()
|
300
|
-
idx = i * 4 + 2
|
301
|
-
# update mAP50-95 and mAP50
|
302
|
-
stats[self.metrics.keys[idx + 1]] = eval.stats_as_dict["AP_all"]
|
303
|
-
stats[self.metrics.keys[idx]] = eval.stats_as_dict["AP_50"]
|
304
|
-
|
305
|
-
if self.is_lvis:
|
306
|
-
tag = "B" if i == 0 else "M"
|
307
|
-
stats[f"metrics/APr({tag})"] = eval.stats_as_dict["APr"]
|
308
|
-
stats[f"metrics/APc({tag})"] = eval.stats_as_dict["APc"]
|
309
|
-
stats[f"metrics/APf({tag})"] = eval.stats_as_dict["APf"]
|
310
|
-
|
311
|
-
if self.is_lvis:
|
312
|
-
stats["fitness"] = stats["metrics/mAP50-95(B)"]
|
313
|
-
|
314
|
-
except Exception as e:
|
315
|
-
LOGGER.warning(f"faster-coco-eval unable to run: {e}")
|
316
|
-
return stats
|
275
|
+
pred_json = self.save_dir / "predictions.json" # predictions
|
276
|
+
anno_json = (
|
277
|
+
self.data["path"]
|
278
|
+
/ "annotations"
|
279
|
+
/ ("instances_val2017.json" if self.is_coco else f"lvis_v1_{self.args.split}.json")
|
280
|
+
) # annotations
|
281
|
+
return super().coco_evaluate(stats, pred_json, anno_json, ["bbox", "segm"], suffix=["Box", "Mask"])
|
@@ -158,7 +158,7 @@ class WorldTrainer(DetectionTrainer):
|
|
158
158
|
return txt_map
|
159
159
|
LOGGER.info(f"Caching text embeddings to '{cache_path}'")
|
160
160
|
assert self.model is not None
|
161
|
-
txt_feats = self.model.get_text_pe(texts, batch, cache_clip_model=False)
|
161
|
+
txt_feats = de_parallel(self.model).get_text_pe(texts, batch, cache_clip_model=False)
|
162
162
|
txt_map = dict(zip(texts, txt_feats.squeeze(0)))
|
163
163
|
torch.save(txt_map, cache_path)
|
164
164
|
return txt_map
|
@@ -222,7 +222,7 @@ class YOLOETrainerFromScratch(YOLOETrainer, WorldTrainerFromScratch):
|
|
222
222
|
return txt_map
|
223
223
|
LOGGER.info(f"Caching text embeddings to '{cache_path}'")
|
224
224
|
assert self.model is not None
|
225
|
-
txt_feats = self.model.get_text_pe(texts, batch, without_reprta=True, cache_clip_model=False)
|
225
|
+
txt_feats = de_parallel(self.model).get_text_pe(texts, batch, without_reprta=True, cache_clip_model=False)
|
226
226
|
txt_map = dict(zip(texts, txt_feats.squeeze(0)))
|
227
227
|
torch.save(txt_map, cache_path)
|
228
228
|
return txt_map
|
ultralytics/nn/autobackend.py
CHANGED
@@ -259,7 +259,11 @@ class AutoBackend(nn.Module):
|
|
259
259
|
session = onnxruntime.InferenceSession(w, providers=providers)
|
260
260
|
else:
|
261
261
|
check_requirements(
|
262
|
-
[
|
262
|
+
[
|
263
|
+
"model-compression-toolkit>=2.3.0,<2.4.1",
|
264
|
+
"sony-custom-layers[torch]>=0.3.0",
|
265
|
+
"onnxruntime-extensions",
|
266
|
+
]
|
263
267
|
)
|
264
268
|
w = next(Path(w).glob("*.onnx"))
|
265
269
|
LOGGER.info(f"Loading {w} for ONNX IMX inference...")
|
ultralytics/nn/text_model.py
CHANGED
@@ -6,6 +6,7 @@ from typing import List, Union
|
|
6
6
|
|
7
7
|
import torch
|
8
8
|
import torch.nn as nn
|
9
|
+
from PIL import Image
|
9
10
|
|
10
11
|
from ultralytics.utils import checks
|
11
12
|
from ultralytics.utils.torch_utils import smart_inference_mode
|
@@ -68,7 +69,7 @@ class CLIP(TextModel):
|
|
68
69
|
>>> print(text_features.shape)
|
69
70
|
"""
|
70
71
|
|
71
|
-
def __init__(self, size: str, device: torch.device):
|
72
|
+
def __init__(self, size: str, device: torch.device) -> None:
|
72
73
|
"""
|
73
74
|
Initialize the CLIP text encoder.
|
74
75
|
|
@@ -85,12 +86,12 @@ class CLIP(TextModel):
|
|
85
86
|
>>> text_features = clip_model.encode_text(["a photo of a cat", "a photo of a dog"])
|
86
87
|
"""
|
87
88
|
super().__init__()
|
88
|
-
self.model = clip.load(size, device=device)
|
89
|
+
self.model, self.image_preprocess = clip.load(size, device=device)
|
89
90
|
self.to(device)
|
90
91
|
self.device = device
|
91
92
|
self.eval()
|
92
93
|
|
93
|
-
def tokenize(self, texts: Union[str, List[str]]):
|
94
|
+
def tokenize(self, texts: Union[str, List[str]]) -> torch.Tensor:
|
94
95
|
"""
|
95
96
|
Convert input texts to CLIP tokens.
|
96
97
|
|
@@ -108,7 +109,7 @@ class CLIP(TextModel):
|
|
108
109
|
return clip.tokenize(texts).to(self.device)
|
109
110
|
|
110
111
|
@smart_inference_mode()
|
111
|
-
def encode_text(self, texts: torch.Tensor, dtype: torch.dtype = torch.float32):
|
112
|
+
def encode_text(self, texts: torch.Tensor, dtype: torch.dtype = torch.float32) -> torch.Tensor:
|
112
113
|
"""
|
113
114
|
Encode tokenized texts into normalized feature vectors.
|
114
115
|
|
@@ -133,6 +134,38 @@ class CLIP(TextModel):
|
|
133
134
|
txt_feats = txt_feats / txt_feats.norm(p=2, dim=-1, keepdim=True)
|
134
135
|
return txt_feats
|
135
136
|
|
137
|
+
@smart_inference_mode()
|
138
|
+
def encode_image(self, image: Union[Image.Image, torch.Tensor], dtype: torch.dtype = torch.float32) -> torch.Tensor:
|
139
|
+
"""
|
140
|
+
Encode preprocessed images into normalized feature vectors.
|
141
|
+
|
142
|
+
This method processes preprocessed image inputs through the CLIP model to generate feature vectors, which are then
|
143
|
+
normalized to unit length. These normalized vectors can be used for text-image similarity comparisons.
|
144
|
+
|
145
|
+
Args:
|
146
|
+
image (PIL.Image | torch.Tensor): Preprocessed image input. If a PIL Image is provided, it will be
|
147
|
+
converted to a tensor using the model's image preprocessing function.
|
148
|
+
dtype (torch.dtype, optional): Data type for output features.
|
149
|
+
|
150
|
+
Returns:
|
151
|
+
(torch.Tensor): Normalized image feature vectors with unit length (L2 norm = 1).
|
152
|
+
|
153
|
+
Examples:
|
154
|
+
>>> from ultralytics.nn.text_model import CLIP
|
155
|
+
>>> from PIL import Image
|
156
|
+
>>> clip_model = CLIP("ViT-B/32", device="cuda")
|
157
|
+
>>> image = Image.open("path/to/image.jpg")
|
158
|
+
>>> image_tensor = clip_model.image_preprocess(image).unsqueeze(0).to("cuda")
|
159
|
+
>>> features = clip_model.encode_image(image_tensor)
|
160
|
+
>>> features.shape
|
161
|
+
torch.Size([1, 512])
|
162
|
+
"""
|
163
|
+
if isinstance(image, Image.Image):
|
164
|
+
image = self.image_preprocess(image).unsqueeze(0).to(self.device)
|
165
|
+
img_feats = self.model.encode_image(image).to(dtype)
|
166
|
+
img_feats = img_feats / img_feats.norm(p=2, dim=-1, keepdim=True)
|
167
|
+
return img_feats
|
168
|
+
|
136
169
|
|
137
170
|
class MobileCLIP(TextModel):
|
138
171
|
"""
|
@@ -160,7 +193,7 @@ class MobileCLIP(TextModel):
|
|
160
193
|
|
161
194
|
config_size_map = {"s0": "s0", "s1": "s1", "s2": "s2", "b": "b", "blt": "b"}
|
162
195
|
|
163
|
-
def __init__(self, size: str, device: torch.device):
|
196
|
+
def __init__(self, size: str, device: torch.device) -> None:
|
164
197
|
"""
|
165
198
|
Initialize the MobileCLIP text encoder.
|
166
199
|
|
@@ -201,7 +234,7 @@ class MobileCLIP(TextModel):
|
|
201
234
|
self.device = device
|
202
235
|
self.eval()
|
203
236
|
|
204
|
-
def tokenize(self, texts: List[str]):
|
237
|
+
def tokenize(self, texts: List[str]) -> torch.Tensor:
|
205
238
|
"""
|
206
239
|
Convert input texts to MobileCLIP tokens.
|
207
240
|
|
@@ -218,7 +251,7 @@ class MobileCLIP(TextModel):
|
|
218
251
|
return self.tokenizer(texts).to(self.device)
|
219
252
|
|
220
253
|
@smart_inference_mode()
|
221
|
-
def encode_text(self, texts: torch.Tensor, dtype: torch.dtype = torch.float32):
|
254
|
+
def encode_text(self, texts: torch.Tensor, dtype: torch.dtype = torch.float32) -> torch.Tensor:
|
222
255
|
"""
|
223
256
|
Encode tokenized texts into normalized feature vectors.
|
224
257
|
|
@@ -286,7 +319,7 @@ class MobileCLIPTS(TextModel):
|
|
286
319
|
self.tokenizer = clip.clip.tokenize
|
287
320
|
self.device = device
|
288
321
|
|
289
|
-
def tokenize(self, texts: List[str]):
|
322
|
+
def tokenize(self, texts: List[str]) -> torch.Tensor:
|
290
323
|
"""
|
291
324
|
Convert input texts to MobileCLIP tokens.
|
292
325
|
|
@@ -303,7 +336,7 @@ class MobileCLIPTS(TextModel):
|
|
303
336
|
return self.tokenizer(texts).to(self.device)
|
304
337
|
|
305
338
|
@smart_inference_mode()
|
306
|
-
def encode_text(self, texts: torch.Tensor, dtype: torch.dtype = torch.float32):
|
339
|
+
def encode_text(self, texts: torch.Tensor, dtype: torch.dtype = torch.float32) -> torch.Tensor:
|
307
340
|
"""
|
308
341
|
Encode tokenized texts into normalized feature vectors.
|
309
342
|
|
@@ -322,10 +355,10 @@ class MobileCLIPTS(TextModel):
|
|
322
355
|
torch.Size([2, 512]) # Actual dimension depends on model size
|
323
356
|
"""
|
324
357
|
# NOTE: no need to do normalization here as it's embedded in the torchscript model
|
325
|
-
return self.encoder(texts)
|
358
|
+
return self.encoder(texts).to(dtype)
|
326
359
|
|
327
360
|
|
328
|
-
def build_text_model(variant: str, device: torch.device = None):
|
361
|
+
def build_text_model(variant: str, device: torch.device = None) -> TextModel:
|
329
362
|
"""
|
330
363
|
Build a text encoding model based on the specified variant.
|
331
364
|
|
ultralytics/solutions/heatmap.py
CHANGED
@@ -43,7 +43,7 @@ class ObjectCounter(BaseSolution):
|
|
43
43
|
self.in_count = 0 # Counter for objects moving inward
|
44
44
|
self.out_count = 0 # Counter for objects moving outward
|
45
45
|
self.counted_ids = [] # List of IDs of objects that have been counted
|
46
|
-
self.
|
46
|
+
self.classwise_count = defaultdict(lambda: {"IN": 0, "OUT": 0}) # Dictionary for counts, categorized by class
|
47
47
|
self.region_initialized = False # Flag indicating whether the region has been initialized
|
48
48
|
|
49
49
|
self.show_in = self.CFG["show_in"]
|
@@ -85,17 +85,17 @@ class ObjectCounter(BaseSolution):
|
|
85
85
|
# Vertical region: Compare x-coordinates to determine direction
|
86
86
|
if current_centroid[0] > prev_position[0]: # Moving right
|
87
87
|
self.in_count += 1
|
88
|
-
self.
|
88
|
+
self.classwise_count[self.names[cls]]["IN"] += 1
|
89
89
|
else: # Moving left
|
90
90
|
self.out_count += 1
|
91
|
-
self.
|
91
|
+
self.classwise_count[self.names[cls]]["OUT"] += 1
|
92
92
|
# Horizontal region: Compare y-coordinates to determine direction
|
93
93
|
elif current_centroid[1] > prev_position[1]: # Moving downward
|
94
94
|
self.in_count += 1
|
95
|
-
self.
|
95
|
+
self.classwise_count[self.names[cls]]["IN"] += 1
|
96
96
|
else: # Moving upward
|
97
97
|
self.out_count += 1
|
98
|
-
self.
|
98
|
+
self.classwise_count[self.names[cls]]["OUT"] += 1
|
99
99
|
self.counted_ids.append(track_id)
|
100
100
|
|
101
101
|
elif len(self.region) > 2: # Polygonal region
|
@@ -111,10 +111,10 @@ class ObjectCounter(BaseSolution):
|
|
111
111
|
and current_centroid[1] > prev_position[1]
|
112
112
|
): # Moving right or downward
|
113
113
|
self.in_count += 1
|
114
|
-
self.
|
114
|
+
self.classwise_count[self.names[cls]]["IN"] += 1
|
115
115
|
else: # Moving left or upward
|
116
116
|
self.out_count += 1
|
117
|
-
self.
|
117
|
+
self.classwise_count[self.names[cls]]["OUT"] += 1
|
118
118
|
self.counted_ids.append(track_id)
|
119
119
|
|
120
120
|
def display_counts(self, plot_im) -> None:
|
@@ -132,8 +132,8 @@ class ObjectCounter(BaseSolution):
|
|
132
132
|
labels_dict = {
|
133
133
|
str.capitalize(key): f"{'IN ' + str(value['IN']) if self.show_in else ''} "
|
134
134
|
f"{'OUT ' + str(value['OUT']) if self.show_out else ''}".strip()
|
135
|
-
for key, value in self.
|
136
|
-
if value["IN"] != 0 or value["OUT"] != 0
|
135
|
+
for key, value in self.classwise_count.items()
|
136
|
+
if value["IN"] != 0 or value["OUT"] != 0 and (self.show_in or self.show_out)
|
137
137
|
}
|
138
138
|
if labels_dict:
|
139
139
|
self.annotator.display_analytics(plot_im, labels_dict, (104, 31, 17), (255, 255, 255), self.margin)
|
@@ -190,6 +190,6 @@ class ObjectCounter(BaseSolution):
|
|
190
190
|
plot_im=plot_im,
|
191
191
|
in_count=self.in_count,
|
192
192
|
out_count=self.out_count,
|
193
|
-
classwise_count=dict(self.
|
193
|
+
classwise_count=dict(self.classwise_count),
|
194
194
|
total_tracks=len(self.track_ids),
|
195
195
|
)
|
@@ -5,10 +5,10 @@ from pathlib import Path
|
|
5
5
|
from typing import Any, List
|
6
6
|
|
7
7
|
import numpy as np
|
8
|
-
import torch
|
9
8
|
from PIL import Image
|
10
9
|
|
11
10
|
from ultralytics.data.utils import IMG_FORMATS
|
11
|
+
from ultralytics.nn.text_model import build_text_model
|
12
12
|
from ultralytics.solutions.solutions import BaseSolution
|
13
13
|
from ultralytics.utils.checks import check_requirements
|
14
14
|
from ultralytics.utils.torch_utils import select_device
|
@@ -29,10 +29,8 @@ class VisualAISearch(BaseSolution):
|
|
29
29
|
device (str): Computation device, e.g., 'cpu' or 'cuda'.
|
30
30
|
faiss_index (str): Path to the FAISS index file.
|
31
31
|
data_path_npy (str): Path to the numpy file storing image paths.
|
32
|
-
model_name (str): Name of the CLIP model to use.
|
33
32
|
data_dir (Path): Path object for the data directory.
|
34
33
|
model: Loaded CLIP model.
|
35
|
-
preprocess: CLIP preprocessing function.
|
36
34
|
index: FAISS index for similarity search.
|
37
35
|
image_paths (List[str]): List of image file paths.
|
38
36
|
|
@@ -51,13 +49,11 @@ class VisualAISearch(BaseSolution):
|
|
51
49
|
def __init__(self, **kwargs: Any) -> None:
|
52
50
|
"""Initialize the VisualAISearch class with FAISS index and CLIP model."""
|
53
51
|
super().__init__(**kwargs)
|
54
|
-
check_requirements(
|
52
|
+
check_requirements("faiss-cpu")
|
55
53
|
|
56
54
|
self.faiss = __import__("faiss")
|
57
|
-
self.clip = __import__("clip")
|
58
55
|
self.faiss_index = "faiss.index"
|
59
56
|
self.data_path_npy = "paths.npy"
|
60
|
-
self.model_name = "ViT-B/32"
|
61
57
|
self.data_dir = Path(self.CFG["data"])
|
62
58
|
self.device = select_device(self.CFG["device"])
|
63
59
|
|
@@ -70,7 +66,7 @@ class VisualAISearch(BaseSolution):
|
|
70
66
|
safe_download(url=f"{ASSETS_URL}/images.zip", unzip=True, retry=3)
|
71
67
|
self.data_dir = Path("images")
|
72
68
|
|
73
|
-
self.model
|
69
|
+
self.model = build_text_model("clip:ViT-B/32", device=self.device)
|
74
70
|
|
75
71
|
self.index = None
|
76
72
|
self.image_paths = []
|
@@ -79,16 +75,11 @@ class VisualAISearch(BaseSolution):
|
|
79
75
|
|
80
76
|
def extract_image_feature(self, path: Path) -> np.ndarray:
|
81
77
|
"""Extract CLIP image embedding from the given image path."""
|
82
|
-
|
83
|
-
tensor = self.preprocess(image).unsqueeze(0).to(self.device)
|
84
|
-
with torch.no_grad():
|
85
|
-
return self.model.encode_image(tensor).cpu().numpy()
|
78
|
+
return self.model.encode_image(Image.open(path)).cpu().numpy()
|
86
79
|
|
87
80
|
def extract_text_feature(self, text: str) -> np.ndarray:
|
88
81
|
"""Extract CLIP text embedding from the given text query."""
|
89
|
-
|
90
|
-
with torch.no_grad():
|
91
|
-
return self.model.encode_text(tokens).cpu().numpy()
|
82
|
+
return self.model.encode_text(self.model.tokenize([text])).cpu().numpy()
|
92
83
|
|
93
84
|
def load_or_build_index(self) -> None:
|
94
85
|
"""
|
@@ -808,10 +808,10 @@ class SolutionResults:
|
|
808
808
|
filled_slots (int): The number of filled slots in a monitored area.
|
809
809
|
email_sent (bool): A flag indicating whether an email notification was sent.
|
810
810
|
total_tracks (int): The total number of tracked objects.
|
811
|
-
region_counts (Dict): The count of objects within a specific region.
|
811
|
+
region_counts (Dict[str, int]): The count of objects within a specific region.
|
812
812
|
speed_dict (Dict[str, float]): A dictionary containing speed information for tracked objects.
|
813
813
|
total_crop_objects (int): Total number of cropped objects using ObjectCropper class.
|
814
|
-
speed (Dict): Performance timing information for tracking and solution processing.
|
814
|
+
speed (Dict[str, float]): Performance timing information for tracking and solution processing.
|
815
815
|
"""
|
816
816
|
|
817
817
|
def __init__(self, **kwargs):
|
ultralytics/utils/__init__.py
CHANGED
@@ -255,11 +255,8 @@ class DataExportMixin:
|
|
255
255
|
Notes:
|
256
256
|
Requires `lxml` package to be installed.
|
257
257
|
"""
|
258
|
-
from ultralytics.utils.checks import check_requirements
|
259
|
-
|
260
|
-
check_requirements("lxml")
|
261
258
|
df = self.to_df(normalize=normalize, decimals=decimals)
|
262
|
-
return '<?xml version="1.0" encoding="utf-8"?>\n<root></root>' if df.empty else df.to_xml()
|
259
|
+
return '<?xml version="1.0" encoding="utf-8"?>\n<root></root>' if df.empty else df.to_xml(parser="etree")
|
263
260
|
|
264
261
|
def to_html(self, normalize=False, decimals=5, index=False):
|
265
262
|
"""
|
ultralytics/utils/instance.py
CHANGED
@@ -406,6 +406,8 @@ class Instances:
|
|
406
406
|
| (self.keypoints[..., 1] < 0)
|
407
407
|
| (self.keypoints[..., 1] > h)
|
408
408
|
] = 0.0
|
409
|
+
self.keypoints[..., 0] = self.keypoints[..., 0].clip(0, w)
|
410
|
+
self.keypoints[..., 1] = self.keypoints[..., 1].clip(0, h)
|
409
411
|
|
410
412
|
def remove_zero_area_boxes(self):
|
411
413
|
"""
|
ultralytics/utils/metrics.py
CHANGED
@@ -1078,23 +1078,21 @@ class DetMetrics(SimpleClass, DataExportMixin):
|
|
1078
1078
|
>>> detection_summary = results.summary()
|
1079
1079
|
>>> print(detection_summary)
|
1080
1080
|
"""
|
1081
|
-
scalars = {
|
1082
|
-
"box-map": round(self.box.map, decimals),
|
1083
|
-
"box-map50": round(self.box.map50, decimals),
|
1084
|
-
"box-map75": round(self.box.map75, decimals),
|
1085
|
-
}
|
1086
1081
|
per_class = {
|
1087
|
-
"
|
1088
|
-
"
|
1089
|
-
"
|
1082
|
+
"Box-P": self.box.p,
|
1083
|
+
"Box-R": self.box.r,
|
1084
|
+
"Box-F1": self.box.f1,
|
1090
1085
|
}
|
1091
1086
|
return [
|
1092
1087
|
{
|
1093
|
-
"
|
1088
|
+
"Class": self.names[self.ap_class_index[i]],
|
1089
|
+
"Images": self.nt_per_image[self.ap_class_index[i]],
|
1090
|
+
"Instances": self.nt_per_class[self.ap_class_index[i]],
|
1094
1091
|
**{k: round(v[i], decimals) for k, v in per_class.items()},
|
1095
|
-
|
1092
|
+
"mAP50": round(self.class_result(i)[2], decimals),
|
1093
|
+
"mAP50-95": round(self.class_result(i)[3], decimals),
|
1096
1094
|
}
|
1097
|
-
for i in range(len(per_class["
|
1095
|
+
for i in range(len(per_class["Box-P"]))
|
1098
1096
|
]
|
1099
1097
|
|
1100
1098
|
|
@@ -1213,19 +1211,14 @@ class SegmentMetrics(DetMetrics):
|
|
1213
1211
|
>>> seg_summary = results.summary(decimals=4)
|
1214
1212
|
>>> print(seg_summary)
|
1215
1213
|
"""
|
1216
|
-
scalars = {
|
1217
|
-
"mask-map": round(self.seg.map, decimals),
|
1218
|
-
"mask-map50": round(self.seg.map50, decimals),
|
1219
|
-
"mask-map75": round(self.seg.map75, decimals),
|
1220
|
-
}
|
1221
1214
|
per_class = {
|
1222
|
-
"
|
1223
|
-
"
|
1224
|
-
"
|
1215
|
+
"Mask-P": self.seg.p,
|
1216
|
+
"Mask-R": self.seg.r,
|
1217
|
+
"Mask-F1": self.seg.f1,
|
1225
1218
|
}
|
1226
1219
|
summary = DetMetrics.summary(self, normalize, decimals) # get box summary
|
1227
1220
|
for i, s in enumerate(summary):
|
1228
|
-
s.update({**{k: round(v[i], decimals) for k, v in per_class.items()}
|
1221
|
+
s.update({**{k: round(v[i], decimals) for k, v in per_class.items()}})
|
1229
1222
|
return summary
|
1230
1223
|
|
1231
1224
|
|
@@ -1357,19 +1350,14 @@ class PoseMetrics(DetMetrics):
|
|
1357
1350
|
>>> pose_summary = results.summary(decimals=4)
|
1358
1351
|
>>> print(pose_summary)
|
1359
1352
|
"""
|
1360
|
-
scalars = {
|
1361
|
-
"pose-map": round(self.pose.map, decimals),
|
1362
|
-
"pose-map50": round(self.pose.map50, decimals),
|
1363
|
-
"pose-map75": round(self.pose.map75, decimals),
|
1364
|
-
}
|
1365
1353
|
per_class = {
|
1366
|
-
"
|
1367
|
-
"
|
1368
|
-
"
|
1354
|
+
"Pose-P": self.pose.p,
|
1355
|
+
"Pose-R": self.pose.r,
|
1356
|
+
"Pose-F1": self.pose.f1,
|
1369
1357
|
}
|
1370
1358
|
summary = DetMetrics.summary(self, normalize, decimals) # get box summary
|
1371
1359
|
for i, s in enumerate(summary):
|
1372
|
-
s.update({**{k: round(v[i], decimals) for k, v in per_class.items()}
|
1360
|
+
s.update({**{k: round(v[i], decimals) for k, v in per_class.items()}})
|
1373
1361
|
return summary
|
1374
1362
|
|
1375
1363
|
|
@@ -1445,7 +1433,7 @@ class ClassifyMetrics(SimpleClass, DataExportMixin):
|
|
1445
1433
|
>>> classify_summary = results.summary(decimals=4)
|
1446
1434
|
>>> print(classify_summary)
|
1447
1435
|
"""
|
1448
|
-
return [{"
|
1436
|
+
return [{"top1_acc": round(self.top1, decimals), "top5_acc": round(self.top5, decimals)}]
|
1449
1437
|
|
1450
1438
|
|
1451
1439
|
class OBBMetrics(DetMetrics):
|
ultralytics/utils/plotting.py
CHANGED
@@ -694,7 +694,7 @@ def plot_images(
|
|
694
694
|
|
695
695
|
Args:
|
696
696
|
labels (Dict[str, Any]): Dictionary containing detection data with keys like 'cls', 'bboxes', 'conf', 'masks', 'keypoints', 'batch_idx', 'img'.
|
697
|
-
images (
|
697
|
+
images (torch.Tensor | np.ndarray]): Batch of images to plot. Shape: (batch_size, channels, height, width).
|
698
698
|
paths (Optional[List[str]]): List of file paths for each image in the batch.
|
699
699
|
fname (str): Output filename for the plotted image grid.
|
700
700
|
names (Optional[Dict[int, str]]): Dictionary mapping class indices to class names.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|