ultralytics 8.3.87__tar.gz → 8.3.88__tar.gz

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.
Files changed (258) hide show
  1. {ultralytics-8.3.87/ultralytics.egg-info → ultralytics-8.3.88}/PKG-INFO +1 -1
  2. {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_solutions.py +34 -45
  3. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/__init__.py +1 -1
  4. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/__init__.py +46 -39
  5. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/augment.py +2 -2
  6. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/__init__.py +14 -6
  7. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/ai_gym.py +39 -28
  8. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/analytics.py +22 -18
  9. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/distance_calculation.py +25 -25
  10. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/heatmap.py +40 -38
  11. ultralytics-8.3.88/ultralytics/solutions/instance_segmentation.py +69 -0
  12. ultralytics-8.3.88/ultralytics/solutions/object_blurrer.py +89 -0
  13. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/object_counter.py +35 -33
  14. ultralytics-8.3.88/ultralytics/solutions/object_cropper.py +84 -0
  15. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/parking_management.py +21 -9
  16. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/queue_management.py +20 -39
  17. ultralytics-8.3.88/ultralytics/solutions/region_counter.py +119 -0
  18. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/security_alarm.py +40 -30
  19. ultralytics-8.3.88/ultralytics/solutions/solutions.py +756 -0
  20. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/speed_estimation.py +34 -31
  21. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/streamlit_inference.py +34 -28
  22. ultralytics-8.3.88/ultralytics/solutions/trackzone.py +79 -0
  23. ultralytics-8.3.88/ultralytics/solutions/vision_eye.py +69 -0
  24. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/utils/kalman_filter.py +23 -23
  25. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/instance.py +3 -3
  26. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/plotting.py +0 -414
  27. {ultralytics-8.3.87 → ultralytics-8.3.88/ultralytics.egg-info}/PKG-INFO +1 -1
  28. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics.egg-info/SOURCES.txt +4 -0
  29. ultralytics-8.3.87/ultralytics/solutions/region_counter.py +0 -116
  30. ultralytics-8.3.87/ultralytics/solutions/solutions.py +0 -178
  31. ultralytics-8.3.87/ultralytics/solutions/trackzone.py +0 -68
  32. {ultralytics-8.3.87 → ultralytics-8.3.88}/LICENSE +0 -0
  33. {ultralytics-8.3.87 → ultralytics-8.3.88}/README.md +0 -0
  34. {ultralytics-8.3.87 → ultralytics-8.3.88}/pyproject.toml +0 -0
  35. {ultralytics-8.3.87 → ultralytics-8.3.88}/setup.cfg +0 -0
  36. {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/__init__.py +0 -0
  37. {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/conftest.py +0 -0
  38. {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_cli.py +0 -0
  39. {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_cuda.py +0 -0
  40. {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_engine.py +0 -0
  41. {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_exports.py +0 -0
  42. {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_integrations.py +0 -0
  43. {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_python.py +0 -0
  44. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/assets/bus.jpg +0 -0
  45. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/assets/zidane.jpg +0 -0
  46. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/Argoverse.yaml +0 -0
  47. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/DOTAv1.5.yaml +0 -0
  48. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/DOTAv1.yaml +0 -0
  49. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/GlobalWheat2020.yaml +0 -0
  50. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/ImageNet.yaml +0 -0
  51. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/Objects365.yaml +0 -0
  52. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/SKU-110K.yaml +0 -0
  53. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/VOC.yaml +0 -0
  54. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/VisDrone.yaml +0 -0
  55. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/african-wildlife.yaml +0 -0
  56. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/brain-tumor.yaml +0 -0
  57. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/carparts-seg.yaml +0 -0
  58. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco-pose.yaml +0 -0
  59. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco.yaml +0 -0
  60. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco128-seg.yaml +0 -0
  61. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco128.yaml +0 -0
  62. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco8-pose.yaml +0 -0
  63. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco8-seg.yaml +0 -0
  64. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco8.yaml +0 -0
  65. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/crack-seg.yaml +0 -0
  66. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/dog-pose.yaml +0 -0
  67. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/dota8.yaml +0 -0
  68. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/hand-keypoints.yaml +0 -0
  69. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/lvis.yaml +0 -0
  70. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/medical-pills.yaml +0 -0
  71. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/open-images-v7.yaml +0 -0
  72. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/package-seg.yaml +0 -0
  73. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/signature.yaml +0 -0
  74. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/tiger-pose.yaml +0 -0
  75. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/xView.yaml +0 -0
  76. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/default.yaml +0 -0
  77. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +0 -0
  78. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-cls.yaml +0 -0
  79. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-obb.yaml +0 -0
  80. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-pose.yaml +0 -0
  81. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-seg.yaml +0 -0
  82. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11.yaml +0 -0
  83. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12-cls.yaml +0 -0
  84. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12-obb.yaml +0 -0
  85. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12-pose.yaml +0 -0
  86. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12-seg.yaml +0 -0
  87. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12.yaml +0 -0
  88. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +0 -0
  89. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +0 -0
  90. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +0 -0
  91. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +0 -0
  92. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10b.yaml +0 -0
  93. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10l.yaml +0 -0
  94. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10m.yaml +0 -0
  95. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10n.yaml +0 -0
  96. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10s.yaml +0 -0
  97. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10x.yaml +0 -0
  98. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v3/yolov3-spp.yaml +0 -0
  99. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v3/yolov3-tiny.yaml +0 -0
  100. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v3/yolov3.yaml +0 -0
  101. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v5/yolov5-p6.yaml +0 -0
  102. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v5/yolov5.yaml +0 -0
  103. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v6/yolov6.yaml +0 -0
  104. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +0 -0
  105. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +0 -0
  106. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-cls.yaml +0 -0
  107. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +0 -0
  108. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +0 -0
  109. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-ghost.yaml +0 -0
  110. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-obb.yaml +0 -0
  111. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-p2.yaml +0 -0
  112. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-p6.yaml +0 -0
  113. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +0 -0
  114. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-pose.yaml +0 -0
  115. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +0 -0
  116. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +0 -0
  117. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-seg.yaml +0 -0
  118. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-world.yaml +0 -0
  119. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-worldv2.yaml +0 -0
  120. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8.yaml +0 -0
  121. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9c-seg.yaml +0 -0
  122. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9c.yaml +0 -0
  123. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9e-seg.yaml +0 -0
  124. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9e.yaml +0 -0
  125. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9m.yaml +0 -0
  126. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9s.yaml +0 -0
  127. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9t.yaml +0 -0
  128. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/solutions/default.yaml +0 -0
  129. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/trackers/botsort.yaml +0 -0
  130. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/trackers/bytetrack.yaml +0 -0
  131. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/__init__.py +0 -0
  132. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/annotator.py +0 -0
  133. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/base.py +0 -0
  134. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/build.py +0 -0
  135. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/converter.py +0 -0
  136. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/dataset.py +0 -0
  137. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/loaders.py +0 -0
  138. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/split_dota.py +0 -0
  139. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/utils.py +0 -0
  140. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/__init__.py +0 -0
  141. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/exporter.py +0 -0
  142. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/model.py +0 -0
  143. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/predictor.py +0 -0
  144. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/results.py +0 -0
  145. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/trainer.py +0 -0
  146. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/tuner.py +0 -0
  147. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/validator.py +0 -0
  148. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/__init__.py +0 -0
  149. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/auth.py +0 -0
  150. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/google/__init__.py +0 -0
  151. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/session.py +0 -0
  152. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/utils.py +0 -0
  153. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/__init__.py +0 -0
  154. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/__init__.py +0 -0
  155. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/model.py +0 -0
  156. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/predict.py +0 -0
  157. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/utils.py +0 -0
  158. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/val.py +0 -0
  159. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/nas/__init__.py +0 -0
  160. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/nas/model.py +0 -0
  161. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/nas/predict.py +0 -0
  162. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/nas/val.py +0 -0
  163. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/__init__.py +0 -0
  164. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/model.py +0 -0
  165. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/predict.py +0 -0
  166. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/train.py +0 -0
  167. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/val.py +0 -0
  168. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/__init__.py +0 -0
  169. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/amg.py +0 -0
  170. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/build.py +0 -0
  171. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/model.py +0 -0
  172. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/__init__.py +0 -0
  173. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/blocks.py +0 -0
  174. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/decoders.py +0 -0
  175. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/encoders.py +0 -0
  176. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/memory_attention.py +0 -0
  177. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/sam.py +0 -0
  178. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/tiny_encoder.py +0 -0
  179. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/transformer.py +0 -0
  180. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/utils.py +0 -0
  181. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/predict.py +0 -0
  182. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/utils/__init__.py +0 -0
  183. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/utils/loss.py +0 -0
  184. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/utils/ops.py +0 -0
  185. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/__init__.py +0 -0
  186. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/classify/__init__.py +0 -0
  187. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/classify/predict.py +0 -0
  188. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/classify/train.py +0 -0
  189. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/classify/val.py +0 -0
  190. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/detect/__init__.py +0 -0
  191. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/detect/predict.py +0 -0
  192. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/detect/train.py +0 -0
  193. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/detect/val.py +0 -0
  194. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/model.py +0 -0
  195. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/obb/__init__.py +0 -0
  196. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/obb/predict.py +0 -0
  197. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/obb/train.py +0 -0
  198. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/obb/val.py +0 -0
  199. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/pose/__init__.py +0 -0
  200. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/pose/predict.py +0 -0
  201. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/pose/train.py +0 -0
  202. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/pose/val.py +0 -0
  203. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/segment/__init__.py +0 -0
  204. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/segment/predict.py +0 -0
  205. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/segment/train.py +0 -0
  206. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/segment/val.py +0 -0
  207. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/world/__init__.py +0 -0
  208. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/world/train.py +0 -0
  209. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/world/train_world.py +0 -0
  210. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/__init__.py +0 -0
  211. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/autobackend.py +0 -0
  212. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/__init__.py +0 -0
  213. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/activation.py +0 -0
  214. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/block.py +0 -0
  215. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/conv.py +0 -0
  216. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/head.py +0 -0
  217. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/transformer.py +0 -0
  218. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/utils.py +0 -0
  219. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/tasks.py +0 -0
  220. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/__init__.py +0 -0
  221. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/basetrack.py +0 -0
  222. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/bot_sort.py +0 -0
  223. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/byte_tracker.py +0 -0
  224. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/track.py +0 -0
  225. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/utils/__init__.py +0 -0
  226. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/utils/gmc.py +0 -0
  227. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/utils/matching.py +0 -0
  228. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/__init__.py +0 -0
  229. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/autobatch.py +0 -0
  230. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/benchmarks.py +0 -0
  231. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/__init__.py +0 -0
  232. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/base.py +0 -0
  233. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/clearml.py +0 -0
  234. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/comet.py +0 -0
  235. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/dvc.py +0 -0
  236. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/hub.py +0 -0
  237. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/mlflow.py +0 -0
  238. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/neptune.py +0 -0
  239. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/raytune.py +0 -0
  240. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/tensorboard.py +0 -0
  241. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/wb.py +0 -0
  242. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/checks.py +0 -0
  243. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/dist.py +0 -0
  244. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/downloads.py +0 -0
  245. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/errors.py +0 -0
  246. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/files.py +0 -0
  247. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/loss.py +0 -0
  248. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/metrics.py +0 -0
  249. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/ops.py +0 -0
  250. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/patches.py +0 -0
  251. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/tal.py +0 -0
  252. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/torch_utils.py +0 -0
  253. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/triton.py +0 -0
  254. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/tuner.py +0 -0
  255. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics.egg-info/dependency_links.txt +0 -0
  256. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics.egg-info/entry_points.txt +0 -0
  257. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics.egg-info/requires.txt +0 -0
  258. {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ultralytics
3
- Version: 8.3.87
3
+ Version: 8.3.88
4
4
  Summary: Ultralytics YOLO 🚀 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
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,11 +1,13 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
+ # This is file for Ultralytics Solutions tests: https://docs.ultralytics.com/solutions/,
3
+ # It includes every solution excluding DistanceCalculation and Security Alarm System.
2
4
 
3
5
  import cv2
4
6
  import pytest
5
7
 
6
8
  from tests import TMP
7
- from ultralytics import YOLO, solutions
8
- from ultralytics.utils import ASSETS_URL, WEIGHTS_DIR
9
+ from ultralytics import solutions
10
+ from ultralytics.utils import ASSETS_URL
9
11
  from ultralytics.utils.downloads import safe_download
10
12
 
11
13
  DEMO_VIDEO = "solutions_ci_demo.mp4" # for all the solutions, except workout and parking
@@ -24,16 +26,23 @@ def test_major_solutions():
24
26
  region_points = [(20, 400), (1080, 400), (1080, 360), (20, 360)]
25
27
  counter = solutions.ObjectCounter(region=region_points, model="yolo11n.pt", show=False) # Test object counter
26
28
  heatmap = solutions.Heatmap(colormap=cv2.COLORMAP_PARULA, model="yolo11n.pt", show=False) # Test heatmaps
27
- heatmap_count = solutions.Heatmap(
29
+ heatmapcounter = solutions.Heatmap(
28
30
  colormap=cv2.COLORMAP_PARULA, model="yolo11n.pt", show=False, region=region_points
29
31
  ) # Test heatmaps with object counting
30
32
  speed = solutions.SpeedEstimator(region=region_points, model="yolo11n.pt", show=False) # Test queue manager
31
33
  queue = solutions.QueueManager(region=region_points, model="yolo11n.pt", show=False) # Test speed estimation
32
- line_analytics = solutions.Analytics(analytics_type="line", model="yolo11n.pt", show=False) # line analytics
33
- pie_analytics = solutions.Analytics(analytics_type="pie", model="yolo11n.pt", show=False) # line analytics
34
- bar_analytics = solutions.Analytics(analytics_type="bar", model="yolo11n.pt", show=False) # line analytics
35
- area_analytics = solutions.Analytics(analytics_type="area", model="yolo11n.pt", show=False) # line analytics
36
- trackzone = solutions.TrackZone(region=region_points, model="yolo11n.pt", show=False) # Test trackzone
34
+ lineanalytics = solutions.Analytics(analytics_type="line", model="yolo11n.pt", show=False) # line analytics
35
+ pieanalytics = solutions.Analytics(analytics_type="pie", model="yolo11n.pt", show=False) # line analytics
36
+ baranalytics = solutions.Analytics(analytics_type="bar", model="yolo11n.pt", show=False) # line analytics
37
+ areaanalytics = solutions.Analytics(analytics_type="area", model="yolo11n.pt", show=False) # line analytics
38
+ trackzone = solutions.TrackZone(region=region_points, model="yolo11n.pt", show=False) # trackzone
39
+ objectcropper = solutions.ObjectCropper(
40
+ model="yolo11n.pt", show=False, crop_dir=str(TMP / "cropped-detections")
41
+ ) # object cropping
42
+ objectblurrer = solutions.ObjectBlurrer(blur_ratio=0.5, model="yolo11n.pt", show=False) # Object blurring
43
+ isegment = solutions.InstanceSegmentation(model="yolo11n-seg.pt", show=False) # Instance segmentation
44
+ visioneye = solutions.VisionEye(model="yolo11n.pt", show=False) # Visioneye
45
+ regioncounter = solutions.RegionCounter(region=region_points, model="yolo11n.pt", show=False) # Region counter
37
46
  frame_count = 0 # Required for analytics
38
47
  while cap.isOpened():
39
48
  success, im0 = cap.read()
@@ -41,16 +50,21 @@ def test_major_solutions():
41
50
  break
42
51
  frame_count += 1
43
52
  original_im0 = im0.copy()
44
- _ = counter.count(original_im0.copy())
45
- _ = heatmap.generate_heatmap(original_im0.copy())
46
- _ = heatmap_count.generate_heatmap(original_im0.copy())
47
- _ = speed.estimate_speed(original_im0.copy())
48
- _ = queue.process_queue(original_im0.copy())
49
- _ = line_analytics.process_data(original_im0.copy(), frame_count)
50
- _ = pie_analytics.process_data(original_im0.copy(), frame_count)
51
- _ = bar_analytics.process_data(original_im0.copy(), frame_count)
52
- _ = area_analytics.process_data(original_im0.copy(), frame_count)
53
- _ = trackzone.trackzone(original_im0.copy())
53
+ _ = counter(original_im0.copy())
54
+ _ = heatmap(original_im0.copy())
55
+ _ = heatmapcounter(original_im0.copy())
56
+ _ = speed(original_im0.copy())
57
+ _ = queue(original_im0.copy())
58
+ _ = lineanalytics(original_im0.copy(), frame_count)
59
+ _ = pieanalytics(original_im0.copy(), frame_count)
60
+ _ = baranalytics(original_im0.copy(), frame_count)
61
+ _ = areaanalytics(original_im0.copy(), frame_count)
62
+ _ = trackzone(original_im0.copy())
63
+ _ = objectcropper(original_im0.copy())
64
+ _ = isegment(original_im0.copy())
65
+ _ = objectblurrer(original_im0.copy())
66
+ _ = visioneye(original_im0.copy())
67
+ _ = regioncounter(original_im0.copy())
54
68
  cap.release()
55
69
 
56
70
  # Test workouts monitoring
@@ -62,7 +76,7 @@ def test_major_solutions():
62
76
  success, im0 = cap.read()
63
77
  if not success:
64
78
  break
65
- _ = gym.monitor(im0)
79
+ _ = gym(im0)
66
80
  cap.release()
67
81
 
68
82
  # Test parking management
@@ -78,35 +92,10 @@ def test_major_solutions():
78
92
  success, im0 = cap.read()
79
93
  if not success:
80
94
  break
81
- _ = parkingmanager.process_data(im0)
95
+ _ = parkingmanager(im0)
82
96
  cap.release()
83
97
 
84
98
 
85
- @pytest.mark.slow
86
- def test_instance_segmentation():
87
- """Test the instance segmentation solution."""
88
- from ultralytics.utils.plotting import Annotator, colors
89
-
90
- model = YOLO(WEIGHTS_DIR / "yolo11n-seg.pt")
91
- names = model.names
92
- cap = cv2.VideoCapture(TMP / DEMO_VIDEO)
93
- assert cap.isOpened(), "Error reading video file"
94
- while cap.isOpened():
95
- success, im0 = cap.read()
96
- if not success:
97
- break
98
- results = model.predict(im0)
99
- annotator = Annotator(im0, line_width=2)
100
- if results[0].masks is not None:
101
- clss = results[0].boxes.cls.cpu().tolist()
102
- masks = results[0].masks.xy
103
- for mask, cls in zip(masks, clss):
104
- color = colors(int(cls), True)
105
- annotator.seg_bbox(mask=mask, mask_color=color, label=names[int(cls)])
106
- cap.release()
107
- cv2.destroyAllWindows()
108
-
109
-
110
99
  @pytest.mark.slow
111
100
  def test_streamlit_predict():
112
101
  """Test streamlit predict live inference solution."""
@@ -1,6 +1,6 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- __version__ = "8.3.87"
3
+ __version__ = "8.3.88"
4
4
 
5
5
  import os
6
6
 
@@ -5,7 +5,7 @@ import subprocess
5
5
  import sys
6
6
  from pathlib import Path
7
7
  from types import SimpleNamespace
8
- from typing import Dict, List, Union
8
+ from typing import Any, Dict, List, Union
9
9
 
10
10
  import cv2
11
11
 
@@ -35,14 +35,18 @@ from ultralytics.utils import (
35
35
 
36
36
  # Define valid solutions
37
37
  SOLUTION_MAP = {
38
- "count": ("ObjectCounter", "count"),
39
- "heatmap": ("Heatmap", "generate_heatmap"),
40
- "queue": ("QueueManager", "process_queue"),
41
- "speed": ("SpeedEstimator", "estimate_speed"),
42
- "workout": ("AIGym", "monitor"),
43
- "analytics": ("Analytics", "process_data"),
44
- "trackzone": ("TrackZone", "trackzone"),
45
- "inference": ("Inference", "inference"),
38
+ "count": "ObjectCounter",
39
+ "crop": "ObjectCropper",
40
+ "blur": "ObjectBlurrer",
41
+ "workout": "AIGym",
42
+ "heatmap": "Heatmap",
43
+ "isegment": "InstanceSegmentation",
44
+ "visioneye": "VisionEye",
45
+ "speed": "SpeedEstimator",
46
+ "queue": "QueueManager",
47
+ "analytics": "Analytics",
48
+ "inference": "Inference",
49
+ "trackzone": "TrackZone",
46
50
  "help": None,
47
51
  }
48
52
 
@@ -238,7 +242,7 @@ CFG_BOOL_KEYS = frozenset(
238
242
  )
239
243
 
240
244
 
241
- def cfg2dict(cfg):
245
+ def cfg2dict(cfg: Union[str, Path, Dict, SimpleNamespace]) -> Dict:
242
246
  """
243
247
  Converts a configuration object to a dictionary.
244
248
 
@@ -273,7 +277,7 @@ def cfg2dict(cfg):
273
277
  return cfg
274
278
 
275
279
 
276
- def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, overrides: Dict = None):
280
+ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, overrides: Dict = None) -> SimpleNamespace:
277
281
  """
278
282
  Load and merge configuration data from a file or dictionary, with optional overrides.
279
283
 
@@ -321,7 +325,7 @@ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, ove
321
325
  return IterableSimpleNamespace(**cfg)
322
326
 
323
327
 
324
- def check_cfg(cfg, hard=True):
328
+ def check_cfg(cfg: Dict, hard: bool = True) -> None:
325
329
  """
326
330
  Checks configuration argument types and values for the Ultralytics library.
327
331
 
@@ -383,7 +387,7 @@ def check_cfg(cfg, hard=True):
383
387
  cfg[k] = bool(v)
384
388
 
385
389
 
386
- def get_save_dir(args, name=None):
390
+ def get_save_dir(args: SimpleNamespace, name: str = None) -> Path:
387
391
  """
388
392
  Returns the directory path for saving outputs, derived from arguments or default settings.
389
393
 
@@ -415,7 +419,7 @@ def get_save_dir(args, name=None):
415
419
  return Path(save_dir)
416
420
 
417
421
 
418
- def _handle_deprecation(custom):
422
+ def _handle_deprecation(custom: Dict) -> Dict:
419
423
  """
420
424
  Handles deprecated configuration keys by mapping them to current equivalents with deprecation warnings.
421
425
 
@@ -453,7 +457,7 @@ def _handle_deprecation(custom):
453
457
  return custom
454
458
 
455
459
 
456
- def check_dict_alignment(base: Dict, custom: Dict, e=None):
460
+ def check_dict_alignment(base: Dict, custom: Dict, e: Exception = None) -> None:
457
461
  """
458
462
  Checks alignment between custom and base configuration dictionaries, handling deprecated keys and providing error
459
463
  messages for mismatched keys.
@@ -507,7 +511,7 @@ def merge_equals_args(args: List[str]) -> List[str]:
507
511
  args (List[str]): A list of strings where each element represents an argument or fragment.
508
512
 
509
513
  Returns:
510
- List[str]: A list of strings where the arguments around isolated '=' are merged and fragments with brackets are joined.
514
+ (List[str]): A list of strings where the arguments around isolated '=' are merged and fragments with brackets are joined.
511
515
 
512
516
  Examples:
513
517
  >>> args = ["arg1", "=", "value", "arg2=", "value2", "arg3", "=value3", "imgsz=[3,", "640,", "640]"]
@@ -634,9 +638,6 @@ def handle_yolo_solutions(args: List[str]) -> None:
634
638
  solutions: https://docs.ultralytics.com/solutions/, It can include solution name, source,
635
639
  and other configuration parameters.
636
640
 
637
- Returns:
638
- None: The function processes video frames and saves the output but doesn't return any value.
639
-
640
641
  Examples:
641
642
  Run people counting solution with default settings:
642
643
  >>> handle_yolo_solutions(["count"])
@@ -660,7 +661,13 @@ def handle_yolo_solutions(args: List[str]) -> None:
660
661
  - The inference solution will be launched using the 'streamlit run' command.
661
662
  - The Streamlit app file is located in the Ultralytics package directory.
662
663
  """
663
- full_args_dict = {**DEFAULT_SOL_DICT, **DEFAULT_CFG_DICT} # arguments dictionary
664
+ full_args_dict = {
665
+ **DEFAULT_SOL_DICT,
666
+ **DEFAULT_CFG_DICT,
667
+ "blur_ratio": 0.5,
668
+ "vision_point": (20, 20),
669
+ "crop_dir": "cropped-detections",
670
+ } # arguments dictionary
664
671
  overrides = {}
665
672
 
666
673
  # check dictionary alignment
@@ -705,21 +712,19 @@ def handle_yolo_solutions(args: List[str]) -> None:
705
712
  else:
706
713
  from ultralytics import solutions
707
714
 
708
- cls, method = SOLUTION_MAP[solution_name] # solution class name, method name and default source
709
- solution = getattr(solutions, cls)(IS_CLI=True, **overrides) # get solution class i.e ObjectCounter
710
- process = getattr(
711
- solution, method
712
- ) # get specific function of class for processing i.e, count from ObjectCounter
715
+ solution = getattr(solutions, SOLUTION_MAP[solution_name])(is_cli=True, **overrides) # class i.e ObjectCounter
713
716
 
714
717
  cap = cv2.VideoCapture(solution.CFG["source"]) # read the video file
715
-
716
- # extract width, height and fps of the video file, create save directory and initialize video writer
717
- w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
718
- if solution_name == "analytics": # analytical graphs follow fixed shape for output i.e w=1920, h=1080
719
- w, h = 1920, 1080
720
- save_dir = get_save_dir(SimpleNamespace(project="runs/solutions", name="exp", exist_ok=False))
721
- save_dir.mkdir(parents=True) # create the output directory i.e. runs/solutions/exp
722
- vw = cv2.VideoWriter(str(save_dir / f"{solution_name}.avi"), cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
718
+ if solution_name != "crop":
719
+ # extract width, height and fps of the video file, create save directory and initialize video writer
720
+ w, h, fps = (
721
+ int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)
722
+ )
723
+ if solution_name == "analytics": # analytical graphs follow fixed shape for output i.e w=1920, h=1080
724
+ w, h = 1280, 720
725
+ save_dir = get_save_dir(SimpleNamespace(project="runs/solutions", name="exp", exist_ok=False))
726
+ save_dir.mkdir(parents=True) # create the output directory i.e. runs/solutions/exp
727
+ vw = cv2.VideoWriter(str(save_dir / f"{solution_name}.avi"), cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
723
728
 
724
729
  try: # Process video frames
725
730
  f_n = 0 # frame number, required for analytical graphs
@@ -727,15 +732,17 @@ def handle_yolo_solutions(args: List[str]) -> None:
727
732
  success, frame = cap.read()
728
733
  if not success:
729
734
  break
730
- frame = process(frame, f_n := f_n + 1) if solution_name == "analytics" else process(frame)
731
- vw.write(frame)
735
+ results = solution(frame, f_n := f_n + 1) if solution_name == "analytics" else solution(frame)
736
+ LOGGER.info(f"🚀 Results: {results}")
737
+ if solution_name != "crop":
738
+ vw.write(results.plot_im)
732
739
  if cv2.waitKey(1) & 0xFF == ord("q"):
733
740
  break
734
741
  finally:
735
742
  cap.release()
736
743
 
737
744
 
738
- def parse_key_value_pair(pair: str = "key=value"):
745
+ def parse_key_value_pair(pair: str = "key=value") -> tuple:
739
746
  """
740
747
  Parses a key-value pair string into separate key and value components.
741
748
 
@@ -769,7 +776,7 @@ def parse_key_value_pair(pair: str = "key=value"):
769
776
  return k, smart_value(v)
770
777
 
771
778
 
772
- def smart_value(v):
779
+ def smart_value(v: str) -> Any:
773
780
  """
774
781
  Converts a string representation of a value to its appropriate Python type.
775
782
 
@@ -814,7 +821,7 @@ def smart_value(v):
814
821
  return v
815
822
 
816
823
 
817
- def entrypoint(debug=""):
824
+ def entrypoint(debug: str = "") -> None:
818
825
  """
819
826
  Ultralytics entrypoint function for parsing and executing command-line arguments.
820
827
 
@@ -986,7 +993,7 @@ def entrypoint(debug=""):
986
993
 
987
994
 
988
995
  # Special modes --------------------------------------------------------------------------------------------------------
989
- def copy_default_cfg():
996
+ def copy_default_cfg() -> None:
990
997
  """
991
998
  Copies the default configuration file and creates a new one with '_copy' appended to its name.
992
999
 
@@ -1193,8 +1193,8 @@ class RandomPerspective:
1193
1193
  Args:
1194
1194
  labels (Dict): A dictionary containing image data and annotations.
1195
1195
  Must include:
1196
- 'img' (ndarray): The input image.
1197
- 'cls' (ndarray): Class labels.
1196
+ 'img' (np.ndarray): The input image.
1197
+ 'cls' (np.ndarray): Class labels.
1198
1198
  'instances' (Instances): Object instances with bounding boxes, segments, and keypoints.
1199
1199
  May include:
1200
1200
  'mosaic_border' (Tuple[int, int]): Border size for mosaic augmentation.
@@ -4,7 +4,10 @@ from .ai_gym import AIGym
4
4
  from .analytics import Analytics
5
5
  from .distance_calculation import DistanceCalculation
6
6
  from .heatmap import Heatmap
7
+ from .instance_segmentation import InstanceSegmentation
8
+ from .object_blurrer import ObjectBlurrer
7
9
  from .object_counter import ObjectCounter
10
+ from .object_cropper import ObjectCropper
8
11
  from .parking_management import ParkingManagement, ParkingPtsSelection
9
12
  from .queue_management import QueueManager
10
13
  from .region_counter import RegionCounter
@@ -12,19 +15,24 @@ from .security_alarm import SecurityAlarm
12
15
  from .speed_estimation import SpeedEstimator
13
16
  from .streamlit_inference import Inference
14
17
  from .trackzone import TrackZone
18
+ from .vision_eye import VisionEye
15
19
 
16
20
  __all__ = (
21
+ "ObjectCounter",
22
+ "ObjectCropper",
23
+ "ObjectBlurrer",
17
24
  "AIGym",
18
- "DistanceCalculation",
25
+ "RegionCounter",
26
+ "SecurityAlarm",
19
27
  "Heatmap",
20
- "ObjectCounter",
28
+ "InstanceSegmentation",
29
+ "VisionEye",
30
+ "SpeedEstimator",
31
+ "DistanceCalculation",
32
+ "QueueManager",
21
33
  "ParkingManagement",
22
34
  "ParkingPtsSelection",
23
- "QueueManager",
24
- "SpeedEstimator",
25
35
  "Analytics",
26
36
  "Inference",
27
- "RegionCounter",
28
37
  "TrackZone",
29
- "SecurityAlarm",
30
38
  )
@@ -1,7 +1,6 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- from ultralytics.solutions.solutions import BaseSolution
4
- from ultralytics.utils.plotting import Annotator
3
+ from ultralytics.solutions.solutions import BaseSolution, SolutionAnnotator, SolutionResults
5
4
 
6
5
 
7
6
  class AIGym(BaseSolution):
@@ -19,27 +18,28 @@ class AIGym(BaseSolution):
19
18
  up_angle (float): Angle threshold for considering the 'up' position of an exercise.
20
19
  down_angle (float): Angle threshold for considering the 'down' position of an exercise.
21
20
  kpts (List[int]): Indices of keypoints used for angle calculation.
22
- annotator (Annotator): Object for drawing annotations on the image.
23
21
 
24
22
  Methods:
25
- monitor: Processes a frame to detect poses, calculate angles, and count repetitions.
23
+ process: Processes a frame to detect poses, calculate angles, and count repetitions.
26
24
 
27
25
  Examples:
28
26
  >>> gym = AIGym(model="yolo11n-pose.pt")
29
27
  >>> image = cv2.imread("gym_scene.jpg")
30
- >>> processed_image = gym.monitor(image)
28
+ >>> results = gym.process(image)
29
+ >>> processed_image = results.plot_im
31
30
  >>> cv2.imshow("Processed Image", processed_image)
32
31
  >>> cv2.waitKey(0)
33
32
  """
34
33
 
35
34
  def __init__(self, **kwargs):
36
- """Initializes AIGym for workout monitoring using pose estimation and predefined angles."""
37
- # Check if the model name ends with '-pose'
38
- if "model" in kwargs and "-pose" not in kwargs["model"]:
39
- kwargs["model"] = "yolo11n-pose.pt"
40
- elif "model" not in kwargs:
41
- kwargs["model"] = "yolo11n-pose.pt"
35
+ """
36
+ Initializes AIGym for workout monitoring using pose estimation and predefined angles.
42
37
 
38
+ Args:
39
+ **kwargs (Any): Keyword arguments passed to the parent class constructor.
40
+ model (str): Model name or path, defaults to "yolo11n-pose.pt".
41
+ """
42
+ kwargs["model"] = kwargs.get("model", "yolo11n-pose.pt")
43
43
  super().__init__(**kwargs)
44
44
  self.count = [] # List for counts, necessary where there are multiple objects in frame
45
45
  self.angle = [] # List for angle, necessary where there are multiple objects in frame
@@ -51,7 +51,7 @@ class AIGym(BaseSolution):
51
51
  self.down_angle = float(self.CFG["down_angle"]) # Pose down predefined angle to consider down pose
52
52
  self.kpts = self.CFG["kpts"] # User selected kpts of workouts storage for further usage
53
53
 
54
- def monitor(self, im0):
54
+ def process(self, im0):
55
55
  """
56
56
  Monitors workouts using Ultralytics YOLO Pose Model.
57
57
 
@@ -60,36 +60,39 @@ class AIGym(BaseSolution):
60
60
  angle thresholds.
61
61
 
62
62
  Args:
63
- im0 (ndarray): Input image for processing.
63
+ im0 (np.ndarray): Input image for processing.
64
64
 
65
65
  Returns:
66
- (ndarray): Processed image with annotations for workout monitoring.
66
+ (SolutionResults): Contains processed image `plot_im`,
67
+ 'workout_count' (list of completed reps),
68
+ 'workout_stage' (list of current stages),
69
+ 'workout_angle' (list of angles), and
70
+ 'total_tracks' (total number of tracked individuals).
67
71
 
68
72
  Examples:
69
73
  >>> gym = AIGym()
70
74
  >>> image = cv2.imread("workout.jpg")
71
- >>> processed_image = gym.monitor(image)
75
+ >>> results = gym.process(image)
76
+ >>> processed_image = results.plot_im
72
77
  """
73
- # Extract tracks
74
- tracks = self.model.track(source=im0, persist=True, classes=self.CFG["classes"], **self.track_add_args)[0]
78
+ annotator = SolutionAnnotator(im0, line_width=self.line_width) # Initialize annotator
79
+
80
+ self.extract_tracks(im0) # Extract tracks (bounding boxes, classes, and masks)
81
+ tracks = self.tracks[0]
75
82
 
76
83
  if tracks.boxes.id is not None:
77
- # Extract and check keypoints
78
- if len(tracks) > len(self.count):
84
+ if len(tracks) > len(self.count): # Add new entries for newly detected people
79
85
  new_human = len(tracks) - len(self.count)
80
86
  self.angle += [0] * new_human
81
87
  self.count += [0] * new_human
82
88
  self.stage += ["-"] * new_human
83
89
 
84
- # Initialize annotator
85
- self.annotator = Annotator(im0, line_width=self.line_width)
86
-
87
90
  # Enumerate over keypoints
88
91
  for ind, k in enumerate(reversed(tracks.keypoints.data)):
89
92
  # Get keypoints and estimate the angle
90
93
  kpts = [k[int(self.kpts[i])].cpu() for i in range(3)]
91
- self.angle[ind] = self.annotator.estimate_pose_angle(*kpts)
92
- im0 = self.annotator.draw_specific_points(k, self.kpts, radius=self.line_width * 3)
94
+ self.angle[ind] = annotator.estimate_pose_angle(*kpts)
95
+ annotator.draw_specific_kpts(k, self.kpts, radius=self.line_width * 3)
93
96
 
94
97
  # Determine stage and count logic based on angle thresholds
95
98
  if self.angle[ind] < self.down_angle:
@@ -100,12 +103,20 @@ class AIGym(BaseSolution):
100
103
  self.stage[ind] = "up"
101
104
 
102
105
  # Display angle, count, and stage text
103
- self.annotator.plot_angle_and_count_and_stage(
106
+ annotator.plot_angle_and_count_and_stage(
104
107
  angle_text=self.angle[ind], # angle text for display
105
108
  count_text=self.count[ind], # count text for workouts
106
109
  stage_text=self.stage[ind], # stage position text
107
110
  center_kpt=k[int(self.kpts[1])], # center keypoint for display
108
111
  )
109
-
110
- self.display_output(im0) # Display output image, if environment support display
111
- return im0 # return an image for writing or further usage
112
+ plot_im = annotator.result()
113
+ self.display_output(plot_im) # Display output image, if environment support display
114
+
115
+ # Return SolutionResults
116
+ return SolutionResults(
117
+ plot_im=plot_im,
118
+ workout_count=self.count,
119
+ workout_stage=self.stage,
120
+ workout_angle=self.angle,
121
+ total_tracks=len(self.track_ids),
122
+ )
@@ -8,7 +8,7 @@ import numpy as np
8
8
  from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
9
9
  from matplotlib.figure import Figure
10
10
 
11
- from ultralytics.solutions.solutions import BaseSolution # Import a parent class
11
+ from ultralytics.solutions.solutions import BaseSolution, SolutionResults # Import a parent class
12
12
 
13
13
 
14
14
  class Analytics(BaseSolution):
@@ -33,16 +33,18 @@ class Analytics(BaseSolution):
33
33
  fig (Figure): Matplotlib figure object for the chart.
34
34
  ax (Axes): Matplotlib axes object for the chart.
35
35
  canvas (FigureCanvas): Canvas for rendering the chart.
36
+ lines (Dict): Dictionary to store line objects for area charts.
37
+ color_mapping (Dict[str, str]): Dictionary mapping class labels to colors for consistent visualization.
36
38
 
37
39
  Methods:
38
- process_data: Processes image data and updates the chart.
40
+ process: Processes image data and updates the chart.
39
41
  update_graph: Updates the chart with new data points.
40
42
 
41
43
  Examples:
42
44
  >>> analytics = Analytics(analytics_type="line")
43
45
  >>> frame = cv2.imread("image.jpg")
44
- >>> processed_frame = analytics.process_data(frame, frame_number=1)
45
- >>> cv2.imshow("Analytics", processed_frame)
46
+ >>> results = analytics.process(frame, frame_number=1)
47
+ >>> cv2.imshow("Analytics", results.plot_im)
46
48
  """
47
49
 
48
50
  def __init__(self, **kwargs):
@@ -59,7 +61,7 @@ class Analytics(BaseSolution):
59
61
  self.title = "Ultralytics Solutions" # window name
60
62
  self.max_points = 45 # maximum points to be drawn on window
61
63
  self.fontsize = 25 # text font size for display
62
- figsize = (19.2, 10.8) # Set output image size 1920 * 1080
64
+ figsize = (12.8, 7.2) # Set output image size 1280 * 720
63
65
  self.color_cycle = cycle(["#DD00BA", "#042AFF", "#FF4447", "#7D24FF", "#BD00FF"])
64
66
 
65
67
  self.total_counts = 0 # count variable for storing total counts i.e. for line
@@ -83,7 +85,7 @@ class Analytics(BaseSolution):
83
85
  if self.type == "pie": # Ensure pie chart is circular
84
86
  self.ax.axis("equal")
85
87
 
86
- def process_data(self, im0, frame_number):
88
+ def process(self, im0, frame_number):
87
89
  """
88
90
  Processes image data and runs object tracking to update analytics charts.
89
91
 
@@ -92,7 +94,8 @@ class Analytics(BaseSolution):
92
94
  frame_number (int): Video frame number for plotting the data.
93
95
 
94
96
  Returns:
95
- (np.ndarray): Processed image with updated analytics chart.
97
+ (SolutionResults): Contains processed image `plot_im`, 'total_tracks' (int, total number of tracked objects)
98
+ and 'classwise_count' (dict, per-class object count).
96
99
 
97
100
  Raises:
98
101
  ModuleNotFoundError: If an unsupported chart type is specified.
@@ -100,26 +103,27 @@ class Analytics(BaseSolution):
100
103
  Examples:
101
104
  >>> analytics = Analytics(analytics_type="line")
102
105
  >>> frame = np.zeros((480, 640, 3), dtype=np.uint8)
103
- >>> processed_frame = analytics.process_data(frame, frame_number=1)
106
+ >>> results = analytics.process(frame, frame_number=1)
104
107
  """
105
108
  self.extract_tracks(im0) # Extract tracks
106
-
107
109
  if self.type == "line":
108
110
  for _ in self.boxes:
109
111
  self.total_counts += 1
110
- im0 = self.update_graph(frame_number=frame_number)
112
+ plot_im = self.update_graph(frame_number=frame_number)
111
113
  self.total_counts = 0
112
114
  elif self.type in {"pie", "bar", "area"}:
113
115
  self.clswise_count = {}
114
- for box, cls in zip(self.boxes, self.clss):
116
+ for cls in self.clss:
115
117
  if self.names[int(cls)] in self.clswise_count:
116
118
  self.clswise_count[self.names[int(cls)]] += 1
117
119
  else:
118
120
  self.clswise_count[self.names[int(cls)]] = 1
119
- im0 = self.update_graph(frame_number=frame_number, count_dict=self.clswise_count, plot=self.type)
121
+ plot_im = self.update_graph(frame_number=frame_number, count_dict=self.clswise_count, plot=self.type)
120
122
  else:
121
123
  raise ModuleNotFoundError(f"{self.type} chart is not supported ❌")
122
- return im0
124
+
125
+ # return output dictionary with summary for more usage
126
+ return SolutionResults(plot_im=plot_im, total_tracks=len(self.track_ids), classwise_count=self.clswise_count)
123
127
 
124
128
  def update_graph(self, frame_number, count_dict=None, plot="line"):
125
129
  """
@@ -135,10 +139,10 @@ class Analytics(BaseSolution):
135
139
  (np.ndarray): Updated image containing the graph.
136
140
 
137
141
  Examples:
138
- >>> analytics = Analytics()
139
- >>> frame_number = 10
140
- >>> count_dict = {"person": 5, "car": 3}
141
- >>> updated_image = analytics.update_graph(frame_number, count_dict, plot="bar")
142
+ >>> analytics = Analytics(analytics_type="bar")
143
+ >>> frame_num = 10
144
+ >>> results_dict = {"person": 5, "car": 3}
145
+ >>> updated_image = analytics.update_graph(frame_num, results_dict, plot="bar")
142
146
  """
143
147
  if count_dict is None:
144
148
  # Single line update
@@ -216,7 +220,7 @@ class Analytics(BaseSolution):
216
220
  self.ax.clear()
217
221
 
218
222
  # Create pie chart and create legend labels with percentages
219
- wedges, autotexts = self.ax.pie(
223
+ wedges, _ = self.ax.pie(
220
224
  counts, labels=labels, startangle=start_angle, textprops={"color": self.fg_color}, autopct=None
221
225
  )
222
226
  legend_labels = [f"{label} ({percentage:.1f}%)" for label, percentage in zip(labels, percentages)]