ultralytics 8.2.91__tar.gz → 8.2.93__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.
Potentially problematic release.
This version of ultralytics might be problematic. Click here for more details.
- {ultralytics-8.2.91/ultralytics.egg-info → ultralytics-8.2.93}/PKG-INFO +1 -1
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/__init__.py +1 -1
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/base.py +5 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/engine/exporter.py +1 -1
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/engine/results.py +17 -2
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/nas/val.py +1 -1
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/modules/transformer.py +0 -1
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/obb/val.py +1 -1
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/pose/val.py +1 -1
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/segment/val.py +1 -1
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/tasks.py +51 -4
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/solutions/object_counter.py +4 -6
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/solutions/queue_management.py +14 -52
- ultralytics-8.2.93/ultralytics/solutions/speed_estimation.py +116 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93/ultralytics.egg-info}/PKG-INFO +1 -1
- ultralytics-8.2.91/ultralytics/solutions/speed_estimation.py +0 -180
- {ultralytics-8.2.91 → ultralytics-8.2.93}/LICENSE +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/README.md +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/pyproject.toml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/setup.cfg +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/conftest.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/test_cli.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/test_cuda.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/test_engine.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/test_explorer.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/test_exports.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/test_integrations.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/test_python.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/tests/test_solutions.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/assets/bus.jpg +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/assets/zidane.jpg +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/Argoverse.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/DOTAv1.5.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/DOTAv1.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/GlobalWheat2020.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/ImageNet.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/Objects365.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/SKU-110K.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/VOC.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/VisDrone.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/african-wildlife.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/brain-tumor.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/carparts-seg.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/coco-pose.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/coco.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/coco128-seg.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/coco128.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/coco8-pose.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/coco8-seg.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/coco8.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/crack-seg.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/dota8.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/lvis.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/open-images-v7.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/package-seg.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/signature.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/tiger-pose.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/datasets/xView.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/default.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v10/yolov10b.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v10/yolov10l.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v10/yolov10m.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v10/yolov10n.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v10/yolov10s.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v10/yolov10x.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v3/yolov3-spp.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v3/yolov3-tiny.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v3/yolov3.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v5/yolov5-p6.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v5/yolov5.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v6/yolov6.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-cls.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-ghost.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-obb.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-p2.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-p6.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-pose.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-seg.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-world.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8-worldv2.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v8/yolov8.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v9/yolov9c-seg.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v9/yolov9c.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v9/yolov9e-seg.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v9/yolov9e.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v9/yolov9m.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v9/yolov9s.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/models/v9/yolov9t.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/trackers/botsort.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/cfg/trackers/bytetrack.yaml +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/annotator.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/augment.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/build.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/converter.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/dataset.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/explorer/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/explorer/explorer.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/explorer/gui/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/explorer/gui/dash.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/explorer/utils.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/loaders.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/split_dota.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/data/utils.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/engine/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/engine/model.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/engine/predictor.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/engine/trainer.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/engine/tuner.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/engine/validator.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/hub/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/hub/auth.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/hub/google/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/hub/session.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/hub/utils.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/fastsam/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/fastsam/model.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/fastsam/predict.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/fastsam/utils.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/fastsam/val.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/nas/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/nas/model.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/nas/predict.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/rtdetr/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/rtdetr/model.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/rtdetr/predict.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/rtdetr/train.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/rtdetr/val.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/amg.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/build.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/model.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/modules/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/modules/blocks.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/modules/decoders.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/modules/encoders.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/modules/memory_attention.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/modules/sam.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/modules/tiny_encoder.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/modules/utils.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/sam/predict.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/utils/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/utils/loss.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/utils/ops.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/classify/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/classify/predict.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/classify/train.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/classify/val.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/detect/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/detect/predict.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/detect/train.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/detect/val.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/model.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/obb/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/obb/predict.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/obb/train.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/pose/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/pose/predict.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/pose/train.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/segment/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/segment/predict.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/segment/train.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/world/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/world/train.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/models/yolo/world/train_world.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/autobackend.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/modules/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/modules/activation.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/modules/block.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/modules/conv.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/modules/head.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/modules/transformer.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/nn/modules/utils.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/solutions/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/solutions/ai_gym.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/solutions/analytics.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/solutions/distance_calculation.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/solutions/heatmap.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/solutions/parking_management.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/solutions/streamlit_inference.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/trackers/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/trackers/basetrack.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/trackers/bot_sort.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/trackers/byte_tracker.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/trackers/track.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/trackers/utils/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/trackers/utils/gmc.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/trackers/utils/kalman_filter.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/trackers/utils/matching.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/autobatch.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/benchmarks.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/__init__.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/base.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/clearml.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/comet.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/dvc.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/hub.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/mlflow.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/neptune.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/raytune.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/tensorboard.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/callbacks/wb.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/checks.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/dist.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/downloads.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/errors.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/files.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/instance.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/loss.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/metrics.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/ops.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/patches.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/plotting.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/tal.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/torch_utils.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/triton.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics/utils/tuner.py +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics.egg-info/SOURCES.txt +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics.egg-info/dependency_links.txt +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics.egg-info/entry_points.txt +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics.egg-info/requires.txt +0 -0
- {ultralytics-8.2.91 → ultralytics-8.2.93}/ultralytics.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ultralytics
|
|
3
|
-
Version: 8.2.
|
|
3
|
+
Version: 8.2.93
|
|
4
4
|
Summary: Ultralytics YOLOv8 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
|
|
5
5
|
Author: Glenn Jocher, Ayush Chaurasia, Jing Qiu
|
|
6
6
|
Maintainer: Glenn Jocher, Ayush Chaurasia, Jing Qiu
|
|
@@ -91,6 +91,11 @@ class BaseDataset(Dataset):
|
|
|
91
91
|
self.npy_files = [Path(f).with_suffix(".npy") for f in self.im_files]
|
|
92
92
|
self.cache = cache.lower() if isinstance(cache, str) else "ram" if cache is True else None
|
|
93
93
|
if (self.cache == "ram" and self.check_cache_ram()) or self.cache == "disk":
|
|
94
|
+
if self.cache == "ram" and hyp.deterministic:
|
|
95
|
+
LOGGER.warning(
|
|
96
|
+
"WARNING ⚠️ cache='ram' may produce non-deterministic training results. "
|
|
97
|
+
"Consider cache='disk' as a deterministic alternative if your disk space allows."
|
|
98
|
+
)
|
|
94
99
|
self.cache_images()
|
|
95
100
|
|
|
96
101
|
# Transforms
|
|
@@ -391,7 +391,7 @@ class Exporter:
|
|
|
391
391
|
"""YOLOv8 ONNX export."""
|
|
392
392
|
requirements = ["onnx>=1.12.0"]
|
|
393
393
|
if self.args.simplify:
|
|
394
|
-
requirements += ["onnxslim==0.1.
|
|
394
|
+
requirements += ["onnxslim==0.1.34", "onnxruntime" + ("-gpu" if torch.cuda.is_available() else "")]
|
|
395
395
|
check_requirements(requirements)
|
|
396
396
|
import onnx # noqa
|
|
397
397
|
|
|
@@ -522,7 +522,13 @@ class Results(SimpleClass):
|
|
|
522
522
|
.contiguous()
|
|
523
523
|
/ 255
|
|
524
524
|
)
|
|
525
|
-
idx =
|
|
525
|
+
idx = (
|
|
526
|
+
pred_boxes.id
|
|
527
|
+
if pred_boxes.id is not None and color_mode == "instance"
|
|
528
|
+
else pred_boxes.cls
|
|
529
|
+
if pred_boxes and color_mode == "class"
|
|
530
|
+
else reversed(range(len(pred_masks)))
|
|
531
|
+
)
|
|
526
532
|
annotator.masks(pred_masks.data, colors=[colors(x, True) for x in idx], im_gpu=im_gpu)
|
|
527
533
|
|
|
528
534
|
# Plot Detect results
|
|
@@ -535,7 +541,16 @@ class Results(SimpleClass):
|
|
|
535
541
|
annotator.box_label(
|
|
536
542
|
box,
|
|
537
543
|
label,
|
|
538
|
-
color=colors(
|
|
544
|
+
color=colors(
|
|
545
|
+
c
|
|
546
|
+
if color_mode == "class"
|
|
547
|
+
else id
|
|
548
|
+
if id is not None
|
|
549
|
+
else i
|
|
550
|
+
if color_mode == "instance"
|
|
551
|
+
else None,
|
|
552
|
+
True,
|
|
553
|
+
),
|
|
539
554
|
rotated=is_obb,
|
|
540
555
|
)
|
|
541
556
|
|
|
@@ -61,7 +61,6 @@ class TwoWayTransformer(nn.Module):
|
|
|
61
61
|
Attributes:
|
|
62
62
|
depth (int): Number of layers in the transformer.
|
|
63
63
|
embedding_dim (int): Channel dimension for input embeddings.
|
|
64
|
-
embedding_dim (int): Channel dimension for input embeddings.
|
|
65
64
|
num_heads (int): Number of heads for multihead attention.
|
|
66
65
|
mlp_dim (int): Internal channel dimension for the MLP block.
|
|
67
66
|
layers (nn.ModuleList): List of TwoWayAttentionBlock layers.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
|
2
2
|
|
|
3
3
|
import contextlib
|
|
4
|
+
import pickle
|
|
5
|
+
import types
|
|
4
6
|
from copy import deepcopy
|
|
5
7
|
from pathlib import Path
|
|
6
8
|
|
|
@@ -750,7 +752,35 @@ def temporary_modules(modules=None, attributes=None):
|
|
|
750
752
|
del sys.modules[old]
|
|
751
753
|
|
|
752
754
|
|
|
753
|
-
|
|
755
|
+
class SafeClass:
|
|
756
|
+
"""A placeholder class to replace unknown classes during unpickling."""
|
|
757
|
+
|
|
758
|
+
def __init__(self, *args, **kwargs):
|
|
759
|
+
"""Initialize SafeClass instance, ignoring all arguments."""
|
|
760
|
+
pass
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
class SafeUnpickler(pickle.Unpickler):
|
|
764
|
+
"""Custom Unpickler that replaces unknown classes with SafeClass."""
|
|
765
|
+
|
|
766
|
+
def find_class(self, module, name):
|
|
767
|
+
"""Attempt to find a class, returning SafeClass if not among safe modules."""
|
|
768
|
+
safe_modules = (
|
|
769
|
+
"torch",
|
|
770
|
+
"collections",
|
|
771
|
+
"collections.abc",
|
|
772
|
+
"builtins",
|
|
773
|
+
"math",
|
|
774
|
+
"numpy",
|
|
775
|
+
# Add other modules considered safe
|
|
776
|
+
)
|
|
777
|
+
if module in safe_modules:
|
|
778
|
+
return super().find_class(module, name)
|
|
779
|
+
else:
|
|
780
|
+
return SafeClass
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
def torch_safe_load(weight, safe_only=False):
|
|
754
784
|
"""
|
|
755
785
|
Attempts to load a PyTorch model with the torch.load() function. If a ModuleNotFoundError is raised, it catches the
|
|
756
786
|
error, logs a warning message, and attempts to install the missing module via the check_requirements() function.
|
|
@@ -758,9 +788,18 @@ def torch_safe_load(weight):
|
|
|
758
788
|
|
|
759
789
|
Args:
|
|
760
790
|
weight (str): The file path of the PyTorch model.
|
|
791
|
+
safe_only (bool): If True, replace unknown classes with SafeClass during loading.
|
|
792
|
+
|
|
793
|
+
Example:
|
|
794
|
+
```python
|
|
795
|
+
from ultralytics.nn.tasks import torch_safe_load
|
|
796
|
+
|
|
797
|
+
ckpt, file = torch_safe_load("path/to/best.pt", safe_only=True)
|
|
798
|
+
```
|
|
761
799
|
|
|
762
800
|
Returns:
|
|
763
|
-
(dict): The loaded
|
|
801
|
+
ckpt (dict): The loaded model checkpoint.
|
|
802
|
+
file (str): The loaded filename
|
|
764
803
|
"""
|
|
765
804
|
from ultralytics.utils.downloads import attempt_download_asset
|
|
766
805
|
|
|
@@ -779,7 +818,15 @@ def torch_safe_load(weight):
|
|
|
779
818
|
"ultralytics.utils.loss.v10DetectLoss": "ultralytics.utils.loss.E2EDetectLoss", # YOLOv10
|
|
780
819
|
},
|
|
781
820
|
):
|
|
782
|
-
|
|
821
|
+
if safe_only:
|
|
822
|
+
# Load via custom pickle module
|
|
823
|
+
safe_pickle = types.ModuleType("safe_pickle")
|
|
824
|
+
safe_pickle.Unpickler = SafeUnpickler
|
|
825
|
+
safe_pickle.load = lambda file_obj: SafeUnpickler(file_obj).load()
|
|
826
|
+
with open(file, "rb") as f:
|
|
827
|
+
ckpt = torch.load(f, pickle_module=safe_pickle)
|
|
828
|
+
else:
|
|
829
|
+
ckpt = torch.load(file, map_location="cpu")
|
|
783
830
|
|
|
784
831
|
except ModuleNotFoundError as e: # e.name is missing module name
|
|
785
832
|
if e.name == "models":
|
|
@@ -809,7 +856,7 @@ def torch_safe_load(weight):
|
|
|
809
856
|
)
|
|
810
857
|
ckpt = {"model": ckpt.model}
|
|
811
858
|
|
|
812
|
-
return ckpt, file
|
|
859
|
+
return ckpt, file
|
|
813
860
|
|
|
814
861
|
|
|
815
862
|
def attempt_load_weights(weights, device=None, inplace=True, fuse=False):
|
|
@@ -60,7 +60,6 @@ class ObjectCounter:
|
|
|
60
60
|
self.out_counts = 0
|
|
61
61
|
self.count_ids = []
|
|
62
62
|
self.class_wise_count = {}
|
|
63
|
-
self.count_txt_thickness = 0
|
|
64
63
|
|
|
65
64
|
# Tracks info
|
|
66
65
|
self.track_history = defaultdict(list)
|
|
@@ -136,7 +135,7 @@ class ObjectCounter:
|
|
|
136
135
|
# Extract tracks
|
|
137
136
|
for box, track_id, cls in zip(boxes, track_ids, clss):
|
|
138
137
|
# Draw bounding box
|
|
139
|
-
annotator.box_label(box, label=
|
|
138
|
+
annotator.box_label(box, label=self.names[cls], color=colors(int(track_id), True))
|
|
140
139
|
|
|
141
140
|
# Store class info
|
|
142
141
|
if self.names[cls] not in self.class_wise_count:
|
|
@@ -182,10 +181,9 @@ class ObjectCounter:
|
|
|
182
181
|
self.count_ids.append(track_id)
|
|
183
182
|
|
|
184
183
|
# Determine the direction of movement (IN or OUT)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if direction > 0:
|
|
184
|
+
dx = (box[0] - prev_position[0]) * (self.counting_region.centroid.x - prev_position[0])
|
|
185
|
+
dy = (box[1] - prev_position[1]) * (self.counting_region.centroid.y - prev_position[1])
|
|
186
|
+
if dx > 0 and dy > 0:
|
|
189
187
|
self.in_counts += 1
|
|
190
188
|
self.class_wise_count[self.names[cls]]["IN"] += 1
|
|
191
189
|
else:
|
|
@@ -20,15 +20,8 @@ class QueueManager:
|
|
|
20
20
|
names,
|
|
21
21
|
reg_pts=None,
|
|
22
22
|
line_thickness=2,
|
|
23
|
-
track_thickness=2,
|
|
24
23
|
view_img=False,
|
|
25
|
-
region_color=(255, 0, 255),
|
|
26
|
-
view_queue_counts=True,
|
|
27
24
|
draw_tracks=False,
|
|
28
|
-
count_txt_color=(255, 255, 255),
|
|
29
|
-
track_color=None,
|
|
30
|
-
region_thickness=5,
|
|
31
|
-
fontsize=0.7,
|
|
32
25
|
):
|
|
33
26
|
"""
|
|
34
27
|
Initializes the QueueManager with specified parameters for tracking and counting objects.
|
|
@@ -38,57 +31,35 @@ class QueueManager:
|
|
|
38
31
|
reg_pts (list of tuples, optional): Points defining the counting region polygon. Defaults to a predefined
|
|
39
32
|
rectangle.
|
|
40
33
|
line_thickness (int, optional): Thickness of the annotation lines. Defaults to 2.
|
|
41
|
-
track_thickness (int, optional): Thickness of the track lines. Defaults to 2.
|
|
42
34
|
view_img (bool, optional): Whether to display the image frames. Defaults to False.
|
|
43
|
-
region_color (tuple, optional): Color of the counting region lines (BGR). Defaults to (255, 0, 255).
|
|
44
|
-
view_queue_counts (bool, optional): Whether to display the queue counts. Defaults to True.
|
|
45
35
|
draw_tracks (bool, optional): Whether to draw tracks of the objects. Defaults to False.
|
|
46
|
-
count_txt_color (tuple, optional): Color of the count text (BGR). Defaults to (255, 255, 255).
|
|
47
|
-
track_color (tuple, optional): Color of the tracks. If None, different colors will be used for different
|
|
48
|
-
tracks. Defaults to None.
|
|
49
|
-
region_thickness (int, optional): Thickness of the counting region lines. Defaults to 5.
|
|
50
|
-
fontsize (float, optional): Font size for the text annotations. Defaults to 0.7.
|
|
51
36
|
"""
|
|
52
|
-
# Mouse events state
|
|
53
|
-
self.is_drawing = False
|
|
54
|
-
self.selected_point = None
|
|
55
|
-
|
|
56
37
|
# Region & Line Information
|
|
57
38
|
self.reg_pts = reg_pts if reg_pts is not None else [(20, 60), (20, 680), (1120, 680), (1120, 60)]
|
|
58
39
|
self.counting_region = (
|
|
59
40
|
Polygon(self.reg_pts) if len(self.reg_pts) >= 3 else Polygon([(20, 60), (20, 680), (1120, 680), (1120, 60)])
|
|
60
41
|
)
|
|
61
|
-
self.region_color = region_color
|
|
62
|
-
self.region_thickness = region_thickness
|
|
63
42
|
|
|
64
|
-
#
|
|
65
|
-
self.im0 = None
|
|
43
|
+
# annotation Information
|
|
66
44
|
self.tf = line_thickness
|
|
67
45
|
self.view_img = view_img
|
|
68
|
-
self.view_queue_counts = view_queue_counts
|
|
69
|
-
self.fontsize = fontsize
|
|
70
46
|
|
|
71
47
|
self.names = names # Class names
|
|
72
|
-
self.annotator = None # Annotator
|
|
73
|
-
self.window_name = "Ultralytics YOLOv8 Queue Manager"
|
|
74
48
|
|
|
75
49
|
# Object counting Information
|
|
76
50
|
self.counts = 0
|
|
77
|
-
self.count_txt_color = count_txt_color
|
|
78
51
|
|
|
79
52
|
# Tracks info
|
|
80
53
|
self.track_history = defaultdict(list)
|
|
81
|
-
self.track_thickness = track_thickness
|
|
82
54
|
self.draw_tracks = draw_tracks
|
|
83
|
-
self.track_color = track_color
|
|
84
55
|
|
|
85
56
|
# Check if environment supports imshow
|
|
86
57
|
self.env_check = check_imshow(warn=True)
|
|
87
58
|
|
|
88
|
-
def extract_and_process_tracks(self, tracks):
|
|
59
|
+
def extract_and_process_tracks(self, tracks, im0):
|
|
89
60
|
"""Extracts and processes tracks for queue management in a video stream."""
|
|
90
61
|
# Initialize annotator and draw the queue region
|
|
91
|
-
|
|
62
|
+
annotator = Annotator(im0, self.tf, self.names)
|
|
92
63
|
self.counts = 0 # Reset counts every frame
|
|
93
64
|
if tracks[0].boxes.id is not None:
|
|
94
65
|
boxes = tracks[0].boxes.xyxy.cpu()
|
|
@@ -98,7 +69,7 @@ class QueueManager:
|
|
|
98
69
|
# Extract tracks
|
|
99
70
|
for box, track_id, cls in zip(boxes, track_ids, clss):
|
|
100
71
|
# Draw bounding box
|
|
101
|
-
|
|
72
|
+
annotator.box_label(box, label=self.names[cls], color=colors(int(track_id), True))
|
|
102
73
|
|
|
103
74
|
# Update track history
|
|
104
75
|
track_line = self.track_history[track_id]
|
|
@@ -108,10 +79,10 @@ class QueueManager:
|
|
|
108
79
|
|
|
109
80
|
# Draw track trails if enabled
|
|
110
81
|
if self.draw_tracks:
|
|
111
|
-
|
|
82
|
+
annotator.draw_centroid_and_tracks(
|
|
112
83
|
track_line,
|
|
113
|
-
color=
|
|
114
|
-
track_thickness=self.
|
|
84
|
+
color=colors(int(track_id), True),
|
|
85
|
+
track_thickness=self.line_thickness,
|
|
115
86
|
)
|
|
116
87
|
|
|
117
88
|
prev_position = self.track_history[track_id][-2] if len(self.track_history[track_id]) > 1 else None
|
|
@@ -125,21 +96,16 @@ class QueueManager:
|
|
|
125
96
|
# Display queue counts
|
|
126
97
|
label = f"Queue Counts : {str(self.counts)}"
|
|
127
98
|
if label is not None:
|
|
128
|
-
|
|
99
|
+
annotator.queue_counts_display(
|
|
129
100
|
label,
|
|
130
101
|
points=self.reg_pts,
|
|
131
|
-
region_color=
|
|
132
|
-
txt_color=
|
|
102
|
+
region_color=(255, 0, 255),
|
|
103
|
+
txt_color=(104, 31, 17),
|
|
133
104
|
)
|
|
134
105
|
|
|
135
|
-
self.display_frames()
|
|
136
|
-
|
|
137
|
-
def display_frames(self):
|
|
138
|
-
"""Displays the current frame with annotations."""
|
|
139
106
|
if self.env_check and self.view_img:
|
|
140
|
-
|
|
141
|
-
cv2.
|
|
142
|
-
cv2.imshow(self.window_name, self.im0)
|
|
107
|
+
annotator.draw_region(reg_pts=self.reg_pts, thickness=self.tf * 2, color=(255, 0, 255))
|
|
108
|
+
cv2.imshow("Ultralytics YOLOv8 Queue Manager", im0)
|
|
143
109
|
# Close window on 'q' key press
|
|
144
110
|
if cv2.waitKey(1) & 0xFF == ord("q"):
|
|
145
111
|
return
|
|
@@ -152,12 +118,8 @@ class QueueManager:
|
|
|
152
118
|
im0 (ndarray): Current frame from the video stream.
|
|
153
119
|
tracks (list): List of tracks obtained from the object tracking process.
|
|
154
120
|
"""
|
|
155
|
-
self.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if self.view_img:
|
|
159
|
-
self.display_frames() # Display the frame if enabled
|
|
160
|
-
return self.im0
|
|
121
|
+
self.extract_and_process_tracks(tracks, im0) # Extract and process tracks
|
|
122
|
+
return im0
|
|
161
123
|
|
|
162
124
|
|
|
163
125
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
|
2
|
+
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from time import time
|
|
5
|
+
|
|
6
|
+
import cv2
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from ultralytics.utils.checks import check_imshow
|
|
10
|
+
from ultralytics.utils.plotting import Annotator, colors
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SpeedEstimator:
|
|
14
|
+
"""A class to estimate the speed of objects in a real-time video stream based on their tracks."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, names, reg_pts=None, view_img=False, line_thickness=2, spdl_dist_thresh=10):
|
|
17
|
+
"""
|
|
18
|
+
Initializes the SpeedEstimator with the given parameters.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
names (dict): Dictionary of class names.
|
|
22
|
+
reg_pts (list, optional): List of region points for speed estimation. Defaults to [(20, 400), (1260, 400)].
|
|
23
|
+
view_img (bool, optional): Whether to display the image with annotations. Defaults to False.
|
|
24
|
+
line_thickness (int, optional): Thickness of the lines for drawing boxes and tracks. Defaults to 2.
|
|
25
|
+
spdl_dist_thresh (int, optional): Distance threshold for speed calculation. Defaults to 10.
|
|
26
|
+
"""
|
|
27
|
+
# Region information
|
|
28
|
+
self.reg_pts = reg_pts if reg_pts is not None else [(20, 400), (1260, 400)]
|
|
29
|
+
|
|
30
|
+
self.names = names # Classes names
|
|
31
|
+
|
|
32
|
+
# Tracking information
|
|
33
|
+
self.trk_history = defaultdict(list)
|
|
34
|
+
|
|
35
|
+
self.view_img = view_img # bool for displaying inference
|
|
36
|
+
self.tf = line_thickness # line thickness for annotator
|
|
37
|
+
self.spd = {} # set for speed data
|
|
38
|
+
self.trkd_ids = [] # list for already speed_estimated and tracked ID's
|
|
39
|
+
self.spdl = spdl_dist_thresh # Speed line distance threshold
|
|
40
|
+
self.trk_pt = {} # set for tracks previous time
|
|
41
|
+
self.trk_pp = {} # set for tracks previous point
|
|
42
|
+
|
|
43
|
+
# Check if the environment supports imshow
|
|
44
|
+
self.env_check = check_imshow(warn=True)
|
|
45
|
+
|
|
46
|
+
def estimate_speed(self, im0, tracks):
|
|
47
|
+
"""
|
|
48
|
+
Estimates the speed of objects based on tracking data.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
im0 (ndarray): Image.
|
|
52
|
+
tracks (list): List of tracks obtained from the object tracking process.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
(ndarray): The image with annotated boxes and tracks.
|
|
56
|
+
"""
|
|
57
|
+
if tracks[0].boxes.id is None:
|
|
58
|
+
return im0
|
|
59
|
+
|
|
60
|
+
boxes = tracks[0].boxes.xyxy.cpu()
|
|
61
|
+
clss = tracks[0].boxes.cls.cpu().tolist()
|
|
62
|
+
t_ids = tracks[0].boxes.id.int().cpu().tolist()
|
|
63
|
+
annotator = Annotator(im0, line_width=self.tf)
|
|
64
|
+
annotator.draw_region(reg_pts=self.reg_pts, color=(255, 0, 255), thickness=self.tf * 2)
|
|
65
|
+
|
|
66
|
+
for box, t_id, cls in zip(boxes, t_ids, clss):
|
|
67
|
+
track = self.trk_history[t_id]
|
|
68
|
+
bbox_center = (float((box[0] + box[2]) / 2), float((box[1] + box[3]) / 2))
|
|
69
|
+
track.append(bbox_center)
|
|
70
|
+
|
|
71
|
+
if len(track) > 30:
|
|
72
|
+
track.pop(0)
|
|
73
|
+
|
|
74
|
+
trk_pts = np.hstack(track).astype(np.int32).reshape((-1, 1, 2))
|
|
75
|
+
|
|
76
|
+
if t_id not in self.trk_pt:
|
|
77
|
+
self.trk_pt[t_id] = 0
|
|
78
|
+
|
|
79
|
+
speed_label = f"{int(self.spd[t_id])} km/h" if t_id in self.spd else self.names[int(cls)]
|
|
80
|
+
bbox_color = colors(int(t_id), True)
|
|
81
|
+
|
|
82
|
+
annotator.box_label(box, speed_label, bbox_color)
|
|
83
|
+
cv2.polylines(im0, [trk_pts], isClosed=False, color=bbox_color, thickness=self.tf)
|
|
84
|
+
cv2.circle(im0, (int(track[-1][0]), int(track[-1][1])), self.tf * 2, bbox_color, -1)
|
|
85
|
+
|
|
86
|
+
# Calculation of object speed
|
|
87
|
+
if not self.reg_pts[0][0] < track[-1][0] < self.reg_pts[1][0]:
|
|
88
|
+
return
|
|
89
|
+
if self.reg_pts[1][1] - self.spdl < track[-1][1] < self.reg_pts[1][1] + self.spdl:
|
|
90
|
+
direction = "known"
|
|
91
|
+
elif self.reg_pts[0][1] - self.spdl < track[-1][1] < self.reg_pts[0][1] + self.spdl:
|
|
92
|
+
direction = "known"
|
|
93
|
+
else:
|
|
94
|
+
direction = "unknown"
|
|
95
|
+
|
|
96
|
+
if self.trk_pt.get(t_id) != 0 and direction != "unknown" and t_id not in self.trkd_ids:
|
|
97
|
+
self.trkd_ids.append(t_id)
|
|
98
|
+
|
|
99
|
+
time_difference = time() - self.trk_pt[t_id]
|
|
100
|
+
if time_difference > 0:
|
|
101
|
+
self.spd[t_id] = np.abs(track[-1][1] - self.trk_pp[t_id][1]) / time_difference
|
|
102
|
+
|
|
103
|
+
self.trk_pt[t_id] = time()
|
|
104
|
+
self.trk_pp[t_id] = track[-1]
|
|
105
|
+
|
|
106
|
+
if self.view_img and self.env_check:
|
|
107
|
+
cv2.imshow("Ultralytics Speed Estimation", im0)
|
|
108
|
+
if cv2.waitKey(1) & 0xFF == ord("q"):
|
|
109
|
+
return
|
|
110
|
+
|
|
111
|
+
return im0
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
names = {0: "person", 1: "car"} # example class names
|
|
116
|
+
speed_estimator = SpeedEstimator(names)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ultralytics
|
|
3
|
-
Version: 8.2.
|
|
3
|
+
Version: 8.2.93
|
|
4
4
|
Summary: Ultralytics YOLOv8 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
|
|
5
5
|
Author: Glenn Jocher, Ayush Chaurasia, Jing Qiu
|
|
6
6
|
Maintainer: Glenn Jocher, Ayush Chaurasia, Jing Qiu
|