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.
- {ultralytics-8.3.87/ultralytics.egg-info → ultralytics-8.3.88}/PKG-INFO +1 -1
- {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_solutions.py +34 -45
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/__init__.py +1 -1
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/__init__.py +46 -39
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/augment.py +2 -2
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/__init__.py +14 -6
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/ai_gym.py +39 -28
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/analytics.py +22 -18
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/distance_calculation.py +25 -25
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/heatmap.py +40 -38
- ultralytics-8.3.88/ultralytics/solutions/instance_segmentation.py +69 -0
- ultralytics-8.3.88/ultralytics/solutions/object_blurrer.py +89 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/object_counter.py +35 -33
- ultralytics-8.3.88/ultralytics/solutions/object_cropper.py +84 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/parking_management.py +21 -9
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/queue_management.py +20 -39
- ultralytics-8.3.88/ultralytics/solutions/region_counter.py +119 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/security_alarm.py +40 -30
- ultralytics-8.3.88/ultralytics/solutions/solutions.py +756 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/speed_estimation.py +34 -31
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/solutions/streamlit_inference.py +34 -28
- ultralytics-8.3.88/ultralytics/solutions/trackzone.py +79 -0
- ultralytics-8.3.88/ultralytics/solutions/vision_eye.py +69 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/utils/kalman_filter.py +23 -23
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/instance.py +3 -3
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/plotting.py +0 -414
- {ultralytics-8.3.87 → ultralytics-8.3.88/ultralytics.egg-info}/PKG-INFO +1 -1
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics.egg-info/SOURCES.txt +4 -0
- ultralytics-8.3.87/ultralytics/solutions/region_counter.py +0 -116
- ultralytics-8.3.87/ultralytics/solutions/solutions.py +0 -178
- ultralytics-8.3.87/ultralytics/solutions/trackzone.py +0 -68
- {ultralytics-8.3.87 → ultralytics-8.3.88}/LICENSE +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/README.md +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/pyproject.toml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/setup.cfg +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/conftest.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_cli.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_cuda.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_engine.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_exports.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_integrations.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/tests/test_python.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/assets/bus.jpg +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/assets/zidane.jpg +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/Argoverse.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/DOTAv1.5.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/DOTAv1.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/GlobalWheat2020.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/ImageNet.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/Objects365.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/SKU-110K.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/VOC.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/VisDrone.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/african-wildlife.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/brain-tumor.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/carparts-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco-pose.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco128-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco128.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco8-pose.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco8-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/coco8.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/crack-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/dog-pose.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/dota8.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/hand-keypoints.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/lvis.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/medical-pills.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/open-images-v7.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/package-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/signature.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/tiger-pose.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/datasets/xView.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/default.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-cls.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-obb.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-pose.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/11/yolo11.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12-cls.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12-obb.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12-pose.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/12/yolo12.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10b.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10l.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10m.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10n.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10s.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v10/yolov10x.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v3/yolov3-spp.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v3/yolov3-tiny.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v3/yolov3.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v5/yolov5-p6.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v5/yolov5.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v6/yolov6.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-cls.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-ghost.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-obb.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-p2.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-p6.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-pose.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-world.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8-worldv2.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v8/yolov8.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9c-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9c.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9e-seg.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9e.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9m.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9s.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/models/v9/yolov9t.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/solutions/default.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/trackers/botsort.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/cfg/trackers/bytetrack.yaml +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/annotator.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/base.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/build.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/converter.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/dataset.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/loaders.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/split_dota.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/data/utils.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/exporter.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/model.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/predictor.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/results.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/trainer.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/tuner.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/engine/validator.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/auth.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/google/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/session.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/hub/utils.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/model.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/predict.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/utils.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/fastsam/val.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/nas/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/nas/model.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/nas/predict.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/nas/val.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/model.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/predict.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/train.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/rtdetr/val.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/amg.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/build.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/model.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/blocks.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/decoders.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/encoders.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/memory_attention.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/sam.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/tiny_encoder.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/transformer.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/modules/utils.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/sam/predict.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/utils/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/utils/loss.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/utils/ops.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/classify/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/classify/predict.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/classify/train.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/classify/val.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/detect/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/detect/predict.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/detect/train.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/detect/val.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/model.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/obb/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/obb/predict.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/obb/train.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/obb/val.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/pose/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/pose/predict.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/pose/train.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/pose/val.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/segment/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/segment/predict.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/segment/train.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/segment/val.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/world/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/world/train.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/models/yolo/world/train_world.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/autobackend.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/activation.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/block.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/conv.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/head.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/transformer.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/modules/utils.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/nn/tasks.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/basetrack.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/bot_sort.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/byte_tracker.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/track.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/utils/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/utils/gmc.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/trackers/utils/matching.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/autobatch.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/benchmarks.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/__init__.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/base.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/clearml.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/comet.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/dvc.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/hub.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/mlflow.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/neptune.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/raytune.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/tensorboard.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/callbacks/wb.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/checks.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/dist.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/downloads.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/errors.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/files.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/loss.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/metrics.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/ops.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/patches.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/tal.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/torch_utils.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/triton.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics/utils/tuner.py +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics.egg-info/dependency_links.txt +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics.egg-info/entry_points.txt +0 -0
- {ultralytics-8.3.87 → ultralytics-8.3.88}/ultralytics.egg-info/requires.txt +0 -0
- {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.
|
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
|
8
|
-
from ultralytics.utils import ASSETS_URL
|
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
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
trackzone = solutions.TrackZone(region=region_points, model="yolo11n.pt", show=False) #
|
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
|
45
|
-
_ = heatmap
|
46
|
-
_ =
|
47
|
-
_ = speed
|
48
|
-
_ = queue
|
49
|
-
_ =
|
50
|
-
_ =
|
51
|
-
_ =
|
52
|
-
_ =
|
53
|
-
_ = trackzone
|
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
|
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
|
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."""
|
@@ -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":
|
39
|
-
"
|
40
|
-
"
|
41
|
-
"
|
42
|
-
"
|
43
|
-
"
|
44
|
-
"
|
45
|
-
"
|
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 = {
|
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
|
-
|
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
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
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
|
-
|
731
|
-
|
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
|
-
"
|
25
|
+
"RegionCounter",
|
26
|
+
"SecurityAlarm",
|
19
27
|
"Heatmap",
|
20
|
-
"
|
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
|
-
|
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
|
-
>>>
|
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
|
-
"""
|
37
|
-
|
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
|
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
|
-
(
|
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
|
-
>>>
|
75
|
+
>>> results = gym.process(image)
|
76
|
+
>>> processed_image = results.plot_im
|
72
77
|
"""
|
73
|
-
#
|
74
|
-
|
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
|
-
#
|
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] =
|
92
|
-
|
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
|
-
|
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(
|
111
|
-
|
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
|
-
|
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
|
-
>>>
|
45
|
-
>>> cv2.imshow("Analytics",
|
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 = (
|
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
|
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
|
-
(
|
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
|
-
>>>
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
>>>
|
140
|
-
>>>
|
141
|
-
>>> updated_image = analytics.update_graph(
|
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,
|
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)]
|