From 857681c7799db7263bc44990f9006d254c67c71c Mon Sep 17 00:00:00 2001 From: "hongliang.yuan" Date: Thu, 3 Apr 2025 14:36:51 +0800 Subject: [PATCH] del useless code in AlphaPose --- cv/pose/alphapose/pytorch/README.md | 30 +- .../hardnet/256x192_hard68_lr1e-3_1x.yaml | 65 - .../hardnet/256x192_hard85_lr1e-3_1x.yaml | 65 - .../coco/hrnet/256x192_w32_lr1e-3.yaml | 84 - .../resnet/.256x192_res50_lr1e-3_1x.yaml.swp | Bin 12288 -> 0 bytes .../resnet/256x192_res152_lr1e-3_1x-duc.yaml | 73 - .../256x192_res50_lr1e-3_1x-concat.yaml | 79 - .../resnet/256x192_res50_lr1e-3_1x-duc.yaml | 73 - .../256x192_res50_lr1e-3_1x-simple.yaml | 65 - .../resnet/256x192_res50_lr1e-3_2x-dcn.yaml | 74 - .../256x192_res50_lr1e-3_2x-regression.yaml | 68 - .../coco/resnet/256x192_res50_lr1e-3_2x.yaml | 65 - .../256x192_adam_lr1e-3-duc-dcn_1x_crop.yaml | 82 - .../hardnet/256x192_hard68_lr1e-3_1x.yaml | 65 - .../resnet/256x192_res50_lr1e-3_1x.yaml | 65 - .../256x192_res50_lr1e-3_2x-regression.yaml | 69 - .../resnet/256x192_res50_lr1e-3_1x.yaml | 65 - .../alphapose/pytorch/detector/effdet_api.py | 289 - .../alphapose/pytorch/detector/effdet_cfg.py | 8 - .../pytorch/detector/efficientdet/README.md | 3 - .../detector/efficientdet/effdet/__init__.py | 4 - .../detector/efficientdet/effdet/anchors.py | 358 - .../detector/efficientdet/effdet/bench.py | 103 - .../efficientdet/effdet/config/config.py | 273 - .../efficientdet/effdet/efficientdet.py | 416 - .../detector/efficientdet/effdet/helpers.py | 38 - .../effdet/object_detection/README.md | 3 - .../effdet/object_detection/__init__.py | 16 - .../effdet/object_detection/argmax_matcher.py | 169 - .../effdet/object_detection/box_coder.py | 143 - .../effdet/object_detection/box_list.py | 190 - .../object_detection/faster_rcnn_box_coder.py | 116 - .../effdet/object_detection/matcher.py | 230 - .../region_similarity_calculator.py | 121 - .../object_detection/target_assigner.py | 263 - .../pytorch/detector/efficientdet/utils.py | 129 - .../efficientdet/weights/get_models.sh | 0 .../pytorch/detector/nms/__init__.py | 7 - .../pytorch/detector/nms/nms_wrapper.py | 80 - .../pytorch/detector/nms/src/nms_cpu.cpp | 73 - .../pytorch/detector/nms/src/nms_cuda.cpp | 19 - .../pytorch/detector/nms/src/nms_kernel.cu | 133 - .../pytorch/detector/nms/src/soft_nms_cpu.cpp | 10325 ---------------- .../pytorch/detector/nms/src/soft_nms_cpu.pyx | 127 - .../pytorch/detector/tracker/README.md | 7 - .../pytorch/detector/tracker/__init__.py | 0 .../pytorch/detector/tracker/cfg/ccmcpe.json | 24 - .../pytorch/detector/tracker/cfg/yolov3.cfg | 833 -- .../pytorch/detector/tracker/models.py | 373 - .../pytorch/detector/tracker/preprocess.py | 63 - .../detector/tracker/tracker/__init__.py | 0 .../detector/tracker/tracker/basetrack.py | 53 - .../detector/tracker/tracker/matching.py | 123 - .../detector/tracker/tracker/multitracker.py | 337 - .../detector/tracker/utils/__init__.py | 0 .../detector/tracker/utils/datasets.py | 411 - .../detector/tracker/utils/evaluation.py | 101 - .../pytorch/detector/tracker/utils/io.py | 112 - .../detector/tracker/utils/kalman_filter.py | 229 - .../pytorch/detector/tracker/utils/log.py | 18 - .../pytorch/detector/tracker/utils/nms.py | 7 - .../detector/tracker/utils/parse_config.py | 35 - .../pytorch/detector/tracker/utils/timer.py | 45 - .../pytorch/detector/tracker/utils/utils.py | 510 - .../detector/tracker/utils/visualization.py | 90 - .../alphapose/pytorch/detector/tracker_api.py | 238 - .../alphapose/pytorch/detector/tracker_cfg.py | 9 - .../alphapose/pytorch/detector/yolo/README.md | 3 - .../pytorch/detector/yolo/__init__.py | 0 .../alphapose/pytorch/detector/yolo/bbox.py | 114 - .../pytorch/detector/yolo/cam_demo.py | 168 - .../detector/yolo/cfg/tiny-yolo-voc.cfg | 134 - .../pytorch/detector/yolo/cfg/yolo-voc.cfg | 258 - .../pytorch/detector/yolo/cfg/yolo.cfg | 258 - .../pytorch/detector/yolo/cfg/yolov3-spp.cfg | 822 -- .../pytorch/detector/yolo/cfg/yolov3.cfg | 789 -- .../pytorch/detector/yolo/darknet.py | 548 - .../alphapose/pytorch/detector/yolo/detect.py | 103 - .../alphapose/pytorch/detector/yolo/pallete | Bin 908 -> 0 bytes .../pytorch/detector/yolo/preprocess.py | 94 - .../alphapose/pytorch/detector/yolo/util.py | 403 - .../pytorch/detector/yolo/video_demo.py | 186 - .../pytorch/detector/yolo/video_demo_half.py | 189 - .../alphapose/pytorch/detector/yolo_api.py | 307 - .../alphapose/pytorch/detector/yolo_cfg.py | 9 - .../detector/yolov5/models/__init__.py | 0 .../pytorch/detector/yolov5/models/common.py | 641 - .../detector/yolov5/models/cuda_impl/Makefile | 11 - .../yolov5/models/cuda_impl/__init__.py | 1 - .../cuda_impl/csrc/cuda/yolov5_decode.cu | 59 - .../csrc/cuda/yolov5_decode_kernel.cuh | 73 - .../cuda_impl/csrc/include/cuda_helper.h | 45 - .../csrc/include/pytorch_cuda_helper.h | 17 - .../models/cuda_impl/csrc/yolov5_decode.cpp | 28 - .../detector/yolov5/models/cuda_impl/setup.py | 40 - .../yolov5/models/cuda_impl/yolov5_decode.py | 26 - .../detector/yolov5/models/experimental.py | 121 - .../detector/yolov5/models/hub/anchors.yaml | 59 - .../yolov5/models/hub/yolov3-spp.yaml | 51 - .../yolov5/models/hub/yolov3-tiny.yaml | 41 - .../detector/yolov5/models/hub/yolov3.yaml | 51 - .../yolov5/models/hub/yolov5-bifpn.yaml | 48 - .../yolov5/models/hub/yolov5-fpn.yaml | 42 - .../detector/yolov5/models/hub/yolov5-p2.yaml | 54 - .../detector/yolov5/models/hub/yolov5-p6.yaml | 56 - .../detector/yolov5/models/hub/yolov5-p7.yaml | 67 - .../yolov5/models/hub/yolov5-panet.yaml | 48 - .../detector/yolov5/models/hub/yolov5l6.yaml | 60 - .../detector/yolov5/models/hub/yolov5m6.yaml | 60 - .../detector/yolov5/models/hub/yolov5n6.yaml | 60 - .../yolov5/models/hub/yolov5s-ghost.yaml | 48 - .../models/hub/yolov5s-transformer.yaml | 48 - .../detector/yolov5/models/hub/yolov5s6.yaml | 60 - .../detector/yolov5/models/hub/yolov5x6.yaml | 60 - .../pytorch/detector/yolov5/models/tf.py | 464 - .../detector/yolov5/models/utils/__init__.py | 37 - .../yolov5/models/utils/activations.py | 101 - .../yolov5/models/utils/augmentations.py | 277 - .../yolov5/models/utils/autoanchor.py | 164 - .../detector/yolov5/models/utils/autobatch.py | 57 - .../yolov5/models/utils/aws/__init__.py | 0 .../detector/yolov5/models/utils/aws/mime.sh | 26 - .../yolov5/models/utils/aws/resume.py | 40 - .../yolov5/models/utils/aws/userdata.sh | 27 - .../detector/yolov5/models/utils/callbacks.py | 77 - .../detector/yolov5/models/utils/datasets.py | 1036 -- .../detector/yolov5/models/utils/downloads.py | 150 - .../models/utils/flask_rest_api/README.md | 73 - .../utils/flask_rest_api/example_request.py | 13 - .../models/utils/flask_rest_api/restapi.py | 37 - .../detector/yolov5/models/utils/general.py | 843 -- .../models/utils/google_app_engine/Dockerfile | 25 - .../additional_requirements.txt | 4 - .../models/utils/google_app_engine/app.yaml | 14 - .../yolov5/models/utils/loggers/__init__.py | 159 - .../models/utils/loggers/wandb/README.md | 152 - .../models/utils/loggers/wandb/__init__.py | 0 .../models/utils/loggers/wandb/log_dataset.py | 27 - .../models/utils/loggers/wandb/sweep.py | 41 - .../models/utils/loggers/wandb/sweep.yaml | 143 - .../models/utils/loggers/wandb/wandb_utils.py | 560 - .../detector/yolov5/models/utils/loss.py | 222 - .../detector/yolov5/models/utils/metrics.py | 344 - .../detector/yolov5/models/utils/plots.py | 470 - .../yolov5/models/utils/torch_utils.py | 318 - .../pytorch/detector/yolov5/models/yolo.py | 334 - .../detector/yolov5/models/yolov5l.yaml | 48 - .../detector/yolov5/models/yolov5m.yaml | 48 - .../detector/yolov5/models/yolov5n.yaml | 48 - .../detector/yolov5/models/yolov5s.yaml | 48 - .../detector/yolov5/models/yolov5x.yaml | 48 - .../pytorch/detector/yolov5/utils/__init__.py | 37 - .../detector/yolov5/utils/activations.py | 101 - .../detector/yolov5/utils/augmentations.py | 277 - .../detector/yolov5/utils/autoanchor.py | 164 - .../detector/yolov5/utils/autobatch.py | 57 - .../detector/yolov5/utils/aws/__init__.py | 0 .../pytorch/detector/yolov5/utils/aws/mime.sh | 26 - .../detector/yolov5/utils/aws/resume.py | 40 - .../detector/yolov5/utils/aws/userdata.sh | 27 - .../detector/yolov5/utils/callbacks.py | 77 - .../pytorch/detector/yolov5/utils/datasets.py | 1036 -- .../detector/yolov5/utils/downloads.py | 150 - .../yolov5/utils/flask_rest_api/README.md | 73 - .../utils/flask_rest_api/example_request.py | 13 - .../yolov5/utils/flask_rest_api/restapi.py | 37 - .../pytorch/detector/yolov5/utils/general.py | 844 -- .../yolov5/utils/google_app_engine/Dockerfile | 25 - .../additional_requirements.txt | 4 - .../yolov5/utils/google_app_engine/app.yaml | 14 - .../detector/yolov5/utils/loggers/__init__.py | 159 - .../yolov5/utils/loggers/wandb/README.md | 152 - .../yolov5/utils/loggers/wandb/__init__.py | 0 .../yolov5/utils/loggers/wandb/log_dataset.py | 27 - .../yolov5/utils/loggers/wandb/sweep.py | 41 - .../yolov5/utils/loggers/wandb/sweep.yaml | 143 - .../yolov5/utils/loggers/wandb/wandb_utils.py | 560 - .../pytorch/detector/yolov5/utils/loss.py | 222 - .../pytorch/detector/yolov5/utils/metrics.py | 344 - .../pytorch/detector/yolov5/utils/plots.py | 470 - .../detector/yolov5/utils/torch_utils.py | 318 - .../alphapose/pytorch/detector/yolov5_api.py | 326 - .../pytorch/scripts/main_pipeline_time.py | 327 - .../scripts/multi_persons_multi_ways_batch.py | 427 - .../pytorch/scripts/multi_ways_batch.py | 432 - .../pytorch/scripts/multi_ways_forward.py | 463 - .../pytorch/scripts/multi_ways_loop.py | 346 - .../pytorch/scripts/multi_ways_process.py | 394 - .../pytorch/scripts/process_utils.py | 130 - .../alphapose/pytorch/scripts/test_demo.py | 277 - .../pytorch/scripts/{trainval => }/train.py | 0 .../pytorch/scripts/{trainval => }/train.sh | 2 +- .../pytorch/scripts/trainval/demo_api.py | 365 - .../scripts/trainval/demo_inference.py | 300 - .../pytorch/scripts/trainval/validate.py | 174 - .../pytorch/scripts/trainval/validate.sh | 29 - .../videos_process/composition_frames.py | 52 - .../scripts/videos_process/extract_frames.py | 70 - cv/pose/alphapose/pytorch/setup.cfg | 2 - cv/pose/alphapose/pytorch/setup.py | 224 - .../pytorch/trackers/PoseFlow/README.md | 119 - .../PoseFlow/alpha-pose-results-sample.json | 169 - .../pytorch/trackers/PoseFlow/matching.py | 128 - .../trackers/PoseFlow/parallel_process.py | 49 - .../trackers/PoseFlow/poseflow_infer.py | 191 - .../pytorch/trackers/PoseFlow/posetrack_data | 1 - .../pytorch/trackers/PoseFlow/poseval | 1 - .../trackers/PoseFlow/requirements.txt | 9 - .../trackers/PoseFlow/tracker-baseline.py | 278 - .../trackers/PoseFlow/tracker-general.py | 242 - .../pytorch/trackers/PoseFlow/utils.py | 291 - cv/pose/alphapose/pytorch/trackers/README.md | 43 - .../pytorch/trackers/ReidModels/ResBnLin.py | 55 - .../pytorch/trackers/ReidModels/ResNet.py | 189 - .../pytorch/trackers/ReidModels/__init__.py | 0 .../trackers/ReidModels/backbone/__init__.py | 0 .../trackers/ReidModels/backbone/googlenet.py | 96 - .../trackers/ReidModels/backbone/lrn.py | 37 - .../trackers/ReidModels/backbone/sqeezenet.py | 64 - .../pytorch/trackers/ReidModels/bn_linear.py | 63 - .../ReidModels/classification/__init__.py | 0 .../ReidModels/classification/classifier.py | 111 - .../ReidModels/classification/rfcn_cls.py | 118 - .../pytorch/trackers/ReidModels/net_utils.py | 160 - .../pytorch/trackers/ReidModels/osnet.py | 597 - .../pytorch/trackers/ReidModels/osnet_ain.py | 540 - .../ReidModels/psroi_pooling/__init__.py | 0 .../ReidModels/psroi_pooling/_ext/__init__.py | 0 .../_ext/psroi_pooling/__init__.py | 15 - .../ReidModels/psroi_pooling/build.py | 33 - .../psroi_pooling/functions/__init__.py | 0 .../psroi_pooling/functions/psroi_pooling.py | 49 - .../trackers/ReidModels/psroi_pooling/make.sh | 10 - .../psroi_pooling/modules/__init__.py | 0 .../psroi_pooling/modules/psroi_pool.py | 18 - .../src/cuda/psroi_pooling_kernel.cu | 199 - .../src/cuda/psroi_pooling_kernel.h | 21 - .../psroi_pooling/src/psroi_pooling_cuda.c | 68 - .../psroi_pooling/src/psroi_pooling_cuda.h | 5 - .../trackers/ReidModels/reid/__init__.py | 53 - .../ReidModels/reid/image_part_aligned.py | 39 - .../pytorch/trackers/ReidModels/resnet_fc.py | 532 - .../alphapose/pytorch/trackers/__init__.py | 20 - .../alphapose/pytorch/trackers/tracker_api.py | 368 - .../alphapose/pytorch/trackers/tracker_cfg.py | 10 - .../pytorch/trackers/tracking/README.md | 2 - .../pytorch/trackers/tracking/__init__.py | 0 .../pytorch/trackers/tracking/basetrack.py | 53 - .../pytorch/trackers/tracking/matching.py | 136 - .../trackers/tracking/utils/__init__.py | 0 .../pytorch/trackers/tracking/utils/io.py | 112 - .../trackers/tracking/utils/kalman_filter.py | 229 - .../pytorch/trackers/tracking/utils/nms.py | 7 - .../trackers/tracking/utils/parse_config.py | 37 - .../pytorch/trackers/tracking/utils/timer.py | 45 - .../pytorch/trackers/tracking/utils/utils.py | 510 - .../pytorch/trackers/utils/basetransforms.py | 816 -- .../alphapose/pytorch/trackers/utils/bbox.py | 133 - .../alphapose/pytorch/trackers/utils/io.py | 112 - .../pytorch/trackers/utils/kalman_filter.py | 278 - .../alphapose/pytorch/trackers/utils/log.py | 18 - .../pytorch/trackers/utils/parse_config.py | 37 - .../alphapose/pytorch/trackers/utils/timer.py | 45 - .../pytorch/trackers/utils/transform.py | 160 - .../alphapose/pytorch/trackers/utils/utils.py | 750 -- 265 files changed, 13 insertions(+), 49412 deletions(-) delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/hardnet/256x192_hard68_lr1e-3_1x.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/hardnet/256x192_hard85_lr1e-3_1x.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/hrnet/256x192_w32_lr1e-3.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/resnet/.256x192_res50_lr1e-3_1x.yaml.swp delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/resnet/256x192_res152_lr1e-3_1x-duc.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/resnet/256x192_res50_lr1e-3_1x-concat.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/resnet/256x192_res50_lr1e-3_1x-duc.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/resnet/256x192_res50_lr1e-3_1x-simple.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/resnet/256x192_res50_lr1e-3_2x-dcn.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/resnet/256x192_res50_lr1e-3_2x-regression.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/coco/resnet/256x192_res50_lr1e-3_2x.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/dense_coco/resnet50/256x192_adam_lr1e-3-duc-dcn_1x_crop.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/halpe_136/hardnet/256x192_hard68_lr1e-3_1x.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/halpe_136/resnet/256x192_res50_lr1e-3_1x.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/halpe_136/resnet/256x192_res50_lr1e-3_2x-regression.yaml delete mode 100755 cv/pose/alphapose/pytorch/configs/halpe_26/resnet/256x192_res50_lr1e-3_1x.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/effdet_api.py delete mode 100755 cv/pose/alphapose/pytorch/detector/effdet_cfg.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/README.md delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/anchors.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/bench.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/config/config.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/efficientdet.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/helpers.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/README.md delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/argmax_matcher.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/box_coder.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/box_list.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/faster_rcnn_box_coder.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/matcher.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/region_similarity_calculator.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/target_assigner.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/utils.py delete mode 100755 cv/pose/alphapose/pytorch/detector/efficientdet/weights/get_models.sh delete mode 100755 cv/pose/alphapose/pytorch/detector/nms/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/nms/nms_wrapper.py delete mode 100755 cv/pose/alphapose/pytorch/detector/nms/src/nms_cpu.cpp delete mode 100755 cv/pose/alphapose/pytorch/detector/nms/src/nms_cuda.cpp delete mode 100755 cv/pose/alphapose/pytorch/detector/nms/src/nms_kernel.cu delete mode 100755 cv/pose/alphapose/pytorch/detector/nms/src/soft_nms_cpu.cpp delete mode 100755 cv/pose/alphapose/pytorch/detector/nms/src/soft_nms_cpu.pyx delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/README.md delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/cfg/ccmcpe.json delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/cfg/yolov3.cfg delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/models.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/preprocess.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/tracker/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/tracker/basetrack.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/tracker/matching.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/tracker/multitracker.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/datasets.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/evaluation.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/io.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/kalman_filter.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/log.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/nms.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/parse_config.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/timer.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/utils.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker/utils/visualization.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker_api.py delete mode 100755 cv/pose/alphapose/pytorch/detector/tracker_cfg.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/README.md delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/bbox.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/cam_demo.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/cfg/tiny-yolo-voc.cfg delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/cfg/yolo-voc.cfg delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/cfg/yolo.cfg delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/cfg/yolov3-spp.cfg delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/cfg/yolov3.cfg delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/darknet.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/detect.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/pallete delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/preprocess.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/util.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/video_demo.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo/video_demo_half.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo_api.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolo_cfg.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/common.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/Makefile delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/cuda/yolov5_decode.cu delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/cuda/yolov5_decode_kernel.cuh delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/include/cuda_helper.h delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/include/pytorch_cuda_helper.h delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/yolov5_decode.cpp delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/setup.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/yolov5_decode.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/experimental.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/anchors.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3-spp.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3-tiny.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-bifpn.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-fpn.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p2.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p6.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p7.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-panet.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5l6.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5m6.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5n6.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s-ghost.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s-transformer.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s6.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5x6.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/tf.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/activations.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/augmentations.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/autoanchor.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/autobatch.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/mime.sh delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/resume.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/userdata.sh delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/callbacks.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/datasets.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/downloads.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/README.md delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/example_request.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/restapi.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/general.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/Dockerfile delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/additional_requirements.txt delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/app.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/README.md delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/log_dataset.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/sweep.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/sweep.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/wandb_utils.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loss.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/metrics.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/plots.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/utils/torch_utils.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/yolo.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5l.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5m.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5n.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5s.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5x.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/activations.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/augmentations.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/autoanchor.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/autobatch.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/mime.sh delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/resume.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/userdata.sh delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/callbacks.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/datasets.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/downloads.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/README.md delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/example_request.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/restapi.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/general.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/Dockerfile delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/additional_requirements.txt delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/app.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/README.md delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/log_dataset.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/sweep.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/sweep.yaml delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/wandb_utils.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/loss.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/metrics.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/plots.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5/utils/torch_utils.py delete mode 100755 cv/pose/alphapose/pytorch/detector/yolov5_api.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/main_pipeline_time.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/multi_persons_multi_ways_batch.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/multi_ways_batch.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/multi_ways_forward.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/multi_ways_loop.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/multi_ways_process.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/process_utils.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/test_demo.py rename cv/pose/alphapose/pytorch/scripts/{trainval => }/train.py (100%) mode change 100755 => 100644 rename cv/pose/alphapose/pytorch/scripts/{trainval => }/train.sh (95%) mode change 100755 => 100644 delete mode 100755 cv/pose/alphapose/pytorch/scripts/trainval/demo_api.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/trainval/demo_inference.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/trainval/validate.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/trainval/validate.sh delete mode 100755 cv/pose/alphapose/pytorch/scripts/videos_process/composition_frames.py delete mode 100755 cv/pose/alphapose/pytorch/scripts/videos_process/extract_frames.py delete mode 100755 cv/pose/alphapose/pytorch/setup.cfg delete mode 100755 cv/pose/alphapose/pytorch/setup.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/README.md delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/alpha-pose-results-sample.json delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/matching.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/parallel_process.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/poseflow_infer.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/posetrack_data delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/poseval delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/requirements.txt delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/tracker-baseline.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/tracker-general.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/PoseFlow/utils.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/README.md delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/ResBnLin.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/ResNet.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/googlenet.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/lrn.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/sqeezenet.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/bn_linear.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/classification/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/classification/classifier.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/classification/rfcn_cls.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/net_utils.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/osnet.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/osnet_ain.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/_ext/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/_ext/psroi_pooling/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/build.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/functions/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/functions/psroi_pooling.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/make.sh delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/modules/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/modules/psroi_pool.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/cuda/psroi_pooling_kernel.cu delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/cuda/psroi_pooling_kernel.h delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/psroi_pooling_cuda.c delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/psroi_pooling_cuda.h delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/reid/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/reid/image_part_aligned.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/ReidModels/resnet_fc.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracker_api.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracker_cfg.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/README.md delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/basetrack.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/matching.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/utils/__init__.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/utils/io.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/utils/kalman_filter.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/utils/nms.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/utils/parse_config.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/utils/timer.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/tracking/utils/utils.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/utils/basetransforms.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/utils/bbox.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/utils/io.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/utils/kalman_filter.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/utils/log.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/utils/parse_config.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/utils/timer.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/utils/transform.py delete mode 100755 cv/pose/alphapose/pytorch/trackers/utils/utils.py diff --git a/cv/pose/alphapose/pytorch/README.md b/cv/pose/alphapose/pytorch/README.md index a4dae3c4e..754a64cea 100755 --- a/cv/pose/alphapose/pytorch/README.md +++ b/cv/pose/alphapose/pytorch/README.md @@ -12,6 +12,7 @@ tracker that achieves both 60+ mAP (66.5 mAP) and 50+ MOTA (58.3 MOTA) on PoseTr | GPU | [IXUCA SDK](https://gitee.com/deep-spark/deepspark#%E5%A4%A9%E6%95%B0%E6%99%BA%E7%AE%97%E8%BD%AF%E4%BB%B6%E6%A0%88-ixuca) | Release | |--------|-----------|---------| +| BI-V150 | 4.2.0 | 25.03 | | BI-V100 | 3.0.0 | 23.06 | ## Model Preparation @@ -25,6 +26,10 @@ Take coco2017 dataset as an example, specify `/path/to/coco2017` to your COCO pa unzipped dataset path structure sholud look like: ```bash +# create soft link to coco +mkdir -p /home/datasets/cv/ +ln -s /path/to/coco2017 /home/datasets/cv/coco + coco2017 ├── annotations │   ├── instances_train2017.json @@ -46,31 +51,20 @@ coco2017 ### Install Dependencies ```bash -# install libGL -yum install mesa-libGL - -# install zlib -wget http://www.zlib.net/fossils/zlib-1.2.9.tar.gz -tar xvf zlib-1.2.9.tar.gz -cd zlib-1.2.9/ -./configure && make install -cd .. -rm -rf zlib-1.2.9.tar.gz zlib-1.2.9/ +# Install libGL +## CentOS +yum install -y mesa-libGL +## Ubuntu +apt install -y libgl1-mesa-glx # install requirements -pip3 install seaborn pandas pycocotools matplotlib -pip3 install easydict tensorboardX opencv-python +pip3 install seaborn pandas pycocotools matplotlib easydict tensorboardX opencv-python ``` ## Model Training ```bash -# create soft link to coco -mkdir -p /home/datasets/cv/ -ln -s /path/to/coco2017 /home/datasets/cv/coco - -# -bash ./scripts/trainval/train.sh ./configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml 1 +bash ./scripts/train.sh ./configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml 1 ``` ## Model Results diff --git a/cv/pose/alphapose/pytorch/configs/coco/hardnet/256x192_hard68_lr1e-3_1x.yaml b/cv/pose/alphapose/pytorch/configs/coco/hardnet/256x192_hard68_lr1e-3_1x.yaml deleted file mode 100755 index dd4d196e1..000000000 --- a/cv/pose/alphapose/pytorch/configs/coco/hardnet/256x192_hard68_lr1e-3_1x.yaml +++ /dev/null @@ -1,65 +0,0 @@ -DATASET: - TRAIN: - TYPE: 'Mscoco' - ROOT: './data/coco/' - IMG_PREFIX: 'train2017' - ANN: 'annotations/person_keypoints_train2017.json' - AUG: - FLIP: true - ROT_FACTOR: 40 - SCALE_FACTOR: 0.3 - NUM_JOINTS_HALF_BODY: 8 - PROB_HALF_BODY: -1 - VAL: - TYPE: 'Mscoco' - ROOT: './data/coco/' - IMG_PREFIX: 'val2017' - ANN: 'annotations/person_keypoints_val2017.json' - TEST: - TYPE: 'Mscoco_det' - ROOT: './data/coco/' - IMG_PREFIX: 'val2017' - DET_FILE: './exp/json/test_det_yolo.json' - ANN: 'annotations/person_keypoints_val2017.json' -DATA_PRESET: - TYPE: 'simple' - SIGMA: 2 - NUM_JOINTS: 17 - IMAGE_SIZE: - - 256 - - 192 - HEATMAP_SIZE: - - 64 - - 48 -MODEL: - TYPE: 'HarDNetPose' - INIT_WEIGHTS: '' - PRETRAINED: '' - TRY_LOAD: '' - FINAL_CONV_KERNEL: 1 - NUM_LAYERS: 68 - DOWN_RATIO: 4 - TRT: False -LOSS: - TYPE: 'MSELoss' -DETECTOR: - NAME: 'yolo' - CONFIG: 'detector/yolo/cfg/yolov3-spp.cfg' - WEIGHTS: 'detector/yolo/data/yolov3-spp.weights' - NMS_THRES: 0.6 - CONFIDENCE: 0.05 -TRAIN: - WORLD_SIZE: 4 - BATCH_SIZE: 32 - BEGIN_EPOCH: 0 - END_EPOCH: 200 - OPTIMIZER: 'adam' - LR: 0.001 - LR_FACTOR: 0.1 - LR_STEP: - - 90 - - 120 - DPG_MILESTONE: 140 - DPG_STEP: - - 160 - - 190 diff --git a/cv/pose/alphapose/pytorch/configs/coco/hardnet/256x192_hard85_lr1e-3_1x.yaml b/cv/pose/alphapose/pytorch/configs/coco/hardnet/256x192_hard85_lr1e-3_1x.yaml deleted file mode 100755 index 627d8c7c9..000000000 --- a/cv/pose/alphapose/pytorch/configs/coco/hardnet/256x192_hard85_lr1e-3_1x.yaml +++ /dev/null @@ -1,65 +0,0 @@ -DATASET: - TRAIN: - TYPE: 'Mscoco' - ROOT: './data/coco/' - IMG_PREFIX: 'train2017' - ANN: 'annotations/person_keypoints_train2017.json' - AUG: - FLIP: true - ROT_FACTOR: 40 - SCALE_FACTOR: 0.3 - NUM_JOINTS_HALF_BODY: 8 - PROB_HALF_BODY: -1 - VAL: - TYPE: 'Mscoco' - ROOT: './data/coco/' - IMG_PREFIX: 'val2017' - ANN: 'annotations/person_keypoints_val2017.json' - TEST: - TYPE: 'Mscoco_det' - ROOT: './data/coco/' - IMG_PREFIX: 'val2017' - DET_FILE: './exp/json/test_det_yolo.json' - ANN: 'annotations/person_keypoints_val2017.json' -DATA_PRESET: - TYPE: 'simple' - SIGMA: 2 - NUM_JOINTS: 17 - IMAGE_SIZE: - - 256 - - 192 - HEATMAP_SIZE: - - 64 - - 48 -MODEL: - TYPE: 'HarDNetPose' - INIT_WEIGHTS: '' - PRETRAINED: '' - TRY_LOAD: '' - FINAL_CONV_KERNEL: 1 - NUM_LAYERS: 85 - DOWN_RATIO: 4 - TRT: False -LOSS: - TYPE: 'MSELoss' -DETECTOR: - NAME: 'yolo' - CONFIG: 'detector/yolo/cfg/yolov3-spp.cfg' - WEIGHTS: 'detector/yolo/data/yolov3-spp.weights' - NMS_THRES: 0.6 - CONFIDENCE: 0.05 -TRAIN: - WORLD_SIZE: 4 - BATCH_SIZE: 32 - BEGIN_EPOCH: 0 - END_EPOCH: 200 - OPTIMIZER: 'adam' - LR: 0.001 - LR_FACTOR: 0.1 - LR_STEP: - - 90 - - 120 - DPG_MILESTONE: 140 - DPG_STEP: - - 160 - - 190 diff --git a/cv/pose/alphapose/pytorch/configs/coco/hrnet/256x192_w32_lr1e-3.yaml b/cv/pose/alphapose/pytorch/configs/coco/hrnet/256x192_w32_lr1e-3.yaml deleted file mode 100755 index d6f08acfe..000000000 --- a/cv/pose/alphapose/pytorch/configs/coco/hrnet/256x192_w32_lr1e-3.yaml +++ /dev/null @@ -1,84 +0,0 @@ -DATASET: - TRAIN: - TYPE: 'Mscoco' - ROOT: './data/coco/' - IMG_PREFIX: 'train2017' - ANN: 'annotations/person_keypoints_train2017.json' - AUG: - FLIP: true - ROT_FACTOR: 45 - SCALE_FACTOR: 0.35 - NUM_JOINTS_HALF_BODY: 8 - PROB_HALF_BODY: 0.3 - VAL: - TYPE: 'Mscoco' - ROOT: './data/coco/' - IMG_PREFIX: 'val2017' - ANN: 'annotations/person_keypoints_val2017.json' - TEST: - TYPE: 'Mscoco_det' - ROOT: './data/coco/' - IMG_PREFIX: 'val2017' - DET_FILE: './exp/json/test_det_yolo.json' - ANN: 'annotations/person_keypoints_val2017.json' -DATA_PRESET: - TYPE: 'simple' - SIGMA: 2 - NUM_JOINTS: 17 - IMAGE_SIZE: - - 256 - - 192 - HEATMAP_SIZE: - - 64 - - 48 -MODEL: - TYPE: 'PoseHighResolutionNet' - PRETRAINED: '' - TRY_LOAD: '' - NUM_LAYERS: 50 - FINAL_CONV_KERNEL: 1 - PRETRAINED_LAYERS: ['*'] - STAGE2: - NUM_MODULES: 1 - NUM_BRANCHES: 2 - NUM_BLOCKS: [4, 4] - NUM_CHANNELS: [32, 64] - BLOCK: 'BASIC' - FUSE_METHOD: 'SUM' - STAGE3: - NUM_MODULES: 4 - NUM_BRANCHES: 3 - NUM_BLOCKS: [4, 4, 4] - NUM_CHANNELS: [32, 64, 128] - BLOCK: 'BASIC' - FUSE_METHOD: 'SUM' - STAGE4: - NUM_MODULES: 3 - NUM_BRANCHES: 4 - NUM_BLOCKS: [4, 4, 4, 4] - NUM_CHANNELS: [32, 64, 128, 256] - BLOCK: 'BASIC' - FUSE_METHOD: 'SUM' -LOSS: - TYPE: 'MSELoss' -DETECTOR: - NAME: 'yolo' - CONFIG: 'detector/yolo/cfg/yolov3-spp.cfg' - WEIGHTS: 'detector/yolo/data/yolov3-spp.weights' - NMS_THRES: 0.6 - CONFIDENCE: 0.05 -TRAIN: - WORLD_SIZE: 4 - BATCH_SIZE: 32 - BEGIN_EPOCH: 0 - END_EPOCH: 270 - OPTIMIZER: 'adam' - LR: 0.001 - LR_FACTOR: 0.1 - LR_STEP: - - 170 - - 200 - DPG_MILESTONE: 210 - DPG_STEP: - - 230 - - 250 \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/configs/coco/resnet/.256x192_res50_lr1e-3_1x.yaml.swp b/cv/pose/alphapose/pytorch/configs/coco/resnet/.256x192_res50_lr1e-3_1x.yaml.swp deleted file mode 100755 index 159526e787c370eb3fe0373187d930a1a6e10c6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2y^q{P7>6f71>6ylE|o)&mV#Z|`*C;KDs$`EU4y@5`;J@`WSLvv-ol=}T05J& zDo8XSQBWe$0Qn0*RFshrf)+X`kkU~=K|upjey`VeTtXBO&;VoU(b(_2GxPeH^+{3Y z6>ZzJmGwrO;X2FM*Ndak>a|<9&VK$Vn`c=;;Xk^xy;e)pciYYOM*Of`bw4{u)T1mN zPm{)t>uNlm?Z>k$Pt@Hk-J6Vaw7Z!)Px3S=)MjVxP`}iS@YvC!>0D3htw=v?9K{FI zhpi&}qycH*!3I`XtEp?$ck!7E%DJbv9-Jnl(ttD|4M+phfHWWtNCVPsI%+X^9|o9nn?vc9qy%w&gg>KS{@JpZ7x7?(_hz{B1!3NWs#w3^6x$@MLx3ba}1bJL+p zd#=+r4dL{Vr!}+=LXI6o;m{WWMb>DjFbBgBkF`-!B)dg6$AR5xrjFtwF7FntdOn*q zZX}cOevwmw<+Ov}jo95ApB{imN_M!7)oV28qElmr2t_FaUEz*LU3MU>EXT~28w6Cg zvt>sX-w{5l>MW(=Y%n_N%DpWm8Up2PM}5-@X#h>@??jf%4NOf1c)lowh~q%DY(LHm z4`-2U%ytc7(a5^e-YA>3HkzT}q0POe)-sIK$z{8&!nFB7ob*yHFSw>dD)n`w1?Ir! z*h1V^E9R4f*%a#;Jme9|3Peb&DhhWT6dR{$R>Z|5OLKLW%=0XbUQ3Q<*(5FUXc14F zn!et66=8ZS{3Jz4Z%qapYH~PJsY@-Ayoj)q5eYw)ZQ27`vTt5Nel^*09^Z9C#Fl5Z zY1i|lz`^WAc{ZEYT&5jwR!&E@X$1<0_z3>SEBv!XQ9;|h+(`1{`R-;k 1: - if has_amp: - print('Using AMP mixed precision.') - self.model = amp.initialize(self.model, opt_level='O1') - else: - print('AMP not installed, running network in FP32.') - - self.model = torch.nn.DataParallel(self.model, device_ids=args.gpus).to(args.device) - else: - self.model.to(args.device) - else: - if has_amp: - print('Using AMP mixed precision.') - self.model = amp.initialize(self.model, opt_level='O1') - else: - print('AMP not installed, running network in FP32.') - self.model.cuda() - - net.eval() - - def image_preprocess(self, img_source): - """ - Pre-process the img before fed to the object detection network - Input: image name(str) or raw image data(ndarray or torch.Tensor,channel GBR) - Output: pre-processed image data(torch.FloatTensor,(1,3,h,w)) - """ - if isinstance(img_source, str): - img, orig_img, im_dim_list = prep_image(img_source, self.inp_dim) - elif isinstance(img_source, torch.Tensor) or isinstance(img_source, np.ndarray): - img, orig_img, im_dim_list = prep_frame(img_source, self.inp_dim) - else: - raise IOError('Unknown image source type: {}'.format(type(img_source))) - - return img - - def images_detection(self, imgs, orig_dim_list): - """ - Feed the img data into object detection network and - collect bbox w.r.t original image size - Input: imgs(torch.FloatTensor,(b,3,h,w)): pre-processed mini-batch image input - orig_dim_list(torch.FloatTensor, (b,(w,h,w,h))): original mini-batch image size - Output: dets(torch.cuda.FloatTensor,(n,(batch_idx,x1,y1,x2,y2,c,s,idx of cls))): human detection results - """ - args = self.detector_opt - if not self.model: - self.load_model() - with torch.no_grad(): - imgs = imgs.to(args.device) if args else imgs.cuda() - scaling_factors = torch.FloatTensor([1./min(self.inp_dim / orig_dim[0], self.inp_dim / orig_dim[1]) for orig_dim in orig_dim_list]).view(-1, 1) - scaling_factors = scaling_factors.to(args.device) if args else scaling_factors.cuda() - prediction = self.model(imgs, scaling_factors) - #change the pred format to alphapose (nms has already been done in effdeteval model) - prediction = prediction.cpu() - write = False - for index, sample in enumerate(prediction): - for det in sample: - score = float(det[4]) - if score < .001: # stop when below this threshold, scores in descending order - break - if int(det[5]) != 1 or score < self.confidence: - continue - det_new = prediction.new(1,8) - det_new[0,0] = index #index of img - det_new[0,1:3] = det[0:2] # bbox x1,y1 - det_new[0,3:5] = det[0:2] + det[2:4] # bbox x2,y2 - det_new[0,6:7] = det[4] # cls conf - det_new[0,7] = det[5] # cls idx - if not write: - dets = det_new - write = True - else: - dets = torch.cat((dets, det_new)) - if not write: - return 0 - - orig_dim_list = torch.index_select(orig_dim_list, 0, dets[:, 0].long()) - for i in range(dets.shape[0]): - dets[i, [1, 3]] = torch.clamp(dets[i, [1, 3]], 0.0, orig_dim_list[i, 0]) - dets[i, [2, 4]] = torch.clamp(dets[i, [2, 4]], 0.0, orig_dim_list[i, 1]) - - return dets - - def detect_one_img(self, img_name): - """ - Detect bboxs in one image - Input: 'str', full path of image - Output: '[{"category_id":1,"score":float,"bbox":[x,y,w,h],"image_id":str},...]', - The output results are similar with coco results type, except that image_id uses full path str - instead of coco %012d id for generalization. - """ - args = self.detector_opt - _CUDA = True - if args: - if args.gpus[0] < 0: - _CUDA = False - if not self.model: - self.load_model() - if isinstance(self.model, torch.nn.DataParallel): - self.model = self.model.module - dets_results = [] - #pre-process(scale, normalize, ...) the image - img, orig_img, img_dim_list = prep_image(img_name, self.inp_dim) - with torch.no_grad(): - img_dim_list = torch.FloatTensor([img_dim_list]).repeat(1, 2) - img = img.to(args.device) if args else img.cuda() - scaling_factor = torch.FloatTensor([1/min(self.inp_dim / orig_dim[0], self.inp_dim / orig_dim[1]) for orig_dim in img_dim_list]).view(-1, 1) - scaling_factor = scaling_factor.to(args.device) if args else scaling_factor.cuda() - prediction = self.model(img, scaling_factor) - #change the pred format to alphapose (nms has already been done in effdeteval model) - prediction = prediction.cpu() - write = False - for index, sample in enumerate(prediction): - for det in sample: - score = float(det[4]) - if score < .001: # stop when below this threshold, scores in descending order - break - if int(det[5]) != 1 or score < self.confidence: - continue - det_new = prediction.new(1,8) - det_new[0,0] = index #index of img - det_new[0,1:3] = det[0:2] # bbox x1,y1 - det_new[0,3:5] = det[0:2] + det[2:4] # bbox x2,y2 - det_new[0,6:7] = det[4] # cls conf - det_new[0,7] = det[5] # cls idx - if not write: - dets = det_new - write = True - else: - dets = torch.cat((dets, det_new)) - if not write: - return None - - img_dim_list = torch.index_select(img_dim_list, 0, dets[:, 0].long()) - for i in range(dets.shape[0]): - dets[i, [1, 3]] = torch.clamp(dets[i, [1, 3]], 0.0, img_dim_list[i, 0]) - dets[i, [2, 4]] = torch.clamp(dets[i, [2, 4]], 0.0, img_dim_list[i, 1]) - - #write results - det_dict = {} - x = float(dets[i, 1]) - y = float(dets[i, 2]) - w = float(dets[i, 3] - dets[i, 1]) - h = float(dets[i, 4] - dets[i, 2]) - det_dict["category_id"] = 1 - det_dict["score"] = float(dets[i, 5]) - det_dict["bbox"] = [x, y, w, h] - det_dict["image_id"] = int(os.path.basename(img_name).split('.')[0]) - dets_results.append(det_dict) - - return dets_results - - - def check_detector(self, img_name): - """ - Detect bboxs in one image - Input: 'str', full path of image - Output: '[{"category_id":1,"score":float,"bbox":[x,y,w,h],"image_id":str},...]', - The output results are similar with coco results type, except that image_id uses full path str - instead of coco %012d id for generalization. - """ - args = self.detector_opt - _CUDA = True - if args: - if args.gpus[0] < 0: - _CUDA = False - if not self.model: - self.load_model() - if isinstance(self.model, torch.nn.DataParallel): - self.model = self.model.module - dets_results = [] - #pre-process(scale, normalize, ...) the image - img, orig_img, img_dim_list = prep_image(img_name, self.inp_dim) - with torch.no_grad(): - img_dim_list = torch.FloatTensor([img_dim_list]).repeat(1, 2) - img = img.to(args.device) if args else img.cuda() - scaling_factor = torch.FloatTensor([1/min(self.inp_dim / orig_dim[0], self.inp_dim / orig_dim[1]) for orig_dim in img_dim_list]).view(-1, 1) - scaling_factor = scaling_factor.to(args.device) if args else scaling_factor.cuda() - output = self.model(img, scaling_factor) - - output = output.cpu() - for index, sample in enumerate(output): - image_id = int(os.path.basename(img_name).split('.')[0]) - for det in sample: - score = float(det[4]) - if score < .001: # stop when below this threshold, scores in descending order - break - #### uncomment it for only human detection - # if int(det[5]) != 1 or score < self.confidence: - # continue - coco_det = dict( - image_id=image_id, - bbox=det[0:4].tolist(), - score=score, - category_id=int(det[5])) - dets_results.append(coco_det) - - return dets_results - -if __name__ == "__main__": -#run with python detector/effdet_api.py /DATA1/Benchmark/coco/ efficientdet_d0 - from pycocotools.coco import COCO - from pycocotools.cocoeval import COCOeval - from easydict import EasyDict as edict - from apis import get_detector - from tqdm import tqdm - import json - - opt = edict() - _coco = COCO(sys.argv[1]+'/annotations/instances_val2017.json') - # _coco = COCO(sys.argv[1]+'/annotations/person_keypoints_val2017.json') - opt.detector = sys.argv[2] - opt.gpus = [0] if torch.cuda.device_count() >= 1 else [-1] - opt.device = torch.device("cuda:" + str(opt.gpus[0]) if opt.gpus[0] >= 0 else "cpu") - image_ids = sorted(_coco.getImgIds()) - det_model = get_detector(opt) - dets = [] - for entry in tqdm(_coco.loadImgs(image_ids)): - abs_path = os.path.join( - sys.argv[1], 'val2017', entry['file_name']) - det = det_model.check_detector(abs_path) - if det: - dets += det - result_file = 'results.json' - json.dump(dets, open(result_file, 'w')) - - coco_results = _coco.loadRes(result_file) - coco_eval = COCOeval(_coco, coco_results, 'bbox') - coco_eval.params.imgIds = image_ids # score only ids we've used - coco_eval.evaluate() - coco_eval.accumulate() - coco_eval.summarize() diff --git a/cv/pose/alphapose/pytorch/detector/effdet_cfg.py b/cv/pose/alphapose/pytorch/detector/effdet_cfg.py deleted file mode 100755 index 8f5e4e04d..000000000 --- a/cv/pose/alphapose/pytorch/detector/effdet_cfg.py +++ /dev/null @@ -1,8 +0,0 @@ -from easydict import EasyDict as edict - -cfg = edict() - -cfg.NMS_THRES = 0.6 # 0.6(0.713) 0.5(0.707) -cfg.CONFIDENCE = 0.2 # 0.15 0.1 -cfg.NUM_CLASSES = 80 -cfg.MAX_DETECTIONS = 200 # 100 diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/README.md b/cv/pose/alphapose/pytorch/detector/efficientdet/README.md deleted file mode 100755 index d600f12dc..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# A PyTorch implementation of a EfficientDet Object Detector - -Forked and modified from https://github.com/rwightman/efficientdet-pytorch, many thanks! diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/__init__.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/__init__.py deleted file mode 100755 index b0291793f..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .efficientdet import EfficientDet -from .bench import DetBenchEval, DetBenchTrain -from .config.config import get_efficientdet_config -from .helpers import load_checkpoint, load_pretrained \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/anchors.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/anchors.py deleted file mode 100755 index f143968b9..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/anchors.py +++ /dev/null @@ -1,358 +0,0 @@ -""" RetinaNet / EfficientDet Anchor Gen - -Adapted for PyTorch from Tensorflow impl at - https://github.com/google/automl/blob/6f6694cec1a48cdb33d5d1551a2d5db8ad227798/efficientdet/anchors.py - -Hacked together by Ross Wightman, original copyright below -""" -# Copyright 2020 Google Research. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -"""Anchor definition. - -This module is borrowed from TPU RetinaNet implementation: -https://github.com/tensorflow/tpu/blob/master/models/official/retinanet/anchors.py -""" -import collections -import numpy as np -import torch -import torch.nn as nn -from torchvision.ops.boxes import batched_nms - -from .object_detection import argmax_matcher -from .object_detection import box_list -from .object_detection import faster_rcnn_box_coder -from .object_detection import region_similarity_calculator -from .object_detection import target_assigner - -# The minimum score to consider a logit for identifying detections. -MIN_CLASS_SCORE = -5.0 - -# The score for a dummy detection -_DUMMY_DETECTION_SCORE = -1e5 - -# The maximum number of (anchor,class) pairs to keep for non-max suppression. -MAX_DETECTION_POINTS = 5000 - -# The maximum number of detections per image. -MAX_DETECTIONS_PER_IMAGE = 100 - - -def decode_box_outputs(rel_codes, anchors, output_xyxy=False): - """Transforms relative regression coordinates to absolute positions. - - Network predictions are normalized and relative to a given anchor; this - reverses the transformation and outputs absolute coordinates for the input image. - - Args: - rel_codes: box regression targets. - - anchors: anchors on all feature levels. - - Returns: - outputs: bounding boxes. - - """ - ycenter_a = (anchors[0] + anchors[2]) / 2 - xcenter_a = (anchors[1] + anchors[3]) / 2 - ha = anchors[2] - anchors[0] - wa = anchors[3] - anchors[1] - ty, tx, th, tw = rel_codes - - w = torch.exp(tw) * wa - h = torch.exp(th) * ha - ycenter = ty * ha + ycenter_a - xcenter = tx * wa + xcenter_a - ymin = ycenter - h / 2. - xmin = xcenter - w / 2. - ymax = ycenter + h / 2. - xmax = xcenter + w / 2. - if output_xyxy: - out = torch.stack([xmin, ymin, xmax, ymax], dim=1) - else: - out = torch.stack([ymin, xmin, ymax, xmax], dim=1) - return out - - -def _generate_anchor_configs(min_level, max_level, num_scales, aspect_ratios): - """Generates mapping from output level to a list of anchor configurations. - - A configuration is a tuple of (num_anchors, scale, aspect_ratio). - - Args: - min_level: integer number of minimum level of the output feature pyramid. - - max_level: integer number of maximum level of the output feature pyramid. - - num_scales: integer number representing intermediate scales added on each level. - For instances, num_scales=2 adds two additional anchor scales [2^0, 2^0.5] on each level. - - aspect_ratios: list of tuples representing the aspect ratio anchors added on each level. - For instances, aspect_ratios = [(1, 1), (1.4, 0.7), (0.7, 1.4)] adds three anchors on each level. - - Returns: - anchor_configs: a dictionary with keys as the levels of anchors and - values as a list of anchor configuration. - """ - anchor_configs = {} - for level in range(min_level, max_level + 1): - anchor_configs[level] = [] - for scale_octave in range(num_scales): - for aspect in aspect_ratios: - anchor_configs[level].append((2 ** level, scale_octave / float(num_scales), aspect)) - return anchor_configs - - -def _generate_anchor_boxes(image_size, anchor_scale, anchor_configs): - """Generates multiscale anchor boxes. - - Args: - image_size: integer number of input image size. The input image has the same dimension for - width and height. The image_size should be divided by the largest feature stride 2^max_level. - - anchor_scale: float number representing the scale of size of the base - anchor to the feature stride 2^level. - - anchor_configs: a dictionary with keys as the levels of anchors and - values as a list of anchor configuration. - - Returns: - anchor_boxes: a numpy array with shape [N, 4], which stacks anchors on all feature levels. - - Raises: - ValueError: input size must be the multiple of largest feature stride. - """ - boxes_all = [] - for _, configs in anchor_configs.items(): - boxes_level = [] - for config in configs: - stride, octave_scale, aspect = config - if image_size % stride != 0: - raise ValueError("input size must be divided by the stride.") - base_anchor_size = anchor_scale * stride * 2 ** octave_scale - anchor_size_x_2 = base_anchor_size * aspect[0] / 2.0 - anchor_size_y_2 = base_anchor_size * aspect[1] / 2.0 - - x = np.arange(stride / 2, image_size, stride) - y = np.arange(stride / 2, image_size, stride) - xv, yv = np.meshgrid(x, y) - xv = xv.reshape(-1) - yv = yv.reshape(-1) - - boxes = np.vstack((yv - anchor_size_y_2, xv - anchor_size_x_2, - yv + anchor_size_y_2, xv + anchor_size_x_2)) - boxes = np.swapaxes(boxes, 0, 1) - boxes_level.append(np.expand_dims(boxes, axis=1)) - # concat anchors on the same level to the reshape NxAx4 - boxes_level = np.concatenate(boxes_level, axis=1) - boxes_all.append(boxes_level.reshape([-1, 4])) - - anchor_boxes = np.vstack(boxes_all) - return anchor_boxes - - -def generate_detections(cls_outputs, box_outputs, anchor_boxes, indices, classes, image_scale, nms_thres=0.5, max_dets=100): - """Generates detections with RetinaNet model outputs and anchors. - - Args: - cls_outputs: a torch tensor with shape [N, 1], which has the highest class - scores on all feature levels. The N is the number of selected - top-K total anchors on all levels. (k being MAX_DETECTION_POINTS) - - box_outputs: a torch tensor with shape [N, 4], which stacks box regression - outputs on all feature levels. The N is the number of selected top-k - total anchors on all levels. (k being MAX_DETECTION_POINTS) - - anchor_boxes: a torch tensor with shape [N, 4], which stacks anchors on all - feature levels. The N is the number of selected top-k total anchors on all levels. - - indices: a torch tensor with shape [N], which is the indices from top-k selection. - - classes: a torch tensor with shape [N], which represents the class - prediction on all selected anchors from top-k selection. - - image_scale: a float tensor representing the scale between original image - and input image for the detector. It is used to rescale detections for - evaluating with the original groundtruth annotations. - - Returns: - detections: detection results in a tensor with shape [MAX_DETECTION_POINTS, 6], - each row representing [x, y, width, height, score, class] - """ - anchor_boxes = anchor_boxes[indices, :] - - # apply bounding box regression to anchors - boxes = decode_box_outputs(box_outputs.T.float(), anchor_boxes.T, output_xyxy=True) - - scores = cls_outputs.sigmoid().squeeze(1).float() - human_idx = classes == 0 - boxes = boxes[human_idx] - scores = scores[human_idx] - classes = classes[human_idx] - top_detection_idx = batched_nms(boxes, scores, classes, iou_threshold=nms_thres) - - # keep only topk scoring predictions - top_detection_idx = top_detection_idx[:max_dets] - boxes = boxes[top_detection_idx] - scores = scores[top_detection_idx, None] - classes = classes[top_detection_idx, None] - - # xyxy to xywh & rescale to original image - boxes[:, 2] -= boxes[:, 0] - boxes[:, 3] -= boxes[:, 1] - boxes *= image_scale - - classes += 1 # back to class idx with background class = 0 - - # stack em and pad out to MAX_DETECTIONS_PER_IMAGE if necessary - detections = torch.cat([boxes, scores, classes.float()], dim=1) - if len(top_detection_idx) < max_dets: - detections = torch.cat([ - detections, - torch.zeros( - (max_dets - len(top_detection_idx), 6), device=detections.device, dtype=detections.dtype) - ], dim=0) - return detections - - -class Anchors(nn.Module): - """RetinaNet Anchors class.""" - - def __init__(self, min_level, max_level, num_scales, aspect_ratios, anchor_scale, image_size): - """Constructs multiscale RetinaNet anchors. - - Args: - min_level: integer number of minimum level of the output feature pyramid. - - max_level: integer number of maximum level of the output feature pyramid. - - num_scales: integer number representing intermediate scales added - on each level. For instances, num_scales=2 adds two additional - anchor scales [2^0, 2^0.5] on each level. - - aspect_ratios: list of tuples representing the aspect ratio anchors added - on each level. For instances, aspect_ratios = - [(1, 1), (1.4, 0.7), (0.7, 1.4)] adds three anchors on each level. - - anchor_scale: float number representing the scale of size of the base - anchor to the feature stride 2^level. - - image_size: integer number of input image size. The input image has the - same dimension for width and height. The image_size should be divided by - the largest feature stride 2^max_level. - """ - super(Anchors, self).__init__() - self.min_level = min_level - self.max_level = max_level - self.num_scales = num_scales - self.aspect_ratios = aspect_ratios - self.anchor_scale = anchor_scale - self.image_size = image_size - self.config = self._generate_configs() - self.register_buffer('boxes', self._generate_boxes()) - - def _generate_configs(self): - """Generate configurations of anchor boxes.""" - return _generate_anchor_configs(self.min_level, self.max_level, self.num_scales, self.aspect_ratios) - - def _generate_boxes(self): - """Generates multiscale anchor boxes.""" - boxes = _generate_anchor_boxes(self.image_size, self.anchor_scale, self.config) - boxes = torch.from_numpy(boxes).float() - return boxes - - def get_anchors_per_location(self): - return self.num_scales * len(self.aspect_ratios) - - -# FIXME PyTorch port of this class and subclasses not tested yet, needed for training -class AnchorLabeler(nn.Module): - """Labeler for multiscale anchor boxes. - """ - - def __init__(self, anchors, num_classes, match_threshold=0.5): - """Constructs anchor labeler to assign labels to anchors. - - Args: - anchors: an instance of class Anchors. - - num_classes: integer number representing number of classes in the dataset. - - match_threshold: float number between 0 and 1 representing the threshold - to assign positive labels for anchors. - """ - super(AnchorLabeler, self).__init__() - similarity_calc = region_similarity_calculator.IouSimilarity() - matcher = argmax_matcher.ArgMaxMatcher( - match_threshold, - unmatched_threshold=match_threshold, - negatives_lower_than_unmatched=True, - force_match_for_each_row=True) - box_coder = faster_rcnn_box_coder.FasterRcnnBoxCoder() - - self.target_assigner = target_assigner.TargetAssigner(similarity_calc, matcher, box_coder) - self.anchors = anchors - self.match_threshold = match_threshold - self.num_classes = num_classes - - def _unpack_labels(self, labels): - """Unpacks an array of labels into multiscales labels.""" - labels_unpacked = [] - anchors = self.anchors - count = 0 - for level in range(anchors.min_level, anchors.max_level + 1): - feat_size = int(anchors.image_size / 2 ** level) - steps = feat_size ** 2 * anchors.get_anchors_per_location() - indices = torch.arange(count, count + steps, device=labels.device) - count += steps - labels_unpacked.append( - torch.index_select(labels, 0, indices).view([feat_size, feat_size, -1])) - return labels_unpacked - - def label_anchors(self, gt_boxes, gt_labels): - """Labels anchors with ground truth inputs. - - Args: - gt_boxes: A float tensor with shape [N, 4] representing groundtruth boxes. - For each row, it stores [y0, x0, y1, x1] for four corners of a box. - - gt_labels: A integer tensor with shape [N, 1] representing groundtruth classes. - - Returns: - cls_targets_dict: ordered dictionary with keys [min_level, min_level+1, ..., max_level]. - The values are tensor with shape [height_l, width_l, num_anchors]. The height_l and width_l - represent the dimension of class logits at l-th level. - - box_targets_dict: ordered dictionary with keys [min_level, min_level+1, ..., max_level]. - The values are tensor with shape [height_l, width_l, num_anchors * 4]. The height_l and - width_l represent the dimension of bounding box regression output at l-th level. - - num_positives: scalar tensor storing number of positives in an image. - """ - gt_box_list = box_list.BoxList(gt_boxes) - anchor_box_list = box_list.BoxList(self.anchors.boxes) - - # cls_weights, box_weights are not used - cls_targets, _, box_targets, _, matches = self.target_assigner.assign(anchor_box_list, gt_box_list, gt_labels) - - # class labels start from 1 and the background class = -1 - cls_targets -= 1 - cls_targets = cls_targets.long() - - # Unpack labels. - cls_targets_dict = self._unpack_labels(cls_targets) - box_targets_dict = self._unpack_labels(box_targets) - num_positives = (matches.match_results != -1).float().sum() - - return cls_targets_dict, box_targets_dict, num_positives diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/bench.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/bench.py deleted file mode 100755 index 1c8966748..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/bench.py +++ /dev/null @@ -1,103 +0,0 @@ -""" PyTorch EfficientDet support benches - -Hacked together by Ross Wightman -""" -import torch -import torch.nn as nn -from .anchors import Anchors, AnchorLabeler, generate_detections, MAX_DETECTION_POINTS - - -def _post_process(config, cls_outputs, box_outputs): - """Selects top-k predictions. - - Post-proc code adapted from Tensorflow version at: https://github.com/google/automl/tree/master/efficientdet - and optimized for PyTorch. - - Args: - config: a parameter dictionary that includes `min_level`, `max_level`, `batch_size`, and `num_classes`. - - cls_outputs: an OrderDict with keys representing levels and values - representing logits in [batch_size, height, width, num_anchors]. - - box_outputs: an OrderDict with keys representing levels and values - representing box regression targets in [batch_size, height, width, num_anchors * 4]. - """ - batch_size = cls_outputs[0].shape[0] - cls_outputs_all = torch.cat([ - cls_outputs[level].permute(0, 2, 3, 1).reshape([batch_size, -1, config.num_classes]) - for level in range(config.num_levels)], 1) - - box_outputs_all = torch.cat([ - box_outputs[level].permute(0, 2, 3, 1).reshape([batch_size, -1, 4]) - for level in range(config.num_levels)], 1) - - _, cls_topk_indices_all = torch.topk(cls_outputs_all.reshape(batch_size, -1), dim=1, k=MAX_DETECTION_POINTS) - indices_all = cls_topk_indices_all // config.num_classes - classes_all = cls_topk_indices_all % config.num_classes - - box_outputs_all_after_topk = torch.gather( - box_outputs_all, 1, indices_all.unsqueeze(2).expand(-1, -1, 4)) - - cls_outputs_all_after_topk = torch.gather( - cls_outputs_all, 1, indices_all.unsqueeze(2).expand(-1, -1, config.num_classes)) - cls_outputs_all_after_topk = torch.gather( - cls_outputs_all_after_topk, 2, classes_all.unsqueeze(2)) - - return cls_outputs_all_after_topk, box_outputs_all_after_topk, indices_all, classes_all - - -class DetBenchEval(nn.Module): - def __init__(self, model, config, nms_thres=0.5, max_dets=100): - super(DetBenchEval, self).__init__() - self.config = config - self.nms_thres = nms_thres - self.max_dets = max_dets - self.model = model - self.anchors = Anchors( - config.min_level, config.max_level, - config.num_scales, config.aspect_ratios, - config.anchor_scale, config.image_size) - - def forward(self, x, image_scales): - class_out, box_out = self.model(x) - class_out, box_out, indices, classes = _post_process(self.config, class_out, box_out) - - batch_detections = [] - # FIXME we may be able to do this as a batch with some tensor reshaping/indexing, PR welcome - for i in range(x.shape[0]): - detections = generate_detections( - class_out[i], box_out[i], self.anchors.boxes, indices[i], classes[i], image_scales[i], - nms_thres=self.nms_thres, max_dets=self.max_dets - ) - batch_detections.append(detections) - return torch.stack(batch_detections, dim=0) - - -class DetBenchTrain(nn.Module): - def __init__(self, model, config): - super(DetBenchTrain, self).__init__() - self.config = config - self.model = model - anchors = Anchors( - config.min_level, config.max_level, - config.num_scales, config.aspect_ratios, - config.anchor_scale, config.image_size) - self.anchor_labeler = AnchorLabeler(anchors, config.num_classes, match_threshold=0.5) - self.loss_fn = None - - def forward(self, x, gt_boxes, gt_labels): - class_out, box_out = self.model(x) - loss = None - gcl = [] - gbl = [] - total_positive = 0 - # FIXME the per-sample organization of reference code less than desirable, should change to batched - for i in range(x.shape[0]): - gt_class_out, gt_box_out, num_positive = self.anchor_labeler.label_anchors(gt_boxes[i], gt_labels[i]) - gcl.append(gt_class_out) - gbl.append(gt_box_out) - total_positive += num_positive - - # FIXME compute loss - - return loss diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/config/config.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/config/config.py deleted file mode 100755 index 29e7da5c3..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/config/config.py +++ /dev/null @@ -1,273 +0,0 @@ -"""EfficientDet Configurations - -Adapted from official impl at https://github.com/google/automl/tree/master/efficientdet - -TODO use a different config system, separate model from train specific hparams -""" - -import ast -import copy -import json -import six - - -def eval_str_fn(val): - if val in {'true', 'false'}: - return val == 'true' - try: - return ast.literal_eval(val) - except ValueError: - return val - - -# pylint: disable=protected-access -class Config(object): - """A config utility class.""" - - def __init__(self, config_dict=None): - self.update(config_dict) - - def __setattr__(self, k, v): - self.__dict__[k] = Config(v) if isinstance(v, dict) else copy.deepcopy(v) - - def __getattr__(self, k): - try: - return self.__dict__[k] - except KeyError: - raise AttributeError - - def __repr__(self): - return repr(self.as_dict()) - - def __str__(self): - try: - return json.dumps(self.as_dict(), indent=4) - except TypeError: - return str(self.as_dict()) - - def _update(self, config_dict, allow_new_keys=True): - """Recursively update internal members.""" - if not config_dict: - return - - for k, v in six.iteritems(config_dict): - if k not in self.__dict__.keys(): - if allow_new_keys: - self.__setattr__(k, v) - else: - raise KeyError('Key `{}` does not exist for overriding. '.format(k)) - else: - if isinstance(v, dict): - self.__dict__[k]._update(v, allow_new_keys) - else: - self.__dict__[k] = copy.deepcopy(v) - - def get(self, k, default_value=None): - return self.__dict__.get(k, default_value) - - def update(self, config_dict): - """Update members while allowing new keys.""" - self._update(config_dict, allow_new_keys=True) - - def override(self, config_dict_or_str): - """Update members while disallowing new keys.""" - if isinstance(config_dict_or_str, str): - config_dict = self.parse_from_str(config_dict_or_str) - elif isinstance(config_dict_or_str, dict): - config_dict = config_dict_or_str - else: - raise ValueError('Unknown value type: {}'.format(config_dict_or_str)) - - self._update(config_dict, allow_new_keys=False) - - def parse_from_str(self, config_str): - """parse from a string in format 'x=a,y=2' and return the dict.""" - if not config_str: - return {} - config_dict = {} - try: - for kv_pair in config_str.split(','): - if not kv_pair: # skip empty string - continue - k, v = kv_pair.split('=') - config_dict[k.strip()] = eval_str_fn(v.strip()) - return config_dict - except ValueError: - raise ValueError('Invalid config_str: {}'.format(config_str)) - - def as_dict(self): - """Returns a dict representation.""" - config_dict = {} - for k, v in six.iteritems(self.__dict__): - if isinstance(v, Config): - config_dict[k] = v.as_dict() - else: - config_dict[k] = copy.deepcopy(v) - return config_dict - - -def default_detection_configs(): - """Returns a default detection configs.""" - h = Config() - - # model name. - h.name = 'tf_efficientdet_d1' - - # input preprocessing parameters - h.image_size = 640 - h.input_rand_hflip = True - h.train_scale_min = 0.1 - h.train_scale_max = 2.0 - h.autoaugment_policy = None - - # dataset specific parameters - h.num_classes = 90 - h.skip_crowd_during_training = True - - # model architecture - h.min_level = 3 - h.max_level = 7 - h.num_levels = h.max_level - h.min_level + 1 - h.num_scales = 3 - h.aspect_ratios = [(1.0, 1.0), (1.4, 0.7), (0.7, 1.4)] - h.anchor_scale = 4.0 - h.pad_type = 'same' - - # is batchnorm training mode - h.is_training_bn = True - - # optimization - h.momentum = 0.9 - h.learning_rate = 0.08 - h.lr_warmup_init = 0.008 - h.lr_warmup_epoch = 1.0 - h.first_lr_drop_epoch = 200.0 - h.second_lr_drop_epoch = 250.0 - h.clip_gradients_norm = 10.0 - h.num_epochs = 300 - - # classification loss - h.alpha = 0.25 - h.gamma = 1.5 - - # localization loss - h.delta = 0.1 - h.box_loss_weight = 50.0 - - # regularization l2 loss. - h.weight_decay = 4e-5 - - # For detection. - h.box_class_repeats = 3 - h.fpn_cell_repeats = 3 - h.fpn_channels = 88 - h.separable_conv = True - h.apply_bn_for_resampling = True - h.conv_after_downsample = False - h.conv_bn_relu_pattern = False - h.use_native_resize_op = False - h.pooling_type = None - - # version. - h.fpn_name = None - h.fpn_config = None - - # No stochastic depth in default. - h.survival_prob = None # FIXME remove - h.drop_path_rate = 0. - - h.lr_decay_method = 'cosine' - h.moving_average_decay = 0.9998 - h.ckpt_var_scope = None - h.backbone_name = 'tf_efficientnet_b1' - h.backbone_config = None - - # RetinaNet. - h.resnet_depth = 50 - return h - - -efficientdet_model_param_dict = { - 'efficientdet_d0': - dict( - name='efficientdet_d0', - backbone_name='tf_efficientnet_b0', - image_size=512, - fpn_channels=64, - fpn_cell_repeats=3, - box_class_repeats=3, - ), - 'efficientdet_d1': - dict( - name='efficientdet_d1', - backbone_name='tf_efficientnet_b1', - image_size=640, - fpn_channels=88, - fpn_cell_repeats=4, - box_class_repeats=3, - ), - 'efficientdet_d2': - dict( - name='efficientdet_d2', - backbone_name='tf_efficientnet_b2', - image_size=768, - fpn_channels=112, - fpn_cell_repeats=5, - box_class_repeats=3, - ), - 'efficientdet_d3': - dict( - name='efficientdet_d3', - backbone_name='tf_efficientnet_b3', - image_size=896, - fpn_channels=160, - fpn_cell_repeats=6, - box_class_repeats=4, - ), - 'efficientdet_d4': - dict( - name='efficientdet_d4', - backbone_name='tf_efficientnet_b4', - image_size=1024, - fpn_channels=224, - fpn_cell_repeats=7, - box_class_repeats=4, - ), - 'efficientdet_d5': - dict( - name='efficientdet_d5', - backbone_name='tf_efficientnet_b5', - image_size=1280, - fpn_channels=288, - fpn_cell_repeats=7, - box_class_repeats=4, - ), - 'efficientdet_d6': - dict( - name='efficientdet_d6', - backbone_name='tf_efficientnet_b6', - image_size=1280, - fpn_channels=384, - fpn_cell_repeats=8, - box_class_repeats=5, - fpn_name='bifpn_sum', # Use unweighted sum for training stability. - ), - 'efficientdet_d7': - dict( - name='efficientdet_d7', - backbone_name='tf_efficientnet_b6', - image_size=1536, - fpn_channels=384, - fpn_cell_repeats=8, - box_class_repeats=5, - anchor_scale=5.0, - fpn_name='bifpn_sum', # Use unweighted sum for training stability. - ), -} - - -def get_efficientdet_config(model_name='efficientdet_d1'): - """Get the default config for EfficientDet based on model name.""" - h = default_detection_configs() - h.override(efficientdet_model_param_dict[model_name]) - return h diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/efficientdet.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/efficientdet.py deleted file mode 100755 index 8483607db..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/efficientdet.py +++ /dev/null @@ -1,416 +0,0 @@ -""" PyTorch EfficientDet model - -Based on official Tensorflow version at: https://github.com/google/automl/tree/master/efficientdet -Paper: https://arxiv.org/abs/1911.09070 - -Hacked together by Ross Wightman -""" -import torch -import torch.nn as nn -import logging -from collections import OrderedDict -from typing import List, Optional -from timm import create_model -from timm.models.layers import create_conv2d, drop_path, create_pool2d, Swish -from .config import config - - -_DEBUG = False - -_ACT_LAYER = Swish - - -class SequentialAppend(nn.Sequential): - def __init__(self, *args): - super(SequentialAppend, self).__init__(*args) - - def forward(self, x: List[torch.Tensor]): - for module in self: - x.append(module(x)) - return x - - -class SequentialAppendLast(nn.Sequential): - def __init__(self, *args): - super(SequentialAppendLast, self).__init__(*args) - - def forward(self, x: List[torch.Tensor]): - for module in self: - x.append(module(x[-1])) - return x - - -class ConvBnAct2d(nn.Module): - def __init__(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, padding='', bias=False, - norm_layer=nn.BatchNorm2d, norm_kwargs=None, act_layer=_ACT_LAYER): - super(ConvBnAct2d, self).__init__() - norm_kwargs = norm_kwargs or {} - self.conv = create_conv2d( - in_channels, out_channels, kernel_size, stride=stride, dilation=dilation, padding=padding, bias=bias) - self.bn = None if norm_layer is None else norm_layer(out_channels, **norm_kwargs) - self.act = None if act_layer is None else act_layer(inplace=True) - - def forward(self, x): - x = self.conv(x) - if self.bn is not None: - x = self.bn(x) - if self.act is not None: - x = self.act(x) - return x - - -class SeparableConv2d(nn.Module): - """ Separable Conv - """ - def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, dilation=1, padding='', bias=False, - channel_multiplier=1.0, pw_kernel_size=1, act_layer=_ACT_LAYER, - norm_layer=nn.BatchNorm2d, norm_kwargs=None): - super(SeparableConv2d, self).__init__() - norm_kwargs = norm_kwargs or {} - - self.conv_dw = create_conv2d( - in_channels, int(in_channels * channel_multiplier), kernel_size, - stride=stride, dilation=dilation, padding=padding, depthwise=True) - - self.conv_pw = create_conv2d( - int(in_channels * channel_multiplier), out_channels, pw_kernel_size, padding=padding, bias=bias) - - self.bn = None if norm_layer is None else norm_layer(out_channels, **norm_kwargs) - self.act = None if act_layer is None else act_layer(inplace=True) - - def forward(self, x): - x = self.conv_dw(x) - x = self.conv_pw(x) - if self.bn is not None: - x = self.bn(x) - if self.act is not None: - x = self.act(x) - return x - - -class ResampleFeatureMap(nn.Sequential): - - def __init__(self, in_channels, out_channels, reduction_ratio=1., pad_type='', pooling_type='max', - norm_layer=nn.BatchNorm2d, norm_kwargs=None, conv_after_downsample=False, apply_bn=False): - super(ResampleFeatureMap, self).__init__() - pooling_type = pooling_type or 'max' - self.in_channels = in_channels - self.out_channels = out_channels - self.reduction_ratio = reduction_ratio - self.conv_after_downsample = conv_after_downsample - - conv = None - if in_channels != out_channels: - conv = ConvBnAct2d( - in_channels, out_channels, kernel_size=1, padding=pad_type, - norm_layer=norm_layer if apply_bn else None, norm_kwargs=norm_kwargs, bias=True, act_layer=None) - - if reduction_ratio > 1: - stride_size = int(reduction_ratio) - if conv is not None and not self.conv_after_downsample: - self.add_module('conv', conv) - self.add_module( - 'downsample', - create_pool2d( - pooling_type, kernel_size=stride_size + 1, stride=stride_size, padding=pad_type)) - if conv is not None and self.conv_after_downsample: - self.add_module('conv', conv) - else: - if conv is not None: - self.add_module('conv', conv) - if reduction_ratio < 1: - scale = int(1 // reduction_ratio) - self.add_module('upsample', nn.UpsamplingNearest2d(scale_factor=scale)) - - # def forward(self, x): - # # here for debugging only - # assert x.shape[1] == self.in_channels - # if self.reduction_ratio > 1: - # if hasattr(self, 'conv') and not self.conv_after_downsample: - # x = self.conv(x) - # x = self.downsample(x) - # if hasattr(self, 'conv') and self.conv_after_downsample: - # x = self.conv(x) - # else: - # if hasattr(self, 'conv'): - # x = self.conv(x) - # if self.reduction_ratio < 1: - # x = self.upsample(x) - # return x - - -class FpnCombine(nn.Module): - def __init__(self, feature_info, fpn_config, fpn_channels, inputs_offsets, target_reduction, pad_type='', - pooling_type='max', norm_layer=nn.BatchNorm2d, norm_kwargs=None, - apply_bn_for_resampling=False, conv_after_downsample=False, weight_method='attn'): - super(FpnCombine, self).__init__() - self.inputs_offsets = inputs_offsets - self.weight_method = weight_method - - self.resample = nn.ModuleDict() - for idx, offset in enumerate(inputs_offsets): - in_channels = fpn_channels - if offset < len(feature_info): - in_channels = feature_info[offset]['num_chs'] - input_reduction = feature_info[offset]['reduction'] - else: - node_idx = offset - len(feature_info) - input_reduction = fpn_config.nodes[node_idx]['reduction'] - reduction_ratio = target_reduction / input_reduction - self.resample[str(offset)] = ResampleFeatureMap( - in_channels, fpn_channels, reduction_ratio=reduction_ratio, pad_type=pad_type, - pooling_type=pooling_type, norm_layer=norm_layer, norm_kwargs=norm_kwargs, - apply_bn=apply_bn_for_resampling, conv_after_downsample=conv_after_downsample) - - if weight_method == 'attn' or weight_method == 'fastattn': - # WSM - self.edge_weights = nn.Parameter(torch.ones(len(inputs_offsets)), requires_grad=True) - else: - self.edge_weights = None - - def forward(self, x): - dtype = x[0].dtype - nodes = [] - for offset in self.inputs_offsets: - input_node = x[offset] - input_node = self.resample[str(offset)](input_node) - nodes.append(input_node) - - if self.weight_method == 'attn': - normalized_weights = torch.softmax(self.edge_weights.type(dtype), dim=0) - x = torch.stack(nodes, dim=-1) * normalized_weights - elif self.weight_method == 'fastattn': - edge_weights = nn.functional.relu(self.edge_weights.type(dtype)) - weights_sum = torch.sum(edge_weights) - x = torch.stack( - [(nodes[i] * edge_weights[i]) / (weights_sum + 0.0001) for i in range(len(nodes))], dim=-1) - elif self.weight_method == 'sum': - x = torch.stack(nodes, dim=-1) - else: - raise ValueError('unknown weight_method {}'.format(self.weight_method)) - x = torch.sum(x, dim=-1) - return x - - -class BiFpnLayer(nn.Module): - def __init__(self, feature_info, fpn_config, fpn_channels, num_levels=5, pad_type='', - pooling_type='max', norm_layer=nn.BatchNorm2d, norm_kwargs=None, act_layer=_ACT_LAYER, - apply_bn_for_resampling=False, conv_after_downsample=True, conv_bn_relu_pattern=False, - separable_conv=True): - super(BiFpnLayer, self).__init__() - self.fpn_config = fpn_config - self.num_levels = num_levels - self.conv_bn_relu_pattern = False - - self.feature_info = [] - self.fnode = SequentialAppend() - for i, fnode_cfg in enumerate(fpn_config.nodes): - logging.debug('fnode {} : {}'.format(i, fnode_cfg)) - fnode_layers = OrderedDict() - - # combine features - reduction = fnode_cfg['reduction'] - fnode_layers['combine'] = FpnCombine( - feature_info, fpn_config, fpn_channels, fnode_cfg['inputs_offsets'], target_reduction=reduction, - pad_type=pad_type, pooling_type=pooling_type, norm_layer=norm_layer, norm_kwargs=norm_kwargs, - apply_bn_for_resampling=apply_bn_for_resampling, conv_after_downsample=conv_after_downsample, - weight_method=fpn_config.weight_method) - self.feature_info.append(dict(num_chs=fpn_channels, reduction=reduction)) - - # after combine ops - after_combine = OrderedDict() - if not conv_bn_relu_pattern: - after_combine['act'] = act_layer(inplace=True) - conv_bias = True - conv_act = None - else: - conv_bias = False - conv_act = act_layer - conv_kwargs = dict( - in_channels=fpn_channels, out_channels=fpn_channels, kernel_size=3, padding=pad_type, - bias=conv_bias, norm_layer=norm_layer, norm_kwargs=norm_kwargs, act_layer=conv_act) - after_combine['conv'] = SeparableConv2d(**conv_kwargs) if separable_conv else ConvBnAct2d(**conv_kwargs) - fnode_layers['after_combine'] = nn.Sequential(after_combine) - - self.fnode.add_module(str(i), nn.Sequential(fnode_layers)) - - self.feature_info = self.feature_info[-num_levels::] - - def forward(self, x): - x = self.fnode(x) - return x[-self.num_levels::] - - -def bifpn_sum_config(base_reduction=8): - """BiFPN config with sum.""" - p = config.Config() - p.nodes = [ - {'reduction': base_reduction << 3, 'inputs_offsets': [3, 4]}, - {'reduction': base_reduction << 2, 'inputs_offsets': [2, 5]}, - {'reduction': base_reduction << 1, 'inputs_offsets': [1, 6]}, - {'reduction': base_reduction, 'inputs_offsets': [0, 7]}, - {'reduction': base_reduction << 1, 'inputs_offsets': [1, 7, 8]}, - {'reduction': base_reduction << 2, 'inputs_offsets': [2, 6, 9]}, - {'reduction': base_reduction << 3, 'inputs_offsets': [3, 5, 10]}, - {'reduction': base_reduction << 4, 'inputs_offsets': [4, 11]}, - ] - p.weight_method = 'sum' - return p - - -def bifpn_attn_config(): - """BiFPN config with fast weighted sum.""" - p = bifpn_sum_config() - p.weight_method = 'attn' - return p - - -def bifpn_fa_config(): - """BiFPN config with fast weighted sum.""" - p = bifpn_sum_config() - p.weight_method = 'fastattn' - return p - - -def get_fpn_config(fpn_name): - if not fpn_name: - fpn_name = 'bifpn_fa' - name_to_config = { - 'bifpn_sum': bifpn_sum_config(), - 'bifpn_attn': bifpn_attn_config(), - 'bifpn_fa': bifpn_fa_config(), - } - return name_to_config[fpn_name] - - -class BiFpn(nn.Module): - - def __init__(self, config, feature_info, norm_layer=nn.BatchNorm2d, norm_kwargs=None, act_layer=_ACT_LAYER): - super(BiFpn, self).__init__() - self.config = config - fpn_config = config.fpn_config or get_fpn_config(config.fpn_name) - - self.resample = SequentialAppendLast() - for level in range(config.num_levels): - if level < len(feature_info): - in_chs = feature_info[level]['num_chs'] - reduction = feature_info[level]['reduction'] - else: - # Adds a coarser level by downsampling the last feature map - reduction_ratio = 2 - self.resample.add_module(str(level), ResampleFeatureMap( - in_channels=in_chs, - out_channels=config.fpn_channels, - pad_type=config.pad_type, - pooling_type=config.pooling_type, - norm_layer=norm_layer, - norm_kwargs=norm_kwargs, - reduction_ratio=reduction_ratio, - apply_bn=config.apply_bn_for_resampling, - conv_after_downsample=config.conv_after_downsample, - )) - in_chs = config.fpn_channels - reduction = int(reduction * reduction_ratio) - feature_info.append(dict(num_chs=in_chs, reduction=reduction)) - - self.cell = nn.Sequential() - for rep in range(config.fpn_cell_repeats): - logging.debug('building cell {}'.format(rep)) - fpn_layer = BiFpnLayer( - feature_info=feature_info, - fpn_config=fpn_config, - fpn_channels=config.fpn_channels, - num_levels=config.num_levels, - pad_type=config.pad_type, - pooling_type=config.pooling_type, - norm_layer=norm_layer, - norm_kwargs=norm_kwargs, - act_layer=act_layer, - separable_conv=config.separable_conv, - apply_bn_for_resampling=config.apply_bn_for_resampling, - conv_after_downsample=config.conv_after_downsample, - conv_bn_relu_pattern=config.conv_bn_relu_pattern - ) - self.cell.add_module(str(rep), fpn_layer) - feature_info = fpn_layer.feature_info - - # FIXME init weights for training - - def forward(self, x): - assert len(self.resample) == self.config.num_levels - len(x) - x = self.resample(x) - x = self.cell(x) - return x - - -class HeadNet(nn.Module): - def __init__(self, config, num_outputs, norm_layer=nn.BatchNorm2d, norm_kwargs=None, - act_layer=_ACT_LAYER, predict_bias_init=None): - super(HeadNet, self).__init__() - norm_kwargs = norm_kwargs or {} - self.config = config - num_anchors = len(config.aspect_ratios) * config.num_scales - - self.conv_rep = nn.ModuleList() - self.bn_rep = nn.ModuleList() - conv_kwargs = dict( - in_channels=config.fpn_channels, out_channels=config.fpn_channels, kernel_size=3, - padding=self.config.pad_type, bias=True, act_layer=None, norm_layer=None) - for i in range(config.box_class_repeats): - conv = SeparableConv2d(**conv_kwargs) if config.separable_conv else ConvBnAct2d(**conv_kwargs) - self.conv_rep.append(conv) - - bn_levels = [] - for _ in range(config.num_levels): - bn_seq = nn.Sequential() - bn_seq.add_module('bn', norm_layer(config.fpn_channels, **norm_kwargs)) - bn_levels.append(bn_seq) - self.bn_rep.append(nn.ModuleList(bn_levels)) - - self.act = act_layer(inplace=True) - - predict_kwargs = dict( - in_channels=config.fpn_channels, out_channels=num_outputs * num_anchors, kernel_size=3, - padding=self.config.pad_type, bias=True, norm_layer=None, act_layer=None) - if config.separable_conv: - self.predict = SeparableConv2d(**predict_kwargs) - else: - self.predict = ConvBnAct2d(**predict_kwargs) - - # FIXME init weights for training - - def forward(self, x): - outputs = [] - for level in range(self.config.num_levels): - x_level = x[level] - for i in range(self.config.box_class_repeats): - x_level_in = x_level - x_level = self.conv_rep[i](x_level) - x_level = self.bn_rep[i][level](x_level) - x_level = self.act(x_level) - if i > 0 and self.config.drop_path_rate: - x_level = drop_path(x_level, self.config.drop_path_rate, self.is_training) - x_level = x_level + x_level_in - outputs.append(self.predict(x_level)) - return outputs - - -class EfficientDet(nn.Module): - - def __init__(self, config, norm_kwargs=None): - super(EfficientDet, self).__init__() - norm_kwargs = norm_kwargs or dict(eps=.001) - self.backbone = create_model( - config.backbone_name, features_only=True, out_indices=(2, 3, 4)) - feature_info = [dict(num_chs=f['num_chs'], reduction=f['reduction']) - for i, f in enumerate(self.backbone.feature_info())] - self.fpn = BiFpn(config, feature_info, norm_kwargs=norm_kwargs) - self.class_net = HeadNet(config, num_outputs=config.num_classes, norm_kwargs=norm_kwargs) - self.box_net = HeadNet(config, num_outputs=4, norm_kwargs=norm_kwargs) - - def forward(self, x): - x = self.backbone(x) - x = self.fpn(x) - x_class = self.class_net(x) - x_box = self.box_net(x) - return x_class, x_box diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/helpers.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/helpers.py deleted file mode 100755 index c5a16ef63..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/helpers.py +++ /dev/null @@ -1,38 +0,0 @@ -import torch -import os -from collections import OrderedDict -try: - from torch.hub import load_state_dict_from_url -except ImportError: - from torch.utils.model_zoo import load_url as load_state_dict_from_url - - -def load_checkpoint(model, checkpoint_path): - if checkpoint_path and os.path.isfile(checkpoint_path): - print("=> Loading checkpoint '{}'".format(checkpoint_path)) - checkpoint = torch.load(checkpoint_path) - if isinstance(checkpoint, dict) and 'state_dict' in checkpoint: - new_state_dict = OrderedDict() - for k, v in checkpoint['state_dict'].items(): - if k.startswith('module'): - name = k[7:] # remove `module.` - else: - name = k - new_state_dict[name] = v - model.load_state_dict(new_state_dict) - else: - model.load_state_dict(checkpoint) - print("=> Loaded checkpoint '{}'".format(checkpoint_path)) - else: - print("=> Error: No checkpoint found at '{}'".format(checkpoint_path)) - raise FileNotFoundError() - - -def load_pretrained(model, url, filter_fn=None, strict=True): - if not url: - print("=> Warning: Pretrained model URL is empty, using random initialization.") - return - state_dict = load_state_dict_from_url(url, progress=False, map_location='cpu') - if filter_fn is not None: - state_dict = filter_fn(state_dict) - model.load_state_dict(state_dict, strict=strict) diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/README.md b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/README.md deleted file mode 100755 index c2ed39020..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Tensorflow Object Detection - -All of this code is adapted/ported/copied from https://github.com/google/automl/tree/552d0facd14f4fe9205a67fb13ecb5690a4d1c94/efficientdet/object_detection \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/__init__.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/__init__.py deleted file mode 100755 index 342543e17..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2020 Google Research. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -# Object detection data loaders and libraries are mostly based on RetinaNet: -# https://github.com/tensorflow/tpu/tree/master/models/official/retinanet diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/argmax_matcher.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/argmax_matcher.py deleted file mode 100755 index 511822172..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/argmax_matcher.py +++ /dev/null @@ -1,169 +0,0 @@ -# Copyright 2020 Google Research. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -"""Argmax matcher implementation. - -This class takes a similarity matrix and matches columns to rows based on the -maximum value per column. One can specify matched_thresholds and -to prevent columns from matching to rows (generally resulting in a negative -training example) and unmatched_theshold to ignore the match (generally -resulting in neither a positive or negative training example). - -This matcher is used in Fast(er)-RCNN. - -Note: matchers are used in TargetAssigners. There is a create_target_assigner -factory function for popular implementations. -""" -import torch -from torch.nn.functional import one_hot -from . import matcher - - -class ArgMaxMatcher(matcher.Matcher): - """Matcher based on highest value. - - This class computes matches from a similarity matrix. Each column is matched - to a single row. - - To support object detection target assignment this class enables setting both - matched_threshold (upper threshold) and unmatched_threshold (lower thresholds) - defining three categories of similarity which define whether examples are - positive, negative, or ignored: - (1) similarity >= matched_threshold: Highest similarity. Matched/Positive! - (2) matched_threshold > similarity >= unmatched_threshold: Medium similarity. - Depending on negatives_lower_than_unmatched, this is either - Unmatched/Negative OR Ignore. - (3) unmatched_threshold > similarity: Lowest similarity. Depending on flag - negatives_lower_than_unmatched, either Unmatched/Negative OR Ignore. - For ignored matches this class sets the values in the Match object to -2. - """ - - def __init__(self, - matched_threshold, - unmatched_threshold=None, - negatives_lower_than_unmatched=True, - force_match_for_each_row=False): - """Construct ArgMaxMatcher. - - Args: - matched_threshold: Threshold for positive matches. Positive if - sim >= matched_threshold, where sim is the maximum value of the - similarity matrix for a given column. Set to None for no threshold. - unmatched_threshold: Threshold for negative matches. Negative if - sim < unmatched_threshold. Defaults to matched_threshold - when set to None. - negatives_lower_than_unmatched: Boolean which defaults to True. If True - then negative matches are the ones below the unmatched_threshold, - whereas ignored matches are in between the matched and unmatched - threshold. If False, then negative matches are in between the matched - and unmatched threshold, and everything lower than unmatched is ignored. - force_match_for_each_row: If True, ensures that each row is matched to - at least one column (which is not guaranteed otherwise if the - matched_threshold is high). Defaults to False. See - argmax_matcher_test.testMatcherForceMatch() for an example. - - Raises: - ValueError: if unmatched_threshold is set but matched_threshold is not set - or if unmatched_threshold > matched_threshold. - """ - if (matched_threshold is None) and (unmatched_threshold is not None): - raise ValueError('Need to also define matched_threshold when unmatched_threshold is defined') - self._matched_threshold = matched_threshold - if unmatched_threshold is None: - self._unmatched_threshold = matched_threshold - else: - if unmatched_threshold > matched_threshold: - raise ValueError('unmatched_threshold needs to be smaller or equal to matched_threshold') - self._unmatched_threshold = unmatched_threshold - if not negatives_lower_than_unmatched: - if self._unmatched_threshold == self._matched_threshold: - raise ValueError('When negatives are in between matched and unmatched thresholds, these ' - 'cannot be of equal value. matched: %s, unmatched: %s', - self._matched_threshold, self._unmatched_threshold) - self._force_match_for_each_row = force_match_for_each_row - self._negatives_lower_than_unmatched = negatives_lower_than_unmatched - - def _match(self, similarity_matrix): - """Tries to match each column of the similarity matrix to a row. - - Args: - similarity_matrix: tensor of shape [N, M] representing any similarity metric. - - Returns: - Match object with corresponding matches for each of M columns. - """ - - def _match_when_rows_are_empty(): - """Performs matching when the rows of similarity matrix are empty. - - When the rows are empty, all detections are false positives. So we return - a tensor of -1's to indicate that the columns do not match to any rows. - - Returns: - matches: int32 tensor indicating the row each column matches to. - """ - return -1 * torch.ones(similarity_matrix.shape[1], dtype=torch.long) - - def _match_when_rows_are_non_empty(): - """Performs matching when the rows of similarity matrix are non empty. - - Returns: - matches: int32 tensor indicating the row each column matches to. - """ - # Matches for each column - matches = torch.argmax(similarity_matrix, 0) - - # Deal with matched and unmatched threshold - if self._matched_threshold is not None: - # Get logical indices of ignored and unmatched columns as tf.int64 - matched_vals = torch.max(similarity_matrix, 0)[0] - below_unmatched_threshold = self._unmatched_threshold > matched_vals - between_thresholds = (matched_vals >= self._unmatched_threshold) & \ - (self._matched_threshold > matched_vals) - - if self._negatives_lower_than_unmatched: - matches = self._set_values_using_indicator(matches, below_unmatched_threshold, -1) - matches = self._set_values_using_indicator(matches, between_thresholds, -2) - else: - matches = self._set_values_using_indicator(matches, below_unmatched_threshold, -2) - matches = self._set_values_using_indicator(matches, between_thresholds, -1) - - if self._force_match_for_each_row: - force_match_column_ids = torch.argmax(similarity_matrix, 1) - force_match_column_indicators = one_hot(force_match_column_ids, similarity_matrix.shape[1]) - force_match_row_ids = torch.argmax(force_match_column_indicators, 0) - force_match_column_mask = torch.max(force_match_column_indicators, 0)[0].bool() - final_matches = torch.where(force_match_column_mask, force_match_row_ids, matches) - return final_matches - else: - return matches - - if similarity_matrix.shape[0] == 0: - return _match_when_rows_are_empty() - else: - return _match_when_rows_are_non_empty() - - def _set_values_using_indicator(self, x, indicator, val): - """Set the indicated fields of x to val. - - Args: - x: tensor. - indicator: boolean with same shape as x. - val: scalar with value to set. - - Returns: - modified tensor. - """ - indicator = indicator.type(x.dtype) - return x * (1 - indicator) + val * indicator diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/box_coder.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/box_coder.py deleted file mode 100755 index 45fa54c4c..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/box_coder.py +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright 2020 Google Research. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -"""Base box coder. - -Box coders convert between coordinate frames, namely image-centric -(with (0,0) on the top left of image) and anchor-centric (with (0,0) being -defined by a specific anchor). - -Users of a BoxCoder can call two methods: - encode: which encodes a box with respect to a given anchor - (or rather, a tensor of boxes wrt a corresponding tensor of anchors) and - decode: which inverts this encoding with a decode operation. -In both cases, the arguments are assumed to be in 1-1 correspondence already; -it is not the job of a BoxCoder to perform matching. -""" -from abc import ABCMeta -from abc import abstractmethod -from abc import abstractproperty - -import torch - -# Box coder types. -FASTER_RCNN = 'faster_rcnn' -KEYPOINT = 'keypoint' -MEAN_STDDEV = 'mean_stddev' -SQUARE = 'square' - - -class BoxCoder(object): - """Abstract base class for box coder.""" - __metaclass__ = ABCMeta - - @abstractproperty - def code_size(self): - """Return the size of each code. - - This number is a constant and should agree with the output of the `encode` - op (e.g. if rel_codes is the output of self.encode(...), then it should have - shape [N, code_size()]). This abstractproperty should be overridden by - implementations. - - Returns: - an integer constant - """ - pass - - def encode(self, boxes, anchors): - """Encode a box list relative to an anchor collection. - - Args: - boxes: BoxList holding N boxes to be encoded - anchors: BoxList of N anchors - - Returns: - a tensor representing N relative-encoded boxes - """ - return self._encode(boxes, anchors) - - def decode(self, rel_codes, anchors): - """Decode boxes that are encoded relative to an anchor collection. - - Args: - rel_codes: a tensor representing N relative-encoded boxes - anchors: BoxList of anchors - - Returns: - boxlist: BoxList holding N boxes encoded in the ordinary way (i.e., - with corners y_min, x_min, y_max, x_max) - """ - return self._decode(rel_codes, anchors) - - @abstractmethod - def _encode(self, boxes, anchors): - """Method to be overridden by implementations. - - Args: - boxes: BoxList holding N boxes to be encoded - anchors: BoxList of N anchors - - Returns: - a tensor representing N relative-encoded boxes - """ - pass - - @abstractmethod - def _decode(self, rel_codes, anchors): - """Method to be overridden by implementations. - - Args: - rel_codes: a tensor representing N relative-encoded boxes - anchors: BoxList of anchors - - Returns: - boxlist: BoxList holding N boxes encoded in the ordinary way (i.e., - with corners y_min, x_min, y_max, x_max) - """ - pass - - -def batch_decode(encoded_boxes, box_coder, anchors): - """Decode a batch of encoded boxes. - - This op takes a batch of encoded bounding boxes and transforms - them to a batch of bounding boxes specified by their corners in - the order of [y_min, x_min, y_max, x_max]. - - Args: - encoded_boxes: a float32 tensor of shape [batch_size, num_anchors, - code_size] representing the location of the objects. - box_coder: a BoxCoder object. - anchors: a BoxList of anchors used to encode `encoded_boxes`. - - Returns: - decoded_boxes: a float32 tensor of shape [batch_size, num_anchors, coder_size] - representing the corners of the objects in the order of [y_min, x_min, y_max, x_max]. - - Raises: - ValueError: if batch sizes of the inputs are inconsistent, or if - the number of anchors inferred from encoded_boxes and anchors are inconsistent. - """ - assert len(encoded_boxes.shape) == 3 - if encoded_boxes.shape[1] != anchors.num_boxes(): - raise ValueError('The number of anchors inferred from encoded_boxes' - ' and anchors are inconsistent: shape[1] of encoded_boxes' - ' %s should be equal to the number of anchors: %s.' % - (encoded_boxes.shape[1], anchors.num_boxes())) - - decoded_boxes = torch.stack([ - box_coder.decode(boxes, anchors).boxes for boxes in encoded_boxes.unbind() - ]) - return decoded_boxes diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/box_list.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/box_list.py deleted file mode 100755 index d3d6e576c..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/box_list.py +++ /dev/null @@ -1,190 +0,0 @@ -# Copyright 2020 Google Research. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -"""Bounding Box List definition. - -BoxList represents a list of bounding boxes as tensorflow -tensors, where each bounding box is represented as a row of 4 numbers, -[y_min, x_min, y_max, x_max]. It is assumed that all bounding boxes -within a given list correspond to a single image. See also -box_list_ops.py for common box related operations (such as area, iou, etc). - -Optionally, users can add additional related fields (such as weights). -We assume the following things to be true about fields: -* they correspond to boxes in the box_list along the 0th dimension -* they have inferable rank at graph construction time -* all dimensions except for possibly the 0th can be inferred - (i.e., not None) at graph construction time. - -Some other notes: - * Following tensorflow conventions, we use height, width ordering, - and correspondingly, y,x (or ymin, xmin, ymax, xmax) ordering - * Tensors are always provided as (flat) [N, 4] tensors. -""" - -import torch - - -class BoxList(object): - """Box collection.""" - - def __init__(self, boxes): - """Constructs box collection. - - Args: - boxes: a tensor of shape [N, 4] representing box corners - - Raises: - ValueError: if invalid dimensions for bbox data or if bbox data is not in float32 format. - """ - if len(boxes.shape) != 2 or boxes.shape[-1] != 4: - raise ValueError('Invalid dimensions for box data.') - if boxes.dtype != torch.float32: - raise ValueError('Invalid tensor type: should be tf.float32') - self.data = {'boxes': boxes} - - def num_boxes(self): - """Returns number of boxes held in collection. - - Returns: - a tensor representing the number of boxes held in the collection. - """ - return self.data['boxes'].shape[0] - - def get_all_fields(self): - """Returns all fields.""" - return self.data.keys() - - def get_extra_fields(self): - """Returns all non-box fields (i.e., everything not named 'boxes').""" - return [k for k in self.data.keys() if k != 'boxes'] - - def add_field(self, field, field_data): - """Add field to box list. - - This method can be used to add related box data such as weights/labels, etc. - - Args: - field: a string key to access the data via `get` - field_data: a tensor containing the data to store in the BoxList - """ - self.data[field] = field_data - - def has_field(self, field): - return field in self.data - - @property - def boxes(self): - """Convenience function for accessing box coordinates. - - Returns: - a tensor with shape [N, 4] representing box coordinates. - """ - return self.get_field('boxes') - - @boxes.setter - def boxes(self, boxes): - """Convenience function for setting box coordinates. - - Args: - boxes: a tensor of shape [N, 4] representing box corners - - Raises: - ValueError: if invalid dimensions for bbox data - """ - if len(boxes.shape) != 2 or boxes.shape[-1] != 4: - raise ValueError('Invalid dimensions for box data.') - self.data['boxes'] = boxes - - def get_field(self, field): - """Accesses a box collection and associated fields. - - This function returns specified field with object; if no field is specified, - it returns the box coordinates. - - Args: - field: this optional string parameter can be used to specify a related field to be accessed. - - Returns: - a tensor representing the box collection or an associated field. - - Raises: - ValueError: if invalid field - """ - if not self.has_field(field): - raise ValueError('field ' + str(field) + ' does not exist') - return self.data[field] - - def set_field(self, field, value): - """Sets the value of a field. - - Updates the field of a box_list with a given value. - - Args: - field: (string) name of the field to set value. - value: the value to assign to the field. - - Raises: - ValueError: if the box_list does not have specified field. - """ - if not self.has_field(field): - raise ValueError('field %s does not exist' % field) - self.data[field] = value - - def get_center_coordinates_and_sizes(self): - """Computes the center coordinates, height and width of the boxes. - - Returns: - a list of 4 1-D tensors [ycenter, xcenter, height, width]. - """ - box_corners = self.boxes - ymin, xmin, ymax, xmax = box_corners.T.unbind() - width = xmax - xmin - height = ymax - ymin - ycenter = ymin + height / 2. - xcenter = xmin + width / 2. - return [ycenter, xcenter, height, width] - - def transpose_coordinates(self): - """Transpose the coordinate representation in a boxlist. - - """ - y_min, x_min, y_max, x_max = self.boxes.chunk(4, dim=1) - self.boxes = torch.cat([x_min, y_min, x_max, y_max], 1) - - def as_tensor_dict(self, fields=None): - """Retrieves specified fields as a dictionary of tensors. - - Args: - fields: (optional) list of fields to return in the dictionary. - If None (default), all fields are returned. - - Returns: - tensor_dict: A dictionary of tensors specified by fields. - - Raises: - ValueError: if specified field is not contained in boxlist. - """ - tensor_dict = {} - if fields is None: - fields = self.get_all_fields() - for field in fields: - if not self.has_field(field): - raise ValueError('boxlist must contain all specified fields') - tensor_dict[field] = self.get_field(field) - return tensor_dict - - @property - def device(self): - return self.data['boxes'].device diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/faster_rcnn_box_coder.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/faster_rcnn_box_coder.py deleted file mode 100755 index a9a6ca2bd..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/faster_rcnn_box_coder.py +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2020 Google Research. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -"""Faster RCNN box coder. - -Faster RCNN box coder follows the coding schema described below: - ty = (y - ya) / ha - tx = (x - xa) / wa - th = log(h / ha) - tw = log(w / wa) - where x, y, w, h denote the box's center coordinates, width and height - respectively. Similarly, xa, ya, wa, ha denote the anchor's center - coordinates, width and height. tx, ty, tw and th denote the anchor-encoded - center, width and height respectively. - - See http://arxiv.org/abs/1506.01497 for details. -""" - -import torch - -from . import box_coder -from . import box_list - -EPS = 1e-8 - - -class FasterRcnnBoxCoder(box_coder.BoxCoder): - """Faster RCNN box coder.""" - - def __init__(self, scale_factors=None): - """Constructor for FasterRcnnBoxCoder. - - Args: - scale_factors: List of 4 positive scalars to scale ty, tx, th and tw. - If set to None, does not perform scaling. For Faster RCNN, - the open-source implementation recommends using [10.0, 10.0, 5.0, 5.0]. - """ - if scale_factors: - assert len(scale_factors) == 4 - for scalar in scale_factors: - assert scalar > 0 - self._scale_factors = scale_factors - - @property - def code_size(self): - return 4 - - def _encode(self, boxes, anchors): - """Encode a box collection with respect to anchor collection. - - Args: - boxes: BoxList holding N boxes to be encoded. - anchors: BoxList of anchors. - - Returns: - a tensor representing N anchor-encoded boxes of the format [ty, tx, th, tw]. - """ - # Convert anchors to the center coordinate representation. - ycenter_a, xcenter_a, ha, wa = anchors.get_center_coordinates_and_sizes() - ycenter, xcenter, h, w = boxes.get_center_coordinates_and_sizes() - # Avoid NaN in division and log below. - ha += EPS - wa += EPS - h += EPS - w += EPS - - tx = (xcenter - xcenter_a) / wa - ty = (ycenter - ycenter_a) / ha - tw = torch.log(w / wa) - th = torch.log(h / ha) - # Scales location targets as used in paper for joint training. - if self._scale_factors: - ty *= self._scale_factors[0] - tx *= self._scale_factors[1] - th *= self._scale_factors[2] - tw *= self._scale_factors[3] - return torch.stack([ty, tx, th, tw]).T - - def _decode(self, rel_codes, anchors): - """Decode relative codes to boxes. - - Args: - rel_codes: a tensor representing N anchor-encoded boxes. - anchors: BoxList of anchors. - - Returns: - boxes: BoxList holding N bounding boxes. - """ - ycenter_a, xcenter_a, ha, wa = anchors.get_center_coordinates_and_sizes() - - ty, tx, th, tw = rel_codes.T.unbind() - if self._scale_factors: - ty /= self._scale_factors[0] - tx /= self._scale_factors[1] - th /= self._scale_factors[2] - tw /= self._scale_factors[3] - w = torch.exp(tw) * wa - h = torch.exp(th) * ha - ycenter = ty * ha + ycenter_a - xcenter = tx * wa + xcenter_a - ymin = ycenter - h / 2. - xmin = xcenter - w / 2. - ymax = ycenter + h / 2. - xmax = xcenter + w / 2. - return box_list.BoxList(torch.stack([ymin, xmin, ymax, xmax]).T) diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/matcher.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/matcher.py deleted file mode 100755 index 67a1702b0..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/matcher.py +++ /dev/null @@ -1,230 +0,0 @@ -# Copyright 2020 Google Research. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -"""Matcher interface and Match class. - -This module defines the Matcher interface and the Match object. The job of the -matcher is to match row and column indices based on the similarity matrix and -other optional parameters. Each column is matched to at most one row. There -are three possibilities for the matching: - -1) match: A column matches a row. -2) no_match: A column does not match any row. -3) ignore: A column that is neither 'match' nor no_match. - -The ignore case is regularly encountered in object detection: when an anchor has -a relatively small overlap with a ground-truth box, one neither wants to -consider this box a positive example (match) nor a negative example (no match). - -The Match class is used to store the match results and it provides simple apis -to query the results. -""" -from abc import ABCMeta -from abc import abstractmethod - -import torch - - -class Match(object): - """Class to store results from the matcher. - - This class is used to store the results from the matcher. It provides - convenient methods to query the matching results. - """ - - def __init__(self, match_results): - """Constructs a Match object. - - Args: - match_results: Integer tensor of shape [N] with (1) match_results[i]>=0, - meaning that column i is matched with row match_results[i]. - (2) match_results[i]=-1, meaning that column i is not matched. - (3) match_results[i]=-2, meaning that column i is ignored. - - Raises: - ValueError: if match_results does not have rank 1 or is not an integer int32 scalar tensor - """ - if len(match_results.shape) != 1: - raise ValueError('match_results should have rank 1') - if match_results.dtype not in (torch.int32, torch.int64): - raise ValueError('match_results should be an int32 or int64 scalar tensor') - self._match_results = match_results - - @property - def match_results(self): - """The accessor for match results. - - Returns: - the tensor which encodes the match results. - """ - return self._match_results - - def matched_column_indices(self): - """Returns column indices that match to some row. - - The indices returned by this op are always sorted in increasing order. - - Returns: - column_indices: int32 tensor of shape [K] with column indices. - """ - return self._reshape_and_cast(torch.where(self._match_results > -1)) - - def matched_column_indicator(self): - """Returns column indices that are matched. - - Returns: - column_indices: int32 tensor of shape [K] with column indices. - """ - return self._match_results >= 0 - - def num_matched_columns(self): - """Returns number (int32 scalar tensor) of matched columns.""" - return self.matched_column_indices() - - def unmatched_column_indices(self): - """Returns column indices that do not match any row. - - The indices returned by this op are always sorted in increasing order. - - Returns: - column_indices: int32 tensor of shape [K] with column indices. - """ - return self._reshape_and_cast(torch.where(self._match_results == -1)) - - def unmatched_column_indicator(self): - """Returns column indices that are unmatched. - - Returns: - column_indices: int32 tensor of shape [K] with column indices. - """ - return self._match_results == -1 - - def num_unmatched_columns(self): - """Returns number (int32 scalar tensor) of unmatched columns.""" - return self.unmatched_column_indices().numel() - - def ignored_column_indices(self): - """Returns column indices that are ignored (neither Matched nor Unmatched). - - The indices returned by this op are always sorted in increasing order. - - Returns: - column_indices: int32 tensor of shape [K] with column indices. - """ - return self._reshape_and_cast(torch.where(self.ignored_column_indicator())) - - def ignored_column_indicator(self): - """Returns boolean column indicator where True means the column is ignored. - - Returns: - column_indicator: boolean vector which is True for all ignored column indices. - """ - return self._match_results == -2 - - def num_ignored_columns(self): - """Returns number (int32 scalar tensor) of matched columns.""" - return self.ignored_column_indices().numel() - - def unmatched_or_ignored_column_indices(self): - """Returns column indices that are unmatched or ignored. - - The indices returned by this op are always sorted in increasing order. - - Returns: - column_indices: int32 tensor of shape [K] with column indices. - """ - return self._reshape_and_cast(torch.where(0 > self._match_results)) - - def matched_row_indices(self): - """Returns row indices that match some column. - - The indices returned by this op are ordered so as to be in correspondence with the output of - matched_column_indicator(). For example if self.matched_column_indicator() is [0,2], - and self.matched_row_indices() is [7, 3], then we know that column 0 was matched to row 7 and - column 2 was matched to row 3. - - Returns: - row_indices: int32 tensor of shape [K] with row indices. - """ - return self._reshape_and_cast(torch.gather(self._match_results, 0, self.matched_column_indices())) - - def _reshape_and_cast(self, t): - return torch.reshape(t, [-1]).long() - - def gather_based_on_match(self, input_tensor, unmatched_value, ignored_value): - """Gathers elements from `input_tensor` based on match results. - - For columns that are matched to a row, gathered_tensor[col] is set to input_tensor[match_results[col]]. - For columns that are unmatched, gathered_tensor[col] is set to unmatched_value. Finally, for columns that - are ignored gathered_tensor[col] is set to ignored_value. - - Note that the input_tensor.shape[1:] must match with unmatched_value.shape - and ignored_value.shape - - Args: - input_tensor: Tensor to gather values from. - unmatched_value: Constant tensor value for unmatched columns. - ignored_value: Constant tensor value for ignored columns. - - Returns: - gathered_tensor: A tensor containing values gathered from input_tensor. - The shape of the gathered tensor is [match_results.shape[0]] + input_tensor.shape[1:]. - """ - ss = torch.stack([ignored_value, unmatched_value]) - input_tensor = torch.cat([ss, input_tensor], dim=0) - gather_indices = torch.clamp(self.match_results + 2, min=0) - gathered_tensor = torch.index_select(input_tensor, 0, gather_indices) - return gathered_tensor - - -class Matcher(object): - """Abstract base class for matcher. - """ - __metaclass__ = ABCMeta - - def match(self, similarity_matrix, **params): - """Computes matches among row and column indices and returns the result. - - Computes matches among the row and column indices based on the similarity - matrix and optional arguments. - - Args: - similarity_matrix: Float tensor of shape [N, M] with pairwise similarity - where higher value means more similar. - scope: Op scope name. Defaults to 'Match' if None. - **params: Additional keyword arguments for specific implementations of - the Matcher. - - Returns: - A Match object with the results of matching. - """ - return Match(self._match(similarity_matrix, **params)) - - @abstractmethod - def _match(self, similarity_matrix, **params): - """Method to be overridden by implementations. - - Args: - similarity_matrix: Float tensor of shape [N, M] with pairwise similarity - where higher value means more similar. - **params: Additional keyword arguments for specific implementations of the Matcher. - - Returns: - match_results: Integer tensor of shape [M]: match_results[i]>=0 means - that column i is matched to row match_results[i], match_results[i]=-1 - means that the column is not matched. match_results[i]=-2 means that - the column is ignored (usually this happens when there is a very weak - match which one neither wants as positive nor negative example). - """ - pass diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/region_similarity_calculator.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/region_similarity_calculator.py deleted file mode 100755 index c4b85b1d2..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/region_similarity_calculator.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright 2020 Google Research. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -"""Region Similarity Calculators for BoxLists. - -Region Similarity Calculators compare a pairwise measure of similarity -between the boxes in two BoxLists. -""" -from abc import ABCMeta -from abc import abstractmethod - -import torch - - -def area(boxlist): - """Computes area of boxes. - - Args: - boxlist: BoxList holding N boxes - - Returns: - a tensor with shape [N] representing box areas. - """ - y_min, x_min, y_max, x_max = boxlist.boxes.chunk(4, dim=1) - out = (y_max - y_min).squeeze(1) * (x_max - x_min).squeeze(1) - return out - - -def intersection(boxlist1, boxlist2): - """Compute pairwise intersection areas between boxes. - - Args: - boxlist1: BoxList holding N boxes - boxlist2: BoxList holding M boxes - - Returns: - a tensor with shape [N, M] representing pairwise intersections - """ - y_min1, x_min1, y_max1, x_max1 = boxlist1.boxes.chunk(4, dim=1) - y_min2, x_min2, y_max2, x_max2 = boxlist2.boxes.chunk(4, dim=1) - all_pairs_min_ymax = torch.min(y_max1, y_max2.T) - all_pairs_max_ymin = torch.max(y_min1, y_min2.T) - intersect_heights = torch.clamp(all_pairs_min_ymax - all_pairs_max_ymin, min=0) - all_pairs_min_xmax = torch.min(x_max1, x_max2.T) - all_pairs_max_xmin = torch.max(x_min1, x_min2.T) - intersect_widths = torch.clamp(all_pairs_min_xmax - all_pairs_max_xmin, min=0) - return intersect_heights * intersect_widths - - -def iou(boxlist1, boxlist2): - """Computes pairwise intersection-over-union between box collections. - - Args: - boxlist1: BoxList holding N boxes - boxlist2: BoxList holding M boxes - - Returns: - a tensor with shape [N, M] representing pairwise iou scores. - """ - intersections = intersection(boxlist1, boxlist2) - areas1 = area(boxlist1) - areas2 = area(boxlist2) - unions = areas1.unsqueeze(1) + areas2.unsqueeze(0) - intersections - return torch.where(intersections == 0.0, torch.zeros_like(intersections), intersections / unions) - - -class RegionSimilarityCalculator(object): - """Abstract base class for region similarity calculator.""" - __metaclass__ = ABCMeta - - def compare(self, boxlist1, boxlist2): - """Computes matrix of pairwise similarity between BoxLists. - - This op (to be overridden) computes a measure of pairwise similarity between - the boxes in the given BoxLists. Higher values indicate more similarity. - - Note that this method simply measures similarity and does not explicitly - perform a matching. - - Args: - boxlist1: BoxList holding N boxes. - boxlist2: BoxList holding M boxes. - - Returns: - a (float32) tensor of shape [N, M] with pairwise similarity score. - """ - return self._compare(boxlist1, boxlist2) - - @abstractmethod - def _compare(self, boxlist1, boxlist2): - pass - - -class IouSimilarity(RegionSimilarityCalculator): - """Class to compute similarity based on Intersection over Union (IOU) metric. - - This class computes pairwise similarity between two BoxLists based on IOU. - """ - - def _compare(self, boxlist1, boxlist2): - """Compute pairwise IOU similarity between the two BoxLists. - - Args: - boxlist1: BoxList holding N boxes. - boxlist2: BoxList holding M boxes. - - Returns: - A tensor with shape [N, M] representing pairwise iou scores. - """ - return iou(boxlist1, boxlist2) diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/target_assigner.py b/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/target_assigner.py deleted file mode 100755 index 5af83179f..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/effdet/object_detection/target_assigner.py +++ /dev/null @@ -1,263 +0,0 @@ -# Copyright 2020 Google Research. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ============================================================================== -"""Base target assigner module. - -The job of a TargetAssigner is, for a given set of anchors (bounding boxes) and -groundtruth detections (bounding boxes), to assign classification and regression -targets to each anchor as well as weights to each anchor (specifying, e.g., -which anchors should not contribute to training loss). - -It assigns classification/regression targets by performing the following steps: -1) Computing pairwise similarity between anchors and groundtruth boxes using a - provided RegionSimilarity Calculator -2) Computing a matching based on the similarity matrix using a provided Matcher -3) Assigning regression targets based on the matching and a provided BoxCoder -4) Assigning classification targets based on the matching and groundtruth labels - -Note that TargetAssigners only operate on detections from a single -image at a time, so any logic for applying a TargetAssigner to multiple -images must be handled externally. -""" -import torch - -from . import box_list - -KEYPOINTS_FIELD_NAME = 'keypoints' - - -class TargetAssigner(object): - """Target assigner to compute classification and regression targets.""" - - def __init__(self, similarity_calc, matcher, box_coder, negative_class_weight=1.0, unmatched_cls_target=None): - """Construct Object Detection Target Assigner. - - Args: - similarity_calc: a RegionSimilarityCalculator - - matcher: Matcher used to match groundtruth to anchors. - - box_coder: BoxCoder used to encode matching groundtruth boxes with respect to anchors. - - negative_class_weight: classification weight to be associated to negative - anchors (default: 1.0). The weight must be in [0., 1.]. - - unmatched_cls_target: a float32 tensor with shape [d_1, d_2, ..., d_k] - which is consistent with the classification target for each - anchor (and can be empty for scalar targets). This shape must thus be - compatible with the groundtruth labels that are passed to the "assign" - function (which have shape [num_gt_boxes, d_1, d_2, ..., d_k]). - If set to None, unmatched_cls_target is set to be [0] for each anchor. - - Raises: - ValueError: if similarity_calc is not a RegionSimilarityCalculator or - if matcher is not a Matcher or if box_coder is not a BoxCoder - """ - self._similarity_calc = similarity_calc - self._matcher = matcher - self._box_coder = box_coder - self._negative_class_weight = negative_class_weight - self._unmatched_cls_target = unmatched_cls_target - - @property - def box_coder(self): - return self._box_coder - - def assign(self, anchors, groundtruth_boxes, groundtruth_labels=None, groundtruth_weights=None, **params): - """Assign classification and regression targets to each anchor. - - For a given set of anchors and groundtruth detections, match anchors - to groundtruth_boxes and assign classification and regression targets to - each anchor as well as weights based on the resulting match (specifying, - e.g., which anchors should not contribute to training loss). - - Anchors that are not matched to anything are given a classification target - of self._unmatched_cls_target which can be specified via the constructor. - - Args: - anchors: a BoxList representing N anchors - - groundtruth_boxes: a BoxList representing M groundtruth boxes - - groundtruth_labels: a tensor of shape [M, d_1, ... d_k] - with labels for each of the ground_truth boxes. The subshape - [d_1, ... d_k] can be empty (corresponding to scalar inputs). When set - to None, groundtruth_labels assumes a binary problem where all - ground_truth boxes get a positive label (of 1). - - groundtruth_weights: a float tensor of shape [M] indicating the weight to - assign to all anchors match to a particular groundtruth box. The weights - must be in [0., 1.]. If None, all weights are set to 1. - - **params: Additional keyword arguments for specific implementations of the Matcher. - - Returns: - cls_targets: a float32 tensor with shape [num_anchors, d_1, d_2 ... d_k], - where the subshape [d_1, ..., d_k] is compatible with groundtruth_labels - which has shape [num_gt_boxes, d_1, d_2, ... d_k]. - - cls_weights: a float32 tensor with shape [num_anchors] - - reg_targets: a float32 tensor with shape [num_anchors, box_code_dimension] - - reg_weights: a float32 tensor with shape [num_anchors] - - match: a matcher.Match object encoding the match between anchors and groundtruth boxes, - with rows corresponding to groundtruth boxes and columns corresponding to anchors. - - Raises: - ValueError: if anchors or groundtruth_boxes are not of type box_list.BoxList - """ - if not isinstance(anchors, box_list.BoxList): - raise ValueError('anchors must be an BoxList') - if not isinstance(groundtruth_boxes, box_list.BoxList): - raise ValueError('groundtruth_boxes must be an BoxList') - - device = anchors.device - - if groundtruth_labels is None: - groundtruth_labels = torch.ones(groundtruth_boxes.num_boxes(), device=device).unsqueeze(0) - groundtruth_labels = groundtruth_labels.unsqueeze(-1) - - if groundtruth_weights is None: - num_gt_boxes = groundtruth_boxes.num_boxes() - if not num_gt_boxes: - num_gt_boxes = groundtruth_boxes.num_boxes() - groundtruth_weights = torch.ones([num_gt_boxes], device=device) - - match_quality_matrix = self._similarity_calc.compare(groundtruth_boxes, anchors) - match = self._matcher.match(match_quality_matrix, **params) - reg_targets = self._create_regression_targets(anchors, groundtruth_boxes, match) - cls_targets = self._create_classification_targets(groundtruth_labels, match) - reg_weights = self._create_regression_weights(match, groundtruth_weights) - cls_weights = self._create_classification_weights(match, groundtruth_weights) - - return cls_targets, cls_weights, reg_targets, reg_weights, match - - def _create_regression_targets(self, anchors, groundtruth_boxes, match): - """Returns a regression target for each anchor. - - Args: - anchors: a BoxList representing N anchors - - groundtruth_boxes: a BoxList representing M groundtruth_boxes - - match: a matcher.Match object - - Returns: - reg_targets: a float32 tensor with shape [N, box_code_dimension] - """ - device = anchors.device - zero_box = torch.zeros(4, device=device) - matched_gt_boxes = match.gather_based_on_match( - groundtruth_boxes.boxes, unmatched_value=zero_box, ignored_value=zero_box) - matched_gt_boxlist = box_list.BoxList(matched_gt_boxes) - if groundtruth_boxes.has_field(KEYPOINTS_FIELD_NAME): - groundtruth_keypoints = groundtruth_boxes.get_field(KEYPOINTS_FIELD_NAME) - zero_kp = torch.zeros(groundtruth_keypoints.shape[1:], device=device) - matched_keypoints = match.gather_based_on_match( - groundtruth_keypoints, unmatched_value=zero_kp, ignored_value=zero_kp) - matched_gt_boxlist.add_field(KEYPOINTS_FIELD_NAME, matched_keypoints) - matched_reg_targets = self._box_coder.encode(matched_gt_boxlist, anchors) - - unmatched_ignored_reg_targets = self._default_regression_target(device).repeat(match.match_results.shape[0], 1) - - matched_anchors_mask = match.matched_column_indicator() - reg_targets = torch.where(matched_anchors_mask.unsqueeze(1), matched_reg_targets, unmatched_ignored_reg_targets) - return reg_targets - - def _default_regression_target(self, device): - """Returns the default target for anchors to regress to. - - Default regression targets are set to zero (though in this implementation what - these targets are set to should not matter as the regression weight of any box - set to regress to the default target is zero). - - Returns: - default_target: a float32 tensor with shape [1, box_code_dimension] - """ - return torch.zeros(1, self._box_coder.code_size, device=device) - - def _create_classification_targets(self, groundtruth_labels, match): - """Create classification targets for each anchor. - - Assign a classification target of for each anchor to the matching - groundtruth label that is provided by match. Anchors that are not matched - to anything are given the target self._unmatched_cls_target - - Args: - groundtruth_labels: a tensor of shape [num_gt_boxes, d_1, ... d_k] - with labels for each of the ground_truth boxes. The subshape - [d_1, ... d_k] can be empty (corresponding to scalar labels). - match: a matcher.Match object that provides a matching between anchors - and groundtruth boxes. - - Returns: - a float32 tensor with shape [num_anchors, d_1, d_2 ... d_k], where the - subshape [d_1, ..., d_k] is compatible with groundtruth_labels which has - shape [num_gt_boxes, d_1, d_2, ... d_k]. - """ - if self._unmatched_cls_target is not None: - uct = self._unmatched_cls_target - else: - uct = torch.scalar_tensor(0, device=groundtruth_labels.device) - return match.gather_based_on_match(groundtruth_labels, unmatched_value=uct, ignored_value=uct) - - def _create_regression_weights(self, match, groundtruth_weights): - """Set regression weight for each anchor. - - Only positive anchors are set to contribute to the regression loss, so this - method returns a weight of 1 for every positive anchor and 0 for every - negative anchor. - - Args: - match: a matcher.Match object that provides a matching between anchors and groundtruth boxes. - groundtruth_weights: a float tensor of shape [M] indicating the weight to - assign to all anchors match to a particular groundtruth box. - - Returns: - a float32 tensor with shape [num_anchors] representing regression weights. - """ - zs = torch.scalar_tensor(0, device=groundtruth_weights.device) - return match.gather_based_on_match(groundtruth_weights, ignored_value=zs, unmatched_value=zs) - - def _create_classification_weights(self, match, groundtruth_weights): - """Create classification weights for each anchor. - - Positive (matched) anchors are associated with a weight of - positive_class_weight and negative (unmatched) anchors are associated with - a weight of negative_class_weight. When anchors are ignored, weights are set - to zero. By default, both positive/negative weights are set to 1.0, - but they can be adjusted to handle class imbalance (which is almost always - the case in object detection). - - Args: - match: a matcher.Match object that provides a matching between anchors and groundtruth boxes. - groundtruth_weights: a float tensor of shape [M] indicating the weight to - assign to all anchors match to a particular groundtruth box. - - Returns: - a float32 tensor with shape [num_anchors] representing classification weights. - """ - ignored = torch.scalar_tensor(0, device=groundtruth_weights.device) - ncw = torch.scalar_tensor(self._negative_class_weight, device=groundtruth_weights.device) - return match.gather_based_on_match(groundtruth_weights, ignored_value=ignored, unmatched_value=ncw) - - def get_box_coder(self): - """Get BoxCoder of this TargetAssigner. - - Returns: - BoxCoder object. - """ - return self._box_coder diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/utils.py b/cv/pose/alphapose/pytorch/detector/efficientdet/utils.py deleted file mode 100755 index 88a617dc6..000000000 --- a/cv/pose/alphapose/pytorch/detector/efficientdet/utils.py +++ /dev/null @@ -1,129 +0,0 @@ -import os -import cv2 -import numpy as np -import torch - -class AverageMeter: - """Computes and stores the average and current value""" - def __init__(self): - self.reset() - - def reset(self): - self.val = 0 - self.avg = 0 - self.sum = 0 - self.count = 0 - - def update(self, val, n=1): - self.val = val - self.sum += val * n - self.count += n - self.avg = self.sum / self.count - - -def get_outdir(path, *paths, inc=False): - outdir = os.path.join(path, *paths) - if not os.path.exists(outdir): - os.makedirs(outdir) - elif inc: - count = 1 - outdir_inc = outdir + '-' + str(count) - while os.path.exists(outdir_inc): - count = count + 1 - outdir_inc = outdir + '-' + str(count) - assert count < 100 - outdir = outdir_inc - os.makedirs(outdir) - return outdir - -def unique(tensor): - tensor_np = tensor.cpu().numpy() - unique_np = np.unique(tensor_np) - unique_tensor = torch.from_numpy(unique_np) - - tensor_res = tensor.new(unique_tensor.shape) - tensor_res.copy_(unique_tensor) - return tensor_res - - -def letterbox_image(img, inp_dim): - '''resize image with unchanged aspect ratio using padding''' - img_w, img_h = img.shape[1], img.shape[0] - w, h = inp_dim - new_w = int(img_w * min(w / img_w, h / img_h)) - new_h = int(img_h * min(w / img_w, h / img_h)) - resized_image = cv2.resize(img, (new_w, new_h))#default is INTER_LINEAR, interpolation=cv2.INTER_CUBIC) - - canvas = np.full((inp_dim[1], inp_dim[0], 3), 0) - - canvas[0:new_h, 0:new_w, :] = resized_image - - return canvas - -def prep_image(img, inp_dim): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = cv2.imread(img) - dim = orig_im.shape[1], orig_im.shape[0] - img = (letterbox_image(orig_im, (inp_dim, inp_dim))) - img_ = img[:, :, ::-1].transpose((2, 0, 1)).copy() - img_ = torch.from_numpy(img_).float().unsqueeze(0) - - mean = torch.tensor([x for x in (0.485, 0.456, 0.406)]).float().view(1, 3, 1, 1) - std = torch.tensor([x for x in (0.229, 0.224, 0.225)]).float().view(1, 3, 1, 1) - img_ = img_.div_(255).sub_(mean).div_(std) - - return img_, orig_im, dim - - -def prep_frame(img, inp_dim): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = img - dim = orig_im.shape[1], orig_im.shape[0] - img = (letterbox_image(orig_im, (inp_dim, inp_dim))) - img_ = img[:, :, ::-1].transpose((2, 0, 1)).copy() - img_ = torch.from_numpy(img_).float().unsqueeze(0) - - mean = torch.tensor([x for x in (0.485, 0.456, 0.406)]).float().view(1, 3, 1, 1) - std = torch.tensor([x for x in (0.229, 0.224, 0.225)]).float().view(1, 3, 1, 1) - img_ = img_.div_(255).sub_(mean).div_(std) - - return img_, orig_im, dim - -def bbox_iou(box1, box2, args=None): - """ - Returns the IoU of two bounding boxes - - - """ - #Get the coordinates of bounding boxes - b1_x1, b1_y1, b1_x2, b1_y2 = box1[:,0], box1[:,1], box1[:,2], box1[:,3] - b2_x1, b2_y1, b2_x2, b2_y2 = box2[:,0], box2[:,1], box2[:,2], box2[:,3] - - #get the corrdinates of the intersection rectangle - inter_rect_x1 = torch.max(b1_x1, b2_x1) - inter_rect_y1 = torch.max(b1_y1, b2_y1) - inter_rect_x2 = torch.min(b1_x2, b2_x2) - inter_rect_y2 = torch.min(b1_y2, b2_y2) - - #Intersection area - if not args: - inter_area = torch.max(inter_rect_x2 - inter_rect_x1 + 1,torch.zeros(inter_rect_x2.shape).cuda())*torch.max(inter_rect_y2 - inter_rect_y1 + 1, torch.zeros(inter_rect_x2.shape).cuda()) - else: - inter_area = torch.max(inter_rect_x2 - inter_rect_x1 + 1,torch.zeros(inter_rect_x2.shape).to(args.device))*torch.max(inter_rect_y2 - inter_rect_y1 + 1, torch.zeros(inter_rect_x2.shape).to(args.device)) - #Union Area - b1_area = (b1_x2 - b1_x1 + 1)*(b1_y2 - b1_y1 + 1) - b2_area = (b2_x2 - b2_x1 + 1)*(b2_y2 - b2_y1 + 1) - - iou = inter_area / (b1_area + b2_area - inter_area) - - return iou diff --git a/cv/pose/alphapose/pytorch/detector/efficientdet/weights/get_models.sh b/cv/pose/alphapose/pytorch/detector/efficientdet/weights/get_models.sh deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/nms/__init__.py b/cv/pose/alphapose/pytorch/detector/nms/__init__.py deleted file mode 100755 index 6cd746a7f..000000000 --- a/cv/pose/alphapose/pytorch/detector/nms/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# from .nms_wrapper import nms, soft_nms -from torchvision.ops import nms -soft_nms = nms - -__all__ = ['nms', 'soft_nms'] diff --git a/cv/pose/alphapose/pytorch/detector/nms/nms_wrapper.py b/cv/pose/alphapose/pytorch/detector/nms/nms_wrapper.py deleted file mode 100755 index 835389e49..000000000 --- a/cv/pose/alphapose/pytorch/detector/nms/nms_wrapper.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -import numpy as np -import torch - -from . import nms_cpu, nms_cuda -from .soft_nms_cpu import soft_nms_cpu - - -def nms(dets, iou_thr, device_id=None): - """Dispatch to either CPU or GPU NMS implementations. - - The input can be either a torch tensor or numpy array. GPU NMS will be used - if the input is a gpu tensor or device_id is specified, otherwise CPU NMS - will be used. The returned type will always be the same as inputs. - - Arguments: - dets (torch.Tensor or np.ndarray): bboxes with scores. - iou_thr (float): IoU threshold for NMS. - device_id (int, optional): when `dets` is a numpy array, if `device_id` - is None, then cpu nms is used, otherwise gpu_nms will be used. - - Returns: - tuple: kept bboxes and indice, which is always the same data type as - the input. - """ - # convert dets (tensor or numpy array) to tensor - if isinstance(dets, torch.Tensor): - is_numpy = False - dets_th = dets.to('cpu') - elif isinstance(dets, np.ndarray): - is_numpy = True - device = 'cpu' if device_id is None else 'cuda:{}'.format(device_id) - dets_th = torch.from_numpy(dets).to(device) - else: - raise TypeError( - 'dets must be either a Tensor or numpy array, but got {}'.format( - type(dets))) - - # execute cpu or cuda nms - if dets_th.shape[0] == 0: - inds = dets_th.new_zeros(0, dtype=torch.long) - else: - if dets_th.is_cuda: - inds = nms_cuda.nms(dets_th, iou_thr) - else: - inds = nms_cpu.nms(dets_th, iou_thr) - - if is_numpy: - inds = inds.cpu().numpy() - return dets[inds, :], inds - - -def soft_nms(dets, iou_thr, method='linear', sigma=0.5, min_score=1e-3): - if isinstance(dets, torch.Tensor): - is_tensor = True - dets_np = dets.detach().cpu().numpy() - elif isinstance(dets, np.ndarray): - is_tensor = False - dets_np = dets - else: - raise TypeError( - 'dets must be either a Tensor or numpy array, but got {}'.format( - type(dets))) - - method_codes = {'linear': 1, 'gaussian': 2} - if method not in method_codes: - raise ValueError('Invalid method for SoftNMS: {}'.format(method)) - new_dets, inds = soft_nms_cpu( - dets_np, - iou_thr, - method=method_codes[method], - sigma=sigma, - min_score=min_score) - - if is_tensor: - return dets.new_tensor(new_dets), dets.new_tensor( - inds, dtype=torch.long) - else: - return new_dets.astype(np.float32), inds.astype(np.int64) diff --git a/cv/pose/alphapose/pytorch/detector/nms/src/nms_cpu.cpp b/cv/pose/alphapose/pytorch/detector/nms/src/nms_cpu.cpp deleted file mode 100755 index dfc439372..000000000 --- a/cv/pose/alphapose/pytorch/detector/nms/src/nms_cpu.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -// Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -// All Rights Reserved. -#include - -template -at::Tensor nms_cpu_kernel(const at::Tensor& dets, const float threshold) { - AT_ASSERTM(!dets.type().is_cuda(), "dets must be a CPU tensor"); - - if (dets.numel() == 0) { - return at::empty({0}, dets.options().dtype(at::kLong).device(at::kCPU)); - } - - auto x1_t = dets.select(1, 0).contiguous(); - auto y1_t = dets.select(1, 1).contiguous(); - auto x2_t = dets.select(1, 2).contiguous(); - auto y2_t = dets.select(1, 3).contiguous(); - auto scores = dets.select(1, 4).contiguous(); - - at::Tensor areas_t = (x2_t - x1_t + 1) * (y2_t - y1_t + 1); - - auto order_t = std::get<1>(scores.sort(0, /* descending=*/true)); - - auto ndets = dets.size(0); - at::Tensor suppressed_t = - at::zeros({ndets}, dets.options().dtype(at::kByte).device(at::kCPU)); - - auto suppressed = suppressed_t.data(); - auto order = order_t.data(); - auto x1 = x1_t.data(); - auto y1 = y1_t.data(); - auto x2 = x2_t.data(); - auto y2 = y2_t.data(); - auto areas = areas_t.data(); - - for (int64_t _i = 0; _i < ndets; _i++) { - auto i = order[_i]; - if (suppressed[i] == 1) continue; - auto ix1 = x1[i]; - auto iy1 = y1[i]; - auto ix2 = x2[i]; - auto iy2 = y2[i]; - auto iarea = areas[i]; - - for (int64_t _j = _i + 1; _j < ndets; _j++) { - auto j = order[_j]; - if (suppressed[j] == 1) continue; - auto xx1 = std::max(ix1, x1[j]); - auto yy1 = std::max(iy1, y1[j]); - auto xx2 = std::min(ix2, x2[j]); - auto yy2 = std::min(iy2, y2[j]); - - auto w = std::max(static_cast(0), xx2 - xx1 + 1); - auto h = std::max(static_cast(0), yy2 - yy1 + 1); - auto inter = w * h; - auto ovr = inter / (iarea + areas[j] - inter); - if (ovr >= threshold) suppressed[j] = 1; - } - } - return at::nonzero(suppressed_t == 0).squeeze(1); -} - -at::Tensor nms(const at::Tensor& dets, const float threshold) { - at::Tensor result; - AT_DISPATCH_FLOATING_TYPES(dets.scalar_type(), "nms", [&] { - result = nms_cpu_kernel(dets, threshold); - }); - return result; -} - -PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { - m.def("nms", &nms, "non-maximum suppression"); -} \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/nms/src/nms_cuda.cpp b/cv/pose/alphapose/pytorch/detector/nms/src/nms_cuda.cpp deleted file mode 100755 index 4e40726be..000000000 --- a/cv/pose/alphapose/pytorch/detector/nms/src/nms_cuda.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -// Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -// All Rights Reserved. -#include - -#define CHECK_CUDA(x) AT_CHECK(x.type().is_cuda(), #x, " must be a CUDAtensor ") - -at::Tensor nms_cuda(const at::Tensor boxes, float nms_overlap_thresh); - -at::Tensor nms(const at::Tensor& dets, const float threshold) { - CHECK_CUDA(dets); - if (dets.numel() == 0) - return at::empty({0}, dets.options().dtype(at::kLong).device(at::kCPU)); - return nms_cuda(dets, threshold); -} - -PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { - m.def("nms", &nms, "non-maximum suppression"); -} \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/nms/src/nms_kernel.cu b/cv/pose/alphapose/pytorch/detector/nms/src/nms_kernel.cu deleted file mode 100755 index e61296100..000000000 --- a/cv/pose/alphapose/pytorch/detector/nms/src/nms_kernel.cu +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -// Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -// All Rights Reserved. -#include -#include - -#include -#include - -#include -#include - -int const threadsPerBlock = sizeof(unsigned long long) * 8; - -__device__ inline float devIoU(float const * const a, float const * const b) { - float left = max(a[0], b[0]), right = min(a[2], b[2]); - float top = max(a[1], b[1]), bottom = min(a[3], b[3]); - float width = max(right - left + 1, 0.f), height = max(bottom - top + 1, 0.f); - float interS = width * height; - float Sa = (a[2] - a[0] + 1) * (a[3] - a[1] + 1); - float Sb = (b[2] - b[0] + 1) * (b[3] - b[1] + 1); - return interS / (Sa + Sb - interS); -} - -__global__ void nms_kernel(const int n_boxes, const float nms_overlap_thresh, - const float *dev_boxes, unsigned long long *dev_mask) { - const int row_start = blockIdx.y; - const int col_start = blockIdx.x; - - // if (row_start > col_start) return; - - const int row_size = - min(n_boxes - row_start * threadsPerBlock, threadsPerBlock); - const int col_size = - min(n_boxes - col_start * threadsPerBlock, threadsPerBlock); - - __shared__ float block_boxes[threadsPerBlock * 5]; - if (threadIdx.x < col_size) { - block_boxes[threadIdx.x * 5 + 0] = - dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 0]; - block_boxes[threadIdx.x * 5 + 1] = - dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 1]; - block_boxes[threadIdx.x * 5 + 2] = - dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 2]; - block_boxes[threadIdx.x * 5 + 3] = - dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 3]; - block_boxes[threadIdx.x * 5 + 4] = - dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 4]; - } - __syncthreads(); - - if (threadIdx.x < row_size) { - const int cur_box_idx = threadsPerBlock * row_start + threadIdx.x; - const float *cur_box = dev_boxes + cur_box_idx * 5; - int i = 0; - unsigned long long t = 0; - int start = 0; - if (row_start == col_start) { - start = threadIdx.x + 1; - } - for (i = start; i < col_size; i++) { - if (devIoU(cur_box, block_boxes + i * 5) > nms_overlap_thresh) { - t |= 1ULL << i; - } - } - const int col_blocks = THCCeilDiv(n_boxes, threadsPerBlock); - dev_mask[cur_box_idx * col_blocks + col_start] = t; - } -} - -// boxes is a N x 5 tensor -at::Tensor nms_cuda(const at::Tensor boxes, float nms_overlap_thresh) { - using scalar_t = float; - AT_ASSERTM(boxes.type().is_cuda(), "boxes must be a CUDA tensor"); - auto scores = boxes.select(1, 4); - auto order_t = std::get<1>(scores.sort(0, /* descending=*/true)); - auto boxes_sorted = boxes.index_select(0, order_t); - - int boxes_num = boxes.size(0); - - const int col_blocks = THCCeilDiv(boxes_num, threadsPerBlock); - - scalar_t* boxes_dev = boxes_sorted.data(); - - THCState *state = at::globalContext().lazyInitCUDA(); // TODO replace with getTHCState - - unsigned long long* mask_dev = NULL; - //THCudaCheck(THCudaMalloc(state, (void**) &mask_dev, - // boxes_num * col_blocks * sizeof(unsigned long long))); - - mask_dev = (unsigned long long*) THCudaMalloc(state, boxes_num * col_blocks * sizeof(unsigned long long)); - - dim3 blocks(THCCeilDiv(boxes_num, threadsPerBlock), - THCCeilDiv(boxes_num, threadsPerBlock)); - dim3 threads(threadsPerBlock); - nms_kernel<<>>(boxes_num, - nms_overlap_thresh, - boxes_dev, - mask_dev); - - std::vector mask_host(boxes_num * col_blocks); - THCudaCheck(cudaMemcpy(&mask_host[0], - mask_dev, - sizeof(unsigned long long) * boxes_num * col_blocks, - cudaMemcpyDeviceToHost)); - - std::vector remv(col_blocks); - memset(&remv[0], 0, sizeof(unsigned long long) * col_blocks); - - at::Tensor keep = at::empty({boxes_num}, boxes.options().dtype(at::kLong).device(at::kCPU)); - int64_t* keep_out = keep.data(); - - int num_to_keep = 0; - for (int i = 0; i < boxes_num; i++) { - int nblock = i / threadsPerBlock; - int inblock = i % threadsPerBlock; - - if (!(remv[nblock] & (1ULL << inblock))) { - keep_out[num_to_keep++] = i; - unsigned long long *p = &mask_host[0] + i * col_blocks; - for (int j = nblock; j < col_blocks; j++) { - remv[j] |= p[j]; - } - } - } - - THCudaFree(state, mask_dev); - // TODO improve this part - return std::get<0>(order_t.index({ - keep.narrow(/*dim=*/0, /*start=*/0, /*length=*/num_to_keep).to( - order_t.device(), keep.scalar_type()) - }).sort(0, false)); -} \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/nms/src/soft_nms_cpu.cpp b/cv/pose/alphapose/pytorch/detector/nms/src/soft_nms_cpu.cpp deleted file mode 100755 index b6252a187..000000000 --- a/cv/pose/alphapose/pytorch/detector/nms/src/soft_nms_cpu.cpp +++ /dev/null @@ -1,10325 +0,0 @@ -/* Generated by Cython 0.29.13 */ - -/* BEGIN: Cython Metadata -{ - "distutils": { - "depends": [ - "/home/jeff/anaconda3/envs/alphapose/lib/python3.6/site-packages/numpy/core/include/numpy/arrayobject.h", - "/home/jeff/anaconda3/envs/alphapose/lib/python3.6/site-packages/numpy/core/include/numpy/ufuncobject.h" - ], - "extra_compile_args": { - "cxx": [ - "-Wno-unused-function", - "-Wno-write-strings" - ] - }, - "include_dirs": [ - "/home/jeff/anaconda3/envs/alphapose/lib/python3.6/site-packages/numpy/core/include" - ], - "language": "c++", - "name": "detector.nms.soft_nms_cpu", - "sources": [ - "detector/nms/src/soft_nms_cpu.pyx" - ] - }, - "module_name": "detector.nms.soft_nms_cpu" -} -END: Cython Metadata */ -// Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -// All Rights Reserved. - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. -#else -#define CYTHON_ABI "0_29_13" -#define CYTHON_HEX_VERSION 0x001D0DF0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) - #endif - #ifndef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #include "longintrepr.h" - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef __cplusplus - #error "Cython files generated with the C++ option must be compiled with a C++ compiler." -#endif -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #else - #define CYTHON_INLINE inline - #endif -#endif -template -void __Pyx_call_destructor(T& x) { - x.~T(); -} -template -class __Pyx_FakeReference { - public: - __Pyx_FakeReference() : ptr(NULL) { } - __Pyx_FakeReference(const T& ref) : ptr(const_cast(&ref)) { } - T *operator->() { return ptr; } - T *operator&() { return ptr; } - operator T&() { return *ptr; } - template bool operator ==(U other) { return *ptr == other; } - template bool operator !=(U other) { return *ptr != other; } - private: - T *ptr; -}; - -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -#else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact - #define PyObject_Unicode PyObject_Str -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) -#else - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t PyInt_AsLong -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : (Py_INCREF(func), func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - - -#define __PYX_ERR(f_index, lineno, Ln_error) \ -{ \ - __pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \ -} - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__detector__nms__soft_nms_cpu -#define __PYX_HAVE_API__detector__nms__soft_nms_cpu -/* Early includes */ -#include -#include -#include "numpy/arrayobject.h" -#include "numpy/ufuncobject.h" -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - -/* Header.proto */ -#if !defined(CYTHON_CCOMPLEX) - #if defined(__cplusplus) - #define CYTHON_CCOMPLEX 1 - #elif defined(_Complex_I) - #define CYTHON_CCOMPLEX 1 - #else - #define CYTHON_CCOMPLEX 0 - #endif -#endif -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - #include - #else - #include - #endif -#endif -#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) - #undef _Complex_I - #define _Complex_I 1.0fj -#endif - - -static const char *__pyx_f[] = { - "detector/nms/src/soft_nms_cpu.pyx", - "__init__.pxd", - "type.pxd", -}; -/* BufferFormatStructs.proto */ -#define IS_UNSIGNED(type) (((type) -1) > 0) -struct __Pyx_StructField_; -#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) -typedef struct { - const char* name; - struct __Pyx_StructField_* fields; - size_t size; - size_t arraysize[8]; - int ndim; - char typegroup; - char is_unsigned; - int flags; -} __Pyx_TypeInfo; -typedef struct __Pyx_StructField_ { - __Pyx_TypeInfo* type; - const char* name; - size_t offset; -} __Pyx_StructField; -typedef struct { - __Pyx_StructField* field; - size_t parent_offset; -} __Pyx_BufFmt_StackElem; -typedef struct { - __Pyx_StructField root; - __Pyx_BufFmt_StackElem* head; - size_t fmt_offset; - size_t new_count, enc_count; - size_t struct_alignment; - int is_complex; - char enc_type; - char new_packmode; - char enc_packmode; - char is_valid_array; -} __Pyx_BufFmt_Context; - - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":776 - * # in Cython to enable them only on the right systems. - * - * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t - */ -typedef npy_int8 __pyx_t_5numpy_int8_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":777 - * - * ctypedef npy_int8 int8_t - * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< - * ctypedef npy_int32 int32_t - * ctypedef npy_int64 int64_t - */ -typedef npy_int16 __pyx_t_5numpy_int16_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":778 - * ctypedef npy_int8 int8_t - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< - * ctypedef npy_int64 int64_t - * #ctypedef npy_int96 int96_t - */ -typedef npy_int32 __pyx_t_5numpy_int32_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":779 - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t - * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< - * #ctypedef npy_int96 int96_t - * #ctypedef npy_int128 int128_t - */ -typedef npy_int64 __pyx_t_5numpy_int64_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":783 - * #ctypedef npy_int128 int128_t - * - * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t - */ -typedef npy_uint8 __pyx_t_5numpy_uint8_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":784 - * - * ctypedef npy_uint8 uint8_t - * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< - * ctypedef npy_uint32 uint32_t - * ctypedef npy_uint64 uint64_t - */ -typedef npy_uint16 __pyx_t_5numpy_uint16_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":785 - * ctypedef npy_uint8 uint8_t - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< - * ctypedef npy_uint64 uint64_t - * #ctypedef npy_uint96 uint96_t - */ -typedef npy_uint32 __pyx_t_5numpy_uint32_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":786 - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t - * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< - * #ctypedef npy_uint96 uint96_t - * #ctypedef npy_uint128 uint128_t - */ -typedef npy_uint64 __pyx_t_5numpy_uint64_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":790 - * #ctypedef npy_uint128 uint128_t - * - * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< - * ctypedef npy_float64 float64_t - * #ctypedef npy_float80 float80_t - */ -typedef npy_float32 __pyx_t_5numpy_float32_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":791 - * - * ctypedef npy_float32 float32_t - * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< - * #ctypedef npy_float80 float80_t - * #ctypedef npy_float128 float128_t - */ -typedef npy_float64 __pyx_t_5numpy_float64_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":800 - * # The int types are mapped a bit surprising -- - * # numpy.int corresponds to 'l' and numpy.long to 'q' - * ctypedef npy_long int_t # <<<<<<<<<<<<<< - * ctypedef npy_longlong long_t - * ctypedef npy_longlong longlong_t - */ -typedef npy_long __pyx_t_5numpy_int_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":801 - * # numpy.int corresponds to 'l' and numpy.long to 'q' - * ctypedef npy_long int_t - * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< - * ctypedef npy_longlong longlong_t - * - */ -typedef npy_longlong __pyx_t_5numpy_long_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":802 - * ctypedef npy_long int_t - * ctypedef npy_longlong long_t - * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< - * - * ctypedef npy_ulong uint_t - */ -typedef npy_longlong __pyx_t_5numpy_longlong_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":804 - * ctypedef npy_longlong longlong_t - * - * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< - * ctypedef npy_ulonglong ulong_t - * ctypedef npy_ulonglong ulonglong_t - */ -typedef npy_ulong __pyx_t_5numpy_uint_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":805 - * - * ctypedef npy_ulong uint_t - * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< - * ctypedef npy_ulonglong ulonglong_t - * - */ -typedef npy_ulonglong __pyx_t_5numpy_ulong_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":806 - * ctypedef npy_ulong uint_t - * ctypedef npy_ulonglong ulong_t - * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< - * - * ctypedef npy_intp intp_t - */ -typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":808 - * ctypedef npy_ulonglong ulonglong_t - * - * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< - * ctypedef npy_uintp uintp_t - * - */ -typedef npy_intp __pyx_t_5numpy_intp_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":809 - * - * ctypedef npy_intp intp_t - * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< - * - * ctypedef npy_double float_t - */ -typedef npy_uintp __pyx_t_5numpy_uintp_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":811 - * ctypedef npy_uintp uintp_t - * - * ctypedef npy_double float_t # <<<<<<<<<<<<<< - * ctypedef npy_double double_t - * ctypedef npy_longdouble longdouble_t - */ -typedef npy_double __pyx_t_5numpy_float_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":812 - * - * ctypedef npy_double float_t - * ctypedef npy_double double_t # <<<<<<<<<<<<<< - * ctypedef npy_longdouble longdouble_t - * - */ -typedef npy_double __pyx_t_5numpy_double_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":813 - * ctypedef npy_double float_t - * ctypedef npy_double double_t - * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< - * - * ctypedef npy_cfloat cfloat_t - */ -typedef npy_longdouble __pyx_t_5numpy_longdouble_t; -/* Declarations.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - typedef ::std::complex< float > __pyx_t_float_complex; - #else - typedef float _Complex __pyx_t_float_complex; - #endif -#else - typedef struct { float real, imag; } __pyx_t_float_complex; -#endif -static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); - -/* Declarations.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - typedef ::std::complex< double > __pyx_t_double_complex; - #else - typedef double _Complex __pyx_t_double_complex; - #endif -#else - typedef struct { double real, imag; } __pyx_t_double_complex; -#endif -static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); - - -/*--- Type declarations ---*/ - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":815 - * ctypedef npy_longdouble longdouble_t - * - * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< - * ctypedef npy_cdouble cdouble_t - * ctypedef npy_clongdouble clongdouble_t - */ -typedef npy_cfloat __pyx_t_5numpy_cfloat_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":816 - * - * ctypedef npy_cfloat cfloat_t - * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< - * ctypedef npy_clongdouble clongdouble_t - * - */ -typedef npy_cdouble __pyx_t_5numpy_cdouble_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":817 - * ctypedef npy_cfloat cfloat_t - * ctypedef npy_cdouble cdouble_t - * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< - * - * ctypedef npy_cdouble complex_t - */ -typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":819 - * ctypedef npy_clongdouble clongdouble_t - * - * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew1(a): - */ -typedef npy_cdouble __pyx_t_5numpy_complex_t; - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* ArgTypeTest.proto */ -#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ - ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ - __Pyx__ArgTypeTest(obj, type, name, exact)) -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); - -/* IsLittleEndian.proto */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void); - -/* BufferFormatCheck.proto */ -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type); - -/* BufferGetAndValidate.proto */ -#define __Pyx_GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)\ - ((obj == Py_None || obj == NULL) ?\ - (__Pyx_ZeroBuffer(buf), 0) :\ - __Pyx__GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)) -static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj, - __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); -static void __Pyx_ZeroBuffer(Py_buffer* buf); -static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); -static Py_ssize_t __Pyx_minusones[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static Py_ssize_t __Pyx_zeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#else -#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectCallNoArg.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); -#else -#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) -#endif - -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* GetModuleGlobalName.proto */ -#if CYTHON_USE_DICT_VERSIONS -#define __Pyx_GetModuleGlobalName(var, name) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ - (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ - __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ - PY_UINT64_T __pyx_dict_version;\ - PyObject *__pyx_dict_cached_value;\ - (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); -#else -#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) -#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); -#endif - -/* PyObjectCall2Args.proto */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); - -/* ObjectGetItem.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key); -#else -#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) -#endif - -/* PyIntBinop.proto */ -#if !CYTHON_COMPILING_IN_PYPY -static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); -#else -#define __Pyx_PyInt_AddObjC(op1, op2, intval, inplace, zerodivision_check)\ - (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2)) -#endif - -/* SetItemInt.proto */ -#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) :\ - __Pyx_SetItemInt_Generic(o, to_py_func(i), v))) -static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); -static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, - int is_list, int wraparound, int boundscheck); - -/* SliceObject.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice( - PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop, - PyObject** py_start, PyObject** py_stop, PyObject** py_slice, - int has_cstart, int has_cstop, int wraparound); - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* DictGetItem.proto */ -#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY -static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key); -#define __Pyx_PyObject_Dict_GetItem(obj, name)\ - (likely(PyDict_CheckExact(obj)) ?\ - __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name)) -#else -#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) -#define __Pyx_PyObject_Dict_GetItem(obj, name) PyObject_GetItem(obj, name) -#endif - -/* RaiseTooManyValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); - -/* RaiseNeedMoreValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); - -/* RaiseNoneIterError.proto */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); - -/* ExtTypeTest.proto */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); - -/* GetTopmostException.proto */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); -#endif - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif - -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* TypeImport.proto */ -#ifndef __PYX_HAVE_RT_ImportType_proto -#define __PYX_HAVE_RT_ImportType_proto -enum __Pyx_ImportType_CheckSize { - __Pyx_ImportType_CheckSize_Error = 0, - __Pyx_ImportType_CheckSize_Warn = 1, - __Pyx_ImportType_CheckSize_Ignore = 2 -}; -static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* BufferStructDeclare.proto */ -typedef struct { - Py_ssize_t shape, strides, suboffsets; -} __Pyx_Buf_DimInfo; -typedef struct { - size_t refcount; - Py_buffer pybuffer; -} __Pyx_Buffer; -typedef struct { - __Pyx_Buffer *rcbuffer; - char *data; - __Pyx_Buf_DimInfo diminfo[8]; -} __Pyx_LocalBuf_ND; - -#if PY_MAJOR_VERSION < 3 - static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); - static void __Pyx_ReleaseBuffer(Py_buffer *view); -#else - #define __Pyx_GetBuffer PyObject_GetBuffer - #define __Pyx_ReleaseBuffer PyBuffer_Release -#endif - - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); - -/* RealImag.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - #define __Pyx_CREAL(z) ((z).real()) - #define __Pyx_CIMAG(z) ((z).imag()) - #else - #define __Pyx_CREAL(z) (__real__(z)) - #define __Pyx_CIMAG(z) (__imag__(z)) - #endif -#else - #define __Pyx_CREAL(z) ((z).real) - #define __Pyx_CIMAG(z) ((z).imag) -#endif -#if defined(__cplusplus) && CYTHON_CCOMPLEX\ - && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) - #define __Pyx_SET_CREAL(z,x) ((z).real(x)) - #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) -#else - #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) - #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) -#endif - -/* Arithmetic.proto */ -#if CYTHON_CCOMPLEX - #define __Pyx_c_eq_float(a, b) ((a)==(b)) - #define __Pyx_c_sum_float(a, b) ((a)+(b)) - #define __Pyx_c_diff_float(a, b) ((a)-(b)) - #define __Pyx_c_prod_float(a, b) ((a)*(b)) - #define __Pyx_c_quot_float(a, b) ((a)/(b)) - #define __Pyx_c_neg_float(a) (-(a)) - #ifdef __cplusplus - #define __Pyx_c_is_zero_float(z) ((z)==(float)0) - #define __Pyx_c_conj_float(z) (::std::conj(z)) - #if 1 - #define __Pyx_c_abs_float(z) (::std::abs(z)) - #define __Pyx_c_pow_float(a, b) (::std::pow(a, b)) - #endif - #else - #define __Pyx_c_is_zero_float(z) ((z)==0) - #define __Pyx_c_conj_float(z) (conjf(z)) - #if 1 - #define __Pyx_c_abs_float(z) (cabsf(z)) - #define __Pyx_c_pow_float(a, b) (cpowf(a, b)) - #endif - #endif -#else - static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex); - static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex); - #if 1 - static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex, __pyx_t_float_complex); - #endif -#endif - -/* Arithmetic.proto */ -#if CYTHON_CCOMPLEX - #define __Pyx_c_eq_double(a, b) ((a)==(b)) - #define __Pyx_c_sum_double(a, b) ((a)+(b)) - #define __Pyx_c_diff_double(a, b) ((a)-(b)) - #define __Pyx_c_prod_double(a, b) ((a)*(b)) - #define __Pyx_c_quot_double(a, b) ((a)/(b)) - #define __Pyx_c_neg_double(a) (-(a)) - #ifdef __cplusplus - #define __Pyx_c_is_zero_double(z) ((z)==(double)0) - #define __Pyx_c_conj_double(z) (::std::conj(z)) - #if 1 - #define __Pyx_c_abs_double(z) (::std::abs(z)) - #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) - #endif - #else - #define __Pyx_c_is_zero_double(z) ((z)==0) - #define __Pyx_c_conj_double(z) (conj(z)) - #if 1 - #define __Pyx_c_abs_double(z) (cabs(z)) - #define __Pyx_c_pow_double(a, b) (cpow(a, b)) - #endif - #endif -#else - static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); - static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); - #if 1 - static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); - #endif -#endif - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - - -/* Module declarations from 'cpython.buffer' */ - -/* Module declarations from 'libc.string' */ - -/* Module declarations from 'libc.stdio' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.type' */ -static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; - -/* Module declarations from 'cpython' */ - -/* Module declarations from 'cpython.object' */ - -/* Module declarations from 'cpython.ref' */ - -/* Module declarations from 'cpython.mem' */ - -/* Module declarations from 'numpy' */ - -/* Module declarations from 'numpy' */ -static PyTypeObject *__pyx_ptype_5numpy_dtype = 0; -static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0; -static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0; -static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0; -static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0; -static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/ - -/* Module declarations from 'detector.nms.soft_nms_cpu' */ -static CYTHON_INLINE __pyx_t_5numpy_float32_t __pyx_f_8detector_3nms_12soft_nms_cpu_max(__pyx_t_5numpy_float32_t, __pyx_t_5numpy_float32_t); /*proto*/ -static CYTHON_INLINE __pyx_t_5numpy_float32_t __pyx_f_8detector_3nms_12soft_nms_cpu_min(__pyx_t_5numpy_float32_t, __pyx_t_5numpy_float32_t); /*proto*/ -static __Pyx_TypeInfo __Pyx_TypeInfo_float = { "float", NULL, sizeof(float), { 0 }, 0, 'R', 0, 0 }; -#define __Pyx_MODULE_NAME "detector.nms.soft_nms_cpu" -extern int __pyx_module_is_main_detector__nms__soft_nms_cpu; -int __pyx_module_is_main_detector__nms__soft_nms_cpu = 0; - -/* Implementation of 'detector.nms.soft_nms_cpu' */ -static PyObject *__pyx_builtin_range; -static PyObject *__pyx_builtin_ValueError; -static PyObject *__pyx_builtin_RuntimeError; -static PyObject *__pyx_builtin_ImportError; -static const char __pyx_k_N[] = "N"; -static const char __pyx_k_i[] = "i"; -static const char __pyx_k_s[] = "s"; -static const char __pyx_k_ih[] = "ih"; -static const char __pyx_k_iw[] = "iw"; -static const char __pyx_k_np[] = "np"; -static const char __pyx_k_ov[] = "ov"; -static const char __pyx_k_ti[] = "ti"; -static const char __pyx_k_ts[] = "ts"; -static const char __pyx_k_ua[] = "ua"; -static const char __pyx_k_x1[] = "x1"; -static const char __pyx_k_x2[] = "x2"; -static const char __pyx_k_y1[] = "y1"; -static const char __pyx_k_y2[] = "y2"; -static const char __pyx_k_exp[] = "exp"; -static const char __pyx_k_pos[] = "pos"; -static const char __pyx_k_tx1[] = "tx1"; -static const char __pyx_k_tx2[] = "tx2"; -static const char __pyx_k_ty1[] = "ty1"; -static const char __pyx_k_ty2[] = "ty2"; -static const char __pyx_k_area[] = "area"; -static const char __pyx_k_copy[] = "copy"; -static const char __pyx_k_inds[] = "inds"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_name[] = "__name__"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_boxes[] = "boxes"; -static const char __pyx_k_numpy[] = "numpy"; -static const char __pyx_k_range[] = "range"; -static const char __pyx_k_shape[] = "shape"; -static const char __pyx_k_sigma[] = "sigma"; -static const char __pyx_k_arange[] = "arange"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_maxpos[] = "maxpos"; -static const char __pyx_k_method[] = "method"; -static const char __pyx_k_weight[] = "weight"; -static const char __pyx_k_iou_thr[] = "iou_thr"; -static const char __pyx_k_box_area[] = "box_area"; -static const char __pyx_k_boxes_in[] = "boxes_in"; -static const char __pyx_k_maxscore[] = "maxscore"; -static const char __pyx_k_min_score[] = "min_score"; -static const char __pyx_k_ValueError[] = "ValueError"; -static const char __pyx_k_ImportError[] = "ImportError"; -static const char __pyx_k_RuntimeError[] = "RuntimeError"; -static const char __pyx_k_soft_nms_cpu[] = "soft_nms_cpu"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_detector_nms_soft_nms_cpu[] = "detector.nms.soft_nms_cpu"; -static const char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous"; -static const char __pyx_k_numpy_core_multiarray_failed_to[] = "numpy.core.multiarray failed to import"; -static const char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)"; -static const char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd"; -static const char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported"; -static const char __pyx_k_detector_nms_src_soft_nms_cpu_py[] = "detector/nms/src/soft_nms_cpu.pyx"; -static const char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous"; -static const char __pyx_k_numpy_core_umath_failed_to_impor[] = "numpy.core.umath failed to import"; -static const char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short."; -static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; -static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; -static PyObject *__pyx_n_s_ImportError; -static PyObject *__pyx_n_s_N; -static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; -static PyObject *__pyx_n_s_RuntimeError; -static PyObject *__pyx_n_s_ValueError; -static PyObject *__pyx_n_s_arange; -static PyObject *__pyx_n_s_area; -static PyObject *__pyx_n_s_box_area; -static PyObject *__pyx_n_s_boxes; -static PyObject *__pyx_n_s_boxes_in; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_n_s_copy; -static PyObject *__pyx_n_s_detector_nms_soft_nms_cpu; -static PyObject *__pyx_kp_s_detector_nms_src_soft_nms_cpu_py; -static PyObject *__pyx_n_s_exp; -static PyObject *__pyx_n_s_i; -static PyObject *__pyx_n_s_ih; -static PyObject *__pyx_n_s_import; -static PyObject *__pyx_n_s_inds; -static PyObject *__pyx_n_s_iou_thr; -static PyObject *__pyx_n_s_iw; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_maxpos; -static PyObject *__pyx_n_s_maxscore; -static PyObject *__pyx_n_s_method; -static PyObject *__pyx_n_s_min_score; -static PyObject *__pyx_n_s_name; -static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous; -static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou; -static PyObject *__pyx_n_s_np; -static PyObject *__pyx_n_s_numpy; -static PyObject *__pyx_kp_u_numpy_core_multiarray_failed_to; -static PyObject *__pyx_kp_u_numpy_core_umath_failed_to_impor; -static PyObject *__pyx_n_s_ov; -static PyObject *__pyx_n_s_pos; -static PyObject *__pyx_n_s_range; -static PyObject *__pyx_n_s_s; -static PyObject *__pyx_n_s_shape; -static PyObject *__pyx_n_s_sigma; -static PyObject *__pyx_n_s_soft_nms_cpu; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_n_s_ti; -static PyObject *__pyx_n_s_ts; -static PyObject *__pyx_n_s_tx1; -static PyObject *__pyx_n_s_tx2; -static PyObject *__pyx_n_s_ty1; -static PyObject *__pyx_n_s_ty2; -static PyObject *__pyx_n_s_ua; -static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; -static PyObject *__pyx_n_s_weight; -static PyObject *__pyx_n_s_x1; -static PyObject *__pyx_n_s_x2; -static PyObject *__pyx_n_s_y1; -static PyObject *__pyx_n_s_y2; -static PyObject *__pyx_pf_8detector_3nms_12soft_nms_cpu_soft_nms_cpu(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_boxes_in, float __pyx_v_iou_thr, unsigned int __pyx_v_method, float __pyx_v_sigma, float __pyx_v_min_score); /* proto */ -static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ -static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */ -static PyObject *__pyx_int_0; -static PyObject *__pyx_int_1; -static PyObject *__pyx_int_2; -static PyObject *__pyx_int_3; -static PyObject *__pyx_int_4; -static PyObject *__pyx_tuple_; -static PyObject *__pyx_tuple__2; -static PyObject *__pyx_tuple__3; -static PyObject *__pyx_tuple__4; -static PyObject *__pyx_tuple__5; -static PyObject *__pyx_tuple__6; -static PyObject *__pyx_tuple__7; -static PyObject *__pyx_tuple__8; -static PyObject *__pyx_codeobj__9; -/* Late includes */ - -/* "detector/nms/src/soft_nms_cpu.pyx":15 - * - * - * cdef inline np.float32_t max(np.float32_t a, np.float32_t b): # <<<<<<<<<<<<<< - * return a if a >= b else b - * - */ - -static CYTHON_INLINE __pyx_t_5numpy_float32_t __pyx_f_8detector_3nms_12soft_nms_cpu_max(__pyx_t_5numpy_float32_t __pyx_v_a, __pyx_t_5numpy_float32_t __pyx_v_b) { - __pyx_t_5numpy_float32_t __pyx_r; - __Pyx_RefNannyDeclarations - __pyx_t_5numpy_float32_t __pyx_t_1; - __Pyx_RefNannySetupContext("max", 0); - - /* "detector/nms/src/soft_nms_cpu.pyx":16 - * - * cdef inline np.float32_t max(np.float32_t a, np.float32_t b): - * return a if a >= b else b # <<<<<<<<<<<<<< - * - * cdef inline np.float32_t min(np.float32_t a, np.float32_t b): - */ - if (((__pyx_v_a >= __pyx_v_b) != 0)) { - __pyx_t_1 = __pyx_v_a; - } else { - __pyx_t_1 = __pyx_v_b; - } - __pyx_r = __pyx_t_1; - goto __pyx_L0; - - /* "detector/nms/src/soft_nms_cpu.pyx":15 - * - * - * cdef inline np.float32_t max(np.float32_t a, np.float32_t b): # <<<<<<<<<<<<<< - * return a if a >= b else b - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "detector/nms/src/soft_nms_cpu.pyx":18 - * return a if a >= b else b - * - * cdef inline np.float32_t min(np.float32_t a, np.float32_t b): # <<<<<<<<<<<<<< - * return a if a <= b else b - * - */ - -static CYTHON_INLINE __pyx_t_5numpy_float32_t __pyx_f_8detector_3nms_12soft_nms_cpu_min(__pyx_t_5numpy_float32_t __pyx_v_a, __pyx_t_5numpy_float32_t __pyx_v_b) { - __pyx_t_5numpy_float32_t __pyx_r; - __Pyx_RefNannyDeclarations - __pyx_t_5numpy_float32_t __pyx_t_1; - __Pyx_RefNannySetupContext("min", 0); - - /* "detector/nms/src/soft_nms_cpu.pyx":19 - * - * cdef inline np.float32_t min(np.float32_t a, np.float32_t b): - * return a if a <= b else b # <<<<<<<<<<<<<< - * - * - */ - if (((__pyx_v_a <= __pyx_v_b) != 0)) { - __pyx_t_1 = __pyx_v_a; - } else { - __pyx_t_1 = __pyx_v_b; - } - __pyx_r = __pyx_t_1; - goto __pyx_L0; - - /* "detector/nms/src/soft_nms_cpu.pyx":18 - * return a if a >= b else b - * - * cdef inline np.float32_t min(np.float32_t a, np.float32_t b): # <<<<<<<<<<<<<< - * return a if a <= b else b - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "detector/nms/src/soft_nms_cpu.pyx":22 - * - * - * def soft_nms_cpu( # <<<<<<<<<<<<<< - * np.ndarray[float, ndim=2] boxes_in, - * float iou_thr, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_8detector_3nms_12soft_nms_cpu_1soft_nms_cpu(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_8detector_3nms_12soft_nms_cpu_1soft_nms_cpu = {"soft_nms_cpu", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8detector_3nms_12soft_nms_cpu_1soft_nms_cpu, METH_VARARGS|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_8detector_3nms_12soft_nms_cpu_1soft_nms_cpu(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyArrayObject *__pyx_v_boxes_in = 0; - float __pyx_v_iou_thr; - unsigned int __pyx_v_method; - float __pyx_v_sigma; - float __pyx_v_min_score; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("soft_nms_cpu (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_boxes_in,&__pyx_n_s_iou_thr,&__pyx_n_s_method,&__pyx_n_s_sigma,&__pyx_n_s_min_score,0}; - PyObject* values[5] = {0,0,0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_boxes_in)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_iou_thr)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("soft_nms_cpu", 0, 2, 5, 1); __PYX_ERR(0, 22, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_method); - if (value) { values[2] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_sigma); - if (value) { values[3] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 4: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_min_score); - if (value) { values[4] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "soft_nms_cpu") < 0)) __PYX_ERR(0, 22, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_boxes_in = ((PyArrayObject *)values[0]); - __pyx_v_iou_thr = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_iou_thr == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 24, __pyx_L3_error) - if (values[2]) { - __pyx_v_method = __Pyx_PyInt_As_unsigned_int(values[2]); if (unlikely((__pyx_v_method == (unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 25, __pyx_L3_error) - } else { - __pyx_v_method = ((unsigned int)1); - } - if (values[3]) { - __pyx_v_sigma = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_sigma == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 26, __pyx_L3_error) - } else { - __pyx_v_sigma = ((float)0.5); - } - if (values[4]) { - __pyx_v_min_score = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_min_score == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 27, __pyx_L3_error) - } else { - __pyx_v_min_score = ((float)0.001); - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("soft_nms_cpu", 0, 2, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 22, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("detector.nms.soft_nms_cpu.soft_nms_cpu", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_boxes_in), __pyx_ptype_5numpy_ndarray, 1, "boxes_in", 0))) __PYX_ERR(0, 23, __pyx_L1_error) - __pyx_r = __pyx_pf_8detector_3nms_12soft_nms_cpu_soft_nms_cpu(__pyx_self, __pyx_v_boxes_in, __pyx_v_iou_thr, __pyx_v_method, __pyx_v_sigma, __pyx_v_min_score); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_8detector_3nms_12soft_nms_cpu_soft_nms_cpu(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_boxes_in, float __pyx_v_iou_thr, unsigned int __pyx_v_method, float __pyx_v_sigma, float __pyx_v_min_score) { - PyObject *__pyx_v_boxes = NULL; - int __pyx_v_N; - float __pyx_v_iw; - float __pyx_v_ih; - float __pyx_v_ua; - int __pyx_v_pos; - float __pyx_v_maxscore; - int __pyx_v_maxpos; - float __pyx_v_x1; - float __pyx_v_x2; - float __pyx_v_y1; - float __pyx_v_y2; - float __pyx_v_tx1; - float __pyx_v_tx2; - float __pyx_v_ty1; - float __pyx_v_ty2; - float __pyx_v_ts; - float __pyx_v_area; - float __pyx_v_weight; - float __pyx_v_ov; - PyObject *__pyx_v_inds = NULL; - PyObject *__pyx_v_i = NULL; - PyObject *__pyx_v_ti = NULL; - CYTHON_UNUSED PyObject *__pyx_v_s = NULL; - __Pyx_LocalBuf_ND __pyx_pybuffernd_boxes_in; - __Pyx_Buffer __pyx_pybuffer_boxes_in; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - Py_ssize_t __pyx_t_6; - PyObject *(*__pyx_t_7)(PyObject *); - float __pyx_t_8; - int __pyx_t_9; - PyObject *__pyx_t_10 = NULL; - long __pyx_t_11; - __Pyx_RefNannySetupContext("soft_nms_cpu", 0); - __pyx_pybuffer_boxes_in.pybuffer.buf = NULL; - __pyx_pybuffer_boxes_in.refcount = 0; - __pyx_pybuffernd_boxes_in.data = NULL; - __pyx_pybuffernd_boxes_in.rcbuffer = &__pyx_pybuffer_boxes_in; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_boxes_in.rcbuffer->pybuffer, (PyObject*)__pyx_v_boxes_in, &__Pyx_TypeInfo_float, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 22, __pyx_L1_error) - } - __pyx_pybuffernd_boxes_in.diminfo[0].strides = __pyx_pybuffernd_boxes_in.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_boxes_in.diminfo[0].shape = __pyx_pybuffernd_boxes_in.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_boxes_in.diminfo[1].strides = __pyx_pybuffernd_boxes_in.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_boxes_in.diminfo[1].shape = __pyx_pybuffernd_boxes_in.rcbuffer->pybuffer.shape[1]; - - /* "detector/nms/src/soft_nms_cpu.pyx":29 - * float min_score=0.001, - * ): - * boxes = boxes_in.copy() # <<<<<<<<<<<<<< - * cdef int N = boxes.shape[0] - * cdef float iw, ih, box_area - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_boxes_in), __pyx_n_s_copy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v_boxes = __pyx_t_1; - __pyx_t_1 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":30 - * ): - * boxes = boxes_in.copy() - * cdef int N = boxes.shape[0] # <<<<<<<<<<<<<< - * cdef float iw, ih, box_area - * cdef float ua - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_boxes, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v_N = __pyx_t_4; - - /* "detector/nms/src/soft_nms_cpu.pyx":33 - * cdef float iw, ih, box_area - * cdef float ua - * cdef int pos = 0 # <<<<<<<<<<<<<< - * cdef float maxscore = 0 - * cdef int maxpos = 0 - */ - __pyx_v_pos = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":34 - * cdef float ua - * cdef int pos = 0 - * cdef float maxscore = 0 # <<<<<<<<<<<<<< - * cdef int maxpos = 0 - * cdef float x1, x2, y1, y2, tx1, tx2, ty1, ty2, ts, area, weight, ov - */ - __pyx_v_maxscore = 0.0; - - /* "detector/nms/src/soft_nms_cpu.pyx":35 - * cdef int pos = 0 - * cdef float maxscore = 0 - * cdef int maxpos = 0 # <<<<<<<<<<<<<< - * cdef float x1, x2, y1, y2, tx1, tx2, ty1, ty2, ts, area, weight, ov - * inds = np.arange(N) - */ - __pyx_v_maxpos = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":37 - * cdef int maxpos = 0 - * cdef float x1, x2, y1, y2, tx1, tx2, ty1, ty2, ts, area, weight, ov - * inds = np.arange(N) # <<<<<<<<<<<<<< - * - * for i in range(N): - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 37, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_arange); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 37, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 37, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_1) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 37, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_inds = __pyx_t_2; - __pyx_t_2 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":39 - * inds = np.arange(N) - * - * for i in range(N): # <<<<<<<<<<<<<< - * maxscore = boxes[i, 4] - * maxpos = i - */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_N); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_range, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) { - __pyx_t_2 = __pyx_t_3; __Pyx_INCREF(__pyx_t_2); __pyx_t_6 = 0; - __pyx_t_7 = NULL; - } else { - __pyx_t_6 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_7 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 39, __pyx_L1_error) - } - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - for (;;) { - if (likely(!__pyx_t_7)) { - if (likely(PyList_CheckExact(__pyx_t_2))) { - if (__pyx_t_6 >= PyList_GET_SIZE(__pyx_t_2)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 39, __pyx_L1_error) - #else - __pyx_t_3 = PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - } else { - if (__pyx_t_6 >= PyTuple_GET_SIZE(__pyx_t_2)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 39, __pyx_L1_error) - #else - __pyx_t_3 = PySequence_ITEM(__pyx_t_2, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - } - } else { - __pyx_t_3 = __pyx_t_7(__pyx_t_2); - if (unlikely(!__pyx_t_3)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(0, 39, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_3); - } - __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3); - __pyx_t_3 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":40 - * - * for i in range(N): - * maxscore = boxes[i, 4] # <<<<<<<<<<<<<< - * maxpos = i - * - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_4); - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 40, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_maxscore = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":41 - * for i in range(N): - * maxscore = boxes[i, 4] - * maxpos = i # <<<<<<<<<<<<<< - * - * tx1 = boxes[i, 0] - */ - __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_v_i); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 41, __pyx_L1_error) - __pyx_v_maxpos = __pyx_t_4; - - /* "detector/nms/src/soft_nms_cpu.pyx":43 - * maxpos = i - * - * tx1 = boxes[i, 0] # <<<<<<<<<<<<<< - * ty1 = boxes[i, 1] - * tx2 = boxes[i, 2] - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 43, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_0); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 43, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 43, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_tx1 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":44 - * - * tx1 = boxes[i, 0] - * ty1 = boxes[i, 1] # <<<<<<<<<<<<<< - * tx2 = boxes[i, 2] - * ty2 = boxes[i, 3] - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 44, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_1); - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 44, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_ty1 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":45 - * tx1 = boxes[i, 0] - * ty1 = boxes[i, 1] - * tx2 = boxes[i, 2] # <<<<<<<<<<<<<< - * ty2 = boxes[i, 3] - * ts = boxes[i, 4] - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_2); - __Pyx_GIVEREF(__pyx_int_2); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_2); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 45, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 45, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_tx2 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":46 - * ty1 = boxes[i, 1] - * tx2 = boxes[i, 2] - * ty2 = boxes[i, 3] # <<<<<<<<<<<<<< - * ts = boxes[i, 4] - * ti = inds[i] - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 46, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_3); - __Pyx_GIVEREF(__pyx_int_3); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_3); - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 46, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 46, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_ty2 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":47 - * tx2 = boxes[i, 2] - * ty2 = boxes[i, 3] - * ts = boxes[i, 4] # <<<<<<<<<<<<<< - * ti = inds[i] - * - */ - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 47, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_4); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 47, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 47, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_ts = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":48 - * ty2 = boxes[i, 3] - * ts = boxes[i, 4] - * ti = inds[i] # <<<<<<<<<<<<<< - * - * pos = i + 1 - */ - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_inds, __pyx_v_i); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 48, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_XDECREF_SET(__pyx_v_ti, __pyx_t_3); - __pyx_t_3 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":50 - * ti = inds[i] - * - * pos = i + 1 # <<<<<<<<<<<<<< - * # get max box - * while pos < N: - */ - __pyx_t_3 = __Pyx_PyInt_AddObjC(__pyx_v_i, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 50, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 50, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_pos = __pyx_t_4; - - /* "detector/nms/src/soft_nms_cpu.pyx":52 - * pos = i + 1 - * # get max box - * while pos < N: # <<<<<<<<<<<<<< - * if maxscore < boxes[pos, 4]: - * maxscore = boxes[pos, 4] - */ - while (1) { - __pyx_t_9 = ((__pyx_v_pos < __pyx_v_N) != 0); - if (!__pyx_t_9) break; - - /* "detector/nms/src/soft_nms_cpu.pyx":53 - * # get max box - * while pos < N: - * if maxscore < boxes[pos, 4]: # <<<<<<<<<<<<<< - * maxscore = boxes[pos, 4] - * maxpos = pos - */ - __pyx_t_3 = PyFloat_FromDouble(__pyx_v_maxscore); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 53, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 53, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_4); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = PyObject_RichCompare(__pyx_t_3, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 53, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 53, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (__pyx_t_9) { - - /* "detector/nms/src/soft_nms_cpu.pyx":54 - * while pos < N: - * if maxscore < boxes[pos, 4]: - * maxscore = boxes[pos, 4] # <<<<<<<<<<<<<< - * maxpos = pos - * pos = pos + 1 - */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_4); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_5); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 54, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_maxscore = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":55 - * if maxscore < boxes[pos, 4]: - * maxscore = boxes[pos, 4] - * maxpos = pos # <<<<<<<<<<<<<< - * pos = pos + 1 - * - */ - __pyx_v_maxpos = __pyx_v_pos; - - /* "detector/nms/src/soft_nms_cpu.pyx":53 - * # get max box - * while pos < N: - * if maxscore < boxes[pos, 4]: # <<<<<<<<<<<<<< - * maxscore = boxes[pos, 4] - * maxpos = pos - */ - } - - /* "detector/nms/src/soft_nms_cpu.pyx":56 - * maxscore = boxes[pos, 4] - * maxpos = pos - * pos = pos + 1 # <<<<<<<<<<<<<< - * - * # add max box as a detection - */ - __pyx_v_pos = (__pyx_v_pos + 1); - } - - /* "detector/nms/src/soft_nms_cpu.pyx":59 - * - * # add max box as a detection - * boxes[i, 0] = boxes[maxpos, 0] # <<<<<<<<<<<<<< - * boxes[i, 1] = boxes[maxpos, 1] - * boxes[i, 2] = boxes[maxpos, 2] - */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 59, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 59, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_0); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 59, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 59, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_0); - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_1, __pyx_t_5) < 0)) __PYX_ERR(0, 59, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":60 - * # add max box as a detection - * boxes[i, 0] = boxes[maxpos, 0] - * boxes[i, 1] = boxes[maxpos, 1] # <<<<<<<<<<<<<< - * boxes[i, 2] = boxes[maxpos, 2] - * boxes[i, 3] = boxes[maxpos, 3] - */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_1); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_1); - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_1, __pyx_t_5) < 0)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":61 - * boxes[i, 0] = boxes[maxpos, 0] - * boxes[i, 1] = boxes[maxpos, 1] - * boxes[i, 2] = boxes[maxpos, 2] # <<<<<<<<<<<<<< - * boxes[i, 3] = boxes[maxpos, 3] - * boxes[i, 4] = boxes[maxpos, 4] - */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 61, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 61, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); - __Pyx_INCREF(__pyx_int_2); - __Pyx_GIVEREF(__pyx_int_2); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_2); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 61, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 61, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_2); - __Pyx_GIVEREF(__pyx_int_2); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_2); - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_1, __pyx_t_5) < 0)) __PYX_ERR(0, 61, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":62 - * boxes[i, 1] = boxes[maxpos, 1] - * boxes[i, 2] = boxes[maxpos, 2] - * boxes[i, 3] = boxes[maxpos, 3] # <<<<<<<<<<<<<< - * boxes[i, 4] = boxes[maxpos, 4] - * inds[i] = inds[maxpos] - */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); - __Pyx_INCREF(__pyx_int_3); - __Pyx_GIVEREF(__pyx_int_3); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_3); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_3); - __Pyx_GIVEREF(__pyx_int_3); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_3); - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_1, __pyx_t_5) < 0)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":63 - * boxes[i, 2] = boxes[maxpos, 2] - * boxes[i, 3] = boxes[maxpos, 3] - * boxes[i, 4] = boxes[maxpos, 4] # <<<<<<<<<<<<<< - * inds[i] = inds[maxpos] - * - */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 63, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 63, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_4); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 63, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 63, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_4); - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_1, __pyx_t_5) < 0)) __PYX_ERR(0, 63, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":64 - * boxes[i, 3] = boxes[maxpos, 3] - * boxes[i, 4] = boxes[maxpos, 4] - * inds[i] = inds[maxpos] # <<<<<<<<<<<<<< - * - * # swap ith box with position of max box - */ - __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_inds, __pyx_v_maxpos, int, 1, __Pyx_PyInt_From_int, 0, 1, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 64, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (unlikely(PyObject_SetItem(__pyx_v_inds, __pyx_v_i, __pyx_t_5) < 0)) __PYX_ERR(0, 64, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":67 - * - * # swap ith box with position of max box - * boxes[maxpos, 0] = tx1 # <<<<<<<<<<<<<< - * boxes[maxpos, 1] = ty1 - * boxes[maxpos, 2] = tx2 - */ - __pyx_t_5 = PyFloat_FromDouble(__pyx_v_tx1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0); - __pyx_t_1 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_3, __pyx_t_5) < 0)) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":68 - * # swap ith box with position of max box - * boxes[maxpos, 0] = tx1 - * boxes[maxpos, 1] = ty1 # <<<<<<<<<<<<<< - * boxes[maxpos, 2] = tx2 - * boxes[maxpos, 3] = ty2 - */ - __pyx_t_5 = PyFloat_FromDouble(__pyx_v_ty1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_1); - __pyx_t_3 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_1, __pyx_t_5) < 0)) __PYX_ERR(0, 68, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":69 - * boxes[maxpos, 0] = tx1 - * boxes[maxpos, 1] = ty1 - * boxes[maxpos, 2] = tx2 # <<<<<<<<<<<<<< - * boxes[maxpos, 3] = ty2 - * boxes[maxpos, 4] = ts - */ - __pyx_t_5 = PyFloat_FromDouble(__pyx_v_tx2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 69, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 69, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 69, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_2); - __Pyx_GIVEREF(__pyx_int_2); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_2); - __pyx_t_1 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_3, __pyx_t_5) < 0)) __PYX_ERR(0, 69, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":70 - * boxes[maxpos, 1] = ty1 - * boxes[maxpos, 2] = tx2 - * boxes[maxpos, 3] = ty2 # <<<<<<<<<<<<<< - * boxes[maxpos, 4] = ts - * inds[maxpos] = ti - */ - __pyx_t_5 = PyFloat_FromDouble(__pyx_v_ty2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_3); - __Pyx_GIVEREF(__pyx_int_3); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_3); - __pyx_t_3 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_1, __pyx_t_5) < 0)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":71 - * boxes[maxpos, 2] = tx2 - * boxes[maxpos, 3] = ty2 - * boxes[maxpos, 4] = ts # <<<<<<<<<<<<<< - * inds[maxpos] = ti - * - */ - __pyx_t_5 = PyFloat_FromDouble(__pyx_v_ts); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_maxpos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_4); - __pyx_t_1 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_3, __pyx_t_5) < 0)) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":72 - * boxes[maxpos, 3] = ty2 - * boxes[maxpos, 4] = ts - * inds[maxpos] = ti # <<<<<<<<<<<<<< - * - * tx1 = boxes[i, 0] - */ - if (unlikely(__Pyx_SetItemInt(__pyx_v_inds, __pyx_v_maxpos, __pyx_v_ti, int, 1, __Pyx_PyInt_From_int, 0, 1, 0) < 0)) __PYX_ERR(0, 72, __pyx_L1_error) - - /* "detector/nms/src/soft_nms_cpu.pyx":74 - * inds[maxpos] = ti - * - * tx1 = boxes[i, 0] # <<<<<<<<<<<<<< - * ty1 = boxes[i, 1] - * tx2 = boxes[i, 2] - */ - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_0); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 74, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_tx1 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":75 - * - * tx1 = boxes[i, 0] - * ty1 = boxes[i, 1] # <<<<<<<<<<<<<< - * tx2 = boxes[i, 2] - * ty2 = boxes[i, 3] - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 75, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_1); - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 75, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_5); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 75, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_ty1 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":76 - * tx1 = boxes[i, 0] - * ty1 = boxes[i, 1] - * tx2 = boxes[i, 2] # <<<<<<<<<<<<<< - * ty2 = boxes[i, 3] - * ts = boxes[i, 4] - */ - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 76, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_2); - __Pyx_GIVEREF(__pyx_int_2); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_2); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 76, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 76, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_tx2 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":77 - * ty1 = boxes[i, 1] - * tx2 = boxes[i, 2] - * ty2 = boxes[i, 3] # <<<<<<<<<<<<<< - * ts = boxes[i, 4] - * - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 77, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_3); - __Pyx_GIVEREF(__pyx_int_3); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_3); - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 77, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_5); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 77, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_ty2 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":78 - * tx2 = boxes[i, 2] - * ty2 = boxes[i, 3] - * ts = boxes[i, 4] # <<<<<<<<<<<<<< - * - * pos = i + 1 - */ - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_INCREF(__pyx_v_i); - __Pyx_GIVEREF(__pyx_v_i); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_i); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_4); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_ts = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":80 - * ts = boxes[i, 4] - * - * pos = i + 1 # <<<<<<<<<<<<<< - * # NMS iterations, note that N changes if detection boxes fall below - * # threshold - */ - __pyx_t_3 = __Pyx_PyInt_AddObjC(__pyx_v_i, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 80, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 80, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_pos = __pyx_t_4; - - /* "detector/nms/src/soft_nms_cpu.pyx":83 - * # NMS iterations, note that N changes if detection boxes fall below - * # threshold - * while pos < N: # <<<<<<<<<<<<<< - * x1 = boxes[pos, 0] - * y1 = boxes[pos, 1] - */ - while (1) { - __pyx_t_9 = ((__pyx_v_pos < __pyx_v_N) != 0); - if (!__pyx_t_9) break; - - /* "detector/nms/src/soft_nms_cpu.pyx":84 - * # threshold - * while pos < N: - * x1 = boxes[pos, 0] # <<<<<<<<<<<<<< - * y1 = boxes[pos, 1] - * x2 = boxes[pos, 2] - */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 84, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 84, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_0); - __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 84, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 84, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_x1 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":85 - * while pos < N: - * x1 = boxes[pos, 0] - * y1 = boxes[pos, 1] # <<<<<<<<<<<<<< - * x2 = boxes[pos, 2] - * y2 = boxes[pos, 3] - */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_1); - __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_y1 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":86 - * x1 = boxes[pos, 0] - * y1 = boxes[pos, 1] - * x2 = boxes[pos, 2] # <<<<<<<<<<<<<< - * y2 = boxes[pos, 3] - * s = boxes[pos, 4] - */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 86, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 86, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_2); - __Pyx_GIVEREF(__pyx_int_2); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_2); - __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 86, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 86, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_x2 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":87 - * y1 = boxes[pos, 1] - * x2 = boxes[pos, 2] - * y2 = boxes[pos, 3] # <<<<<<<<<<<<<< - * s = boxes[pos, 4] - * - */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 87, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 87, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_3); - __Pyx_GIVEREF(__pyx_int_3); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_3); - __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 87, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 87, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_y2 = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":88 - * x2 = boxes[pos, 2] - * y2 = boxes[pos, 3] - * s = boxes[pos, 4] # <<<<<<<<<<<<<< - * - * area = (x2 - x1 + 1) * (y2 - y1 + 1) - */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 88, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 88, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_4); - __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 88, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF_SET(__pyx_v_s, __pyx_t_3); - __pyx_t_3 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":90 - * s = boxes[pos, 4] - * - * area = (x2 - x1 + 1) * (y2 - y1 + 1) # <<<<<<<<<<<<<< - * iw = (min(tx2, x2) - max(tx1, x1) + 1) - * if iw > 0: - */ - __pyx_v_area = (((__pyx_v_x2 - __pyx_v_x1) + 1.0) * ((__pyx_v_y2 - __pyx_v_y1) + 1.0)); - - /* "detector/nms/src/soft_nms_cpu.pyx":91 - * - * area = (x2 - x1 + 1) * (y2 - y1 + 1) - * iw = (min(tx2, x2) - max(tx1, x1) + 1) # <<<<<<<<<<<<<< - * if iw > 0: - * ih = (min(ty2, y2) - max(ty1, y1) + 1) - */ - __pyx_v_iw = ((__pyx_f_8detector_3nms_12soft_nms_cpu_min(__pyx_v_tx2, __pyx_v_x2) - __pyx_f_8detector_3nms_12soft_nms_cpu_max(__pyx_v_tx1, __pyx_v_x1)) + 1.0); - - /* "detector/nms/src/soft_nms_cpu.pyx":92 - * area = (x2 - x1 + 1) * (y2 - y1 + 1) - * iw = (min(tx2, x2) - max(tx1, x1) + 1) - * if iw > 0: # <<<<<<<<<<<<<< - * ih = (min(ty2, y2) - max(ty1, y1) + 1) - * if ih > 0: - */ - __pyx_t_9 = ((__pyx_v_iw > 0.0) != 0); - if (__pyx_t_9) { - - /* "detector/nms/src/soft_nms_cpu.pyx":93 - * iw = (min(tx2, x2) - max(tx1, x1) + 1) - * if iw > 0: - * ih = (min(ty2, y2) - max(ty1, y1) + 1) # <<<<<<<<<<<<<< - * if ih > 0: - * ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) - */ - __pyx_v_ih = ((__pyx_f_8detector_3nms_12soft_nms_cpu_min(__pyx_v_ty2, __pyx_v_y2) - __pyx_f_8detector_3nms_12soft_nms_cpu_max(__pyx_v_ty1, __pyx_v_y1)) + 1.0); - - /* "detector/nms/src/soft_nms_cpu.pyx":94 - * if iw > 0: - * ih = (min(ty2, y2) - max(ty1, y1) + 1) - * if ih > 0: # <<<<<<<<<<<<<< - * ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) - * ov = iw * ih / ua # iou between max box and detection box - */ - __pyx_t_9 = ((__pyx_v_ih > 0.0) != 0); - if (__pyx_t_9) { - - /* "detector/nms/src/soft_nms_cpu.pyx":95 - * ih = (min(ty2, y2) - max(ty1, y1) + 1) - * if ih > 0: - * ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) # <<<<<<<<<<<<<< - * ov = iw * ih / ua # iou between max box and detection box - * - */ - __pyx_v_ua = ((double)(((((__pyx_v_tx2 - __pyx_v_tx1) + 1.0) * ((__pyx_v_ty2 - __pyx_v_ty1) + 1.0)) + __pyx_v_area) - (__pyx_v_iw * __pyx_v_ih))); - - /* "detector/nms/src/soft_nms_cpu.pyx":96 - * if ih > 0: - * ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) - * ov = iw * ih / ua # iou between max box and detection box # <<<<<<<<<<<<<< - * - * if method == 1: # linear - */ - __pyx_t_8 = (__pyx_v_iw * __pyx_v_ih); - if (unlikely(__pyx_v_ua == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 96, __pyx_L1_error) - } - __pyx_v_ov = (__pyx_t_8 / __pyx_v_ua); - - /* "detector/nms/src/soft_nms_cpu.pyx":98 - * ov = iw * ih / ua # iou between max box and detection box - * - * if method == 1: # linear # <<<<<<<<<<<<<< - * if ov > iou_thr: - * weight = 1 - ov - */ - switch (__pyx_v_method) { - case 1: - - /* "detector/nms/src/soft_nms_cpu.pyx":99 - * - * if method == 1: # linear - * if ov > iou_thr: # <<<<<<<<<<<<<< - * weight = 1 - ov - * else: - */ - __pyx_t_9 = ((__pyx_v_ov > __pyx_v_iou_thr) != 0); - if (__pyx_t_9) { - - /* "detector/nms/src/soft_nms_cpu.pyx":100 - * if method == 1: # linear - * if ov > iou_thr: - * weight = 1 - ov # <<<<<<<<<<<<<< - * else: - * weight = 1 - */ - __pyx_v_weight = (1.0 - __pyx_v_ov); - - /* "detector/nms/src/soft_nms_cpu.pyx":99 - * - * if method == 1: # linear - * if ov > iou_thr: # <<<<<<<<<<<<<< - * weight = 1 - ov - * else: - */ - goto __pyx_L12; - } - - /* "detector/nms/src/soft_nms_cpu.pyx":102 - * weight = 1 - ov - * else: - * weight = 1 # <<<<<<<<<<<<<< - * elif method == 2: # gaussian - * weight = np.exp(-(ov * ov) / sigma) - */ - /*else*/ { - __pyx_v_weight = 1.0; - } - __pyx_L12:; - - /* "detector/nms/src/soft_nms_cpu.pyx":98 - * ov = iw * ih / ua # iou between max box and detection box - * - * if method == 1: # linear # <<<<<<<<<<<<<< - * if ov > iou_thr: - * weight = 1 - ov - */ - break; - case 2: - - /* "detector/nms/src/soft_nms_cpu.pyx":104 - * weight = 1 - * elif method == 2: # gaussian - * weight = np.exp(-(ov * ov) / sigma) # <<<<<<<<<<<<<< - * else: # original NMS - * if ov > iou_thr: - */ - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_exp); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_8 = (-(__pyx_v_ov * __pyx_v_ov)); - if (unlikely(__pyx_v_sigma == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 104, __pyx_L1_error) - } - __pyx_t_5 = PyFloat_FromDouble((__pyx_t_8 / __pyx_v_sigma)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_10 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) { - __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_1); - if (likely(__pyx_t_10)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); - __Pyx_INCREF(__pyx_t_10); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_1, function); - } - } - __pyx_t_3 = (__pyx_t_10) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_10, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_5); - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_8 = __pyx_PyFloat_AsFloat(__pyx_t_3); if (unlikely((__pyx_t_8 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_weight = __pyx_t_8; - - /* "detector/nms/src/soft_nms_cpu.pyx":103 - * else: - * weight = 1 - * elif method == 2: # gaussian # <<<<<<<<<<<<<< - * weight = np.exp(-(ov * ov) / sigma) - * else: # original NMS - */ - break; - default: - - /* "detector/nms/src/soft_nms_cpu.pyx":106 - * weight = np.exp(-(ov * ov) / sigma) - * else: # original NMS - * if ov > iou_thr: # <<<<<<<<<<<<<< - * weight = 0 - * else: - */ - __pyx_t_9 = ((__pyx_v_ov > __pyx_v_iou_thr) != 0); - if (__pyx_t_9) { - - /* "detector/nms/src/soft_nms_cpu.pyx":107 - * else: # original NMS - * if ov > iou_thr: - * weight = 0 # <<<<<<<<<<<<<< - * else: - * weight = 1 - */ - __pyx_v_weight = 0.0; - - /* "detector/nms/src/soft_nms_cpu.pyx":106 - * weight = np.exp(-(ov * ov) / sigma) - * else: # original NMS - * if ov > iou_thr: # <<<<<<<<<<<<<< - * weight = 0 - * else: - */ - goto __pyx_L13; - } - - /* "detector/nms/src/soft_nms_cpu.pyx":109 - * weight = 0 - * else: - * weight = 1 # <<<<<<<<<<<<<< - * - * boxes[pos, 4] = weight * boxes[pos, 4] - */ - /*else*/ { - __pyx_v_weight = 1.0; - } - __pyx_L13:; - break; - } - - /* "detector/nms/src/soft_nms_cpu.pyx":111 - * weight = 1 - * - * boxes[pos, 4] = weight * boxes[pos, 4] # <<<<<<<<<<<<<< - * - * # if box score falls below threshold, discard the box by - */ - __pyx_t_3 = PyFloat_FromDouble(__pyx_v_weight); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_4); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = PyNumber_Multiply(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_4); - __pyx_t_1 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_3, __pyx_t_5) < 0)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":115 - * # if box score falls below threshold, discard the box by - * # swapping with last box update N - * if boxes[pos, 4] < min_score: # <<<<<<<<<<<<<< - * boxes[pos, 0] = boxes[N-1, 0] - * boxes[pos, 1] = boxes[N-1, 1] - */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_4); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = PyFloat_FromDouble(__pyx_v_min_score); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (__pyx_t_9) { - - /* "detector/nms/src/soft_nms_cpu.pyx":116 - * # swapping with last box update N - * if boxes[pos, 4] < min_score: - * boxes[pos, 0] = boxes[N-1, 0] # <<<<<<<<<<<<<< - * boxes[pos, 1] = boxes[N-1, 1] - * boxes[pos, 2] = boxes[N-1, 2] - */ - __pyx_t_1 = __Pyx_PyInt_From_long((__pyx_v_N - 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_0); - __pyx_t_3 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_5, __pyx_t_1) < 0)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":117 - * if boxes[pos, 4] < min_score: - * boxes[pos, 0] = boxes[N-1, 0] - * boxes[pos, 1] = boxes[N-1, 1] # <<<<<<<<<<<<<< - * boxes[pos, 2] = boxes[N-1, 2] - * boxes[pos, 3] = boxes[N-1, 3] - */ - __pyx_t_1 = __Pyx_PyInt_From_long((__pyx_v_N - 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_1); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_1); - __pyx_t_5 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_3, __pyx_t_1) < 0)) __PYX_ERR(0, 117, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":118 - * boxes[pos, 0] = boxes[N-1, 0] - * boxes[pos, 1] = boxes[N-1, 1] - * boxes[pos, 2] = boxes[N-1, 2] # <<<<<<<<<<<<<< - * boxes[pos, 3] = boxes[N-1, 3] - * boxes[pos, 4] = boxes[N-1, 4] - */ - __pyx_t_1 = __Pyx_PyInt_From_long((__pyx_v_N - 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 118, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 118, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_2); - __Pyx_GIVEREF(__pyx_int_2); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_2); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 118, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 118, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 118, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_2); - __Pyx_GIVEREF(__pyx_int_2); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_2); - __pyx_t_3 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_5, __pyx_t_1) < 0)) __PYX_ERR(0, 118, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":119 - * boxes[pos, 1] = boxes[N-1, 1] - * boxes[pos, 2] = boxes[N-1, 2] - * boxes[pos, 3] = boxes[N-1, 3] # <<<<<<<<<<<<<< - * boxes[pos, 4] = boxes[N-1, 4] - * inds[pos] = inds[N - 1] - */ - __pyx_t_1 = __Pyx_PyInt_From_long((__pyx_v_N - 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_3); - __Pyx_GIVEREF(__pyx_int_3); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_3); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5); - __Pyx_INCREF(__pyx_int_3); - __Pyx_GIVEREF(__pyx_int_3); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_3); - __pyx_t_5 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_3, __pyx_t_1) < 0)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":120 - * boxes[pos, 2] = boxes[N-1, 2] - * boxes[pos, 3] = boxes[N-1, 3] - * boxes[pos, 4] = boxes[N-1, 4] # <<<<<<<<<<<<<< - * inds[pos] = inds[N - 1] - * N = N - 1 - */ - __pyx_t_1 = __Pyx_PyInt_From_long((__pyx_v_N - 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 120, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 120, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_4); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_boxes, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 120, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 120, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 120, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __Pyx_INCREF(__pyx_int_4); - __Pyx_GIVEREF(__pyx_int_4); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_int_4); - __pyx_t_3 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_boxes, __pyx_t_5, __pyx_t_1) < 0)) __PYX_ERR(0, 120, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":121 - * boxes[pos, 3] = boxes[N-1, 3] - * boxes[pos, 4] = boxes[N-1, 4] - * inds[pos] = inds[N - 1] # <<<<<<<<<<<<<< - * N = N - 1 - * pos = pos - 1 - */ - __pyx_t_11 = (__pyx_v_N - 1); - __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_inds, __pyx_t_11, long, 1, __Pyx_PyInt_From_long, 0, 1, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (unlikely(__Pyx_SetItemInt(__pyx_v_inds, __pyx_v_pos, __pyx_t_1, int, 1, __Pyx_PyInt_From_int, 0, 1, 0) < 0)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":122 - * boxes[pos, 4] = boxes[N-1, 4] - * inds[pos] = inds[N - 1] - * N = N - 1 # <<<<<<<<<<<<<< - * pos = pos - 1 - * - */ - __pyx_v_N = (__pyx_v_N - 1); - - /* "detector/nms/src/soft_nms_cpu.pyx":123 - * inds[pos] = inds[N - 1] - * N = N - 1 - * pos = pos - 1 # <<<<<<<<<<<<<< - * - * pos = pos + 1 - */ - __pyx_v_pos = (__pyx_v_pos - 1); - - /* "detector/nms/src/soft_nms_cpu.pyx":115 - * # if box score falls below threshold, discard the box by - * # swapping with last box update N - * if boxes[pos, 4] < min_score: # <<<<<<<<<<<<<< - * boxes[pos, 0] = boxes[N-1, 0] - * boxes[pos, 1] = boxes[N-1, 1] - */ - } - - /* "detector/nms/src/soft_nms_cpu.pyx":94 - * if iw > 0: - * ih = (min(ty2, y2) - max(ty1, y1) + 1) - * if ih > 0: # <<<<<<<<<<<<<< - * ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) - * ov = iw * ih / ua # iou between max box and detection box - */ - } - - /* "detector/nms/src/soft_nms_cpu.pyx":92 - * area = (x2 - x1 + 1) * (y2 - y1 + 1) - * iw = (min(tx2, x2) - max(tx1, x1) + 1) - * if iw > 0: # <<<<<<<<<<<<<< - * ih = (min(ty2, y2) - max(ty1, y1) + 1) - * if ih > 0: - */ - } - - /* "detector/nms/src/soft_nms_cpu.pyx":125 - * pos = pos - 1 - * - * pos = pos + 1 # <<<<<<<<<<<<<< - * - * return boxes[:N], inds[:N] - */ - __pyx_v_pos = (__pyx_v_pos + 1); - } - - /* "detector/nms/src/soft_nms_cpu.pyx":39 - * inds = np.arange(N) - * - * for i in range(N): # <<<<<<<<<<<<<< - * maxscore = boxes[i, 4] - * maxpos = i - */ - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":127 - * pos = pos + 1 - * - * return boxes[:N], inds[:N] # <<<<<<<<<<<<<< - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyObject_GetSlice(__pyx_v_boxes, 0, __pyx_v_N, NULL, NULL, NULL, 0, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 127, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyObject_GetSlice(__pyx_v_inds, 0, __pyx_v_N, NULL, NULL, NULL, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 127, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 127, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1); - __pyx_t_2 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; - - /* "detector/nms/src/soft_nms_cpu.pyx":22 - * - * - * def soft_nms_cpu( # <<<<<<<<<<<<<< - * np.ndarray[float, ndim=2] boxes_in, - * float iou_thr, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_10); - { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_boxes_in.rcbuffer->pybuffer); - __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("detector.nms.soft_nms_cpu.soft_nms_cpu", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - goto __pyx_L2; - __pyx_L0:; - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_boxes_in.rcbuffer->pybuffer); - __pyx_L2:; - __Pyx_XDECREF(__pyx_v_boxes); - __Pyx_XDECREF(__pyx_v_inds); - __Pyx_XDECREF(__pyx_v_i); - __Pyx_XDECREF(__pyx_v_ti); - __Pyx_XDECREF(__pyx_v_s); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":258 - * # experimental exception made for __getbuffer__ and __releasebuffer__ - * # -- the details of this may change. - * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< - * # This implementation of getbuffer is geared towards Cython - * # requirements, and does not yet fulfill the PEP. - */ - -/* Python wrapper */ -static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); - __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_v_i; - int __pyx_v_ndim; - int __pyx_v_endian_detector; - int __pyx_v_little_endian; - int __pyx_v_t; - char *__pyx_v_f; - PyArray_Descr *__pyx_v_descr = 0; - int __pyx_v_offset; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - PyArray_Descr *__pyx_t_7; - PyObject *__pyx_t_8 = NULL; - char *__pyx_t_9; - if (__pyx_v_info == NULL) { - PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); - return -1; - } - __Pyx_RefNannySetupContext("__getbuffer__", 0); - __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(__pyx_v_info->obj); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":265 - * - * cdef int i, ndim - * cdef int endian_detector = 1 # <<<<<<<<<<<<<< - * cdef bint little_endian = ((&endian_detector)[0] != 0) - * - */ - __pyx_v_endian_detector = 1; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":266 - * cdef int i, ndim - * cdef int endian_detector = 1 - * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< - * - * ndim = PyArray_NDIM(self) - */ - __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":268 - * cdef bint little_endian = ((&endian_detector)[0] != 0) - * - * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<< - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) - */ - __pyx_v_ndim = PyArray_NDIM(__pyx_v_self); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":270 - * ndim = PyArray_NDIM(self) - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") - */ - __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":271 - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)): # <<<<<<<<<<<<<< - * raise ValueError(u"ndarray is not C contiguous") - * - */ - __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_ARRAY_C_CONTIGUOUS) != 0)) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":270 - * ndim = PyArray_NDIM(self) - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") - */ - if (unlikely(__pyx_t_1)) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":272 - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 272, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 272, __pyx_L1_error) - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":270 - * ndim = PyArray_NDIM(self) - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 - * raise ValueError(u"ndarray is not C contiguous") - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") - */ - __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L7_bool_binop_done; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":275 - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)): # <<<<<<<<<<<<<< - * raise ValueError(u"ndarray is not Fortran contiguous") - * - */ - __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_ARRAY_F_CONTIGUOUS) != 0)) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L7_bool_binop_done:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 - * raise ValueError(u"ndarray is not C contiguous") - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") - */ - if (unlikely(__pyx_t_1)) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":276 - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< - * - * info.buf = PyArray_DATA(self) - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 276, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 276, __pyx_L1_error) - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 - * raise ValueError(u"ndarray is not C contiguous") - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":278 - * raise ValueError(u"ndarray is not Fortran contiguous") - * - * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<< - * info.ndim = ndim - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - */ - __pyx_v_info->buf = PyArray_DATA(__pyx_v_self); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":279 - * - * info.buf = PyArray_DATA(self) - * info.ndim = ndim # <<<<<<<<<<<<<< - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - * # Allocate new buffer for strides and shape info. - */ - __pyx_v_info->ndim = __pyx_v_ndim; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":280 - * info.buf = PyArray_DATA(self) - * info.ndim = ndim - * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< - * # Allocate new buffer for strides and shape info. - * # This is allocated as one block, strides first. - */ - __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); - if (__pyx_t_1) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":283 - * # Allocate new buffer for strides and shape info. - * # This is allocated as one block, strides first. - * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) # <<<<<<<<<<<<<< - * info.shape = info.strides + ndim - * for i in range(ndim): - */ - __pyx_v_info->strides = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * 2) * ((size_t)__pyx_v_ndim)))); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":284 - * # This is allocated as one block, strides first. - * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) - * info.shape = info.strides + ndim # <<<<<<<<<<<<<< - * for i in range(ndim): - * info.strides[i] = PyArray_STRIDES(self)[i] - */ - __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":285 - * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) - * info.shape = info.strides + ndim - * for i in range(ndim): # <<<<<<<<<<<<<< - * info.strides[i] = PyArray_STRIDES(self)[i] - * info.shape[i] = PyArray_DIMS(self)[i] - */ - __pyx_t_4 = __pyx_v_ndim; - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":286 - * info.shape = info.strides + ndim - * for i in range(ndim): - * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<< - * info.shape[i] = PyArray_DIMS(self)[i] - * else: - */ - (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":287 - * for i in range(ndim): - * info.strides[i] = PyArray_STRIDES(self)[i] - * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<< - * else: - * info.strides = PyArray_STRIDES(self) - */ - (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]); - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":280 - * info.buf = PyArray_DATA(self) - * info.ndim = ndim - * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< - * # Allocate new buffer for strides and shape info. - * # This is allocated as one block, strides first. - */ - goto __pyx_L9; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":289 - * info.shape[i] = PyArray_DIMS(self)[i] - * else: - * info.strides = PyArray_STRIDES(self) # <<<<<<<<<<<<<< - * info.shape = PyArray_DIMS(self) - * info.suboffsets = NULL - */ - /*else*/ { - __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self)); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":290 - * else: - * info.strides = PyArray_STRIDES(self) - * info.shape = PyArray_DIMS(self) # <<<<<<<<<<<<<< - * info.suboffsets = NULL - * info.itemsize = PyArray_ITEMSIZE(self) - */ - __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self)); - } - __pyx_L9:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":291 - * info.strides = PyArray_STRIDES(self) - * info.shape = PyArray_DIMS(self) - * info.suboffsets = NULL # <<<<<<<<<<<<<< - * info.itemsize = PyArray_ITEMSIZE(self) - * info.readonly = not PyArray_ISWRITEABLE(self) - */ - __pyx_v_info->suboffsets = NULL; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":292 - * info.shape = PyArray_DIMS(self) - * info.suboffsets = NULL - * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<< - * info.readonly = not PyArray_ISWRITEABLE(self) - * - */ - __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":293 - * info.suboffsets = NULL - * info.itemsize = PyArray_ITEMSIZE(self) - * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<< - * - * cdef int t - */ - __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0)); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":296 - * - * cdef int t - * cdef char* f = NULL # <<<<<<<<<<<<<< - * cdef dtype descr = PyArray_DESCR(self) - * cdef int offset - */ - __pyx_v_f = NULL; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":297 - * cdef int t - * cdef char* f = NULL - * cdef dtype descr = PyArray_DESCR(self) # <<<<<<<<<<<<<< - * cdef int offset - * - */ - __pyx_t_7 = PyArray_DESCR(__pyx_v_self); - __pyx_t_3 = ((PyObject *)__pyx_t_7); - __Pyx_INCREF(__pyx_t_3); - __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3); - __pyx_t_3 = 0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":300 - * cdef int offset - * - * info.obj = self # <<<<<<<<<<<<<< - * - * if not PyDataType_HASFIELDS(descr): - */ - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); - __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":302 - * info.obj = self - * - * if not PyDataType_HASFIELDS(descr): # <<<<<<<<<<<<<< - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or - */ - __pyx_t_1 = ((!(PyDataType_HASFIELDS(__pyx_v_descr) != 0)) != 0); - if (__pyx_t_1) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":303 - * - * if not PyDataType_HASFIELDS(descr): - * t = descr.type_num # <<<<<<<<<<<<<< - * if ((descr.byteorder == c'>' and little_endian) or - * (descr.byteorder == c'<' and not little_endian)): - */ - __pyx_t_4 = __pyx_v_descr->type_num; - __pyx_v_t = __pyx_t_4; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":304 - * if not PyDataType_HASFIELDS(descr): - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0); - if (!__pyx_t_2) { - goto __pyx_L15_next_or; - } else { - } - __pyx_t_2 = (__pyx_v_little_endian != 0); - if (!__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L14_bool_binop_done; - } - __pyx_L15_next_or:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":305 - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or - * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< - * raise ValueError(u"Non-native byte order not supported") - * if t == NPY_BYTE: f = "b" - */ - __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L14_bool_binop_done:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":304 - * if not PyDataType_HASFIELDS(descr): - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - if (unlikely(__pyx_t_1)) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":306 - * if ((descr.byteorder == c'>' and little_endian) or - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< - * if t == NPY_BYTE: f = "b" - * elif t == NPY_UBYTE: f = "B" - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 306, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 306, __pyx_L1_error) - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":304 - * if not PyDataType_HASFIELDS(descr): - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":307 - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<< - * elif t == NPY_UBYTE: f = "B" - * elif t == NPY_SHORT: f = "h" - */ - switch (__pyx_v_t) { - case NPY_BYTE: - __pyx_v_f = ((char *)"b"); - break; - case NPY_UBYTE: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":308 - * raise ValueError(u"Non-native byte order not supported") - * if t == NPY_BYTE: f = "b" - * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<< - * elif t == NPY_SHORT: f = "h" - * elif t == NPY_USHORT: f = "H" - */ - __pyx_v_f = ((char *)"B"); - break; - case NPY_SHORT: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":309 - * if t == NPY_BYTE: f = "b" - * elif t == NPY_UBYTE: f = "B" - * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<< - * elif t == NPY_USHORT: f = "H" - * elif t == NPY_INT: f = "i" - */ - __pyx_v_f = ((char *)"h"); - break; - case NPY_USHORT: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":310 - * elif t == NPY_UBYTE: f = "B" - * elif t == NPY_SHORT: f = "h" - * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<< - * elif t == NPY_INT: f = "i" - * elif t == NPY_UINT: f = "I" - */ - __pyx_v_f = ((char *)"H"); - break; - case NPY_INT: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":311 - * elif t == NPY_SHORT: f = "h" - * elif t == NPY_USHORT: f = "H" - * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<< - * elif t == NPY_UINT: f = "I" - * elif t == NPY_LONG: f = "l" - */ - __pyx_v_f = ((char *)"i"); - break; - case NPY_UINT: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":312 - * elif t == NPY_USHORT: f = "H" - * elif t == NPY_INT: f = "i" - * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<< - * elif t == NPY_LONG: f = "l" - * elif t == NPY_ULONG: f = "L" - */ - __pyx_v_f = ((char *)"I"); - break; - case NPY_LONG: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":313 - * elif t == NPY_INT: f = "i" - * elif t == NPY_UINT: f = "I" - * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<< - * elif t == NPY_ULONG: f = "L" - * elif t == NPY_LONGLONG: f = "q" - */ - __pyx_v_f = ((char *)"l"); - break; - case NPY_ULONG: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":314 - * elif t == NPY_UINT: f = "I" - * elif t == NPY_LONG: f = "l" - * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<< - * elif t == NPY_LONGLONG: f = "q" - * elif t == NPY_ULONGLONG: f = "Q" - */ - __pyx_v_f = ((char *)"L"); - break; - case NPY_LONGLONG: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":315 - * elif t == NPY_LONG: f = "l" - * elif t == NPY_ULONG: f = "L" - * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<< - * elif t == NPY_ULONGLONG: f = "Q" - * elif t == NPY_FLOAT: f = "f" - */ - __pyx_v_f = ((char *)"q"); - break; - case NPY_ULONGLONG: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":316 - * elif t == NPY_ULONG: f = "L" - * elif t == NPY_LONGLONG: f = "q" - * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<< - * elif t == NPY_FLOAT: f = "f" - * elif t == NPY_DOUBLE: f = "d" - */ - __pyx_v_f = ((char *)"Q"); - break; - case NPY_FLOAT: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":317 - * elif t == NPY_LONGLONG: f = "q" - * elif t == NPY_ULONGLONG: f = "Q" - * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<< - * elif t == NPY_DOUBLE: f = "d" - * elif t == NPY_LONGDOUBLE: f = "g" - */ - __pyx_v_f = ((char *)"f"); - break; - case NPY_DOUBLE: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":318 - * elif t == NPY_ULONGLONG: f = "Q" - * elif t == NPY_FLOAT: f = "f" - * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<< - * elif t == NPY_LONGDOUBLE: f = "g" - * elif t == NPY_CFLOAT: f = "Zf" - */ - __pyx_v_f = ((char *)"d"); - break; - case NPY_LONGDOUBLE: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":319 - * elif t == NPY_FLOAT: f = "f" - * elif t == NPY_DOUBLE: f = "d" - * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<< - * elif t == NPY_CFLOAT: f = "Zf" - * elif t == NPY_CDOUBLE: f = "Zd" - */ - __pyx_v_f = ((char *)"g"); - break; - case NPY_CFLOAT: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":320 - * elif t == NPY_DOUBLE: f = "d" - * elif t == NPY_LONGDOUBLE: f = "g" - * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<< - * elif t == NPY_CDOUBLE: f = "Zd" - * elif t == NPY_CLONGDOUBLE: f = "Zg" - */ - __pyx_v_f = ((char *)"Zf"); - break; - case NPY_CDOUBLE: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":321 - * elif t == NPY_LONGDOUBLE: f = "g" - * elif t == NPY_CFLOAT: f = "Zf" - * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<< - * elif t == NPY_CLONGDOUBLE: f = "Zg" - * elif t == NPY_OBJECT: f = "O" - */ - __pyx_v_f = ((char *)"Zd"); - break; - case NPY_CLONGDOUBLE: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":322 - * elif t == NPY_CFLOAT: f = "Zf" - * elif t == NPY_CDOUBLE: f = "Zd" - * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<< - * elif t == NPY_OBJECT: f = "O" - * else: - */ - __pyx_v_f = ((char *)"Zg"); - break; - case NPY_OBJECT: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":323 - * elif t == NPY_CDOUBLE: f = "Zd" - * elif t == NPY_CLONGDOUBLE: f = "Zg" - * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<< - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - */ - __pyx_v_f = ((char *)"O"); - break; - default: - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":325 - * elif t == NPY_OBJECT: f = "O" - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< - * info.format = f - * return - */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 325, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_8 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 325, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 325, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 325, __pyx_L1_error) - break; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":326 - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - * info.format = f # <<<<<<<<<<<<<< - * return - * else: - */ - __pyx_v_info->format = __pyx_v_f; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":327 - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - * info.format = f - * return # <<<<<<<<<<<<<< - * else: - * info.format = PyObject_Malloc(_buffer_format_string_len) - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":302 - * info.obj = self - * - * if not PyDataType_HASFIELDS(descr): # <<<<<<<<<<<<<< - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":329 - * return - * else: - * info.format = PyObject_Malloc(_buffer_format_string_len) # <<<<<<<<<<<<<< - * info.format[0] = c'^' # Native data types, manual alignment - * offset = 0 - */ - /*else*/ { - __pyx_v_info->format = ((char *)PyObject_Malloc(0xFF)); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":330 - * else: - * info.format = PyObject_Malloc(_buffer_format_string_len) - * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<< - * offset = 0 - * f = _util_dtypestring(descr, info.format + 1, - */ - (__pyx_v_info->format[0]) = '^'; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":331 - * info.format = PyObject_Malloc(_buffer_format_string_len) - * info.format[0] = c'^' # Native data types, manual alignment - * offset = 0 # <<<<<<<<<<<<<< - * f = _util_dtypestring(descr, info.format + 1, - * info.format + _buffer_format_string_len, - */ - __pyx_v_offset = 0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":332 - * info.format[0] = c'^' # Native data types, manual alignment - * offset = 0 - * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<< - * info.format + _buffer_format_string_len, - * &offset) - */ - __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 0xFF), (&__pyx_v_offset)); if (unlikely(__pyx_t_9 == ((char *)NULL))) __PYX_ERR(1, 332, __pyx_L1_error) - __pyx_v_f = __pyx_t_9; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":335 - * info.format + _buffer_format_string_len, - * &offset) - * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<< - * - * def __releasebuffer__(ndarray self, Py_buffer* info): - */ - (__pyx_v_f[0]) = '\x00'; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":258 - * # experimental exception made for __getbuffer__ and __releasebuffer__ - * # -- the details of this may change. - * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< - * # This implementation of getbuffer is geared towards Cython - * # requirements, and does not yet fulfill the PEP. - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - if (__pyx_v_info->obj != NULL) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - goto __pyx_L2; - __pyx_L0:; - if (__pyx_v_info->obj == Py_None) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - __pyx_L2:; - __Pyx_XDECREF((PyObject *)__pyx_v_descr); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":337 - * f[0] = c'\0' # Terminate format string - * - * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) - */ - -/* Python wrapper */ -static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/ -static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0); - __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) { - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("__releasebuffer__", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":338 - * - * def __releasebuffer__(ndarray self, Py_buffer* info): - * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - */ - __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0); - if (__pyx_t_1) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":339 - * def __releasebuffer__(ndarray self, Py_buffer* info): - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) # <<<<<<<<<<<<<< - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - * PyObject_Free(info.strides) - */ - PyObject_Free(__pyx_v_info->format); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":338 - * - * def __releasebuffer__(ndarray self, Py_buffer* info): - * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":340 - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< - * PyObject_Free(info.strides) - * # info.shape was stored after info.strides in the same block - */ - __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); - if (__pyx_t_1) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":341 - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - * PyObject_Free(info.strides) # <<<<<<<<<<<<<< - * # info.shape was stored after info.strides in the same block - * - */ - PyObject_Free(__pyx_v_info->strides); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":340 - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< - * PyObject_Free(info.strides) - * # info.shape was stored after info.strides in the same block - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":337 - * f[0] = c'\0' # Terminate format string - * - * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":821 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":822 - * - * cdef inline object PyArray_MultiIterNew1(a): - * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew2(a, b): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 822, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":821 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":824 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":825 - * - * cdef inline object PyArray_MultiIterNew2(a, b): - * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 825, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":824 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":827 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":828 - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 828, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":827 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":830 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":831 - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): - * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 831, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":830 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":833 - * return PyArray_MultiIterNew(4, a, b, c, d) - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":834 - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): - * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 834, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":833 - * return PyArray_MultiIterNew(4, a, b, c, d) - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":836 - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("PyDataType_SHAPE", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":837 - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: - */ - __pyx_t_1 = (PyDataType_HASSUBARRAY(__pyx_v_d) != 0); - if (__pyx_t_1) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":838 - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape # <<<<<<<<<<<<<< - * else: - * return () - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject*)__pyx_v_d->subarray->shape)); - __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":837 - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":840 - * return d.subarray.shape - * else: - * return () # <<<<<<<<<<<<<< - * - * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_empty_tuple); - __pyx_r = __pyx_empty_tuple; - goto __pyx_L0; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":836 - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":842 - * return () - * - * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< - * # Recursive utility function used in __getbuffer__ to get format - * # string. The new location in the format string is returned. - */ - -static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) { - PyArray_Descr *__pyx_v_child = 0; - int __pyx_v_endian_detector; - int __pyx_v_little_endian; - PyObject *__pyx_v_fields = 0; - PyObject *__pyx_v_childname = NULL; - PyObject *__pyx_v_new_offset = NULL; - PyObject *__pyx_v_t = NULL; - char *__pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - int __pyx_t_6; - int __pyx_t_7; - long __pyx_t_8; - char *__pyx_t_9; - __Pyx_RefNannySetupContext("_util_dtypestring", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":847 - * - * cdef dtype child - * cdef int endian_detector = 1 # <<<<<<<<<<<<<< - * cdef bint little_endian = ((&endian_detector)[0] != 0) - * cdef tuple fields - */ - __pyx_v_endian_detector = 1; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":848 - * cdef dtype child - * cdef int endian_detector = 1 - * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< - * cdef tuple fields - * - */ - __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":851 - * cdef tuple fields - * - * for childname in descr.names: # <<<<<<<<<<<<<< - * fields = descr.fields[childname] - * child, new_offset = fields - */ - if (unlikely(__pyx_v_descr->names == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); - __PYX_ERR(1, 851, __pyx_L1_error) - } - __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; - for (;;) { - if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(1, 851, __pyx_L1_error) - #else - __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 851, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); - __pyx_t_3 = 0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":852 - * - * for childname in descr.names: - * fields = descr.fields[childname] # <<<<<<<<<<<<<< - * child, new_offset = fields - * - */ - if (unlikely(__pyx_v_descr->fields == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 852, __pyx_L1_error) - } - __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 852, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(1, 852, __pyx_L1_error) - __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":853 - * for childname in descr.names: - * fields = descr.fields[childname] - * child, new_offset = fields # <<<<<<<<<<<<<< - * - * if (end - f) - (new_offset - offset[0]) < 15: - */ - if (likely(__pyx_v_fields != Py_None)) { - PyObject* sequence = __pyx_v_fields; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(1, 853, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - #else - __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 853, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 853, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - #endif - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 853, __pyx_L1_error) - } - if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) __PYX_ERR(1, 853, __pyx_L1_error) - __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3)); - __pyx_t_3 = 0; - __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4); - __pyx_t_4 = 0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":855 - * child, new_offset = fields - * - * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - */ - __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 855, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 855, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 855, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0); - if (unlikely(__pyx_t_6)) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":856 - * - * if (end - f) - (new_offset - offset[0]) < 15: - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< - * - * if ((child.byteorder == c'>' and little_endian) or - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 856, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 856, __pyx_L1_error) - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":855 - * child, new_offset = fields - * - * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":858 - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0); - if (!__pyx_t_7) { - goto __pyx_L8_next_or; - } else { - } - __pyx_t_7 = (__pyx_v_little_endian != 0); - if (!__pyx_t_7) { - } else { - __pyx_t_6 = __pyx_t_7; - goto __pyx_L7_bool_binop_done; - } - __pyx_L8_next_or:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":859 - * - * if ((child.byteorder == c'>' and little_endian) or - * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< - * raise ValueError(u"Non-native byte order not supported") - * # One could encode it in the format string and have Cython - */ - __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0); - if (__pyx_t_7) { - } else { - __pyx_t_6 = __pyx_t_7; - goto __pyx_L7_bool_binop_done; - } - __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0); - __pyx_t_6 = __pyx_t_7; - __pyx_L7_bool_binop_done:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":858 - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - if (unlikely(__pyx_t_6)) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":860 - * if ((child.byteorder == c'>' and little_endian) or - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< - * # One could encode it in the format string and have Cython - * # complain instead, BUT: < and > in format strings also imply - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 860, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 860, __pyx_L1_error) - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":858 - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":870 - * - * # Output padding bytes - * while offset[0] < new_offset: # <<<<<<<<<<<<<< - * f[0] = 120 # "x"; pad byte - * f += 1 - */ - while (1) { - __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 870, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 870, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 870, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (!__pyx_t_6) break; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":871 - * # Output padding bytes - * while offset[0] < new_offset: - * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<< - * f += 1 - * offset[0] += 1 - */ - (__pyx_v_f[0]) = 0x78; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":872 - * while offset[0] < new_offset: - * f[0] = 120 # "x"; pad byte - * f += 1 # <<<<<<<<<<<<<< - * offset[0] += 1 - * - */ - __pyx_v_f = (__pyx_v_f + 1); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":873 - * f[0] = 120 # "x"; pad byte - * f += 1 - * offset[0] += 1 # <<<<<<<<<<<<<< - * - * offset[0] += child.itemsize - */ - __pyx_t_8 = 0; - (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1); - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":875 - * offset[0] += 1 - * - * offset[0] += child.itemsize # <<<<<<<<<<<<<< - * - * if not PyDataType_HASFIELDS(child): - */ - __pyx_t_8 = 0; - (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":877 - * offset[0] += child.itemsize - * - * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< - * t = child.type_num - * if end - f < 5: - */ - __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0); - if (__pyx_t_6) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":878 - * - * if not PyDataType_HASFIELDS(child): - * t = child.type_num # <<<<<<<<<<<<<< - * if end - f < 5: - * raise RuntimeError(u"Format string allocated too short.") - */ - __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 878, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); - __pyx_t_4 = 0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":879 - * if not PyDataType_HASFIELDS(child): - * t = child.type_num - * if end - f < 5: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short.") - * - */ - __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0); - if (unlikely(__pyx_t_6)) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":880 - * t = child.type_num - * if end - f < 5: - * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< - * - * # Until ticket #99 is fixed, use integers to avoid warnings - */ - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 880, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(1, 880, __pyx_L1_error) - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":879 - * if not PyDataType_HASFIELDS(child): - * t = child.type_num - * if end - f < 5: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short.") - * - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":883 - * - * # Until ticket #99 is fixed, use integers to avoid warnings - * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<< - * elif t == NPY_UBYTE: f[0] = 66 #"B" - * elif t == NPY_SHORT: f[0] = 104 #"h" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_BYTE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 883, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 883, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 883, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 98; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":884 - * # Until ticket #99 is fixed, use integers to avoid warnings - * if t == NPY_BYTE: f[0] = 98 #"b" - * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<< - * elif t == NPY_SHORT: f[0] = 104 #"h" - * elif t == NPY_USHORT: f[0] = 72 #"H" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UBYTE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 884, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 884, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 884, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 66; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":885 - * if t == NPY_BYTE: f[0] = 98 #"b" - * elif t == NPY_UBYTE: f[0] = 66 #"B" - * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<< - * elif t == NPY_USHORT: f[0] = 72 #"H" - * elif t == NPY_INT: f[0] = 105 #"i" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_SHORT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 885, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 885, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 885, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x68; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":886 - * elif t == NPY_UBYTE: f[0] = 66 #"B" - * elif t == NPY_SHORT: f[0] = 104 #"h" - * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<< - * elif t == NPY_INT: f[0] = 105 #"i" - * elif t == NPY_UINT: f[0] = 73 #"I" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_USHORT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 886, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 886, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 886, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 72; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":887 - * elif t == NPY_SHORT: f[0] = 104 #"h" - * elif t == NPY_USHORT: f[0] = 72 #"H" - * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<< - * elif t == NPY_UINT: f[0] = 73 #"I" - * elif t == NPY_LONG: f[0] = 108 #"l" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_INT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 887, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 887, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 887, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x69; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":888 - * elif t == NPY_USHORT: f[0] = 72 #"H" - * elif t == NPY_INT: f[0] = 105 #"i" - * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<< - * elif t == NPY_LONG: f[0] = 108 #"l" - * elif t == NPY_ULONG: f[0] = 76 #"L" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UINT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 888, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 888, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 888, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 73; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":889 - * elif t == NPY_INT: f[0] = 105 #"i" - * elif t == NPY_UINT: f[0] = 73 #"I" - * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<< - * elif t == NPY_ULONG: f[0] = 76 #"L" - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 889, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 889, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 889, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x6C; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":890 - * elif t == NPY_UINT: f[0] = 73 #"I" - * elif t == NPY_LONG: f[0] = 108 #"l" - * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<< - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 890, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 890, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 890, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 76; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":891 - * elif t == NPY_LONG: f[0] = 108 #"l" - * elif t == NPY_ULONG: f[0] = 76 #"L" - * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<< - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - * elif t == NPY_FLOAT: f[0] = 102 #"f" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 891, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 891, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 891, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x71; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":892 - * elif t == NPY_ULONG: f[0] = 76 #"L" - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<< - * elif t == NPY_FLOAT: f[0] = 102 #"f" - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 892, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 892, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 892, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 81; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":893 - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<< - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_FLOAT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 893, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 893, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 893, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x66; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":894 - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - * elif t == NPY_FLOAT: f[0] = 102 #"f" - * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<< - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 894, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 894, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 894, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x64; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":895 - * elif t == NPY_FLOAT: f[0] = 102 #"f" - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<< - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 895, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 895, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 895, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x67; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":896 - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<< - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 896, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 896, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 896, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 90; - (__pyx_v_f[1]) = 0x66; - __pyx_v_f = (__pyx_v_f + 1); - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":897 - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<< - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg - * elif t == NPY_OBJECT: f[0] = 79 #"O" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 897, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 897, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 897, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 90; - (__pyx_v_f[1]) = 0x64; - __pyx_v_f = (__pyx_v_f + 1); - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":898 - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<< - * elif t == NPY_OBJECT: f[0] = 79 #"O" - * else: - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 898, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 898, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 898, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 90; - (__pyx_v_f[1]) = 0x67; - __pyx_v_f = (__pyx_v_f + 1); - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":899 - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg - * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<< - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_OBJECT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 899, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 899, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 899, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (likely(__pyx_t_6)) { - (__pyx_v_f[0]) = 79; - goto __pyx_L15; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":901 - * elif t == NPY_OBJECT: f[0] = 79 #"O" - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< - * f += 1 - * else: - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyUnicode_FormatSafe(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 901, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 901, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(1, 901, __pyx_L1_error) - } - __pyx_L15:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":902 - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - * f += 1 # <<<<<<<<<<<<<< - * else: - * # Cython ignores struct boundary information ("T{...}"), - */ - __pyx_v_f = (__pyx_v_f + 1); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":877 - * offset[0] += child.itemsize - * - * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< - * t = child.type_num - * if end - f < 5: - */ - goto __pyx_L13; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":906 - * # Cython ignores struct boundary information ("T{...}"), - * # so don't output it - * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<< - * return f - * - */ - /*else*/ { - __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == ((char *)NULL))) __PYX_ERR(1, 906, __pyx_L1_error) - __pyx_v_f = __pyx_t_9; - } - __pyx_L13:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":851 - * cdef tuple fields - * - * for childname in descr.names: # <<<<<<<<<<<<<< - * fields = descr.fields[childname] - * child, new_offset = fields - */ - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":907 - * # so don't output it - * f = _util_dtypestring(child, f, end, offset) - * return f # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_f; - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":842 - * return () - * - * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< - * # Recursive utility function used in __getbuffer__ to get format - * # string. The new location in the format string is returned. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_child); - __Pyx_XDECREF(__pyx_v_fields); - __Pyx_XDECREF(__pyx_v_childname); - __Pyx_XDECREF(__pyx_v_new_offset); - __Pyx_XDECREF(__pyx_v_t); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1022 - * int _import_umath() except -1 - * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) - */ - -static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("set_array_base", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1023 - * - * cdef inline void set_array_base(ndarray arr, object base): - * Py_INCREF(base) # important to do this before stealing the reference below! # <<<<<<<<<<<<<< - * PyArray_SetBaseObject(arr, base) - * - */ - Py_INCREF(__pyx_v_base); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1024 - * cdef inline void set_array_base(ndarray arr, object base): - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) # <<<<<<<<<<<<<< - * - * cdef inline object get_array_base(ndarray arr): - */ - (void)(PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base)); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1022 - * int _import_umath() except -1 - * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1026 - * PyArray_SetBaseObject(arr, base) - * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * base = PyArray_BASE(arr) - * if base is NULL: - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { - PyObject *__pyx_v_base; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("get_array_base", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1027 - * - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) # <<<<<<<<<<<<<< - * if base is NULL: - * return None - */ - __pyx_v_base = PyArray_BASE(__pyx_v_arr); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1028 - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) - * if base is NULL: # <<<<<<<<<<<<<< - * return None - * return base - */ - __pyx_t_1 = ((__pyx_v_base == NULL) != 0); - if (__pyx_t_1) { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1029 - * base = PyArray_BASE(arr) - * if base is NULL: - * return None # <<<<<<<<<<<<<< - * return base - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1028 - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) - * if base is NULL: # <<<<<<<<<<<<<< - * return None - * return base - */ - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1030 - * if base is NULL: - * return None - * return base # <<<<<<<<<<<<<< - * - * # Versions of the import_* functions which are more suitable for - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_base)); - __pyx_r = ((PyObject *)__pyx_v_base); - goto __pyx_L0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1026 - * PyArray_SetBaseObject(arr, base) - * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * base = PyArray_BASE(arr) - * if base is NULL: - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1034 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * _import_array() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - __Pyx_RefNannySetupContext("import_array", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1035 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * _import_array() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1036 - * cdef inline int import_array() except -1: - * try: - * _import_array() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") - */ - __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1036, __pyx_L3_error) - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1035 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * _import_array() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1037 - * try: - * _import_array() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.multiarray failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1037, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1038 - * _import_array() - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_umath() except -1: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1038, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 1038, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1035 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * _import_array() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1034 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * _import_array() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1040 - * raise ImportError("numpy.core.multiarray failed to import") - * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - __Pyx_RefNannySetupContext("import_umath", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1041 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1042 - * cdef inline int import_umath() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.umath failed to import") - */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1042, __pyx_L3_error) - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1041 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1043 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1043, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1044 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1044, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 1044, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1041 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1040 - * raise ImportError("numpy.core.multiarray failed to import") - * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1046 - * raise ImportError("numpy.core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - __Pyx_RefNannySetupContext("import_ufunc", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1047 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1048 - * cdef inline int import_ufunc() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.umath failed to import") - */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1048, __pyx_L3_error) - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1047 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1049 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1049, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1050 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1050, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 1050, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1047 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1046 - * raise ImportError("numpy.core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec_soft_nms_cpu(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec_soft_nms_cpu}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "soft_nms_cpu", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0}, - {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0}, - {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, - {&__pyx_n_s_N, __pyx_k_N, sizeof(__pyx_k_N), 0, 0, 1, 1}, - {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0}, - {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, - {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, - {&__pyx_n_s_arange, __pyx_k_arange, sizeof(__pyx_k_arange), 0, 0, 1, 1}, - {&__pyx_n_s_area, __pyx_k_area, sizeof(__pyx_k_area), 0, 0, 1, 1}, - {&__pyx_n_s_box_area, __pyx_k_box_area, sizeof(__pyx_k_box_area), 0, 0, 1, 1}, - {&__pyx_n_s_boxes, __pyx_k_boxes, sizeof(__pyx_k_boxes), 0, 0, 1, 1}, - {&__pyx_n_s_boxes_in, __pyx_k_boxes_in, sizeof(__pyx_k_boxes_in), 0, 0, 1, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_copy, __pyx_k_copy, sizeof(__pyx_k_copy), 0, 0, 1, 1}, - {&__pyx_n_s_detector_nms_soft_nms_cpu, __pyx_k_detector_nms_soft_nms_cpu, sizeof(__pyx_k_detector_nms_soft_nms_cpu), 0, 0, 1, 1}, - {&__pyx_kp_s_detector_nms_src_soft_nms_cpu_py, __pyx_k_detector_nms_src_soft_nms_cpu_py, sizeof(__pyx_k_detector_nms_src_soft_nms_cpu_py), 0, 0, 1, 0}, - {&__pyx_n_s_exp, __pyx_k_exp, sizeof(__pyx_k_exp), 0, 0, 1, 1}, - {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, - {&__pyx_n_s_ih, __pyx_k_ih, sizeof(__pyx_k_ih), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_s_inds, __pyx_k_inds, sizeof(__pyx_k_inds), 0, 0, 1, 1}, - {&__pyx_n_s_iou_thr, __pyx_k_iou_thr, sizeof(__pyx_k_iou_thr), 0, 0, 1, 1}, - {&__pyx_n_s_iw, __pyx_k_iw, sizeof(__pyx_k_iw), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_maxpos, __pyx_k_maxpos, sizeof(__pyx_k_maxpos), 0, 0, 1, 1}, - {&__pyx_n_s_maxscore, __pyx_k_maxscore, sizeof(__pyx_k_maxscore), 0, 0, 1, 1}, - {&__pyx_n_s_method, __pyx_k_method, sizeof(__pyx_k_method), 0, 0, 1, 1}, - {&__pyx_n_s_min_score, __pyx_k_min_score, sizeof(__pyx_k_min_score), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0}, - {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0}, - {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, - {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, - {&__pyx_kp_u_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 1, 0, 0}, - {&__pyx_kp_u_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 1, 0, 0}, - {&__pyx_n_s_ov, __pyx_k_ov, sizeof(__pyx_k_ov), 0, 0, 1, 1}, - {&__pyx_n_s_pos, __pyx_k_pos, sizeof(__pyx_k_pos), 0, 0, 1, 1}, - {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, - {&__pyx_n_s_s, __pyx_k_s, sizeof(__pyx_k_s), 0, 0, 1, 1}, - {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1}, - {&__pyx_n_s_sigma, __pyx_k_sigma, sizeof(__pyx_k_sigma), 0, 0, 1, 1}, - {&__pyx_n_s_soft_nms_cpu, __pyx_k_soft_nms_cpu, sizeof(__pyx_k_soft_nms_cpu), 0, 0, 1, 1}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_ti, __pyx_k_ti, sizeof(__pyx_k_ti), 0, 0, 1, 1}, - {&__pyx_n_s_ts, __pyx_k_ts, sizeof(__pyx_k_ts), 0, 0, 1, 1}, - {&__pyx_n_s_tx1, __pyx_k_tx1, sizeof(__pyx_k_tx1), 0, 0, 1, 1}, - {&__pyx_n_s_tx2, __pyx_k_tx2, sizeof(__pyx_k_tx2), 0, 0, 1, 1}, - {&__pyx_n_s_ty1, __pyx_k_ty1, sizeof(__pyx_k_ty1), 0, 0, 1, 1}, - {&__pyx_n_s_ty2, __pyx_k_ty2, sizeof(__pyx_k_ty2), 0, 0, 1, 1}, - {&__pyx_n_s_ua, __pyx_k_ua, sizeof(__pyx_k_ua), 0, 0, 1, 1}, - {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0}, - {&__pyx_n_s_weight, __pyx_k_weight, sizeof(__pyx_k_weight), 0, 0, 1, 1}, - {&__pyx_n_s_x1, __pyx_k_x1, sizeof(__pyx_k_x1), 0, 0, 1, 1}, - {&__pyx_n_s_x2, __pyx_k_x2, sizeof(__pyx_k_x2), 0, 0, 1, 1}, - {&__pyx_n_s_y1, __pyx_k_y1, sizeof(__pyx_k_y1), 0, 0, 1, 1}, - {&__pyx_n_s_y2, __pyx_k_y2, sizeof(__pyx_k_y2), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 39, __pyx_L1_error) - __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 272, __pyx_L1_error) - __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(1, 856, __pyx_L1_error) - __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(1, 1038, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":272 - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - */ - __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 272, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":276 - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< - * - * info.buf = PyArray_DATA(self) - */ - __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 276, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__2); - __Pyx_GIVEREF(__pyx_tuple__2); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":306 - * if ((descr.byteorder == c'>' and little_endian) or - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< - * if t == NPY_BYTE: f = "b" - * elif t == NPY_UBYTE: f = "B" - */ - __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 306, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__3); - __Pyx_GIVEREF(__pyx_tuple__3); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":856 - * - * if (end - f) - (new_offset - offset[0]) < 15: - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< - * - * if ((child.byteorder == c'>' and little_endian) or - */ - __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 856, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__4); - __Pyx_GIVEREF(__pyx_tuple__4); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":880 - * t = child.type_num - * if end - f < 5: - * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< - * - * # Until ticket #99 is fixed, use integers to avoid warnings - */ - __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 880, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__5); - __Pyx_GIVEREF(__pyx_tuple__5); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1038 - * _import_array() - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_umath() except -1: - */ - __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_numpy_core_multiarray_failed_to); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 1038, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__6); - __Pyx_GIVEREF(__pyx_tuple__6); - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1044 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 1044, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__7); - __Pyx_GIVEREF(__pyx_tuple__7); - - /* "detector/nms/src/soft_nms_cpu.pyx":22 - * - * - * def soft_nms_cpu( # <<<<<<<<<<<<<< - * np.ndarray[float, ndim=2] boxes_in, - * float iou_thr, - */ - __pyx_tuple__8 = PyTuple_Pack(30, __pyx_n_s_boxes_in, __pyx_n_s_iou_thr, __pyx_n_s_method, __pyx_n_s_sigma, __pyx_n_s_min_score, __pyx_n_s_boxes, __pyx_n_s_N, __pyx_n_s_iw, __pyx_n_s_ih, __pyx_n_s_box_area, __pyx_n_s_ua, __pyx_n_s_pos, __pyx_n_s_maxscore, __pyx_n_s_maxpos, __pyx_n_s_x1, __pyx_n_s_x2, __pyx_n_s_y1, __pyx_n_s_y2, __pyx_n_s_tx1, __pyx_n_s_tx2, __pyx_n_s_ty1, __pyx_n_s_ty2, __pyx_n_s_ts, __pyx_n_s_area, __pyx_n_s_weight, __pyx_n_s_ov, __pyx_n_s_inds, __pyx_n_s_i, __pyx_n_s_ti, __pyx_n_s_s); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__8); - __Pyx_GIVEREF(__pyx_tuple__8); - __pyx_codeobj__9 = (PyObject*)__Pyx_PyCode_New(5, 0, 30, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__8, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_detector_nms_src_soft_nms_cpu_py, __pyx_n_s_soft_nms_cpu, 22, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__9)) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) __PYX_ERR(0, 1, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", - #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyTypeObject), - #else - sizeof(PyHeapTypeObject), - #endif - __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(2, 9, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 206, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_5numpy_dtype = __Pyx_ImportType(__pyx_t_1, "numpy", "dtype", sizeof(PyArray_Descr), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_dtype) __PYX_ERR(1, 206, __pyx_L1_error) - __pyx_ptype_5numpy_flatiter = __Pyx_ImportType(__pyx_t_1, "numpy", "flatiter", sizeof(PyArrayIterObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_flatiter) __PYX_ERR(1, 229, __pyx_L1_error) - __pyx_ptype_5numpy_broadcast = __Pyx_ImportType(__pyx_t_1, "numpy", "broadcast", sizeof(PyArrayMultiIterObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_broadcast) __PYX_ERR(1, 233, __pyx_L1_error) - __pyx_ptype_5numpy_ndarray = __Pyx_ImportType(__pyx_t_1, "numpy", "ndarray", sizeof(PyArrayObject), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_ndarray) __PYX_ERR(1, 242, __pyx_L1_error) - __pyx_ptype_5numpy_ufunc = __Pyx_ImportType(__pyx_t_1, "numpy", "ufunc", sizeof(PyUFuncObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_5numpy_ufunc) __PYX_ERR(1, 918, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#if PY_MAJOR_VERSION < 3 -#ifdef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC void -#else -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#endif -#else -#ifdef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC initsoft_nms_cpu(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC initsoft_nms_cpu(void) -#else -__Pyx_PyMODINIT_FUNC PyInit_soft_nms_cpu(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit_soft_nms_cpu(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec_soft_nms_cpu(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module 'soft_nms_cpu' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_soft_nms_cpu(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - #ifdef WITH_THREAD /* Python build with threading support? */ - PyEval_InitThreads(); - #endif - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("soft_nms_cpu", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_detector__nms__soft_nms_cpu) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "detector.nms.soft_nms_cpu")) { - if (unlikely(PyDict_SetItemString(modules, "detector.nms.soft_nms_cpu", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) goto __pyx_L1_error; - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) goto __pyx_L1_error; - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - (void)__Pyx_modinit_type_init_code(); - if (unlikely(__Pyx_modinit_type_import_code() != 0)) goto __pyx_L1_error; - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "detector/nms/src/soft_nms_cpu.pyx":11 - * # cython: language_level=3, boundscheck=False - * - * import numpy as np # <<<<<<<<<<<<<< - * cimport numpy as np - * - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 11, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 11, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":22 - * - * - * def soft_nms_cpu( # <<<<<<<<<<<<<< - * np.ndarray[float, ndim=2] boxes_in, - * float iou_thr, - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8detector_3nms_12soft_nms_cpu_1soft_nms_cpu, NULL, __pyx_n_s_detector_nms_soft_nms_cpu); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_soft_nms_cpu, __pyx_t_1) < 0) __PYX_ERR(0, 22, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "detector/nms/src/soft_nms_cpu.pyx":1 - * # ---------------------------------------------------------- # <<<<<<<<<<<<<< - * # Soft-NMS: Improving Object Detection With One Line of Code - * # Copyright (c) University of Maryland, College Park - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "../../anaconda3/envs/alphapose/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1046 - * raise ImportError("numpy.core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init detector.nms.soft_nms_cpu", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init detector.nms.soft_nms_cpu"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* ArgTypeTest */ -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) -{ - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - else if (exact) { - #if PY_MAJOR_VERSION == 2 - if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; - #endif - } - else { - if (likely(__Pyx_TypeCheck(obj, type))) return 1; - } - PyErr_Format(PyExc_TypeError, - "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", - name, type->tp_name, Py_TYPE(obj)->tp_name); - return 0; -} - -/* IsLittleEndian */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void) -{ - union { - uint32_t u32; - uint8_t u8[4]; - } S; - S.u32 = 0x01020304; - return S.u8[0] == 4; -} - -/* BufferFormatCheck */ -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type) { - stack[0].field = &ctx->root; - stack[0].parent_offset = 0; - ctx->root.type = type; - ctx->root.name = "buffer dtype"; - ctx->root.offset = 0; - ctx->head = stack; - ctx->head->field = &ctx->root; - ctx->fmt_offset = 0; - ctx->head->parent_offset = 0; - ctx->new_packmode = '@'; - ctx->enc_packmode = '@'; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->is_complex = 0; - ctx->is_valid_array = 0; - ctx->struct_alignment = 0; - while (type->typegroup == 'S') { - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = 0; - type = type->fields->type; - } -} -static int __Pyx_BufFmt_ParseNumber(const char** ts) { - int count; - const char* t = *ts; - if (*t < '0' || *t > '9') { - return -1; - } else { - count = *t++ - '0'; - while (*t >= '0' && *t <= '9') { - count *= 10; - count += *t++ - '0'; - } - } - *ts = t; - return count; -} -static int __Pyx_BufFmt_ExpectNumber(const char **ts) { - int number = __Pyx_BufFmt_ParseNumber(ts); - if (number == -1) - PyErr_Format(PyExc_ValueError,\ - "Does not understand character buffer dtype format string ('%c')", **ts); - return number; -} -static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { - PyErr_Format(PyExc_ValueError, - "Unexpected format string character: '%c'", ch); -} -static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { - switch (ch) { - case 'c': return "'char'"; - case 'b': return "'signed char'"; - case 'B': return "'unsigned char'"; - case 'h': return "'short'"; - case 'H': return "'unsigned short'"; - case 'i': return "'int'"; - case 'I': return "'unsigned int'"; - case 'l': return "'long'"; - case 'L': return "'unsigned long'"; - case 'q': return "'long long'"; - case 'Q': return "'unsigned long long'"; - case 'f': return (is_complex ? "'complex float'" : "'float'"); - case 'd': return (is_complex ? "'complex double'" : "'double'"); - case 'g': return (is_complex ? "'complex long double'" : "'long double'"); - case 'T': return "a struct"; - case 'O': return "Python object"; - case 'P': return "a pointer"; - case 's': case 'p': return "a string"; - case 0: return "end"; - default: return "unparseable format string"; - } -} -static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return 2; - case 'i': case 'I': case 'l': case 'L': return 4; - case 'q': case 'Q': return 8; - case 'f': return (is_complex ? 8 : 4); - case 'd': return (is_complex ? 16 : 8); - case 'g': { - PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); - return 0; - } - case 'O': case 'P': return sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { - switch (ch) { - case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(short); - case 'i': case 'I': return sizeof(int); - case 'l': case 'L': return sizeof(long); - #ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(PY_LONG_LONG); - #endif - case 'f': return sizeof(float) * (is_complex ? 2 : 1); - case 'd': return sizeof(double) * (is_complex ? 2 : 1); - case 'g': return sizeof(long double) * (is_complex ? 2 : 1); - case 'O': case 'P': return sizeof(void*); - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } - } -} -typedef struct { char c; short x; } __Pyx_st_short; -typedef struct { char c; int x; } __Pyx_st_int; -typedef struct { char c; long x; } __Pyx_st_long; -typedef struct { char c; float x; } __Pyx_st_float; -typedef struct { char c; double x; } __Pyx_st_double; -typedef struct { char c; long double x; } __Pyx_st_longdouble; -typedef struct { char c; void *x; } __Pyx_st_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; -#endif -static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); -#endif - case 'f': return sizeof(__Pyx_st_float) - sizeof(float); - case 'd': return sizeof(__Pyx_st_double) - sizeof(double); - case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -/* These are for computing the padding at the end of the struct to align - on the first member of the struct. This will probably the same as above, - but we don't have any guarantees. - */ -typedef struct { short x; char c; } __Pyx_pad_short; -typedef struct { int x; char c; } __Pyx_pad_int; -typedef struct { long x; char c; } __Pyx_pad_long; -typedef struct { float x; char c; } __Pyx_pad_float; -typedef struct { double x; char c; } __Pyx_pad_double; -typedef struct { long double x; char c; } __Pyx_pad_longdouble; -typedef struct { void *x; char c; } __Pyx_pad_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; -#endif -static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); -#endif - case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); - case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); - case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { - switch (ch) { - case 'c': - return 'H'; - case 'b': case 'h': case 'i': - case 'l': case 'q': case 's': case 'p': - return 'I'; - case 'B': case 'H': case 'I': case 'L': case 'Q': - return 'U'; - case 'f': case 'd': case 'g': - return (is_complex ? 'C' : 'R'); - case 'O': - return 'O'; - case 'P': - return 'P'; - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } - } -} -static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { - if (ctx->head == NULL || ctx->head->field == &ctx->root) { - const char* expected; - const char* quote; - if (ctx->head == NULL) { - expected = "end"; - quote = ""; - } else { - expected = ctx->head->field->type->name; - quote = "'"; - } - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected %s%s%s but got %s", - quote, expected, quote, - __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); - } else { - __Pyx_StructField* field = ctx->head->field; - __Pyx_StructField* parent = (ctx->head - 1)->field; - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", - field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), - parent->type->name, field->name); - } -} -static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { - char group; - size_t size, offset, arraysize = 1; - if (ctx->enc_type == 0) return 0; - if (ctx->head->field->type->arraysize[0]) { - int i, ndim = 0; - if (ctx->enc_type == 's' || ctx->enc_type == 'p') { - ctx->is_valid_array = ctx->head->field->type->ndim == 1; - ndim = 1; - if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { - PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %zu", - ctx->head->field->type->arraysize[0], ctx->enc_count); - return -1; - } - } - if (!ctx->is_valid_array) { - PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", - ctx->head->field->type->ndim, ndim); - return -1; - } - for (i = 0; i < ctx->head->field->type->ndim; i++) { - arraysize *= ctx->head->field->type->arraysize[i]; - } - ctx->is_valid_array = 0; - ctx->enc_count = 1; - } - group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); - do { - __Pyx_StructField* field = ctx->head->field; - __Pyx_TypeInfo* type = field->type; - if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { - size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); - } else { - size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); - } - if (ctx->enc_packmode == '@') { - size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); - size_t align_mod_offset; - if (align_at == 0) return -1; - align_mod_offset = ctx->fmt_offset % align_at; - if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; - if (ctx->struct_alignment == 0) - ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, - ctx->is_complex); - } - if (type->size != size || type->typegroup != group) { - if (type->typegroup == 'C' && type->fields != NULL) { - size_t parent_offset = ctx->head->parent_offset + field->offset; - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = parent_offset; - continue; - } - if ((type->typegroup == 'H' || group == 'H') && type->size == size) { - } else { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } - } - offset = ctx->head->parent_offset + field->offset; - if (ctx->fmt_offset != offset) { - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", - (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); - return -1; - } - ctx->fmt_offset += size; - if (arraysize) - ctx->fmt_offset += (arraysize - 1) * size; - --ctx->enc_count; - while (1) { - if (field == &ctx->root) { - ctx->head = NULL; - if (ctx->enc_count != 0) { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } - break; - } - ctx->head->field = ++field; - if (field->type == NULL) { - --ctx->head; - field = ctx->head->field; - continue; - } else if (field->type->typegroup == 'S') { - size_t parent_offset = ctx->head->parent_offset + field->offset; - if (field->type->fields->type == NULL) continue; - field = field->type->fields; - ++ctx->head; - ctx->head->field = field; - ctx->head->parent_offset = parent_offset; - break; - } else { - break; - } - } - } while (ctx->enc_count); - ctx->enc_type = 0; - ctx->is_complex = 0; - return 0; -} -static PyObject * -__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) -{ - const char *ts = *tsp; - int i = 0, number; - int ndim = ctx->head->field->type->ndim; -; - ++ts; - if (ctx->new_count != 1) { - PyErr_SetString(PyExc_ValueError, - "Cannot handle repeated arrays in format string"); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - while (*ts && *ts != ')') { - switch (*ts) { - case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; - default: break; - } - number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return NULL; - if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) - return PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %d", - ctx->head->field->type->arraysize[i], number); - if (*ts != ',' && *ts != ')') - return PyErr_Format(PyExc_ValueError, - "Expected a comma in format string, got '%c'", *ts); - if (*ts == ',') ts++; - i++; - } - if (i != ndim) - return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", - ctx->head->field->type->ndim, i); - if (!*ts) { - PyErr_SetString(PyExc_ValueError, - "Unexpected end of format string, expected ')'"); - return NULL; - } - ctx->is_valid_array = 1; - ctx->new_count = 1; - *tsp = ++ts; - return Py_None; -} -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { - int got_Z = 0; - while (1) { - switch(*ts) { - case 0: - if (ctx->enc_type != 0 && ctx->head == NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - if (ctx->head != NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - return ts; - case ' ': - case '\r': - case '\n': - ++ts; - break; - case '<': - if (!__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '>': - case '!': - if (__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '=': - case '@': - case '^': - ctx->new_packmode = *ts++; - break; - case 'T': - { - const char* ts_after_sub; - size_t i, struct_count = ctx->new_count; - size_t struct_alignment = ctx->struct_alignment; - ctx->new_count = 1; - ++ts; - if (*ts != '{') { - PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - ctx->enc_count = 0; - ctx->struct_alignment = 0; - ++ts; - ts_after_sub = ts; - for (i = 0; i != struct_count; ++i) { - ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); - if (!ts_after_sub) return NULL; - } - ts = ts_after_sub; - if (struct_alignment) ctx->struct_alignment = struct_alignment; - } - break; - case '}': - { - size_t alignment = ctx->struct_alignment; - ++ts; - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - if (alignment && ctx->fmt_offset % alignment) { - ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); - } - } - return ts; - case 'x': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->fmt_offset += ctx->new_count; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->enc_packmode = ctx->new_packmode; - ++ts; - break; - case 'Z': - got_Z = 1; - ++ts; - if (*ts != 'f' && *ts != 'd' && *ts != 'g') { - __Pyx_BufFmt_RaiseUnexpectedChar('Z'); - return NULL; - } - CYTHON_FALLTHROUGH; - case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': - case 'l': case 'L': case 'q': case 'Q': - case 'f': case 'd': case 'g': - case 'O': case 'p': - if (ctx->enc_type == *ts && got_Z == ctx->is_complex && - ctx->enc_packmode == ctx->new_packmode) { - ctx->enc_count += ctx->new_count; - ctx->new_count = 1; - got_Z = 0; - ++ts; - break; - } - CYTHON_FALLTHROUGH; - case 's': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_count = ctx->new_count; - ctx->enc_packmode = ctx->new_packmode; - ctx->enc_type = *ts; - ctx->is_complex = got_Z; - ++ts; - ctx->new_count = 1; - got_Z = 0; - break; - case ':': - ++ts; - while(*ts != ':') ++ts; - ++ts; - break; - case '(': - if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; - break; - default: - { - int number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return NULL; - ctx->new_count = (size_t)number; - } - } - } -} - -/* BufferGetAndValidate */ - static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { - if (unlikely(info->buf == NULL)) return; - if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; - __Pyx_ReleaseBuffer(info); -} -static void __Pyx_ZeroBuffer(Py_buffer* buf) { - buf->buf = NULL; - buf->obj = NULL; - buf->strides = __Pyx_zeros; - buf->shape = __Pyx_zeros; - buf->suboffsets = __Pyx_minusones; -} -static int __Pyx__GetBufferAndValidate( - Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, - int nd, int cast, __Pyx_BufFmt_StackElem* stack) -{ - buf->buf = NULL; - if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) { - __Pyx_ZeroBuffer(buf); - return -1; - } - if (unlikely(buf->ndim != nd)) { - PyErr_Format(PyExc_ValueError, - "Buffer has wrong number of dimensions (expected %d, got %d)", - nd, buf->ndim); - goto fail; - } - if (!cast) { - __Pyx_BufFmt_Context ctx; - __Pyx_BufFmt_Init(&ctx, stack, dtype); - if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; - } - if (unlikely((size_t)buf->itemsize != dtype->size)) { - PyErr_Format(PyExc_ValueError, - "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", - buf->itemsize, (buf->itemsize > 1) ? "s" : "", - dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); - goto fail; - } - if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; - return 0; -fail:; - __Pyx_SafeReleaseBuffer(buf); - return -1; -} - -/* PyFunctionFastCall */ - #if CYTHON_FAST_PYCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { - return NULL; - } - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif -#endif - -/* PyObjectCall */ - #if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = func->ob_type->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallMethO */ - #if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallNoArg */ - #if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, NULL, 0); - } -#endif -#ifdef __Pyx_CyFunction_USED - if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) -#else - if (likely(PyCFunction_Check(func))) -#endif - { - if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { - return __Pyx_PyObject_CallMethO(func, NULL); - } - } - return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); -} -#endif - -/* PyCFunctionFastCall */ - #if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); - } -} -#endif - -/* PyObjectCallOneArg */ - #if CYTHON_COMPILING_IN_CPYTHON -static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_New(1); - if (unlikely(!args)) return NULL; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, &arg, 1); - } -#endif - if (likely(PyCFunction_Check(func))) { - if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { - return __Pyx_PyObject_CallMethO(func, arg); -#if CYTHON_FAST_PYCCALL - } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { - return __Pyx_PyCFunction_FastCall(func, &arg, 1); -#endif - } - } - return __Pyx__PyObject_CallOneArg(func, arg); -} -#else -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_Pack(1, arg); - if (unlikely(!args)) return NULL; - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -#endif - -/* GetItemInt */ - static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (!j) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return m->sq_item(o, i); - } - } -#else - if (is_list || PySequence_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* PyDictVersioning */ - #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* GetModuleGlobalName */ - #if CYTHON_USE_DICT_VERSIONS -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) -#else -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) -#endif -{ - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 - result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } else if (unlikely(PyErr_Occurred())) { - return NULL; - } -#else - result = PyDict_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } -#endif -#else - result = PyObject_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } - PyErr_Clear(); -#endif - return __Pyx_GetBuiltinName(name); -} - -/* PyObjectCall2Args */ - static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { - PyObject *args, *result = NULL; - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyFunction_FastCall(function, args, 2); - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyCFunction_FastCall(function, args, 2); - } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(arg1); - PyTuple_SET_ITEM(args, 0, arg1); - Py_INCREF(arg2); - PyTuple_SET_ITEM(args, 1, arg2); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); -done: - return result; -} - -/* ObjectGetItem */ - #if CYTHON_USE_TYPE_SLOTS -static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) { - PyObject *runerr; - Py_ssize_t key_value; - PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence; - if (unlikely(!(m && m->sq_item))) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name); - return NULL; - } - key_value = __Pyx_PyIndex_AsSsize_t(index); - if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { - return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); - } - if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { - PyErr_Clear(); - PyErr_Format(PyExc_IndexError, "cannot fit '%.200s' into an index-sized integer", Py_TYPE(index)->tp_name); - } - return NULL; -} -static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { - PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping; - if (likely(m && m->mp_subscript)) { - return m->mp_subscript(obj, key); - } - return __Pyx_PyObject_GetIndex(obj, key); -} -#endif - -/* PyIntBinop */ - #if !CYTHON_COMPILING_IN_PYPY -static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, int inplace, int zerodivision_check) { - (void)inplace; - (void)zerodivision_check; - #if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(op1))) { - const long b = intval; - long x; - long a = PyInt_AS_LONG(op1); - x = (long)((unsigned long)a + b); - if (likely((x^a) >= 0 || (x^b) >= 0)) - return PyInt_FromLong(x); - return PyLong_Type.tp_as_number->nb_add(op1, op2); - } - #endif - #if CYTHON_USE_PYLONG_INTERNALS - if (likely(PyLong_CheckExact(op1))) { - const long b = intval; - long a, x; -#ifdef HAVE_LONG_LONG - const PY_LONG_LONG llb = intval; - PY_LONG_LONG lla, llx; -#endif - const digit* digits = ((PyLongObject*)op1)->ob_digit; - const Py_ssize_t size = Py_SIZE(op1); - if (likely(__Pyx_sst_abs(size) <= 1)) { - a = likely(size) ? digits[0] : 0; - if (size == -1) a = -a; - } else { - switch (size) { - case -2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case -3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case -4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - default: return PyLong_Type.tp_as_number->nb_add(op1, op2); - } - } - x = a + b; - return PyLong_FromLong(x); -#ifdef HAVE_LONG_LONG - long_long: - llx = lla + llb; - return PyLong_FromLongLong(llx); -#endif - - - } - #endif - if (PyFloat_CheckExact(op1)) { - const long b = intval; - double a = PyFloat_AS_DOUBLE(op1); - double result; - PyFPE_START_PROTECT("add", return NULL) - result = ((double)a) + (double)b; - PyFPE_END_PROTECT(result) - return PyFloat_FromDouble(result); - } - return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2); -} -#endif - -/* SetItemInt */ - static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { - int r; - if (!j) return -1; - r = PyObject_SetItem(o, j, v); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, - CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o)); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o)))) { - PyObject* old = PyList_GET_ITEM(o, n); - Py_INCREF(v); - PyList_SET_ITEM(o, n, v); - Py_DECREF(old); - return 1; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_ass_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return -1; - PyErr_Clear(); - } - } - return m->sq_ass_item(o, i, v); - } - } -#else -#if CYTHON_COMPILING_IN_PYPY - if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) -#else - if (is_list || PySequence_Check(o)) -#endif - { - return PySequence_SetItem(o, i, v); - } -#endif - return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v); -} - -/* SliceObject */ - static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj, - Py_ssize_t cstart, Py_ssize_t cstop, - PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice, - int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) { -#if CYTHON_USE_TYPE_SLOTS - PyMappingMethods* mp; -#if PY_MAJOR_VERSION < 3 - PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence; - if (likely(ms && ms->sq_slice)) { - if (!has_cstart) { - if (_py_start && (*_py_start != Py_None)) { - cstart = __Pyx_PyIndex_AsSsize_t(*_py_start); - if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; - } else - cstart = 0; - } - if (!has_cstop) { - if (_py_stop && (*_py_stop != Py_None)) { - cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop); - if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; - } else - cstop = PY_SSIZE_T_MAX; - } - if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) { - Py_ssize_t l = ms->sq_length(obj); - if (likely(l >= 0)) { - if (cstop < 0) { - cstop += l; - if (cstop < 0) cstop = 0; - } - if (cstart < 0) { - cstart += l; - if (cstart < 0) cstart = 0; - } - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - goto bad; - PyErr_Clear(); - } - } - return ms->sq_slice(obj, cstart, cstop); - } -#endif - mp = Py_TYPE(obj)->tp_as_mapping; - if (likely(mp && mp->mp_subscript)) -#endif - { - PyObject* result; - PyObject *py_slice, *py_start, *py_stop; - if (_py_slice) { - py_slice = *_py_slice; - } else { - PyObject* owned_start = NULL; - PyObject* owned_stop = NULL; - if (_py_start) { - py_start = *_py_start; - } else { - if (has_cstart) { - owned_start = py_start = PyInt_FromSsize_t(cstart); - if (unlikely(!py_start)) goto bad; - } else - py_start = Py_None; - } - if (_py_stop) { - py_stop = *_py_stop; - } else { - if (has_cstop) { - owned_stop = py_stop = PyInt_FromSsize_t(cstop); - if (unlikely(!py_stop)) { - Py_XDECREF(owned_start); - goto bad; - } - } else - py_stop = Py_None; - } - py_slice = PySlice_New(py_start, py_stop, Py_None); - Py_XDECREF(owned_start); - Py_XDECREF(owned_stop); - if (unlikely(!py_slice)) goto bad; - } -#if CYTHON_USE_TYPE_SLOTS - result = mp->mp_subscript(obj, py_slice); -#else - result = PyObject_GetItem(obj, py_slice); -#endif - if (!_py_slice) { - Py_DECREF(py_slice); - } - return result; - } - PyErr_Format(PyExc_TypeError, - "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name); -bad: - return NULL; -} - -/* PyErrFetchRestore */ - #if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* RaiseException */ - #if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, - CYTHON_UNUSED PyObject *cause) { - __Pyx_PyThreadState_declare - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { -#if CYTHON_COMPILING_IN_PYPY - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#else - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* DictGetItem */ - #if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY -static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { - PyObject *value; - value = PyDict_GetItemWithError(d, key); - if (unlikely(!value)) { - if (!PyErr_Occurred()) { - if (unlikely(PyTuple_Check(key))) { - PyObject* args = PyTuple_Pack(1, key); - if (likely(args)) { - PyErr_SetObject(PyExc_KeyError, args); - Py_DECREF(args); - } - } else { - PyErr_SetObject(PyExc_KeyError, key); - } - } - return NULL; - } - Py_INCREF(value); - return value; -} -#endif - -/* RaiseTooManyValuesToUnpack */ - static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); -} - -/* RaiseNeedMoreValuesToUnpack */ - static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { - PyErr_Format(PyExc_ValueError, - "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", - index, (index == 1) ? "" : "s"); -} - -/* RaiseNoneIterError */ - static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); -} - -/* ExtTypeTest */ - static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - if (likely(__Pyx_TypeCheck(obj, type))) - return 1; - PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", - Py_TYPE(obj)->tp_name, type->tp_name); - return 0; -} - -/* GetTopmostException */ - #if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * -__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; - } - return exc_info; -} -#endif - -/* SaveResetException */ - #if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - *type = exc_info->exc_type; - *value = exc_info->exc_value; - *tb = exc_info->exc_traceback; - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - #endif - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = type; - exc_info->exc_value = value; - exc_info->exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -#endif - -/* PyErrExceptionMatches */ - #if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; icurexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; - if (unlikely(PyTuple_Check(err))) - return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); -} -#endif - -/* GetException */ - #if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif -{ - PyObject *local_type, *local_value, *local_tb; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - -/* TypeImport */ - #ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, - size_t size, enum __Pyx_ImportType_CheckSize check_size) -{ - PyObject *result = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - result = PyObject_GetAttrString(module, class_name); - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if ((size_t)basicsize < size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(result); - return NULL; -} -#endif - -/* Import */ - static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) - goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; - } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) - goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if (strchr(__Pyx_MODULE_NAME, '.')) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif - } - } -bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; -} - -/* CLineInTraceback */ - #ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ - static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ - #include "compile.h" -#include "frameobject.h" -#include "traceback.h" -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(filename); - #else - py_srcfile = PyUnicode_FromString(filename); - #endif - if (!py_srcfile) goto bad; - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - Py_DECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) goto bad; - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -#if PY_MAJOR_VERSION < 3 -static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { - if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); - if (__Pyx_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags); - PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); - return -1; -} -static void __Pyx_ReleaseBuffer(Py_buffer *view) { - PyObject *obj = view->obj; - if (!obj) return; - if (PyObject_CheckBuffer(obj)) { - PyBuffer_Release(view); - return; - } - if ((0)) {} - else if (__Pyx_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); - view->obj = NULL; - Py_DECREF(obj); -} -#endif - - - /* CIntFromPyVerify */ - #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(int), - little, !is_unsigned); - } -} - -/* Declarations */ - #if CYTHON_CCOMPLEX - #ifdef __cplusplus - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - return ::std::complex< float >(x, y); - } - #else - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - return x + y*(__pyx_t_float_complex)_Complex_I; - } - #endif -#else - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - __pyx_t_float_complex z; - z.real = x; - z.imag = y; - return z; - } -#endif - -/* Arithmetic */ - #if CYTHON_CCOMPLEX -#else - static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - return (a.real == b.real) && (a.imag == b.imag); - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real + b.real; - z.imag = a.imag + b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real - b.real; - z.imag = a.imag - b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real * b.real - a.imag * b.imag; - z.imag = a.real * b.imag + a.imag * b.real; - return z; - } - #if 1 - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - if (b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); - } else if (fabsf(b.real) >= fabsf(b.imag)) { - if (b.real == 0 && b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.imag); - } else { - float r = b.imag / b.real; - float s = (float)(1.0) / (b.real + b.imag * r); - return __pyx_t_float_complex_from_parts( - (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); - } - } else { - float r = b.real / b.imag; - float s = (float)(1.0) / (b.imag + b.real * r); - return __pyx_t_float_complex_from_parts( - (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); - } - } - #else - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - if (b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); - } else { - float denom = b.real * b.real + b.imag * b.imag; - return __pyx_t_float_complex_from_parts( - (a.real * b.real + a.imag * b.imag) / denom, - (a.imag * b.real - a.real * b.imag) / denom); - } - } - #endif - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex a) { - __pyx_t_float_complex z; - z.real = -a.real; - z.imag = -a.imag; - return z; - } - static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex a) { - return (a.real == 0) && (a.imag == 0); - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex a) { - __pyx_t_float_complex z; - z.real = a.real; - z.imag = -a.imag; - return z; - } - #if 1 - static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex z) { - #if !defined(HAVE_HYPOT) || defined(_MSC_VER) - return sqrtf(z.real*z.real + z.imag*z.imag); - #else - return hypotf(z.real, z.imag); - #endif - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - float r, lnr, theta, z_r, z_theta; - if (b.imag == 0 && b.real == (int)b.real) { - if (b.real < 0) { - float denom = a.real * a.real + a.imag * a.imag; - a.real = a.real / denom; - a.imag = -a.imag / denom; - b.real = -b.real; - } - switch ((int)b.real) { - case 0: - z.real = 1; - z.imag = 0; - return z; - case 1: - return a; - case 2: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(a, a); - case 3: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(z, a); - case 4: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(z, z); - } - } - if (a.imag == 0) { - if (a.real == 0) { - return a; - } else if (b.imag == 0) { - z.real = powf(a.real, b.real); - z.imag = 0; - return z; - } else if (a.real > 0) { - r = a.real; - theta = 0; - } else { - r = -a.real; - theta = atan2f(0.0, -1.0); - } - } else { - r = __Pyx_c_abs_float(a); - theta = atan2f(a.imag, a.real); - } - lnr = logf(r); - z_r = expf(lnr * b.real - theta * b.imag); - z_theta = theta * b.real + lnr * b.imag; - z.real = z_r * cosf(z_theta); - z.imag = z_r * sinf(z_theta); - return z; - } - #endif -#endif - -/* Declarations */ - #if CYTHON_CCOMPLEX - #ifdef __cplusplus - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - return ::std::complex< double >(x, y); - } - #else - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - return x + y*(__pyx_t_double_complex)_Complex_I; - } - #endif -#else - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - __pyx_t_double_complex z; - z.real = x; - z.imag = y; - return z; - } -#endif - -/* Arithmetic */ - #if CYTHON_CCOMPLEX -#else - static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - return (a.real == b.real) && (a.imag == b.imag); - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real + b.real; - z.imag = a.imag + b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real - b.real; - z.imag = a.imag - b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real * b.real - a.imag * b.imag; - z.imag = a.real * b.imag + a.imag * b.real; - return z; - } - #if 1 - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - if (b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else if (fabs(b.real) >= fabs(b.imag)) { - if (b.real == 0 && b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); - } else { - double r = b.imag / b.real; - double s = (double)(1.0) / (b.real + b.imag * r); - return __pyx_t_double_complex_from_parts( - (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); - } - } else { - double r = b.real / b.imag; - double s = (double)(1.0) / (b.imag + b.real * r); - return __pyx_t_double_complex_from_parts( - (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); - } - } - #else - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - if (b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else { - double denom = b.real * b.real + b.imag * b.imag; - return __pyx_t_double_complex_from_parts( - (a.real * b.real + a.imag * b.imag) / denom, - (a.imag * b.real - a.real * b.imag) / denom); - } - } - #endif - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { - __pyx_t_double_complex z; - z.real = -a.real; - z.imag = -a.imag; - return z; - } - static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { - return (a.real == 0) && (a.imag == 0); - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { - __pyx_t_double_complex z; - z.real = a.real; - z.imag = -a.imag; - return z; - } - #if 1 - static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { - #if !defined(HAVE_HYPOT) || defined(_MSC_VER) - return sqrt(z.real*z.real + z.imag*z.imag); - #else - return hypot(z.real, z.imag); - #endif - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - double r, lnr, theta, z_r, z_theta; - if (b.imag == 0 && b.real == (int)b.real) { - if (b.real < 0) { - double denom = a.real * a.real + a.imag * a.imag; - a.real = a.real / denom; - a.imag = -a.imag / denom; - b.real = -b.real; - } - switch ((int)b.real) { - case 0: - z.real = 1; - z.imag = 0; - return z; - case 1: - return a; - case 2: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(a, a); - case 3: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(z, a); - case 4: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(z, z); - } - } - if (a.imag == 0) { - if (a.real == 0) { - return a; - } else if (b.imag == 0) { - z.real = pow(a.real, b.real); - z.imag = 0; - return z; - } else if (a.real > 0) { - r = a.real; - theta = 0; - } else { - r = -a.real; - theta = atan2(0.0, -1.0); - } - } else { - r = __Pyx_c_abs_double(a); - theta = atan2(a.imag, a.real); - } - lnr = log(r); - z_r = exp(lnr * b.real - theta * b.imag); - z_theta = theta * b.real + lnr * b.imag; - z.real = z_r * cos(z_theta); - z.imag = z_r * sin(z_theta); - return z; - } - #endif -#endif - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value) { - const enum NPY_TYPES neg_one = (enum NPY_TYPES) ((enum NPY_TYPES) 0 - (enum NPY_TYPES) 1), const_zero = (enum NPY_TYPES) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(enum NPY_TYPES) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(enum NPY_TYPES) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum NPY_TYPES) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(enum NPY_TYPES), - little, !is_unsigned); - } -} - -/* CIntFromPy */ - static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *x) { - const unsigned int neg_one = (unsigned int) ((unsigned int) 0 - (unsigned int) 1), const_zero = (unsigned int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(unsigned int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(unsigned int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (unsigned int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (unsigned int) 0; - case 1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, digits[0]) - case 2: - if (8 * sizeof(unsigned int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(unsigned int) >= 2 * PyLong_SHIFT) { - return (unsigned int) (((((unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(unsigned int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(unsigned int) >= 3 * PyLong_SHIFT) { - return (unsigned int) (((((((unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(unsigned int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(unsigned int) >= 4 * PyLong_SHIFT) { - return (unsigned int) (((((((((unsigned int)digits[3]) << PyLong_SHIFT) | (unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (unsigned int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(unsigned int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(unsigned int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(unsigned int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(unsigned int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (unsigned int) 0; - case -1: __PYX_VERIFY_RETURN_INT(unsigned int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, +digits[0]) - case -2: - if (8 * sizeof(unsigned int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(unsigned int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(unsigned int) - 1 > 2 * PyLong_SHIFT) { - return (unsigned int) (((unsigned int)-1)*(((((unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(unsigned int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(unsigned int) - 1 > 2 * PyLong_SHIFT) { - return (unsigned int) ((((((unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(unsigned int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(unsigned int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(unsigned int) - 1 > 3 * PyLong_SHIFT) { - return (unsigned int) (((unsigned int)-1)*(((((((unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(unsigned int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(unsigned int) - 1 > 3 * PyLong_SHIFT) { - return (unsigned int) ((((((((unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(unsigned int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(unsigned int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(unsigned int) - 1 > 4 * PyLong_SHIFT) { - return (unsigned int) (((unsigned int)-1)*(((((((((unsigned int)digits[3]) << PyLong_SHIFT) | (unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(unsigned int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(unsigned int) - 1 > 4 * PyLong_SHIFT) { - return (unsigned int) ((((((((((unsigned int)digits[3]) << PyLong_SHIFT) | (unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(unsigned int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(unsigned int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(unsigned int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(unsigned int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - unsigned int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (unsigned int) -1; - } - } else { - unsigned int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (unsigned int) -1; - val = __Pyx_PyInt_As_unsigned_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to unsigned int"); - return (unsigned int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to unsigned int"); - return (unsigned int) -1; -} - -/* CIntFromPy */ - static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* CIntFromPy */ - static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* FastTypeChecks */ - #if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; ip) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ diff --git a/cv/pose/alphapose/pytorch/detector/nms/src/soft_nms_cpu.pyx b/cv/pose/alphapose/pytorch/detector/nms/src/soft_nms_cpu.pyx deleted file mode 100755 index 97f53f18d..000000000 --- a/cv/pose/alphapose/pytorch/detector/nms/src/soft_nms_cpu.pyx +++ /dev/null @@ -1,127 +0,0 @@ -# ---------------------------------------------------------- -# Soft-NMS: Improving Object Detection With One Line of Code -# Copyright (c) University of Maryland, College Park -# Licensed under The MIT License [see LICENSE for details] -# Written by Navaneeth Bodla and Bharat Singh -# Modified by Kai Chen -# ---------------------------------------------------------- - -# cython: language_level=3, boundscheck=False - -import numpy as np -cimport numpy as np - - -cdef inline np.float32_t max(np.float32_t a, np.float32_t b): - return a if a >= b else b - -cdef inline np.float32_t min(np.float32_t a, np.float32_t b): - return a if a <= b else b - - -def soft_nms_cpu( - np.ndarray[float, ndim=2] boxes_in, - float iou_thr, - unsigned int method=1, - float sigma=0.5, - float min_score=0.001, -): - boxes = boxes_in.copy() - cdef int N = boxes.shape[0] - cdef float iw, ih, box_area - cdef float ua - cdef int pos = 0 - cdef float maxscore = 0 - cdef int maxpos = 0 - cdef float x1, x2, y1, y2, tx1, tx2, ty1, ty2, ts, area, weight, ov - inds = np.arange(N) - - for i in range(N): - maxscore = boxes[i, 4] - maxpos = i - - tx1 = boxes[i, 0] - ty1 = boxes[i, 1] - tx2 = boxes[i, 2] - ty2 = boxes[i, 3] - ts = boxes[i, 4] - ti = inds[i] - - pos = i + 1 - # get max box - while pos < N: - if maxscore < boxes[pos, 4]: - maxscore = boxes[pos, 4] - maxpos = pos - pos = pos + 1 - - # add max box as a detection - boxes[i, 0] = boxes[maxpos, 0] - boxes[i, 1] = boxes[maxpos, 1] - boxes[i, 2] = boxes[maxpos, 2] - boxes[i, 3] = boxes[maxpos, 3] - boxes[i, 4] = boxes[maxpos, 4] - inds[i] = inds[maxpos] - - # swap ith box with position of max box - boxes[maxpos, 0] = tx1 - boxes[maxpos, 1] = ty1 - boxes[maxpos, 2] = tx2 - boxes[maxpos, 3] = ty2 - boxes[maxpos, 4] = ts - inds[maxpos] = ti - - tx1 = boxes[i, 0] - ty1 = boxes[i, 1] - tx2 = boxes[i, 2] - ty2 = boxes[i, 3] - ts = boxes[i, 4] - - pos = i + 1 - # NMS iterations, note that N changes if detection boxes fall below - # threshold - while pos < N: - x1 = boxes[pos, 0] - y1 = boxes[pos, 1] - x2 = boxes[pos, 2] - y2 = boxes[pos, 3] - s = boxes[pos, 4] - - area = (x2 - x1 + 1) * (y2 - y1 + 1) - iw = (min(tx2, x2) - max(tx1, x1) + 1) - if iw > 0: - ih = (min(ty2, y2) - max(ty1, y1) + 1) - if ih > 0: - ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) - ov = iw * ih / ua # iou between max box and detection box - - if method == 1: # linear - if ov > iou_thr: - weight = 1 - ov - else: - weight = 1 - elif method == 2: # gaussian - weight = np.exp(-(ov * ov) / sigma) - else: # original NMS - if ov > iou_thr: - weight = 0 - else: - weight = 1 - - boxes[pos, 4] = weight * boxes[pos, 4] - - # if box score falls below threshold, discard the box by - # swapping with last box update N - if boxes[pos, 4] < min_score: - boxes[pos, 0] = boxes[N-1, 0] - boxes[pos, 1] = boxes[N-1, 1] - boxes[pos, 2] = boxes[N-1, 2] - boxes[pos, 3] = boxes[N-1, 3] - boxes[pos, 4] = boxes[N-1, 4] - inds[pos] = inds[N - 1] - N = N - 1 - pos = pos - 1 - - pos = pos + 1 - - return boxes[:N], inds[:N] diff --git a/cv/pose/alphapose/pytorch/detector/tracker/README.md b/cv/pose/alphapose/pytorch/detector/tracker/README.md deleted file mode 100755 index 70626eb0f..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## Introduction -MOT Tracker adapted from [Towards-Realtime-MOT](https://github.com/Zhongdao/Towards-Realtime-MOT), many thanks to their wonderful work! - -#### Getting started -Download detector [JDE-1088x608](https://github.com/Zhongdao/Towards-Realtime-MOT#pretrained-model-and-baseline-models) and place it under `AlphaPose/detector/tracker/data/` - -Enable tracking by setting the detector as tracker: `--detector tracker` \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/tracker/__init__.py b/cv/pose/alphapose/pytorch/detector/tracker/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/tracker/cfg/ccmcpe.json b/cv/pose/alphapose/pytorch/detector/tracker/cfg/ccmcpe.json deleted file mode 100755 index 92143b820..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/cfg/ccmcpe.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "root":"/home/wangzd/datasets/MOT", - "train": - { - "mot17":"./data/mot17.train", - "caltech":"./data/caltech.train", - "citypersons":"./data/citypersons.train", - "cuhksysu":"./data/cuhksysu.train", - "prw":"./data/prw.train", - "eth":"./data/eth.train" - }, - "test_emb": - { - "caltech":"./data/caltech.10k.val", - "cuhksysu":"./data/cuhksysu.val", - "prw":"./data/prw.val" - }, - "test": - { - "mot19":"./data/mot19.train", - "caltech":"./data/caltech.val", - "citypersons":"./data/citypersons.val" - } -} diff --git a/cv/pose/alphapose/pytorch/detector/tracker/cfg/yolov3.cfg b/cv/pose/alphapose/pytorch/detector/tracker/cfg/yolov3.cfg deleted file mode 100755 index 7dc4b337b..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/cfg/yolov3.cfg +++ /dev/null @@ -1,833 +0,0 @@ -[net] -# Testing -#batch=1 -#subdivisions=1 -# Training -batch=16 -subdivisions=1 -width=608 -height=1088 -channels=3 -momentum=0.9 -decay=0.0005 -angle=0 -saturation = 1.5 -exposure = 1.5 -hue=.1 - -learning_rate=0.001 -burn_in=1000 -max_batches = 500200 -policy=steps -steps=400000,450000 -scales=.1,.1 - -[convolutional] -batch_normalize=1 -filters=32 -size=3 -stride=1 -pad=1 -activation=leaky - -# Downsample - -[convolutional] -batch_normalize=1 -filters=64 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=32 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=64 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=64 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=64 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -###################### - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=24 -activation=linear - -######### embedding ########### -[route] -layers = -3 - -[convolutional] -size=3 -stride=1 -pad=1 -filters=512 -activation=linear - -[route] -layers = -3, -1 -############################### - - -[yolo] -mask = 8,9,10,11 -anchors = 8,24, 11, 34, 16,48, 23,68, 32,96, 45,135, 64,192, 90,271, 128,384, 180,540, 256,640, 512,640 -classes=1 -num=12 -jitter=.3 -ignore_thresh = .7 -truth_thresh = 1 -random=1 - - -[route] -layers = -7 - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[upsample] -stride=2 - -[route] -layers = -1, 61 - - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=512 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=512 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=512 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=24 -activation=linear - -######### embedding ########### -[route] -layers = -3 - -[convolutional] -size=3 -stride=1 -pad=1 -filters=512 -activation=linear - -[route] -layers = -3, -1 -############################### - -[yolo] -mask = 4,5,6,7 -anchors = 8,24, 11, 34, 16,48, 23,68, 32,96, 45,135, 64,192, 90,271, 128,384, 180,540, 256,640, 512,640 -classes=1 -num=12 -jitter=.3 -ignore_thresh = .7 -truth_thresh = 1 -random=1 - - - -[route] -layers = -7 - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[upsample] -stride=2 - -[route] -layers = -1, 36 - - - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=256 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=256 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=256 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=24 -activation=linear - - - -######### embedding ########### -[route] -layers = -3 - -[convolutional] -size=3 -stride=1 -pad=1 -filters=512 -activation=linear - -[route] -layers = -3, -1 -############################### - -[yolo] -mask = 0,1,2,3 -anchors = 8,24, 11,34, 16,48, 23,68, 32,96, 45,135, 64,192, 90,271, 128,384, 180,540, 256,640, 512,640 -classes=1 -num=12 -jitter=.3 -ignore_thresh = .7 -truth_thresh = 1 -random=1 diff --git a/cv/pose/alphapose/pytorch/detector/tracker/models.py b/cv/pose/alphapose/pytorch/detector/tracker/models.py deleted file mode 100755 index 5c6a1acd8..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/models.py +++ /dev/null @@ -1,373 +0,0 @@ -import os -from collections import defaultdict,OrderedDict - -import torch.nn as nn - -from tracker.utils.parse_config import * -from tracker.utils.utils import * -# from utils.syncbn import SyncBN -import time -import math - -batch_norm=nn.BatchNorm2d - -def create_modules(module_defs): - """ - Constructs module list of layer blocks from module configuration in module_defs - """ - hyperparams = module_defs.pop(0) - output_filters = [int(hyperparams['channels'])] - module_list = nn.ModuleList() - yolo_layer_count = 0 - for i, module_def in enumerate(module_defs): - modules = nn.Sequential() - - if module_def['type'] == 'convolutional': - bn = int(module_def['batch_normalize']) - filters = int(module_def['filters']) - kernel_size = int(module_def['size']) - pad = (kernel_size - 1) // 2 if int(module_def['pad']) else 0 - modules.add_module('conv_%d' % i, nn.Conv2d(in_channels=output_filters[-1], - out_channels=filters, - kernel_size=kernel_size, - stride=int(module_def['stride']), - padding=pad, - bias=not bn)) - if bn: - modules.add_module('batch_norm_%d' % i, batch_norm(filters)) - if module_def['activation'] == 'leaky': - modules.add_module('leaky_%d' % i, nn.LeakyReLU(0.1)) - - elif module_def['type'] == 'maxpool': - kernel_size = int(module_def['size']) - stride = int(module_def['stride']) - if kernel_size == 2 and stride == 1: - modules.add_module('_debug_padding_%d' % i, nn.ZeroPad2d((0, 1, 0, 1))) - maxpool = nn.MaxPool2d(kernel_size=kernel_size, stride=stride, padding=int((kernel_size - 1) // 2)) - modules.add_module('maxpool_%d' % i, maxpool) - - elif module_def['type'] == 'upsample': - upsample = Upsample(scale_factor=int(module_def['stride'])) - modules.add_module('upsample_%d' % i, upsample) - - elif module_def['type'] == 'route': - layers = [int(x) for x in module_def['layers'].split(',')] - filters = sum([output_filters[i + 1 if i > 0 else i] for i in layers]) - modules.add_module('route_%d' % i, EmptyLayer()) - - elif module_def['type'] == 'shortcut': - filters = output_filters[int(module_def['from'])] - modules.add_module('shortcut_%d' % i, EmptyLayer()) - - elif module_def['type'] == 'yolo': - anchor_idxs = [int(x) for x in module_def['mask'].split(',')] - # Extract anchors - anchors = [float(x) for x in module_def['anchors'].split(',')] - anchors = [(anchors[i], anchors[i + 1]) for i in range(0, len(anchors), 2)] - anchors = [anchors[i] for i in anchor_idxs] - nC = int(module_def['classes']) # number of classes - img_size = (int(hyperparams['width']),int(hyperparams['height'])) - # Define detection layer - yolo_layer = YOLOLayer(anchors, nC, hyperparams['nID'], img_size, yolo_layer_count, cfg=hyperparams['cfg']) - modules.add_module('yolo_%d' % i, yolo_layer) - yolo_layer_count += 1 - - # Register module list and number of output filters - module_list.append(modules) - output_filters.append(filters) - - return hyperparams, module_list - - -class EmptyLayer(nn.Module): - """Placeholder for 'route' and 'shortcut' layers""" - - def __init__(self): - super(EmptyLayer, self).__init__() - - def forward(self, x): - return x - - -class Upsample(nn.Module): - # Custom Upsample layer (nn.Upsample gives deprecated warning message) - - def __init__(self, scale_factor=1, mode='nearest'): - super(Upsample, self).__init__() - self.scale_factor = scale_factor - self.mode = mode - - def forward(self, x): - return F.interpolate(x, scale_factor=self.scale_factor, mode=self.mode) - - -class YOLOLayer(nn.Module): - def __init__(self, anchors, nC, nID, img_size, yolo_layer, cfg): - super(YOLOLayer, self).__init__() - self.layer = yolo_layer - nA = len(anchors) - self.anchors = torch.FloatTensor(anchors) - self.nA = nA # number of anchors (3) - self.nC = nC # number of classes (80) - self.nID = nID # number of identities - self.img_size = 0 - self.emb_dim = 512 - - self.SmoothL1Loss = nn.SmoothL1Loss() - self.SoftmaxLoss = nn.CrossEntropyLoss(ignore_index=-1) - self.CrossEntropyLoss = nn.CrossEntropyLoss() - self.IDLoss = nn.CrossEntropyLoss(ignore_index=-1) - self.s_c = nn.Parameter(-4.15*torch.ones(1)) # -4.15 - self.s_r = nn.Parameter(-4.85*torch.ones(1)) # -4.85 - self.s_id = nn.Parameter(-2.3*torch.ones(1)) # -2.3 - self.emb_scale = math.sqrt(2) * math.log(self.nID-1) - - - def forward(self, p_cat, img_size, targets=None, classifier=None, test_emb=False): - p, p_emb = p_cat[:, :24, ...], p_cat[:, 24:, ...] - nB, nGh, nGw = p.shape[0], p.shape[-2], p.shape[-1] - - if self.img_size != img_size: - create_grids(self, img_size, nGh, nGw) - - self.grid_xy = self.grid_xy.to(p) - self.anchor_wh = self.anchor_wh.to(p) - - p = p.view(nB, self.nA, self.nC + 5, nGh, nGw).permute(0, 1, 3, 4, 2).contiguous() # prediction - - p_emb = p_emb.permute(0,2,3,1).contiguous() - p_box = p[..., :4] - p_conf = p[..., 4:6].permute(0, 4, 1, 2, 3) # Conf - - # Training - if targets is not None: - if test_emb: - tconf, tbox, tids = build_targets_max(targets, self.anchor_vec.cuda(), self.nA, self.nC, nGh, nGw) - else: - tconf, tbox, tids = build_targets_thres(targets, self.anchor_vec.cuda(), self.nA, self.nC, nGh, nGw) - tconf, tbox, tids = tconf.cuda(), tbox.cuda(), tids.cuda() - mask = tconf > 0 - - # Compute losses - nT = sum([len(x) for x in targets]) # number of targets - nM = mask.sum().float() # number of anchors (assigned to targets) - nP = torch.ones_like(mask).sum().float() - if nM > 0: - lbox = self.SmoothL1Loss(p_box[mask], tbox[mask]) - else: - FT = torch.cuda.FloatTensor if p_conf.is_cuda else torch.FloatTensor - lbox, lconf = FT([0]), FT([0]) - lconf = self.SoftmaxLoss(p_conf, tconf) - lid = torch.Tensor(1).fill_(0).squeeze().cuda() - emb_mask,_ = mask.max(1) - - # For convenience we use max(1) to decide the id, TODO: more reseanable strategy - tids,_ = tids.max(1) - tids = tids[emb_mask] - embedding = p_emb[emb_mask].contiguous() - embedding = self.emb_scale * F.normalize(embedding) - nI = emb_mask.sum().float() - - if test_emb: - if np.prod(embedding.shape)==0 or np.prod(tids.shape) == 0: - return torch.zeros(0, self. emb_dim+1).cuda() - emb_and_gt = torch.cat([embedding, tids.float()], dim=1) - return emb_and_gt - - if len(embedding) > 1: - logits = classifier(embedding).contiguous() - lid = self.IDLoss(logits, tids.squeeze()) - - # Sum loss components - loss = torch.exp(-self.s_r)*lbox + torch.exp(-self.s_c)*lconf + torch.exp(-self.s_id)*lid + \ - (self.s_r + self.s_c + self.s_id) - loss *= 0.5 - - return loss, loss.item(), lbox.item(), lconf.item(), lid.item(), nT - - else: - p_conf = torch.softmax(p_conf, dim=1)[:,1,...].unsqueeze(-1) - p_emb = p_emb.unsqueeze(1).repeat(1,self.nA,1,1,1).contiguous() - p_cls = torch.zeros(nB,self.nA,nGh,nGw,1).to(p) # Temp - p = torch.cat([p_box, p_conf, p_cls, p_emb], dim=-1) - p[..., :4] = decode_delta_map(p[..., :4], self.anchor_vec.to(p)) - p[..., :4] *= self.stride - - return p.view(nB, -1, p.shape[-1]) - - -class Darknet(nn.Module): - """YOLOv3 object detection model""" - - def __init__(self, cfg_path, img_size=(1088, 608), nID=1591, test_emb=False): - super(Darknet, self).__init__() - - self.module_defs = parse_model_cfg(cfg_path) - self.module_defs[0]['cfg'] = cfg_path - self.module_defs[0]['nID'] = nID - self.hyperparams, self.module_list = create_modules(self.module_defs) - self.img_size = img_size - self.loss_names = ['loss', 'box', 'conf', 'id', 'nT'] - self.losses = OrderedDict() - for ln in self.loss_names: - self.losses[ln] = 0 - self.emb_dim = 512 - self.classifier = nn.Linear(self.emb_dim, nID) - self.test_emb=test_emb - - - def forward(self, x, targets=None, targets_len=None): - self.losses = OrderedDict() - for ln in self.loss_names: - self.losses[ln] = 0 - is_training = (targets is not None) and (not self.test_emb) - #img_size = x.shape[-1] - layer_outputs = [] - output = [] - - for i, (module_def, module) in enumerate(zip(self.module_defs, self.module_list)): - mtype = module_def['type'] - if mtype in ['convolutional', 'upsample', 'maxpool']: - x = module(x) - elif mtype == 'route': - layer_i = [int(x) for x in module_def['layers'].split(',')] - if len(layer_i) == 1: - x = layer_outputs[layer_i[0]] - else: - x = torch.cat([layer_outputs[i] for i in layer_i], 1) - elif mtype == 'shortcut': - layer_i = int(module_def['from']) - x = layer_outputs[-1] + layer_outputs[layer_i] - elif mtype == 'yolo': - if is_training: # get loss - targets = [targets[i][:int(l)] for i,l in enumerate(targets_len)] - x, *losses = module[0](x, self.img_size, targets, self.classifier) - for name, loss in zip(self.loss_names, losses): - self.losses[name] += loss - elif self.test_emb: - targets = [targets[i][:int(l)] for i,l in enumerate(targets_len)] - x = module[0](x, self.img_size, targets, self.classifier, self.test_emb) - else: # get detections - x = module[0](x, self.img_size) - output.append(x) - layer_outputs.append(x) - - if is_training: - self.losses['nT'] /= 3 - output = [o.squeeze() for o in output] - return sum(output), torch.Tensor(list(self.losses.values())).cuda() - elif self.test_emb: - return torch.cat(output, 0) - return torch.cat(output, 1) - - -def create_grids(self, img_size, nGh, nGw): - self.stride = img_size[0]/nGw - assert self.stride == img_size[1] / nGh - - # build xy offsets - grid_x = torch.arange(nGw).repeat((nGh, 1)).view((1, 1, nGh, nGw)).float() - grid_y = torch.arange(nGh).repeat((nGw, 1)).transpose(0,1).view((1, 1, nGh, nGw)).float() - #grid_y = grid_x.permute(0, 1, 3, 2) - self.grid_xy = torch.stack((grid_x, grid_y), 4) - - # build wh gains - self.anchor_vec = self.anchors / self.stride - self.anchor_wh = self.anchor_vec.view(1, self.nA, 1, 1, 2) - - -def load_darknet_weights(self, weights, cutoff=-1): - # Parses and loads the weights stored in 'weights' - # cutoff: save layers between 0 and cutoff (if cutoff = -1 all are saved) - weights_file = weights.split(os.sep)[-1] - - # Try to download weights if not available locally - if not os.path.isfile(weights): - try: - os.system('wget https://pjreddie.com/media/files/' + weights_file + ' -O ' + weights) - except IOError: - print(weights + ' not found') - - # Establish cutoffs - if weights_file == 'darknet53.conv.74': - cutoff = 75 - elif weights_file == 'yolov3-tiny.conv.15': - cutoff = 15 - - # Open the weights file - fp = open(weights, 'rb') - header = np.fromfile(fp, dtype=np.int32, count=5) # First five are header values - - # Needed to write header when saving weights - self.header_info = header - - self.seen = header[3] # number of images seen during training - weights = np.fromfile(fp, dtype=np.float32) # The rest are weights - fp.close() - - ptr = 0 - for i, (module_def, module) in enumerate(zip(self.module_defs[:cutoff], self.module_list[:cutoff])): - if module_def['type'] == 'convolutional': - conv_layer = module[0] - if module_def['batch_normalize']: - # Load BN bias, weights, running mean and running variance - bn_layer = module[1] - num_b = bn_layer.bias.numel() # Number of biases - # Bias - bn_b = torch.from_numpy(weights[ptr:ptr + num_b]).view_as(bn_layer.bias) - bn_layer.bias.data.copy_(bn_b) - ptr += num_b - # Weight - bn_w = torch.from_numpy(weights[ptr:ptr + num_b]).view_as(bn_layer.weight) - bn_layer.weight.data.copy_(bn_w) - ptr += num_b - # Running Mean - bn_rm = torch.from_numpy(weights[ptr:ptr + num_b]).view_as(bn_layer.running_mean) - bn_layer.running_mean.data.copy_(bn_rm) - ptr += num_b - # Running Var - bn_rv = torch.from_numpy(weights[ptr:ptr + num_b]).view_as(bn_layer.running_var) - bn_layer.running_var.data.copy_(bn_rv) - ptr += num_b - else: - # Load conv. bias - num_b = conv_layer.bias.numel() - conv_b = torch.from_numpy(weights[ptr:ptr + num_b]).view_as(conv_layer.bias) - conv_layer.bias.data.copy_(conv_b) - ptr += num_b - # Load conv. weights - num_w = conv_layer.weight.numel() - conv_w = torch.from_numpy(weights[ptr:ptr + num_w]).view_as(conv_layer.weight) - conv_layer.weight.data.copy_(conv_w) - ptr += num_w - - -""" - @:param path - path of the new weights file - @:param cutoff - save layers between 0 and cutoff (cutoff = -1 -> all are saved) -""" - - -def save_weights(self, path, cutoff=-1): - fp = open(path, 'wb') - self.header_info[3] = self.seen # number of images seen during training - self.header_info.tofile(fp) - - # Iterate through layers - for i, (module_def, module) in enumerate(zip(self.module_defs[:cutoff], self.module_list[:cutoff])): - if module_def['type'] == 'convolutional': - conv_layer = module[0] - # If batch norm, load bn first - if module_def['batch_normalize']: - bn_layer = module[1] - bn_layer.bias.data.cpu().numpy().tofile(fp) - bn_layer.weight.data.cpu().numpy().tofile(fp) - bn_layer.running_mean.data.cpu().numpy().tofile(fp) - bn_layer.running_var.data.cpu().numpy().tofile(fp) - # Load conv bias - else: - conv_layer.bias.data.cpu().numpy().tofile(fp) - # Load conv weights - conv_layer.weight.data.cpu().numpy().tofile(fp) - - fp.close() diff --git a/cv/pose/alphapose/pytorch/detector/tracker/preprocess.py b/cv/pose/alphapose/pytorch/detector/tracker/preprocess.py deleted file mode 100755 index 741d20b64..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/preprocess.py +++ /dev/null @@ -1,63 +0,0 @@ -from __future__ import division - -import torch -import torch.nn as nn -import torch.nn.functional as F -from torch.autograd import Variable -import numpy as np -import cv2 -import matplotlib.pyplot as plt -try: - from util import count_parameters as count - from util import convert2cpu as cpu -except ImportError: - from yolo.util import count_parameters as count - from yolo.util import convert2cpu as cpu -from PIL import Image, ImageDraw - - -def letterbox_image(img, img_size=(1088, 608), color=(127.5, 127.5, 127.5)): - # resize a rectangular image to a padded rectangular - height=img_size[1] - width=img_size[0] - shape = img.shape[:2] # shape = [height, width] - ratio = min(float(height)/shape[0], float(width)/shape[1]) - new_shape = (round(shape[1] * ratio), round(shape[0] * ratio)) # new_shape = [width, height] - dw = (width - new_shape[0]) / 2 # width padding - dh = (height - new_shape[1]) / 2 # height padding - top, bottom = round(dh - 0.1), round(dh + 0.1) - left, right = round(dw - 0.1), round(dw + 0.1) - img = cv2.resize(img, new_shape, interpolation=cv2.INTER_AREA) # resized, no border - img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # padded rectangular - return img - - -def prep_image(img, img_size=(1088, 608)): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = cv2.imread(img) - dim = orig_im.shape[1], orig_im.shape[0] - img = (letterbox_image(orig_im, img_size)) - img_ = img[:, :, ::-1].transpose((2, 0, 1)).copy() - img_ = torch.from_numpy(img_).float().div(255.0).unsqueeze(0) - return img_, orig_im, dim - - -def prep_frame(img, img_size=(1088, 608)): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = img - dim = orig_im.shape[1], orig_im.shape[0] - img = (letterbox_image(orig_im, img_size)) - img_ = img[:, :, ::-1].transpose((2, 0, 1)).copy() - img_ = torch.from_numpy(img_).float().div(255.0).unsqueeze(0) - return img_, orig_im, dim - diff --git a/cv/pose/alphapose/pytorch/detector/tracker/tracker/__init__.py b/cv/pose/alphapose/pytorch/detector/tracker/tracker/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/tracker/tracker/basetrack.py b/cv/pose/alphapose/pytorch/detector/tracker/tracker/basetrack.py deleted file mode 100755 index c702f13e5..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/tracker/basetrack.py +++ /dev/null @@ -1,53 +0,0 @@ -import numpy as np -from collections import OrderedDict - - -class TrackState(object): - New = 0 - Tracked = 1 - Lost = 2 - Removed = 3 - - -class BaseTrack(object): - _count = 0 - - track_id = 0 - is_activated = False - state = TrackState.New - - history = OrderedDict() - features = [] - curr_feature = None - score = 0 - start_frame = 0 - frame_id = 0 - time_since_update = 0 - - # multi-camera - location = (np.inf, np.inf) - - @property - def end_frame(self): - return self.frame_id - - @staticmethod - def next_id(): - BaseTrack._count += 1 - return BaseTrack._count - - def activate(self, *args): - raise NotImplementedError - - def predict(self): - raise NotImplementedError - - def update(self, *args, **kwargs): - raise NotImplementedError - - def mark_lost(self): - self.state = TrackState.Lost - - def mark_removed(self): - self.state = TrackState.Removed - diff --git a/cv/pose/alphapose/pytorch/detector/tracker/tracker/matching.py b/cv/pose/alphapose/pytorch/detector/tracker/tracker/matching.py deleted file mode 100755 index be83ea15c..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/tracker/matching.py +++ /dev/null @@ -1,123 +0,0 @@ -import cv2 -import numpy as np -import scipy -from scipy.spatial.distance import cdist -from scipy.optimize import linear_sum_assignment - -from cython_bbox import bbox_overlaps as bbox_ious -from tracker.utils import kalman_filter -import time - -def merge_matches(m1, m2, shape): - O,P,Q = shape - m1 = np.asarray(m1) - m2 = np.asarray(m2) - - M1 = scipy.sparse.coo_matrix((np.ones(len(m1)), (m1[:, 0], m1[:, 1])), shape=(O, P)) - M2 = scipy.sparse.coo_matrix((np.ones(len(m2)), (m2[:, 0], m2[:, 1])), shape=(P, Q)) - - mask = M1*M2 - match = mask.nonzero() - match = list(zip(match[0], match[1])) - unmatched_O = tuple(set(range(O)) - set([i for i, j in match])) - unmatched_Q = tuple(set(range(Q)) - set([j for i, j in match])) - - return match, unmatched_O, unmatched_Q - - -def _indices_to_matches(cost_matrix, indices, thresh): - matched_cost = cost_matrix[tuple(zip(*indices))] - matched_mask = (matched_cost <= thresh) - - matches = indices[matched_mask] - unmatched_a = tuple(set(range(cost_matrix.shape[0])) - set(matches[:, 0])) - unmatched_b = tuple(set(range(cost_matrix.shape[1])) - set(matches[:, 1])) - - return matches, unmatched_a, unmatched_b - - -def linear_assignment(cost_matrix, thresh): - """ - Simple linear assignment - :type cost_matrix: np.ndarray - :type thresh: float - :return: matches, unmatched_a, unmatched_b - """ - if cost_matrix.size == 0: - return np.empty((0, 2), dtype=int), tuple(range(cost_matrix.shape[0])), tuple(range(cost_matrix.shape[1])) - - cost_matrix[cost_matrix > thresh] = thresh + 1e-4 - row_ind, col_ind = linear_sum_assignment(cost_matrix) - indices = np.column_stack((row_ind, col_ind)) - - return _indices_to_matches(cost_matrix, indices, thresh) - - -def ious(atlbrs, btlbrs): - """ - Compute cost based on IoU - :type atlbrs: list[tlbr] | np.ndarray - :type atlbrs: list[tlbr] | np.ndarray - - :rtype ious np.ndarray - """ - ious = np.zeros((len(atlbrs), len(btlbrs)), dtype=np.float) - if ious.size == 0: - return ious - - ious = bbox_ious( - np.ascontiguousarray(atlbrs, dtype=np.float), - np.ascontiguousarray(btlbrs, dtype=np.float) - ) - - return ious - - -def iou_distance(atracks, btracks): - """ - Compute cost based on IoU - :type atracks: list[STrack] - :type btracks: list[STrack] - - :rtype cost_matrix np.ndarray - """ - - if (len(atracks)>0 and isinstance(atracks[0], np.ndarray)) or (len(btracks) > 0 and isinstance(btracks[0], np.ndarray)): - atlbrs = atracks - btlbrs = btracks - else: - atlbrs = [track.tlbr for track in atracks] - btlbrs = [track.tlbr for track in btracks] - _ious = ious(atlbrs, btlbrs) - cost_matrix = 1 - _ious - - return cost_matrix - -def embedding_distance(tracks, detections, metric='cosine'): - """ - :param tracks: list[STrack] - :param detections: list[BaseTrack] - :param metric: - :return: cost_matrix np.ndarray - """ - - cost_matrix = np.zeros((len(tracks), len(detections)), dtype=np.float) - if cost_matrix.size == 0: - return cost_matrix - det_features = np.asarray([track.curr_feat for track in detections], dtype=np.float) - for i, track in enumerate(tracks): - cost_matrix[i, :] = np.maximum(0.0, cdist(track.smooth_feat.reshape(1,-1), det_features, metric)) - return cost_matrix - - -def gate_cost_matrix(kf, cost_matrix, tracks, detections, only_position=False): - if cost_matrix.size == 0: - return cost_matrix - gating_dim = 2 if only_position else 4 - gating_threshold = kalman_filter.chi2inv95[gating_dim] - measurements = np.asarray([det.to_xyah() for det in detections]) - for row, track in enumerate(tracks): - gating_distance = kf.gating_distance( - track.mean, track.covariance, measurements, only_position) - cost_matrix[row, gating_distance > gating_threshold] = np.inf - return cost_matrix diff --git a/cv/pose/alphapose/pytorch/detector/tracker/tracker/multitracker.py b/cv/pose/alphapose/pytorch/detector/tracker/tracker/multitracker.py deleted file mode 100755 index 64a579987..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/tracker/multitracker.py +++ /dev/null @@ -1,337 +0,0 @@ -import numpy as np -from collections import deque -import itertools -import os -import os.path as osp -import time -import torch - -from tracker.utils.utils import * -from tracker.utils.log import logger -from tracker.utils.kalman_filter import KalmanFilter -from tracker.models import * -from tracker.tracker import matching -from tracker.tracker.basetrack import BaseTrack, TrackState - - -class STrack(BaseTrack): - - def __init__(self, tlwh, score, temp_feat, buffer_size=30): - - # wait activate - self._tlwh = np.asarray(tlwh, dtype=np.float) - self.kalman_filter = None - self.mean, self.covariance = None, None - self.is_activated = False - - self.score = score - self.tracklet_len = 0 - - self.smooth_feat = None - self.update_features(temp_feat) - self.features = deque([], maxlen=buffer_size) - self.alpha = 0.9 - - def update_features(self, feat): - self.curr_feat = feat - if self.smooth_feat is None: - self.smooth_feat = feat - else: - self.smooth_feat = self.alpha *self.smooth_feat + (1-self.alpha) * feat - self.features.append(feat) - self.smooth_feat /= np.linalg.norm(self.smooth_feat) - - def predict(self): - mean_state = self.mean.copy() - if self.state != TrackState.Tracked: - mean_state[7] = 0 - self.mean, self.covariance = self.kalman_filter.predict(mean_state, self.covariance) - - - def activate(self, kalman_filter, frame_id): - """Start a new tracklet""" - self.kalman_filter = kalman_filter - self.track_id = self.next_id() - self.mean, self.covariance = self.kalman_filter.initiate(self.tlwh_to_xyah(self._tlwh)) - - self.tracklet_len = 0 - self.state = TrackState.Tracked - #self.is_activated = True - self.frame_id = frame_id - self.start_frame = frame_id - - def re_activate(self, new_track, frame_id, new_id=False): - self.mean, self.covariance = self.kalman_filter.update( - self.mean, self.covariance, self.tlwh_to_xyah(new_track.tlwh) - ) - - self.update_features(new_track.curr_feat) - self.tracklet_len = 0 - self.state = TrackState.Tracked - self.is_activated = True - self.frame_id = frame_id - if new_id: - self.track_id = self.next_id() - - def update(self, new_track, frame_id, update_feature=True): - """ - Update a matched track - :type new_track: STrack - :type frame_id: int - :type update_feature: bool - :return: - """ - self.frame_id = frame_id - self.tracklet_len += 1 - - new_tlwh = new_track.tlwh - self.mean, self.covariance = self.kalman_filter.update( - self.mean, self.covariance, self.tlwh_to_xyah(new_tlwh)) - self.state = TrackState.Tracked - self.is_activated = True - - self.score = new_track.score - if update_feature: - self.update_features(new_track.curr_feat) - - @property - def tlwh(self): - """Get current position in bounding box format `(top left x, top left y, - width, height)`. - """ - if self.mean is None: - return self._tlwh.copy() - ret = self.mean[:4].copy() - ret[2] *= ret[3] - ret[:2] -= ret[2:] / 2 - return ret - - @property - def tlbr(self): - """Convert bounding box to format `(min x, min y, max x, max y)`, i.e., - `(top left, bottom right)`. - """ - ret = self.tlwh.copy() - ret[2:] += ret[:2] - return ret - - @staticmethod - def tlwh_to_xyah(tlwh): - """Convert bounding box to format `(center x, center y, aspect ratio, - height)`, where the aspect ratio is `width / height`. - """ - ret = np.asarray(tlwh).copy() - ret[:2] += ret[2:] / 2 - ret[2] /= ret[3] - return ret - - def to_xyah(self): - return self.tlwh_to_xyah(self.tlwh) - - @staticmethod - def tlbr_to_tlwh(tlbr): - ret = np.asarray(tlbr).copy() - ret[2:] -= ret[:2] - return ret - - @staticmethod - def tlwh_to_tlbr(tlwh): - ret = np.asarray(tlwh).copy() - ret[2:] += ret[:2] - return ret - - def __repr__(self): - return 'OT_{}_({}-{})'.format(self.track_id, self.start_frame, self.end_frame) - - -class JDETracker(object): - def __init__(self, args, frame_rate=30): - self.args = args - self.model = Darknet(args.cfg, args.img_size, nID=14455) - # load_darknet_weights(self.model, args.weights) - self.model.load_state_dict(torch.load(args.weights, map_location='cpu')['model'], strict=False) - - if args: - if len(args.gpus) > 1: - self.model = torch.nn.DataParallel(self.model, device_ids=args.gpus).to(args.device) - else: - self.model.to(args.device) - else: - self.model.cuda() - self.model.eval() - - self.tracked_stracks = [] # type: list[STrack] - self.lost_stracks = [] # type: list[STrack] - self.removed_stracks = [] # type: list[STrack] - - self.frame_id = 0 - self.det_thresh = args.conf_thres - self.buffer_size = int(frame_rate / 30.0 * args.track_buffer) - self.max_time_lost = self.buffer_size - - self.kalman_filter = KalmanFilter() - - def update(self, im_blob, img0): - self.frame_id += 1 - activated_starcks = [] - refind_stracks = [] - lost_stracks = [] - removed_stracks = [] - - t1 = time.time() - ''' Step 1: Network forward, get detections & embeddings''' - with torch.no_grad(): - pred = self.model(im_blob) - pred = pred[pred[:, :, 4] > self.args.conf_thres] - if len(pred) > 0: - dets = non_max_suppression(pred.unsqueeze(0), self.args.conf_thres, self.args.nms_thres)[0].cpu() - scale_coords(self.args.img_size, dets[:, :4], img0.shape).round() - '''Detections''' - detections = [STrack(STrack.tlbr_to_tlwh(tlbrs[:4]), tlbrs[4], f.numpy(), 30) for - (tlbrs, f) in zip(dets[:, :5], dets[:, -self.model.emb_dim:])] - else: - detections = [] - - t2 = time.time() - # print('Forward: {} s'.format(t2-t1)) - - ''' Add newly detected tracklets to tracked_stracks''' - unconfirmed = [] - tracked_stracks = [] # type: list[STrack] - for track in self.tracked_stracks: - if not track.is_activated: - unconfirmed.append(track) - else: - tracked_stracks.append(track) - - ''' Step 2: First association, with embedding''' - strack_pool = joint_stracks(tracked_stracks, self.lost_stracks) - # Predict the current location with KF - for strack in strack_pool: - strack.predict() - - dists = matching.embedding_distance(strack_pool, detections) - dists = matching.gate_cost_matrix(self.kalman_filter, dists, strack_pool, detections) - matches, u_track, u_detection = matching.linear_assignment(dists, thresh=0.7) - - for itracked, idet in matches: - track = strack_pool[itracked] - det = detections[idet] - if track.state == TrackState.Tracked: - track.update(detections[idet], self.frame_id) - activated_starcks.append(track) - else: - track.re_activate(det, self.frame_id, new_id=False) - refind_stracks.append(track) - - ''' Step 3: Second association, with IOU''' - detections = [detections[i] for i in u_detection] - r_tracked_stracks = [strack_pool[i] for i in u_track if strack_pool[i].state==TrackState.Tracked ] - dists = matching.iou_distance(r_tracked_stracks, detections) - matches, u_track, u_detection = matching.linear_assignment(dists, thresh=0.5) - - for itracked, idet in matches: - track = r_tracked_stracks[itracked] - det = detections[idet] - if track.state == TrackState.Tracked: - track.update(det, self.frame_id) - activated_starcks.append(track) - else: - track.re_activate(det, self.frame_id, new_id=False) - refind_stracks.append(track) - - for it in u_track: - track = r_tracked_stracks[it] - if not track.state == TrackState.Lost: - track.mark_lost() - lost_stracks.append(track) - - '''Deal with unconfirmed tracks, usually tracks with only one beginning frame''' - detections = [detections[i] for i in u_detection] - dists = matching.iou_distance(unconfirmed, detections) - matches, u_unconfirmed, u_detection = matching.linear_assignment(dists, thresh=0.7) - for itracked, idet in matches: - unconfirmed[itracked].update(detections[idet], self.frame_id) - activated_starcks.append(unconfirmed[itracked]) - for it in u_unconfirmed: - track = unconfirmed[it] - track.mark_removed() - removed_stracks.append(track) - - """ Step 4: Init new stracks""" - for inew in u_detection: - track = detections[inew] - if track.score < self.det_thresh: - continue - track.activate(self.kalman_filter, self.frame_id) - activated_starcks.append(track) - - """ Step 5: Update state""" - for track in self.lost_stracks: - if self.frame_id - track.end_frame > self.max_time_lost: - track.mark_removed() - removed_stracks.append(track) - t4 = time.time() - # print('Ramained match {} s'.format(t4-t3)) - - self.tracked_stracks = [t for t in self.tracked_stracks if t.state == TrackState.Tracked] - self.tracked_stracks = joint_stracks(self.tracked_stracks, activated_starcks) - self.tracked_stracks = joint_stracks(self.tracked_stracks, refind_stracks) - # self.lost_stracks = [t for t in self.lost_stracks if t.state == TrackState.Lost] # type: list[STrack] - self.lost_stracks = sub_stracks(self.lost_stracks, self.tracked_stracks) - self.lost_stracks.extend(lost_stracks) - self.lost_stracks = sub_stracks(self.lost_stracks, self.removed_stracks) - self.removed_stracks.extend(removed_stracks) - self.tracked_stracks, self.lost_stracks = remove_duplicate_stracks(self.tracked_stracks, self.lost_stracks) - - # get scores of lost tracks - output_stracks = [track for track in self.tracked_stracks if track.is_activated] - - logger.debug('===========Frame {}=========='.format(self.frame_id)) - logger.debug('Activated: {}'.format([track.track_id for track in activated_starcks])) - logger.debug('Refind: {}'.format([track.track_id for track in refind_stracks])) - logger.debug('Lost: {}'.format([track.track_id for track in lost_stracks])) - logger.debug('Removed: {}'.format([track.track_id for track in removed_stracks])) - t5 = time.time() - # print('Final {} s'.format(t5-t4)) - return output_stracks - -def joint_stracks(tlista, tlistb): - exists = {} - res = [] - for t in tlista: - exists[t.track_id] = 1 - res.append(t) - for t in tlistb: - tid = t.track_id - if not exists.get(tid, 0): - exists[tid] = 1 - res.append(t) - return res - -def sub_stracks(tlista, tlistb): - stracks = {} - for t in tlista: - stracks[t.track_id] = t - for t in tlistb: - tid = t.track_id - if stracks.get(tid, 0): - del stracks[tid] - return list(stracks.values()) - -def remove_duplicate_stracks(stracksa, stracksb): - pdist = matching.iou_distance(stracksa, stracksb) - pairs = np.where(pdist<0.15) - dupa, dupb = list(), list() - for p,q in zip(*pairs): - timep = stracksa[p].frame_id - stracksa[p].start_frame - timeq = stracksb[q].frame_id - stracksb[q].start_frame - if timep > timeq: - dupb.append(q) - else: - dupa.append(p) - resa = [t for i,t in enumerate(stracksa) if not i in dupa] - resb = [t for i,t in enumerate(stracksb) if not i in dupb] - return resa, resb - - diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/__init__.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/datasets.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/datasets.py deleted file mode 100755 index a20a93727..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/datasets.py +++ /dev/null @@ -1,411 +0,0 @@ -import glob -import math -import os -import os.path as osp -import random -import time -from collections import OrderedDict - -import cv2 -import numpy as np -import torch - -from torch.utils.data import Dataset -from utils.utils import xyxy2xywh - -class LoadImages: # for inference - def __init__(self, path, img_size=(1088, 608)): - if os.path.isdir(path): - image_format = ['.jpg', '.jpeg', '.png', '.tif'] - self.files = sorted(glob.glob('%s/*.*' % path)) - self.files = list(filter(lambda x: os.path.splitext(x)[1].lower() in image_format, self.files)) - elif os.path.isfile(path): - self.files = [path] - - self.nF = len(self.files) # number of image files - self.width = img_size[0] - self.height = img_size[1] - self.count = 0 - - assert self.nF > 0, 'No images found in ' + path - - def __iter__(self): - self.count = -1 - return self - - def __next__(self): - self.count += 1 - if self.count == self.nF: - raise StopIteration - img_path = self.files[self.count] - - # Read image - img0 = cv2.imread(img_path) # BGR - assert img0 is not None, 'Failed to load ' + img_path - - # Padded resize - img, _, _, _ = letterbox(img0, height=self.height, width=self.width) - - # Normalize RGB - img = img[:, :, ::-1].transpose(2, 0, 1) - img = np.ascontiguousarray(img, dtype=np.float32) - img /= 255.0 - - # cv2.imwrite(img_path + '.letterbox.jpg', 255 * img.transpose((1, 2, 0))[:, :, ::-1]) # save letterbox image - return img_path, img, img0 - - def __getitem__(self, idx): - idx = idx % self.nF - img_path = self.files[idx] - - # Read image - img0 = cv2.imread(img_path) # BGR - assert img0 is not None, 'Failed to load ' + img_path - - # Padded resize - img, _, _, _ = letterbox(img0, height=self.height, width=self.width) - - # Normalize RGB - img = img[:, :, ::-1].transpose(2, 0, 1) - img = np.ascontiguousarray(img, dtype=np.float32) - img /= 255.0 - - return img_path, img, img0 - - def __len__(self): - return self.nF # number of files - - -class LoadVideo: # for inference - def __init__(self, path, img_size=(1088, 608)): - self.cap = cv2.VideoCapture(path) - self.frame_rate = int(round(self.cap.get(cv2.CAP_PROP_FPS))) - self.vw = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)) - self.vh = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) - self.vn = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT)) - - self.width = img_size[0] - self.height = img_size[1] - self.count = 0 - - self.w, self.h = self.get_size(self.vw, self.vh, self.width, self.height) - print('Lenth of the video: {:d} frames'.format(self.vn)) - - def get_size(self, vw, vh, dw, dh): - wa, ha = float(dw) / vw, float(dh) / vh - a = min(wa, ha) - return int(vw *a), int(vh*a) - - def __iter__(self): - self.count = -1 - return self - - def __next__(self): - self.count += 1 - if self.count == len(self): - raise StopIteration - # Read image - res, img0 = self.cap.read() # BGR - assert img0 is not None, 'Failed to load frame {:d}'.format(self.count) - img0 = cv2.resize(img0, (self.w, self.h)) - - # Padded resize - img, _, _, _ = letterbox(img0, height=self.height, width=self.width) - - # Normalize RGB - img = img[:, :, ::-1].transpose(2, 0, 1) - img = np.ascontiguousarray(img, dtype=np.float32) - img /= 255.0 - - # cv2.imwrite(img_path + '.letterbox.jpg', 255 * img.transpose((1, 2, 0))[:, :, ::-1]) # save letterbox image - return self.count, img, img0 - - def __len__(self): - return self.vn # number of files - - -class LoadImagesAndLabels: # for training - def __init__(self, path, img_size=(1088,608), augment=False, transforms=None): - with open(path, 'r') as file: - self.img_files = file.readlines() - self.img_files = [x.replace('\n', '') for x in self.img_files] - self.img_files = list(filter(lambda x: len(x) > 0, self.img_files)) - - self.label_files = [x.replace('images', 'labels_with_ids').replace('.png', '.txt').replace('.jpg', '.txt') - for x in self.img_files] - - self.nF = len(self.img_files) # number of image files - self.width = img_size[0] - self.height = img_size[1] - self.augment = augment - self.transforms = transforms - - - def __getitem__(self, files_index): - img_path = self.img_files[files_index] - label_path = self.label_files[files_index] - return self.get_data(img_path, label_path) - - def get_data(self, img_path, label_path): - height = self.height - width = self.width - img = cv2.imread(img_path) # BGR - if img is None: - raise ValueError('File corrupt {}'.format(img_path)) - augment_hsv = True - if self.augment and augment_hsv: - # SV augmentation by 50% - fraction = 0.50 - img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) - S = img_hsv[:, :, 1].astype(np.float32) - V = img_hsv[:, :, 2].astype(np.float32) - - a = (random.random() * 2 - 1) * fraction + 1 - S *= a - if a > 1: - np.clip(S, a_min=0, a_max=255, out=S) - - a = (random.random() * 2 - 1) * fraction + 1 - V *= a - if a > 1: - np.clip(V, a_min=0, a_max=255, out=V) - - img_hsv[:, :, 1] = S.astype(np.uint8) - img_hsv[:, :, 2] = V.astype(np.uint8) - cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR, dst=img) - - h, w, _ = img.shape - img, ratio, padw, padh = letterbox(img, height=height, width=width) - - # Load labels - if os.path.isfile(label_path): - labels0 = np.loadtxt(label_path, dtype=np.float32).reshape(-1, 6) - - # Normalized xywh to pixel xyxy format - labels = labels0.copy() - labels[:, 2] = ratio * w * (labels0[:, 2] - labels0[:, 4] / 2) + padw - labels[:, 3] = ratio * h * (labels0[:, 3] - labels0[:, 5] / 2) + padh - labels[:, 4] = ratio * w * (labels0[:, 2] + labels0[:, 4] / 2) + padw - labels[:, 5] = ratio * h * (labels0[:, 3] + labels0[:, 5] / 2) + padh - else: - labels = np.array([]) - - # Augment image and labels - if self.augment: - img, labels, M = random_affine(img, labels, degrees=(-5, 5), translate=(0.10, 0.10), scale=(0.50, 1.20)) - - plotFlag = False - if plotFlag: - import matplotlib - matplotlib.use('Agg') - import matplotlib.pyplot as plt - plt.figure(figsize=(50, 50)) - plt.imshow(img[:, :, ::-1]) - plt.plot(labels[:, [1, 3, 3, 1, 1]].T, labels[:, [2, 2, 4, 4, 2]].T, '.-') - plt.axis('off') - plt.savefig('test.jpg') - time.sleep(10) - - nL = len(labels) - if nL > 0: - # convert xyxy to xywh - labels[:, 2:6] = xyxy2xywh(labels[:, 2:6].copy()) #/ height - labels[:, 2] /= width - labels[:, 3] /= height - labels[:, 4] /= width - labels[:, 5] /= height - if self.augment: - # random left-right flip - lr_flip = True - if lr_flip & (random.random() > 0.5): - img = np.fliplr(img) - if nL > 0: - labels[:, 2] = 1 - labels[:, 2] - - img = np.ascontiguousarray(img[ :, :, ::-1]) # BGR to RGB - if self.transforms is not None: - img = self.transforms(img) - - return img, labels, img_path, (h, w) - - def __len__(self): - return self.nF # number of batches - - -def letterbox(img, height=608, width=1088, color=(127.5, 127.5, 127.5)): # resize a rectangular image to a padded rectangular - shape = img.shape[:2] # shape = [height, width] - ratio = min(float(height)/shape[0], float(width)/shape[1]) - new_shape = (round(shape[1] * ratio), round(shape[0] * ratio)) # new_shape = [width, height] - dw = (width - new_shape[0]) / 2 # width padding - dh = (height - new_shape[1]) / 2 # height padding - top, bottom = round(dh - 0.1), round(dh + 0.1) - left, right = round(dw - 0.1), round(dw + 0.1) - img = cv2.resize(img, new_shape, interpolation=cv2.INTER_AREA) # resized, no border - img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # padded rectangular - return img, ratio, dw, dh - - -def random_affine(img, targets=None, degrees=(-10, 10), translate=(.1, .1), scale=(.9, 1.1), shear=(-2, 2), - borderValue=(127.5, 127.5, 127.5)): - # torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(.1, .1), scale=(.9, 1.1), shear=(-10, 10)) - # https://medium.com/uruvideo/dataset-augmentation-with-random-homographies-a8f4b44830d4 - - border = 0 # width of added border (optional) - height = img.shape[0] - width = img.shape[1] - - # Rotation and Scale - R = np.eye(3) - a = random.random() * (degrees[1] - degrees[0]) + degrees[0] - # a += random.choice([-180, -90, 0, 90]) # 90deg rotations added to small rotations - s = random.random() * (scale[1] - scale[0]) + scale[0] - R[:2] = cv2.getRotationMatrix2D(angle=a, center=(img.shape[1] / 2, img.shape[0] / 2), scale=s) - - # Translation - T = np.eye(3) - T[0, 2] = (random.random() * 2 - 1) * translate[0] * img.shape[0] + border # x translation (pixels) - T[1, 2] = (random.random() * 2 - 1) * translate[1] * img.shape[1] + border # y translation (pixels) - - # Shear - S = np.eye(3) - S[0, 1] = math.tan((random.random() * (shear[1] - shear[0]) + shear[0]) * math.pi / 180) # x shear (deg) - S[1, 0] = math.tan((random.random() * (shear[1] - shear[0]) + shear[0]) * math.pi / 180) # y shear (deg) - - M = S @ T @ R # Combined rotation matrix. ORDER IS IMPORTANT HERE!! - imw = cv2.warpPerspective(img, M, dsize=(width, height), flags=cv2.INTER_LINEAR, - borderValue=borderValue) # BGR order borderValue - - # Return warped points also - if targets is not None: - if len(targets) > 0: - n = targets.shape[0] - points = targets[:, 2:6].copy() - area0 = (points[:, 2] - points[:, 0]) * (points[:, 3] - points[:, 1]) - - # warp points - xy = np.ones((n * 4, 3)) - xy[:, :2] = points[:, [0, 1, 2, 3, 0, 3, 2, 1]].reshape(n * 4, 2) # x1y1, x2y2, x1y2, x2y1 - xy = (xy @ M.T)[:, :2].reshape(n, 8) - - # create new boxes - x = xy[:, [0, 2, 4, 6]] - y = xy[:, [1, 3, 5, 7]] - xy = np.concatenate((x.min(1), y.min(1), x.max(1), y.max(1))).reshape(4, n).T - - # apply angle-based reduction - radians = a * math.pi / 180 - reduction = max(abs(math.sin(radians)), abs(math.cos(radians))) ** 0.5 - x = (xy[:, 2] + xy[:, 0]) / 2 - y = (xy[:, 3] + xy[:, 1]) / 2 - w = (xy[:, 2] - xy[:, 0]) * reduction - h = (xy[:, 3] - xy[:, 1]) * reduction - xy = np.concatenate((x - w / 2, y - h / 2, x + w / 2, y + h / 2)).reshape(4, n).T - - # reject warped points outside of image - np.clip(xy[:, 0], 0, width, out=xy[:, 0]) - np.clip(xy[:, 2], 0, width, out=xy[:, 2]) - np.clip(xy[:, 1], 0, height, out=xy[:, 1]) - np.clip(xy[:, 3], 0, height, out=xy[:, 3]) - w = xy[:, 2] - xy[:, 0] - h = xy[:, 3] - xy[:, 1] - area = w * h - ar = np.maximum(w / (h + 1e-16), h / (w + 1e-16)) - i = (w > 4) & (h > 4) & (area / (area0 + 1e-16) > 0.1) & (ar < 10) - - targets = targets[i] - targets[:, 2:6] = xy[i] - - return imw, targets, M - else: - return imw - -def collate_fn(batch): - imgs, labels, paths, sizes = zip(*batch) - batch_size = len(labels) - imgs = torch.stack(imgs, 0) - max_box_len = max([l.shape[0] for l in labels]) - labels = [torch.from_numpy(l) for l in labels] - filled_labels = torch.zeros(batch_size, max_box_len, 6) - labels_len = torch.zeros(batch_size) - - for i in range(batch_size): - isize = labels[i].shape[0] - if len(labels[i])>0: - filled_labels[i, :isize, :] = labels[i] - labels_len[i] = isize - - return imgs, filled_labels, paths, sizes, labels_len.unsqueeze(1) - - -class JointDataset(LoadImagesAndLabels): # for training - def __init__(self, root, paths, img_size=(1088,608), augment=False, transforms=None): - - dataset_names = paths.keys() - self.img_files = OrderedDict() - self.label_files = OrderedDict() - self.tid_num = OrderedDict() - self.tid_start_index = OrderedDict() - for ds, path in paths.items(): - with open(path, 'r') as file: - self.img_files[ds] = file.readlines() - self.img_files[ds] = [osp.join(root, x.strip()) for x in self.img_files[ds]] - self.img_files[ds] = list(filter(lambda x: len(x) > 0, self.img_files[ds])) - - self.label_files[ds] = [x.replace('images', 'labels_with_ids').replace('.png', '.txt').replace('.jpg', '.txt') - for x in self.img_files[ds]] - - for ds, label_paths in self.label_files.items(): - max_index = -1 - for lp in label_paths: - lb = np.loadtxt(lp) - if len(lb) < 1: - continue - if len(lb.shape) < 2: - img_max = lb[1] - else: - img_max = np.max(lb[:,1]) - if img_max >max_index: - max_index = img_max - self.tid_num[ds] = max_index + 1 - - last_index = 0 - for i, (k, v) in enumerate(self.tid_num.items()): - self.tid_start_index[k] = last_index - last_index += v - - self.nID = int(last_index+1) - self.nds = [len(x) for x in self.img_files.values()] - self.cds = [sum(self.nds[:i]) for i in range(len(self.nds))] - self.nF = sum(self.nds) - self.width = img_size[0] - self.height = img_size[1] - self.augment = augment - self.transforms = transforms - - print('='*80) - print('dataset summary') - print(self.tid_num) - print('total # identities:', self.nID) - print('start index') - print(self.tid_start_index) - print('='*80) - - - def __getitem__(self, files_index): - - for i, c in enumerate(self.cds): - if files_index >= c: - ds = list(self.label_files.keys())[i] - start_index = c - - img_path = self.img_files[ds][files_index - start_index] - label_path = self.label_files[ds][files_index - start_index] - - imgs, labels, img_path, (h, w) = self.get_data(img_path, label_path) - for i, _ in enumerate(labels): - if labels[i,1] > -1: - labels[i,1] += self.tid_start_index[ds] - - return imgs, labels, img_path, (h, w) - - diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/evaluation.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/evaluation.py deleted file mode 100755 index b7e6a5847..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/evaluation.py +++ /dev/null @@ -1,101 +0,0 @@ -import os -import numpy as np -import copy -import motmetrics as mm - -from utils.io import read_results, unzip_objs - - -class Evaluator(object): - - def __init__(self, data_root, seq_name, data_type): - self.data_root = data_root - self.seq_name = seq_name - self.data_type = data_type - - self.load_annotations() - self.reset_accumulator() - - def load_annotations(self): - assert self.data_type == 'mot' - - gt_filename = os.path.join(self.data_root, self.seq_name, 'gt', 'gt.txt') - self.gt_frame_dict = read_results(gt_filename, self.data_type, is_gt=True) - self.gt_ignore_frame_dict = read_results(gt_filename, self.data_type, is_ignore=True) - - def reset_accumulator(self): - self.acc = mm.MOTAccumulator(auto_id=True) - - def eval_frame(self, frame_id, trk_tlwhs, trk_ids, rtn_events=False): - # results - trk_tlwhs = np.copy(trk_tlwhs) - trk_ids = np.copy(trk_ids) - - # gts - gt_objs = self.gt_frame_dict.get(frame_id, []) - gt_tlwhs, gt_ids = unzip_objs(gt_objs)[:2] - - # ignore boxes - ignore_objs = self.gt_ignore_frame_dict.get(frame_id, []) - ignore_tlwhs = unzip_objs(ignore_objs)[0] - - # remove ignored results - keep = np.ones(len(trk_tlwhs), dtype=bool) - iou_distance = mm.distances.iou_matrix(ignore_tlwhs, trk_tlwhs, max_iou=0.5) - match_is, match_js = mm.lap.linear_sum_assignment(iou_distance) - match_is, match_js = map(lambda a: np.asarray(a, dtype=int), [match_is, match_js]) - match_ious = iou_distance[match_is, match_js] - - match_js = np.asarray(match_js, dtype=int) - match_js = match_js[np.logical_not(np.isnan(match_ious))] - keep[match_js] = False - trk_tlwhs = trk_tlwhs[keep] - trk_ids = trk_ids[keep] - - # get distance matrix - iou_distance = mm.distances.iou_matrix(gt_tlwhs, trk_tlwhs, max_iou=0.5) - - # acc - self.acc.update(gt_ids, trk_ids, iou_distance) - - if rtn_events and iou_distance.size > 0 and hasattr(self.acc, 'last_mot_events'): - events = self.acc.last_mot_events # only supported by https://github.com/longcw/py-motmetrics - else: - events = None - return events - - def eval_file(self, filename): - self.reset_accumulator() - - result_frame_dict = read_results(filename, self.data_type, is_gt=False) - frames = sorted(list(set(self.gt_frame_dict.keys()) | set(result_frame_dict.keys()))) - for frame_id in frames: - trk_objs = result_frame_dict.get(frame_id, []) - trk_tlwhs, trk_ids = unzip_objs(trk_objs)[:2] - self.eval_frame(frame_id, trk_tlwhs, trk_ids, rtn_events=False) - - return self.acc - - @staticmethod - def get_summary(accs, names, metrics=('mota', 'num_switches', 'idp', 'idr', 'idf1', 'precision', 'recall')): - names = copy.deepcopy(names) - if metrics is None: - metrics = mm.metrics.motchallenge_metrics - metrics = copy.deepcopy(metrics) - - mh = mm.metrics.create() - summary = mh.compute_many( - accs, - metrics=metrics, - names=names, - generate_overall=True - ) - - return summary - - @staticmethod - def save_summary(summary, filename): - import pandas as pd - writer = pd.ExcelWriter(filename) - summary.to_excel(writer) - writer.save() diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/io.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/io.py deleted file mode 100755 index f70decdb2..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/io.py +++ /dev/null @@ -1,112 +0,0 @@ -import os -from typing import Dict -import numpy as np - -from utils.log import logger - - -def write_results(filename, results_dict: Dict, data_type: str): - if not filename: - return - path = os.path.dirname(filename) - if not os.path.exists(path): - os.makedirs(path) - - if data_type in ('mot', 'mcmot', 'lab'): - save_format = '{frame},{id},{x1},{y1},{w},{h},1,-1,-1,-1\n' - elif data_type == 'kitti': - save_format = '{frame} {id} pedestrian -1 -1 -10 {x1} {y1} {x2} {y2} -1 -1 -1 -1000 -1000 -1000 -10 {score}\n' - else: - raise ValueError(data_type) - - with open(filename, 'w') as f: - for frame_id, frame_data in results_dict.items(): - if data_type == 'kitti': - frame_id -= 1 - for tlwh, track_id in frame_data: - if track_id < 0: - continue - x1, y1, w, h = tlwh - x2, y2 = x1 + w, y1 + h - line = save_format.format(frame=frame_id, id=track_id, x1=x1, y1=y1, x2=x2, y2=y2, w=w, h=h, score=1.0) - f.write(line) - logger.info('Save results to {}'.format(filename)) - - -def read_results(filename, data_type: str, is_gt=False, is_ignore=False): - if data_type in ('mot', 'lab'): - read_fun = read_mot_results - else: - raise ValueError('Unknown data type: {}'.format(data_type)) - - return read_fun(filename, is_gt, is_ignore) - - -""" -labels={'ped', ... % 1 -'person_on_vhcl', ... % 2 -'car', ... % 3 -'bicycle', ... % 4 -'mbike', ... % 5 -'non_mot_vhcl', ... % 6 -'static_person', ... % 7 -'distractor', ... % 8 -'occluder', ... % 9 -'occluder_on_grnd', ... %10 -'occluder_full', ... % 11 -'reflection', ... % 12 -'crowd' ... % 13 -}; -""" - - -def read_mot_results(filename, is_gt, is_ignore): - valid_labels = {1} - ignore_labels = {2, 7, 8, 12} - results_dict = dict() - if os.path.isfile(filename): - with open(filename, 'r') as f: - for line in f.readlines(): - linelist = line.split(',') - if len(linelist) < 7: - continue - fid = int(linelist[0]) - if fid < 1: - continue - results_dict.setdefault(fid, list()) - - if is_gt: - if 'MOT16-' in filename or 'MOT17-' in filename: - label = int(float(linelist[7])) - mark = int(float(linelist[6])) - if mark == 0 or label not in valid_labels: - continue - score = 1 - elif is_ignore: - if 'MOT16-' in filename or 'MOT17-' in filename: - label = int(float(linelist[7])) - vis_ratio = float(linelist[8]) - if label not in ignore_labels and vis_ratio >= 0: - continue - else: - continue - score = 1 - else: - score = float(linelist[6]) - - tlwh = tuple(map(float, linelist[2:6])) - target_id = int(linelist[1]) - - results_dict[fid].append((tlwh, target_id, score)) - - return results_dict - - -def unzip_objs(objs): - if len(objs) > 0: - tlwhs, ids, scores = zip(*objs) - else: - tlwhs, ids, scores = [], [], [] - tlwhs = np.asarray(tlwhs, dtype=float).reshape(-1, 4) - - return tlwhs, ids, scores \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/kalman_filter.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/kalman_filter.py deleted file mode 100755 index 5b10e8d24..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/kalman_filter.py +++ /dev/null @@ -1,229 +0,0 @@ -# vim: expandtab:ts=4:sw=4 -import numpy as np -import scipy.linalg - - -""" -Table for the 0.95 quantile of the chi-square distribution with N degrees of -freedom (contains values for N=1, ..., 9). Taken from MATLAB/Octave's chi2inv -function and used as Mahalanobis gating threshold. -""" -chi2inv95 = { - 1: 3.8415, - 2: 5.9915, - 3: 7.8147, - 4: 9.4877, - 5: 11.070, - 6: 12.592, - 7: 14.067, - 8: 15.507, - 9: 16.919} - - -class KalmanFilter(object): - """ - A simple Kalman filter for tracking bounding boxes in image space. - - The 8-dimensional state space - - x, y, a, h, vx, vy, va, vh - - contains the bounding box center position (x, y), aspect ratio a, height h, - and their respective velocities. - - Object motion follows a constant velocity model. The bounding box location - (x, y, a, h) is taken as direct observation of the state space (linear - observation model). - - """ - - def __init__(self): - ndim, dt = 4, 1. - - # Create Kalman filter model matrices. - self._motion_mat = np.eye(2 * ndim, 2 * ndim) - for i in range(ndim): - self._motion_mat[i, ndim + i] = dt - self._update_mat = np.eye(ndim, 2 * ndim) - - # Motion and observation uncertainty are chosen relative to the current - # state estimate. These weights control the amount of uncertainty in - # the model. This is a bit hacky. - self._std_weight_position = 1. / 20 - self._std_weight_velocity = 1. / 160 - - def initiate(self, measurement): - """Create track from unassociated measurement. - - Parameters - ---------- - measurement : ndarray - Bounding box coordinates (x, y, a, h) with center position (x, y), - aspect ratio a, and height h. - - Returns - ------- - (ndarray, ndarray) - Returns the mean vector (8 dimensional) and covariance matrix (8x8 - dimensional) of the new track. Unobserved velocities are initialized - to 0 mean. - - """ - mean_pos = measurement - mean_vel = np.zeros_like(mean_pos) - mean = np.r_[mean_pos, mean_vel] - - std = [ - 2 * self._std_weight_position * measurement[3], - 2 * self._std_weight_position * measurement[3], - 1e-2, - 2 * self._std_weight_position * measurement[3], - 10 * self._std_weight_velocity * measurement[3], - 10 * self._std_weight_velocity * measurement[3], - 1e-5, - 10 * self._std_weight_velocity * measurement[3]] - covariance = np.diag(np.square(std)) - return mean, covariance - - def predict(self, mean, covariance): - """Run Kalman filter prediction step. - - Parameters - ---------- - mean : ndarray - The 8 dimensional mean vector of the object state at the previous - time step. - covariance : ndarray - The 8x8 dimensional covariance matrix of the object state at the - previous time step. - - Returns - ------- - (ndarray, ndarray) - Returns the mean vector and covariance matrix of the predicted - state. Unobserved velocities are initialized to 0 mean. - - """ - std_pos = [ - self._std_weight_position * mean[3], - self._std_weight_position * mean[3], - 1e-2, - self._std_weight_position * mean[3]] - std_vel = [ - self._std_weight_velocity * mean[3], - self._std_weight_velocity * mean[3], - 1e-5, - self._std_weight_velocity * mean[3]] - motion_cov = np.diag(np.square(np.r_[std_pos, std_vel])) - - mean = np.dot(self._motion_mat, mean) - covariance = np.linalg.multi_dot(( - self._motion_mat, covariance, self._motion_mat.T)) + motion_cov - - return mean, covariance - - def project(self, mean, covariance): - """Project state distribution to measurement space. - - Parameters - ---------- - mean : ndarray - The state's mean vector (8 dimensional array). - covariance : ndarray - The state's covariance matrix (8x8 dimensional). - - Returns - ------- - (ndarray, ndarray) - Returns the projected mean and covariance matrix of the given state - estimate. - - """ - std = [ - self._std_weight_position * mean[3], - self._std_weight_position * mean[3], - 1e-1, - self._std_weight_position * mean[3]] - innovation_cov = np.diag(np.square(std)) - - mean = np.dot(self._update_mat, mean) - covariance = np.linalg.multi_dot(( - self._update_mat, covariance, self._update_mat.T)) - return mean, covariance + innovation_cov - - def update(self, mean, covariance, measurement): - """Run Kalman filter correction step. - - Parameters - ---------- - mean : ndarray - The predicted state's mean vector (8 dimensional). - covariance : ndarray - The state's covariance matrix (8x8 dimensional). - measurement : ndarray - The 4 dimensional measurement vector (x, y, a, h), where (x, y) - is the center position, a the aspect ratio, and h the height of the - bounding box. - - Returns - ------- - (ndarray, ndarray) - Returns the measurement-corrected state distribution. - - """ - projected_mean, projected_cov = self.project(mean, covariance) - - chol_factor, lower = scipy.linalg.cho_factor( - projected_cov, lower=True, check_finite=False) - kalman_gain = scipy.linalg.cho_solve( - (chol_factor, lower), np.dot(covariance, self._update_mat.T).T, - check_finite=False).T - innovation = measurement - projected_mean - - new_mean = mean + np.dot(innovation, kalman_gain.T) - new_covariance = covariance - np.linalg.multi_dot(( - kalman_gain, projected_cov, kalman_gain.T)) - return new_mean, new_covariance - - def gating_distance(self, mean, covariance, measurements, - only_position=False): - """Compute gating distance between state distribution and measurements. - - A suitable distance threshold can be obtained from `chi2inv95`. If - `only_position` is False, the chi-square distribution has 4 degrees of - freedom, otherwise 2. - - Parameters - ---------- - mean : ndarray - Mean vector over the state distribution (8 dimensional). - covariance : ndarray - Covariance of the state distribution (8x8 dimensional). - measurements : ndarray - An Nx4 dimensional matrix of N measurements, each in - format (x, y, a, h) where (x, y) is the bounding box center - position, a the aspect ratio, and h the height. - only_position : Optional[bool] - If True, distance computation is done with respect to the bounding - box center position only. - - Returns - ------- - ndarray - Returns an array of length N, where the i-th element contains the - squared Mahalanobis distance between (mean, covariance) and - `measurements[i]`. - - """ - mean, covariance = self.project(mean, covariance) - if only_position: - mean, covariance = mean[:2], covariance[:2, :2] - measurements = measurements[:, :2] - - cholesky_factor = np.linalg.cholesky(covariance) - d = measurements - mean - z = scipy.linalg.solve_triangular( - cholesky_factor, d.T, lower=True, check_finite=False, - overwrite_b=True) - squared_maha = np.sum(z * z, axis=0) - return squared_maha \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/log.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/log.py deleted file mode 100755 index 394e1e8c9..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/log.py +++ /dev/null @@ -1,18 +0,0 @@ -import logging - - -def get_logger(name='root'): - formatter = logging.Formatter( - # fmt='%(asctime)s [%(levelname)s]: %(filename)s(%(funcName)s:%(lineno)s) >> %(message)s') - fmt='%(asctime)s [%(levelname)s]: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') - - handler = logging.StreamHandler() - handler.setFormatter(formatter) - - logger = logging.getLogger(name) - logger.setLevel(logging.DEBUG) - logger.addHandler(handler) - return logger - - -logger = get_logger('root') diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/nms.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/nms.py deleted file mode 100755 index 81a0e893c..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/nms.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -# from ._utils import _C -from utils import _C - -nms = _C.nms -# nms.__doc__ = """ -# This function performs Non-maximum suppresion""" diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/parse_config.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/parse_config.py deleted file mode 100755 index b29fd2a03..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/parse_config.py +++ /dev/null @@ -1,35 +0,0 @@ -def parse_model_cfg(path): - """Parses the yolo-v3 layer configuration file and returns module definitions""" - file = open(path, 'r') - lines = file.read().split('\n') - lines = [x for x in lines if x and not x.startswith('#')] - lines = [x.rstrip().lstrip() for x in lines] # get rid of fringe whitespaces - module_defs = [] - for line in lines: - if line.startswith('['): # This marks the start of a new block - module_defs.append({}) - module_defs[-1]['type'] = line[1:-1].rstrip() - if module_defs[-1]['type'] == 'convolutional': - module_defs[-1]['batch_normalize'] = 0 - else: - key, value = line.split("=") - value = value.strip() - module_defs[-1][key.rstrip()] = value.strip() - - return module_defs - - -def parse_data_cfg(path): - """Parses the data configuration file""" - options = dict() - options['gpus'] = '0' - options['num_workers'] = '10' - with open(path, 'r') as fp: - lines = fp.readlines() - for line in lines: - line = line.strip() - if line == '' or line.startswith('#'): - continue - key, value = line.split('=') - options[key.strip()] = value.strip() - return options diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/timer.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/timer.py deleted file mode 100755 index e79f1a310..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/timer.py +++ /dev/null @@ -1,45 +0,0 @@ -# -------------------------------------------------------- -# Fast R-CNN -# Copyright (c) 2015 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ross Girshick -# -------------------------------------------------------- - -import time - - -class Timer(object): - """A simple timer.""" - def __init__(self): - self.total_time = 0. - self.calls = 0 - self.start_time = 0. - self.diff = 0. - self.average_time = 0. - - self.duration = 0. - - def tic(self): - # using time.time instead of time.clock because time time.clock - # does not normalize for multithreading - self.start_time = time.time() - - def toc(self, average=True): - self.diff = time.time() - self.start_time - self.total_time += self.diff - self.calls += 1 - self.average_time = self.total_time / self.calls - if average: - self.duration = self.average_time - else: - self.duration = self.diff - return self.duration - - def clear(self): - self.total_time = 0. - self.calls = 0 - self.start_time = 0. - self.diff = 0. - self.average_time = 0. - self.duration = 0. - diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/utils.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/utils.py deleted file mode 100755 index cf7e63684..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/utils.py +++ /dev/null @@ -1,510 +0,0 @@ -import glob -import random -import time -import os -import os.path as osp - -import cv2 -import matplotlib.pyplot as plt -import numpy as np -import torch -import torch.nn.functional as F - -import platform -if platform.system() != 'Windows': - from detector.nms import nms_wrapper - -# Set printoptions -torch.set_printoptions(linewidth=1320, precision=5, profile='long') -np.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format}) # format short g, %precision=5 - -def mkdir_if_missing(d): - if not osp.exists(d): - os.makedirs(d) - - -def float3(x): # format floats to 3 decimals - return float(format(x, '.3f')) - - -def init_seeds(seed=0): - random.seed(seed) - np.random.seed(seed) - torch.manual_seed(seed) - torch.cuda.manual_seed(seed) - torch.cuda.manual_seed_all(seed) - - -def load_classes(path): - """ - Loads class labels at 'path' - """ - fp = open(path, 'r') - names = fp.read().split('\n') - return list(filter(None, names)) # filter removes empty strings (such as last line) - - -def model_info(model): # Plots a line-by-line description of a PyTorch model - n_p = sum(x.numel() for x in model.parameters()) # number parameters - n_g = sum(x.numel() for x in model.parameters() if x.requires_grad) # number gradients - print('\n%5s %50s %9s %12s %20s %12s %12s' % ('layer', 'name', 'gradient', 'parameters', 'shape', 'mu', 'sigma')) - for i, (name, p) in enumerate(model.named_parameters()): - name = name.replace('module_list.', '') - print('%5g %50s %9s %12g %20s %12.3g %12.3g' % ( - i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std())) - print('Model Summary: %g layers, %g parameters, %g gradients\n' % (i + 1, n_p, n_g)) - - - -def plot_one_box(x, img, color=None, label=None, line_thickness=None): # Plots one bounding box on image img - tl = line_thickness or round(0.0004 * max(img.shape[0:2])) + 1 # line thickness - color = color or [random.randint(0, 255) for _ in range(3)] - c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3])) - cv2.rectangle(img, c1, c2, color, thickness=tl) - if label: - tf = max(tl - 1, 1) # font thickness - t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0] - c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3 - cv2.rectangle(img, c1, c2, color, -1) # filled - cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA) - - -def weights_init_normal(m): - classname = m.__class__.__name__ - if classname.find('Conv') != -1: - torch.nn.init.normal_(m.weight.data, 0.0, 0.03) - elif classname.find('BatchNorm2d') != -1: - torch.nn.init.normal_(m.weight.data, 1.0, 0.03) - torch.nn.init.constant_(m.bias.data, 0.0) - - -def xyxy2xywh(x): - # Convert bounding box format from [x1, y1, x2, y2] to [x, y, w, h] - y = torch.zeros(x.shape) if x.dtype is torch.float32 else np.zeros(x.shape) - y[:, 0] = (x[:, 0] + x[:, 2]) / 2 - y[:, 1] = (x[:, 1] + x[:, 3]) / 2 - y[:, 2] = x[:, 2] - x[:, 0] - y[:, 3] = x[:, 3] - x[:, 1] - return y - - -def xywh2xyxy(x): - # Convert bounding box format from [x, y, w, h] to [x1, y1, x2, y2] - y = torch.zeros(x.shape) if x.dtype is torch.float32 else np.zeros(x.shape) - y[:, 0] = (x[:, 0] - x[:, 2] / 2) - y[:, 1] = (x[:, 1] - x[:, 3] / 2) - y[:, 2] = (x[:, 0] + x[:, 2] / 2) - y[:, 3] = (x[:, 1] + x[:, 3] / 2) - return y - - -def scale_coords(img_size, coords, img0_shape): - # Rescale x1, y1, x2, y2 from 416 to image size - coords = coords.cpu().clone() - gain_w = float(img_size[0]) / img0_shape[0] # gain = old / new - gain_h = float(img_size[1]) / img0_shape[1] - gain = min(gain_w, gain_h) - pad_x = (img_size[0] - img0_shape[0] * gain) / 2 # width padding - pad_y = (img_size[1] - img0_shape[1] * gain) / 2 # height padding - coords[:, [0, 2]] -= pad_x - coords[:, [1, 3]] -= pad_y - coords[:, 0:4] /= gain - coords[:, :4] = torch.clamp(coords[:, :4], min=0) - return coords - - -def ap_per_class(tp, conf, pred_cls, target_cls): - """ Compute the average precision, given the recall and precision curves. - Method originally from https://github.com/rafaelpadilla/Object-Detection-Metrics. - # Arguments - tp: True positives (list). - conf: Objectness value from 0-1 (list). - pred_cls: Predicted object classes (list). - target_cls: True object classes (list). - # Returns - The average precision as computed in py-faster-rcnn. - """ - - # lists/pytorch to numpy - tp, conf, pred_cls, target_cls = np.array(tp), np.array(conf), np.array(pred_cls), np.array(target_cls) - - # Sort by objectness - i = np.argsort(-conf) - tp, conf, pred_cls = tp[i], conf[i], pred_cls[i] - - # Find unique classes - unique_classes = np.unique(np.concatenate((pred_cls, target_cls), 0)) - - # Create Precision-Recall curve and compute AP for each class - ap, p, r = [], [], [] - for c in unique_classes: - i = pred_cls == c - n_gt = sum(target_cls == c) # Number of ground truth objects - n_p = sum(i) # Number of predicted objects - - if (n_p == 0) and (n_gt == 0): - continue - elif (n_p == 0) or (n_gt == 0): - ap.append(0) - r.append(0) - p.append(0) - else: - # Accumulate FPs and TPs - fpc = np.cumsum(1 - tp[i]) - tpc = np.cumsum(tp[i]) - - # Recall - recall_curve = tpc / (n_gt + 1e-16) - r.append(tpc[-1] / (n_gt + 1e-16)) - - # Precision - precision_curve = tpc / (tpc + fpc) - p.append(tpc[-1] / (tpc[-1] + fpc[-1])) - - # AP from recall-precision curve - ap.append(compute_ap(recall_curve, precision_curve)) - - return np.array(ap), unique_classes.astype('int32'), np.array(r), np.array(p) - - -def compute_ap(recall, precision): - """ Compute the average precision, given the recall and precision curves. - Code originally from https://github.com/rbgirshick/py-faster-rcnn. - # Arguments - recall: The recall curve (list). - precision: The precision curve (list). - # Returns - The average precision as computed in py-faster-rcnn. - """ - # correct AP calculation - # first append sentinel values at the end - - mrec = np.concatenate(([0.], recall, [1.])) - mpre = np.concatenate(([0.], precision, [0.])) - - # compute the precision envelope - for i in range(mpre.size - 1, 0, -1): - mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i]) - - # to calculate area under PR curve, look for points - # where X axis (recall) changes value - i = np.where(mrec[1:] != mrec[:-1])[0] - - # and sum (\Delta recall) * prec - ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) - return ap - - -def bbox_iou(box1, box2, x1y1x2y2=False): - """ - Returns the IoU of two bounding boxes - """ - N, M = len(box1), len(box2) - if x1y1x2y2: - # Get the coordinates of bounding boxes - b1_x1, b1_y1, b1_x2, b1_y2 = box1[:, 0], box1[:, 1], box1[:, 2], box1[:, 3] - b2_x1, b2_y1, b2_x2, b2_y2 = box2[:, 0], box2[:, 1], box2[:, 2], box2[:, 3] - else: - # Transform from center and width to exact coordinates - b1_x1, b1_x2 = box1[:, 0] - box1[:, 2] / 2, box1[:, 0] + box1[:, 2] / 2 - b1_y1, b1_y2 = box1[:, 1] - box1[:, 3] / 2, box1[:, 1] + box1[:, 3] / 2 - b2_x1, b2_x2 = box2[:, 0] - box2[:, 2] / 2, box2[:, 0] + box2[:, 2] / 2 - b2_y1, b2_y2 = box2[:, 1] - box2[:, 3] / 2, box2[:, 1] + box2[:, 3] / 2 - - # get the coordinates of the intersection rectangle - inter_rect_x1 = torch.max(b1_x1.unsqueeze(1), b2_x1) - inter_rect_y1 = torch.max(b1_y1.unsqueeze(1), b2_y1) - inter_rect_x2 = torch.min(b1_x2.unsqueeze(1), b2_x2) - inter_rect_y2 = torch.min(b1_y2.unsqueeze(1), b2_y2) - # Intersection area - inter_area = torch.clamp(inter_rect_x2 - inter_rect_x1, 0) * torch.clamp(inter_rect_y2 - inter_rect_y1, 0) - # Union Area - b1_area = ((b1_x2 - b1_x1) * (b1_y2 - b1_y1)) - b1_area = ((b1_x2 - b1_x1) * (b1_y2 - b1_y1)).view(-1,1).expand(N,M) - b2_area = ((b2_x2 - b2_x1) * (b2_y2 - b2_y1)).view(1,-1).expand(N,M) - - return inter_area / (b1_area + b2_area - inter_area + 1e-16) - - -def build_targets_max(target, anchor_wh, nA, nC, nGh, nGw): - """ - returns nT, nCorrect, tx, ty, tw, th, tconf, tcls - """ - nB = len(target) # number of images in batch - - txy = torch.zeros(nB, nA, nGh, nGw, 2).cuda() # batch size, anchors, grid size - twh = torch.zeros(nB, nA, nGh, nGw, 2).cuda() - tconf = torch.LongTensor(nB, nA, nGh, nGw).fill_(0).cuda() - tcls = torch.ByteTensor(nB, nA, nGh, nGw, nC).fill_(0).cuda() # nC = number of classes - tid = torch.LongTensor(nB, nA, nGh, nGw, 1).fill_(-1).cuda() - for b in range(nB): - t = target[b] - t_id = t[:, 1].clone().long().cuda() - t = t[:,[0,2,3,4,5]] - nTb = len(t) # number of targets - if nTb == 0: - continue - - #gxy, gwh = t[:, 1:3] * nG, t[:, 3:5] * nG - gxy, gwh = t[: , 1:3].clone() , t[:, 3:5].clone() - gxy[:, 0] = gxy[:, 0] * nGw - gxy[:, 1] = gxy[:, 1] * nGh - gwh[:, 0] = gwh[:, 0] * nGw - gwh[:, 1] = gwh[:, 1] * nGh - gi = torch.clamp(gxy[:, 0], min=0, max=nGw -1).long() - gj = torch.clamp(gxy[:, 1], min=0, max=nGh -1).long() - - # Get grid box indices and prevent overflows (i.e. 13.01 on 13 anchors) - #gi, gj = torch.clamp(gxy.long(), min=0, max=nG - 1).t() - #gi, gj = gxy.long().t() - - # iou of targets-anchors (using wh only) - box1 = gwh - box2 = anchor_wh.unsqueeze(1) - inter_area = torch.min(box1, box2).prod(2) - iou = inter_area / (box1.prod(1) + box2.prod(2) - inter_area + 1e-16) - - # Select best iou_pred and anchor - iou_best, a = iou.max(0) # best anchor [0-2] for each target - - # Select best unique target-anchor combinations - if nTb > 1: - _, iou_order = torch.sort(-iou_best) # best to worst - - # Unique anchor selection - u = torch.stack((gi, gj, a), 0)[:, iou_order] - # _, first_unique = np.unique(u, axis=1, return_index=True) # first unique indices - first_unique = return_torch_unique_index(u, torch.unique(u, dim=1)) # torch alternative - i = iou_order[first_unique] - # best anchor must share significant commonality (iou) with target - i = i[iou_best[i] > 0.60] # TODO: examine arbitrary threshold - if len(i) == 0: - continue - - a, gj, gi, t = a[i], gj[i], gi[i], t[i] - t_id = t_id[i] - if len(t.shape) == 1: - t = t.view(1, 5) - else: - if iou_best < 0.60: - continue - - tc, gxy, gwh = t[:, 0].long(), t[:, 1:3].clone(), t[:, 3:5].clone() - gxy[:, 0] = gxy[:, 0] * nGw - gxy[:, 1] = gxy[:, 1] * nGh - gwh[:, 0] = gwh[:, 0] * nGw - gwh[:, 1] = gwh[:, 1] * nGh - - # XY coordinates - txy[b, a, gj, gi] = gxy - gxy.floor() - - # Width and height - twh[b, a, gj, gi] = torch.log(gwh / anchor_wh[a]) # yolo method - # twh[b, a, gj, gi] = torch.sqrt(gwh / anchor_wh[a]) / 2 # power method - - # One-hot encoding of label - tcls[b, a, gj, gi, tc] = 1 - tconf[b, a, gj, gi] = 1 - tid[b, a, gj, gi] = t_id.unsqueeze(1) - tbox = torch.cat([txy, twh], -1) - return tconf, tbox, tid - - - -def build_targets_thres(target, anchor_wh, nA, nC, nGh, nGw): - ID_THRESH = 0.5 - FG_THRESH = 0.5 - BG_THRESH = 0.4 - nB = len(target) # number of images in batch - assert(len(anchor_wh)==nA) - - tbox = torch.zeros(nB, nA, nGh, nGw, 4).cuda() # batch size, anchors, grid size - tconf = torch.LongTensor(nB, nA, nGh, nGw).fill_(0).cuda() - tid = torch.LongTensor(nB, nA, nGh, nGw, 1).fill_(-1).cuda() - for b in range(nB): - t = target[b] - t_id = t[:, 1].clone().long().cuda() - t = t[:,[0,2,3,4,5]] - nTb = len(t) # number of targets - if nTb == 0: - continue - - gxy, gwh = t[: , 1:3].clone() , t[:, 3:5].clone() - gxy[:, 0] = gxy[:, 0] * nGw - gxy[:, 1] = gxy[:, 1] * nGh - gwh[:, 0] = gwh[:, 0] * nGw - gwh[:, 1] = gwh[:, 1] * nGh - gxy[:, 0] = torch.clamp(gxy[:, 0], min=0, max=nGw -1) - gxy[:, 1] = torch.clamp(gxy[:, 1], min=0, max=nGh -1) - - gt_boxes = torch.cat([gxy, gwh], dim=1) # Shape Ngx4 (xc, yc, w, h) - - anchor_mesh = generate_anchor(nGh, nGw, anchor_wh) - anchor_list = anchor_mesh.permute(0,2,3,1).contiguous().view(-1, 4) # Shpae (nA x nGh x nGw) x 4 - #print(anchor_list.shape, gt_boxes.shape) - iou_pdist = bbox_iou(anchor_list, gt_boxes) # Shape (nA x nGh x nGw) x Ng - iou_max, max_gt_index = torch.max(iou_pdist, dim=1) # Shape (nA x nGh x nGw), both - - iou_map = iou_max.view(nA, nGh, nGw) - gt_index_map = max_gt_index.view(nA, nGh, nGw) - - #nms_map = pooling_nms(iou_map, 3) - - id_index = iou_map > ID_THRESH - fg_index = iou_map > FG_THRESH - bg_index = iou_map < BG_THRESH - ign_index = (iou_map < FG_THRESH) * (iou_map > BG_THRESH) - tconf[b][fg_index] = 1 - tconf[b][bg_index] = 0 - tconf[b][ign_index] = -1 - - gt_index = gt_index_map[fg_index] - gt_box_list = gt_boxes[gt_index] - gt_id_list = t_id[gt_index_map[id_index]] - #print(gt_index.shape, gt_index_map[id_index].shape, gt_boxes.shape) - if torch.sum(fg_index) > 0: - tid[b][id_index] = gt_id_list.unsqueeze(1) - fg_anchor_list = anchor_list.view(nA, nGh, nGw, 4)[fg_index] - delta_target = encode_delta(gt_box_list, fg_anchor_list) - tbox[b][fg_index] = delta_target - return tconf, tbox, tid - -def generate_anchor(nGh, nGw, anchor_wh): - nA = len(anchor_wh) - yy, xx =torch.meshgrid(torch.arange(nGh), torch.arange(nGw)) - - mesh = torch.stack([xx, yy], dim=0).to(anchor_wh) # Shape 2, nGh, nGw - mesh = mesh.unsqueeze(0).repeat(nA,1,1,1).float() # Shape nA x 2 x nGh x nGw - anchor_offset_mesh = anchor_wh.unsqueeze(-1).unsqueeze(-1).repeat(1, 1, nGh,nGw) # Shape nA x 2 x nGh x nGw - anchor_mesh = torch.cat([mesh, anchor_offset_mesh], dim=1) # Shape nA x 4 x nGh x nGw - return anchor_mesh - -def encode_delta(gt_box_list, fg_anchor_list): - px, py, pw, ph = fg_anchor_list[:, 0], fg_anchor_list[:,1], \ - fg_anchor_list[:, 2], fg_anchor_list[:,3] - gx, gy, gw, gh = gt_box_list[:, 0], gt_box_list[:, 1], \ - gt_box_list[:, 2], gt_box_list[:, 3] - dx = (gx - px) / pw - dy = (gy - py) / ph - dw = torch.log(gw/pw) - dh = torch.log(gh/ph) - return torch.stack([dx, dy, dw, dh], dim=1) - -def decode_delta(delta, fg_anchor_list): - px, py, pw, ph = fg_anchor_list[:, 0], fg_anchor_list[:,1], \ - fg_anchor_list[:, 2], fg_anchor_list[:,3] - dx, dy, dw, dh = delta[:, 0], delta[:, 1], delta[:, 2], delta[:, 3] - gx = pw * dx + px - gy = ph * dy + py - gw = pw * torch.exp(dw) - gh = ph * torch.exp(dh) - return torch.stack([gx, gy, gw, gh], dim=1) - -def decode_delta_map(delta_map, anchors): - ''' - :param: delta_map, shape (nB, nA, nGh, nGw, 4) - :param: anchors, shape (nA,4) - ''' - nB, nA, nGh, nGw, _ = delta_map.shape - anchor_mesh = generate_anchor(nGh, nGw, anchors) - anchor_mesh = anchor_mesh.permute(0,2,3,1).contiguous() # Shpae (nA x nGh x nGw) x 4 - anchor_mesh = anchor_mesh.unsqueeze(0).repeat(nB,1,1,1,1) - pred_list = decode_delta(delta_map.view(-1,4), anchor_mesh.view(-1,4)) - pred_map = pred_list.view(nB, nA, nGh, nGw, 4) - return pred_map - - -def pooling_nms(heatmap, kernel=1): - pad = (kernel -1 ) // 2 - hmax = F.max_pool2d(heatmap, (kernel, kernel), stride=1, padding=pad) - keep = (hmax == heatmap).float() - return keep * heatmap - -def soft_nms(dets, sigma=0.5, Nt=0.3, threshold=0.05, method=1): - keep = cpu_soft_nms(np.ascontiguousarray(dets, dtype=np.float32), - np.float32(sigma), np.float32(Nt), - np.float32(threshold), - np.uint8(method)) - return keep - -def non_max_suppression(prediction, conf_thres=0.5, nms_thres=0.4, method=-1): - """ - Removes detections with lower object confidence score than 'conf_thres' - Non-Maximum Suppression to further filter detections. - Returns detections with shape: - (x1, y1, x2, y2, object_conf, class_score, class_pred) - """ - - output = [None for _ in range(len(prediction))] - for image_i, pred in enumerate(prediction): - # Filter out confidence scores below threshold - # Get score and class with highest confidence - - v = pred[:, 4] > conf_thres - v = v.nonzero().squeeze() - if len(v.shape) == 0: - v = v.unsqueeze(0) - - pred = pred[v] - - # If none are remaining => process next image - nP = pred.shape[0] - if not nP: - continue - # From (center x, center y, width, height) to (x1, y1, x2, y2) - pred[:, :4] = xywh2xyxy(pred[:, :4]) - - - # Non-maximum suppression - if method == -1 and platform.system() != 'Windows': - #We use faster rcnn implementation of nms (soft nms is optional) - nms_op = getattr(nms_wrapper, 'nms') - #nms_op input:(n,(x1,y1,x2,y2,c)) - #nms_op output: input[inds,:], inds - _, nms_indices = nms_op(pred[:,:5], nms_thres) - - else: - dets = pred[:, :5].clone().contiguous().data.cpu().numpy() - nms_indices = soft_nms(dets, Nt=nms_thres, method=method) - det_max = pred[nms_indices] - - if len(det_max) > 0: - # Add max detections to outputs - output[image_i] = det_max if output[image_i] is None else torch.cat((output[image_i], det_max)) - - return output - - -def return_torch_unique_index(u, uv): - n = uv.shape[1] # number of columns - first_unique = torch.zeros(n, device=u.device).long() - for j in range(n): - first_unique[j] = (uv[:, j:j + 1] == u).all(0).nonzero()[0] - - return first_unique - - -def strip_optimizer_from_checkpoint(filename='weights/best.pt'): - # Strip optimizer from *.pt files for lighter files (reduced by 2/3 size) - - a = torch.load(filename, map_location='cpu') - a['optimizer'] = [] - torch.save(a, filename.replace('.pt', '_lite.pt')) - - -def plot_results(): - # Plot YOLO training results file 'results.txt' - # import os; os.system('wget https://storage.googleapis.com/ultralytics/yolov3/results_v1.txt') - - plt.figure(figsize=(14, 7)) - s = ['X + Y', 'Width + Height', 'Confidence', 'Classification', 'Total Loss', 'mAP', 'Recall', 'Precision'] - files = sorted(glob.glob('results*.txt')) - for f in files: - results = np.loadtxt(f, usecols=[2, 3, 4, 5, 6, 9, 10, 11]).T # column 11 is mAP - x = range(1, results.shape[1]) - for i in range(8): - plt.subplot(2, 4, i + 1) - plt.plot(x, results[i, x], marker='.', label=f) - plt.title(s[i]) - if i == 0: - plt.legend() diff --git a/cv/pose/alphapose/pytorch/detector/tracker/utils/visualization.py b/cv/pose/alphapose/pytorch/detector/tracker/utils/visualization.py deleted file mode 100755 index b075f325e..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker/utils/visualization.py +++ /dev/null @@ -1,90 +0,0 @@ -import numpy as np -import cv2 - - -def tlwhs_to_tlbrs(tlwhs): - tlbrs = np.copy(tlwhs) - if len(tlbrs) == 0: - return tlbrs - tlbrs[:, 2] += tlwhs[:, 0] - tlbrs[:, 3] += tlwhs[:, 1] - return tlbrs - - -def get_color(idx): - idx = idx * 3 - color = ((37 * idx) % 255, (17 * idx) % 255, (29 * idx) % 255) - - return color - - -def resize_image(image, max_size=800): - if max(image.shape[:2]) > max_size: - scale = float(max_size) / max(image.shape[:2]) - image = cv2.resize(image, None, fx=scale, fy=scale) - return image - - -def plot_tracking(image, tlwhs, obj_ids, scores=None, frame_id=0, fps=0., ids2=None): - im = np.ascontiguousarray(np.copy(image)) - im_h, im_w = im.shape[:2] - - top_view = np.zeros([im_w, im_w, 3], dtype=np.uint8) + 255 - - text_scale = max(1, image.shape[1] / 1600.) - text_thickness = 1 if text_scale > 1.1 else 1 - line_thickness = max(1, int(image.shape[1] / 500.)) - - radius = max(5, int(im_w/140.)) - cv2.putText(im, 'frame: %d fps: %.2f num: %d' % (frame_id, fps, len(tlwhs)), - (0, int(15 * text_scale)), cv2.FONT_HERSHEY_PLAIN, text_scale, (0, 0, 255), thickness=2) - - for i, tlwh in enumerate(tlwhs): - x1, y1, w, h = tlwh - intbox = tuple(map(int, (x1, y1, x1 + w, y1 + h))) - obj_id = int(obj_ids[i]) - id_text = '{}'.format(int(obj_id)) - if ids2 is not None: - id_text = id_text + ', {}'.format(int(ids2[i])) - _line_thickness = 1 if obj_id <= 0 else line_thickness - color = get_color(abs(obj_id)) - cv2.rectangle(im, intbox[0:2], intbox[2:4], color=color, thickness=line_thickness) - cv2.putText(im, id_text, (intbox[0], intbox[1] + 30), cv2.FONT_HERSHEY_PLAIN, text_scale, (0, 0, 255), - thickness=text_thickness) - return im - - -def plot_trajectory(image, tlwhs, track_ids): - image = image.copy() - for one_tlwhs, track_id in zip(tlwhs, track_ids): - color = get_color(int(track_id)) - for tlwh in one_tlwhs: - x1, y1, w, h = tuple(map(int, tlwh)) - cv2.circle(image, (int(x1 + 0.5 * w), int(y1 + h)), 2, color, thickness=2) - - return image - - -def plot_detections(image, tlbrs, scores=None, color=(255, 0, 0), ids=None): - im = np.copy(image) - text_scale = max(1, image.shape[1] / 800.) - thickness = 2 if text_scale > 1.3 else 1 - for i, det in enumerate(tlbrs): - x1, y1, x2, y2 = np.asarray(det[:4], dtype=np.int) - if len(det) >= 7: - label = 'det' if det[5] > 0 else 'trk' - if ids is not None: - text = '{}# {:.2f}: {:d}'.format(label, det[6], ids[i]) - cv2.putText(im, text, (x1, y1 + 30), cv2.FONT_HERSHEY_PLAIN, text_scale, (0, 255, 255), - thickness=thickness) - else: - text = '{}# {:.2f}'.format(label, det[6]) - - if scores is not None: - text = '{:.2f}'.format(scores[i]) - cv2.putText(im, text, (x1, y1 + 30), cv2.FONT_HERSHEY_PLAIN, text_scale, (0, 255, 255), - thickness=thickness) - - cv2.rectangle(im, (x1, y1), (x2, y2), color, 2) - - return im diff --git a/cv/pose/alphapose/pytorch/detector/tracker_api.py b/cv/pose/alphapose/pytorch/detector/tracker_api.py deleted file mode 100755 index adfe4137c..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker_api.py +++ /dev/null @@ -1,238 +0,0 @@ -# ----------------------------------------------------- -# Copyright (c) Shanghai Jiao Tong University. All rights reserved. -# Written by Haoshu Fang (fhaoshu@gmail.com) -# ----------------------------------------------------- - -"""API of yolo tracker""" -import os -import sys -sys.path.insert(0, os.path.dirname(__file__)) -from abc import ABC, abstractmethod -import platform - -import torch -import numpy as np - -from tracker.tracker.multitracker import STrack, joint_stracks, sub_stracks, remove_duplicate_stracks - -from tracker.preprocess import prep_image, prep_frame -from tracker.utils.kalman_filter import KalmanFilter -from tracker.utils.utils import non_max_suppression, scale_coords -from tracker.utils.log import logger -from tracker.tracker import matching -from tracker.tracker.basetrack import BaseTrack, TrackState -from tracker.models import Darknet - -from detector.apis import BaseDetector - - -class Tracker(BaseDetector): - def __init__(self, cfg, opt=None): - super(Tracker, self).__init__() - - self.tracker_opt = opt - self.model_cfg = cfg.get('CONFIG', 'detector/tracker/cfg/yolov3.cfg') - self.model_weights = cfg.get('WEIGHTS', 'detector/tracker/data/jde.1088x608.uncertainty.pt') - self.img_size = cfg.get('IMG_SIZE', (1088, 608)) - self.nms_thres = cfg.get('NMS_THRES', 0.6) - self.confidence = cfg.get('CONFIDENCE', 0.05) - self.max_time_lost = cfg.get('BUFFER_SIZE', 30) # buffer - self.model = None - - self.tracked_stracks = [] # type: list[STrack] - self.lost_stracks = [] # type: list[STrack] - self.removed_stracks = [] # type: list[STrack] - - self.frame_id = 0 - self.emb_dim = None - - - self.kalman_filter = KalmanFilter() - - def load_model(self): - print('Loading tracking model..') - self.model = Darknet(self.model_cfg, self.img_size, nID=14455) - # load_darknet_weights(self.model, args.weights) - self.model.load_state_dict(torch.load(self.model_weights, map_location='cpu')['model'], strict=False) - self.emb_dim = self.model.emb_dim - - if self.tracker_opt: - if len(self.tracker_opt.gpus) > 1: - self.model = torch.nn.DataParallel(self.model, device_ids=self.tracker_opt.gpus).to(self.tracker_opt.device) - else: - self.model.to(self.tracker_opt.device) - else: - self.model.cuda() - self.model.eval() - print("Network successfully loaded") - - - - def image_preprocess(self, img_source): - """ - Pre-process the img before fed to the object detection network - Input: image name(str) or raw image data(ndarray or torch.Tensor,channel GBR) - Output: pre-processed image data(torch.FloatTensor,(1,3,h,w)) - """ - if isinstance(img_source, str): - img, orig_img, im_dim_list = prep_image(img_source, self.img_size) - elif isinstance(img_source, torch.Tensor) or isinstance(img_source, np.ndarray): - img, orig_img, im_dim_list = prep_frame(img_source, self.img_size) - else: - raise IOError('Unknown image source type: {}'.format(type(img_source))) - - return img - - def images_detection(self, imgs, orig_dim_list): - """ - Feed the img data into object detection network and - collect bbox w.r.t original image size - Input: imgs(torch.FloatTensor,(b,3,h,w)): pre-processed mini-batch image input - orig_dim_list(torch.FloatTensor, (b,(w,h,w,h))): original mini-batch image size - Output: dets(torch.cuda.FloatTensor,(n,(batch_idx,x1,y1,x2,y2,c,s,idx of cls))): human detection results - """ - args = self.tracker_opt - _CUDA = True - if args: - if args.gpus[0] < 0: - _CUDA = False - if not self.model: - self.load_model() - - - activated_starcks = [] - refind_stracks = [] - lost_stracks = [] - removed_stracks = [] - - ''' Step 1: Network forward, get detections & embeddings''' - with torch.no_grad(): - imgs = imgs.to(args.device) if args else imgs.cuda() - pred = self.model(imgs) - - if len(pred) > 0: - dets = non_max_suppression(pred, self.confidence, self.nms_thres) - - output_stracks = [] - for image_i in range(len(imgs)): - self.frame_id += 1 - if dets[image_i] is not None: - det_i = scale_coords(self.img_size, dets[image_i], orig_dim_list[image_i]) - '''Detections''' - detections = [STrack(STrack.tlbr_to_tlwh(tlbrs[:4]), tlbrs[4], f.numpy(), 30) for - (tlbrs, f) in zip(det_i[:, :5], det_i[:, -self.emb_dim:])] - else: - detections = [] - - - ''' Add newly detected tracklets to tracked_stracks''' - unconfirmed = [] - tracked_stracks = [] # type: list[STrack] - for track in self.tracked_stracks: - if not track.is_activated: - unconfirmed.append(track) - else: - tracked_stracks.append(track) - - ''' Step 2: First association, with embedding''' - strack_pool = joint_stracks(tracked_stracks, self.lost_stracks) - # Predict the current location with KF - for strack in strack_pool: - strack.predict() - - dists = matching.embedding_distance(strack_pool, detections) - dists = matching.gate_cost_matrix(self.kalman_filter, dists, strack_pool, detections) - matches, u_track, u_detection = matching.linear_assignment(dists, thresh=0.7) - - for itracked, idet in matches: - track = strack_pool[itracked] - det = detections[idet] - if track.state == TrackState.Tracked: - track.update(detections[idet], self.frame_id) - activated_starcks.append(track) - else: - track.re_activate(det, self.frame_id, new_id=False) - refind_stracks.append(track) - - ''' Step 3: Second association, with IOU''' - detections = [detections[i] for i in u_detection] - r_tracked_stracks = [strack_pool[i] for i in u_track if strack_pool[i].state==TrackState.Tracked ] - dists = matching.iou_distance(r_tracked_stracks, detections) - matches, u_track, u_detection = matching.linear_assignment(dists, thresh=0.5) - - for itracked, idet in matches: - track = r_tracked_stracks[itracked] - det = detections[idet] - if track.state == TrackState.Tracked: - track.update(det, self.frame_id) - activated_starcks.append(track) - else: - track.re_activate(det, self.frame_id, new_id=False) - refind_stracks.append(track) - - for it in u_track: - track = r_tracked_stracks[it] - if not track.state == TrackState.Lost: - track.mark_lost() - lost_stracks.append(track) - - '''Deal with unconfirmed tracks, usually tracks with only one beginning frame''' - detections = [detections[i] for i in u_detection] - dists = matching.iou_distance(unconfirmed, detections) - matches, u_unconfirmed, u_detection = matching.linear_assignment(dists, thresh=0.7) - for itracked, idet in matches: - unconfirmed[itracked].update(detections[idet], self.frame_id) - activated_starcks.append(unconfirmed[itracked]) - for it in u_unconfirmed: - track = unconfirmed[it] - track.mark_removed() - removed_stracks.append(track) - - """ Step 4: Init new stracks""" - for inew in u_detection: - track = detections[inew] - if track.score < self.confidence: - continue - track.activate(self.kalman_filter, self.frame_id) - activated_starcks.append(track) - - """ Step 5: Update state""" - for track in self.lost_stracks: - if self.frame_id - track.end_frame > self.max_time_lost: - track.mark_removed() - removed_stracks.append(track) - - self.tracked_stracks = [t for t in self.tracked_stracks if t.state == TrackState.Tracked] - self.tracked_stracks = joint_stracks(self.tracked_stracks, activated_starcks) - self.tracked_stracks = joint_stracks(self.tracked_stracks, refind_stracks) - # self.lost_stracks = [t for t in self.lost_stracks if t.state == TrackState.Lost] # type: list[STrack] - self.lost_stracks = sub_stracks(self.lost_stracks, self.tracked_stracks) - self.lost_stracks.extend(lost_stracks) - self.lost_stracks = sub_stracks(self.lost_stracks, self.removed_stracks) - self.removed_stracks.extend(removed_stracks) - self.tracked_stracks, self.lost_stracks = remove_duplicate_stracks(self.tracked_stracks, self.lost_stracks) - - if self.tracker_opt.debug: - logger.debug('===========Frame {}=========='.format(self.frame_id)) - logger.debug('Activated: {}'.format([track.track_id for track in activated_starcks])) - logger.debug('Refind: {}'.format([track.track_id for track in refind_stracks])) - logger.debug('Lost: {}'.format([track.track_id for track in lost_stracks])) - logger.debug('Removed: {}'.format([track.track_id for track in removed_stracks])) - - # Add tracks to outputs - for t in self.tracked_stracks: - tlwh = t.tlwh - tid = t.track_id - tlbr = t.tlbr - ts = t.score - if tlwh[2] * tlwh[3] > self.tracker_opt.min_box_area: - res = torch.tensor([image_i, tlbr[0], tlbr[1], tlbr[2], tlbr[3], ts, tid]) - output_stracks.append(res) - - if len(output_stracks) == 0: - return 0 - - return torch.stack(output_stracks) - - def detect_one_img(self, img_name): - pass \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/tracker_cfg.py b/cv/pose/alphapose/pytorch/detector/tracker_cfg.py deleted file mode 100755 index e8bd55c1a..000000000 --- a/cv/pose/alphapose/pytorch/detector/tracker_cfg.py +++ /dev/null @@ -1,9 +0,0 @@ -from easydict import EasyDict as edict - -cfg = edict() -cfg.CONFIG = 'detector/tracker/cfg/yolov3.cfg' -cfg.WEIGHTS = 'detector/tracker/data/jde.1088x608.uncertainty.pt' -cfg.IMG_SIZE = (1088, 608) -cfg.NMS_THRES = 0.6 -cfg.CONFIDENCE = 0.4 -cfg.BUFFER_SIZE = 30 # frame buffer \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/detector/yolo/README.md b/cv/pose/alphapose/pytorch/detector/yolo/README.md deleted file mode 100755 index ed47930a3..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# A PyTorch implementation of a YOLO v3 Object Detector - -Forked from https://github.com/ayooshkathuria/pytorch-yolo-v3 diff --git a/cv/pose/alphapose/pytorch/detector/yolo/__init__.py b/cv/pose/alphapose/pytorch/detector/yolo/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/yolo/bbox.py b/cv/pose/alphapose/pytorch/detector/yolo/bbox.py deleted file mode 100755 index 6a3c3bcd1..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/bbox.py +++ /dev/null @@ -1,114 +0,0 @@ -from __future__ import division - -import torch -import random - -import numpy as np -import cv2 - -def confidence_filter(result, confidence): - conf_mask = (result[:,:,4] > confidence).float().unsqueeze(2) - result = result*conf_mask - - return result - -def confidence_filter_cls(result, confidence): - max_scores = torch.max(result[:,:,5:25], 2)[0] - res = torch.cat((result, max_scores),2) - print(res.shape) - - - cond_1 = (res[:,:,4] > confidence).float() - cond_2 = (res[:,:,25] > 0.995).float() - - conf = cond_1 + cond_2 - conf = torch.clamp(conf, 0.0, 1.0) - conf = conf.unsqueeze(2) - result = result*conf - return result - - - -def get_abs_coord(box): - box[2], box[3] = abs(box[2]), abs(box[3]) - x1 = (box[0] - box[2]/2) - 1 - y1 = (box[1] - box[3]/2) - 1 - x2 = (box[0] + box[2]/2) - 1 - y2 = (box[1] + box[3]/2) - 1 - return x1, y1, x2, y2 - - - -def sanity_fix(box): - if (box[0] > box[2]): - box[0], box[2] = box[2], box[0] - - if (box[1] > box[3]): - box[1], box[3] = box[3], box[1] - - return box - -def bbox_iou(box1, box2, args=None): - """ - Returns the IoU of two bounding boxes - - - """ - #Get the coordinates of bounding boxes - b1_x1, b1_y1, b1_x2, b1_y2 = box1[:,0], box1[:,1], box1[:,2], box1[:,3] - b2_x1, b2_y1, b2_x2, b2_y2 = box2[:,0], box2[:,1], box2[:,2], box2[:,3] - - #get the corrdinates of the intersection rectangle - inter_rect_x1 = torch.max(b1_x1, b2_x1) - inter_rect_y1 = torch.max(b1_y1, b2_y1) - inter_rect_x2 = torch.min(b1_x2, b2_x2) - inter_rect_y2 = torch.min(b1_y2, b2_y2) - - #Intersection area - if not args: - inter_area = torch.max(inter_rect_x2 - inter_rect_x1 + 1,torch.zeros(inter_rect_x2.shape).cuda())*torch.max(inter_rect_y2 - inter_rect_y1 + 1, torch.zeros(inter_rect_x2.shape).cuda()) - else: - inter_area = torch.max(inter_rect_x2 - inter_rect_x1 + 1,torch.zeros(inter_rect_x2.shape).to(args.device))*torch.max(inter_rect_y2 - inter_rect_y1 + 1, torch.zeros(inter_rect_x2.shape).to(args.device)) - #Union Area - b1_area = (b1_x2 - b1_x1 + 1)*(b1_y2 - b1_y1 + 1) - b2_area = (b2_x2 - b2_x1 + 1)*(b2_y2 - b2_y1 + 1) - - iou = inter_area / (b1_area + b2_area - inter_area) - - return iou - - -def pred_corner_coord(prediction): - #Get indices of non-zero confidence bboxes - ind_nz = torch.nonzero(prediction[:,:,4]).transpose(0,1).contiguous() - - box = prediction[ind_nz[0], ind_nz[1]] - - - box_a = box.new(box.shape) - box_a[:,0] = (box[:,0] - box[:,2]/2) - box_a[:,1] = (box[:,1] - box[:,3]/2) - box_a[:,2] = (box[:,0] + box[:,2]/2) - box_a[:,3] = (box[:,1] + box[:,3]/2) - box[:,:4] = box_a[:,:4] - - prediction[ind_nz[0], ind_nz[1]] = box - - return prediction - - - - -def write(x, batches, results, colors, classes): - c1 = tuple(x[1:3].int()) - c2 = tuple(x[3:5].int()) - img = results[int(x[0])] - cls = int(x[-1]) - label = "{0}".format(classes[cls]) - color = random.choice(colors) - cv2.rectangle(img, c1, c2,color, 1) - t_size = cv2.getTextSize(label, cv2.FONT_HERSHEY_PLAIN, 1 , 1)[0] - c2 = c1[0] + t_size[0] + 3, c1[1] + t_size[1] + 4 - cv2.rectangle(img, c1, c2,color, -1) - cv2.putText(img, label, (c1[0], c1[1] + t_size[1] + 4), cv2.FONT_HERSHEY_PLAIN, 1, [225,255,255], 1); - return img diff --git a/cv/pose/alphapose/pytorch/detector/yolo/cam_demo.py b/cv/pose/alphapose/pytorch/detector/yolo/cam_demo.py deleted file mode 100755 index 5fdb002d9..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/cam_demo.py +++ /dev/null @@ -1,168 +0,0 @@ -from __future__ import division -import time -import torch -import torch.nn as nn -from torch.autograd import Variable -import numpy as np -import cv2 -from util import * -from darknet import Darknet -from preprocess import prep_image, inp_to_image -import pandas as pd -import random -import argparse -import pickle as pkl - -def get_test_input(input_dim, CUDA): - img = cv2.imread("imgs/messi.jpg") - img = cv2.resize(img, (input_dim, input_dim)) - img_ = img[:,:,::-1].transpose((2,0,1)) - img_ = img_[np.newaxis,:,:,:]/255.0 - img_ = torch.from_numpy(img_).float() - img_ = Variable(img_) - - if CUDA: - img_ = img_.cuda() - - return img_ - -def prep_image(img, inp_dim): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = img - dim = orig_im.shape[1], orig_im.shape[0] - img = cv2.resize(orig_im, (inp_dim, inp_dim)) - img_ = img[:,:,::-1].transpose((2,0,1)).copy() - img_ = torch.from_numpy(img_).float().div(255.0).unsqueeze(0) - return img_, orig_im, dim - -def write(x, img): - c1 = tuple(x[1:3].int()) - c2 = tuple(x[3:5].int()) - cls = int(x[-1]) - label = "{0}".format(classes[cls]) - color = random.choice(colors) - cv2.rectangle(img, c1, c2,color, 1) - t_size = cv2.getTextSize(label, cv2.FONT_HERSHEY_PLAIN, 1 , 1)[0] - c2 = c1[0] + t_size[0] + 3, c1[1] + t_size[1] + 4 - cv2.rectangle(img, c1, c2,color, -1) - cv2.putText(img, label, (c1[0], c1[1] + t_size[1] + 4), cv2.FONT_HERSHEY_PLAIN, 1, [225,255,255], 1); - return img - -def arg_parse(): - """ - Parse arguements to the detect module - - """ - - - parser = argparse.ArgumentParser(description='YOLO v3 Cam Demo') - parser.add_argument("--confidence", dest = "confidence", help = "Object Confidence to filter predictions", default = 0.25) - parser.add_argument("--nms_thresh", dest = "nms_thresh", help = "NMS Threshhold", default = 0.4) - parser.add_argument("--reso", dest = 'reso', help = - "Input resolution of the network. Increase to increase accuracy. Decrease to increase speed", - default = "160", type = str) - return parser.parse_args() - - - -if __name__ == '__main__': - cfgfile = "cfg/yolov3-spp.cfg" - weightsfile = "yolov3-spp.weights" - num_classes = 80 - - args = arg_parse() - confidence = float(args.confidence) - nms_thesh = float(args.nms_thresh) - start = 0 - CUDA = torch.cuda.is_available() - - - - - num_classes = 80 - bbox_attrs = 5 + num_classes - - model = Darknet(cfgfile) - model.load_weights(weightsfile) - - model.net_info["height"] = args.reso - inp_dim = int(model.net_info["height"]) - - assert inp_dim % 32 == 0 - assert inp_dim > 32 - - if CUDA: - model.cuda() - - model.eval() - - videofile = 'video.avi' - - cap = cv2.VideoCapture(0) - - assert cap.isOpened(), 'Cannot capture source' - - frames = 0 - start = time.time() - while cap.isOpened(): - - ret, frame = cap.read() - if ret: - - img, orig_im, dim = prep_image(frame, inp_dim) - -# im_dim = torch.FloatTensor(dim).repeat(1,2) - - - if CUDA: - im_dim = im_dim.cuda() - img = img.cuda() - - - output = model(Variable(img), CUDA) - output = write_results(output, confidence, num_classes, nms = True, nms_conf = nms_thesh) - - if type(output) == int: - frames += 1 - print("FPS of the video is {:5.2f}".format( frames / (time.time() - start))) - cv2.imshow("frame", orig_im) - key = cv2.waitKey(1) - if key & 0xFF == ord('q'): - break - continue - - - - output[:,1:5] = torch.clamp(output[:,1:5], 0.0, float(inp_dim))/inp_dim - -# im_dim = im_dim.repeat(output.size(0), 1) - output[:,[1,3]] *= frame.shape[1] - output[:,[2,4]] *= frame.shape[0] - - - classes = load_classes('data/coco.names') - colors = pkl.load(open("pallete", "rb")) - - list(map(lambda x: write(x, orig_im), output)) - - - cv2.imshow("frame", orig_im) - key = cv2.waitKey(1) - if key & 0xFF == ord('q'): - break - frames += 1 - print("FPS of the video is {:5.2f}".format( frames / (time.time() - start))) - - - else: - break - - - - - diff --git a/cv/pose/alphapose/pytorch/detector/yolo/cfg/tiny-yolo-voc.cfg b/cv/pose/alphapose/pytorch/detector/yolo/cfg/tiny-yolo-voc.cfg deleted file mode 100755 index ab2c066a2..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/cfg/tiny-yolo-voc.cfg +++ /dev/null @@ -1,134 +0,0 @@ -[net] -batch=64 -subdivisions=8 -width=416 -height=416 -channels=3 -momentum=0.9 -decay=0.0005 -angle=0 -saturation = 1.5 -exposure = 1.5 -hue=.1 - -learning_rate=0.001 -max_batches = 40200 -policy=steps -steps=-1,100,20000,30000 -scales=.1,10,.1,.1 - -[convolutional] -batch_normalize=1 -filters=16 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=32 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=64 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=1 - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -########### - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=125 -activation=linear - -[region] -anchors = 1.08,1.19, 3.42,4.41, 6.63,11.38, 9.42,5.11, 16.62,10.52 -bias_match=1 -classes=20 -coords=4 -num=5 -softmax=1 -jitter=.2 -rescore=1 - -object_scale=5 -noobject_scale=1 -class_scale=1 -coord_scale=1 - -absolute=1 -thresh = .6 -random=1 diff --git a/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolo-voc.cfg b/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolo-voc.cfg deleted file mode 100755 index d5bdfc1c5..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolo-voc.cfg +++ /dev/null @@ -1,258 +0,0 @@ -[net] -# Testing -batch=64 -subdivisions=8 -# Training -# batch=64 -# subdivisions=8 -height=416 -width=416 -channels=3 -momentum=0.9 -decay=0.0005 -angle=0 -saturation = 1.5 -exposure = 1.5 -hue=.1 - -learning_rate=0.001 -burn_in=1000 -max_batches = 80200 -policy=steps -steps=-1,500,40000,60000 -scales=0.1,10,.1,.1 - -[convolutional] -batch_normalize=1 -filters=32 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=64 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=64 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - - -####### - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[route] -layers=-9 - -[convolutional] -batch_normalize=1 -size=1 -stride=1 -pad=1 -filters=64 -activation=leaky - -[reorg] -stride=2 - -[route] -layers=-1,-4 - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=125 -activation=linear - - -[region] -anchors = 1.3221, 1.73145, 3.19275, 4.00944, 5.05587, 8.09892, 9.47112, 4.84053, 11.2364, 10.0071 -bias_match=1 -classes=20 -coords=4 -num=5 -softmax=1 -jitter=.3 -rescore=1 - -object_scale=5 -noobject_scale=1 -class_scale=1 -coord_scale=1 - -absolute=1 -thresh = .6 -random=1 diff --git a/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolo.cfg b/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolo.cfg deleted file mode 100755 index 2a0cd98fb..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolo.cfg +++ /dev/null @@ -1,258 +0,0 @@ -[net] -# Testing -batch=1 -subdivisions=1 -# Training -# batch=64 -# subdivisions=8 -width=416 -height=416 -channels=3 -momentum=0.9 -decay=0.0005 -angle=0 -saturation = 1.5 -exposure = 1.5 -hue=.1 - -learning_rate=0.001 -burn_in=1000 -max_batches = 500200 -policy=steps -steps=400000,450000 -scales=.1,.1 - -[convolutional] -batch_normalize=1 -filters=32 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=64 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=64 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[maxpool] -size=2 -stride=2 - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - - -####### - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[route] -layers=-9 - -[convolutional] -batch_normalize=1 -size=1 -stride=1 -pad=1 -filters=64 -activation=leaky - -[reorg] -stride=2 - -[route] -layers=-1,-4 - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=425 -activation=linear - - -[region] -anchors = 0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, 9.77052, 9.16828 -bias_match=1 -classes=80 -coords=4 -num=5 -softmax=1 -jitter=.3 -rescore=1 - -object_scale=5 -noobject_scale=1 -class_scale=1 -coord_scale=1 - -absolute=1 -thresh = .6 -random=1 diff --git a/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolov3-spp.cfg b/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolov3-spp.cfg deleted file mode 100755 index 4ad2a052d..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolov3-spp.cfg +++ /dev/null @@ -1,822 +0,0 @@ -[net] -# Testing -batch=1 -subdivisions=1 -# Training -# batch=64 -# subdivisions=16 -width=608 -height=608 -channels=3 -momentum=0.9 -decay=0.0005 -angle=0 -saturation = 1.5 -exposure = 1.5 -hue=.1 - -learning_rate=0.001 -burn_in=1000 -max_batches = 500200 -policy=steps -steps=400000,450000 -scales=.1,.1 - -[convolutional] -batch_normalize=1 -filters=32 -size=3 -stride=1 -pad=1 -activation=leaky - -# Downsample - -[convolutional] -batch_normalize=1 -filters=64 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=32 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=64 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=64 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=64 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -###################### - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -### SPP ### -[maxpool] -stride=1 -size=5 - -[route] -layers=-2 - -[maxpool] -stride=1 -size=9 - -[route] -layers=-4 - -[maxpool] -stride=1 -size=13 - -[route] -layers=-1,-3,-5,-6 - -### End SPP ### - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=255 -activation=linear - - -[yolo] -mask = 6,7,8 -anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 -classes=80 -num=9 -jitter=.3 -ignore_thresh = .7 -truth_thresh = 1 -random=1 - - -[route] -layers = -4 - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[upsample] -stride=2 - -[route] -layers = -1, 61 - - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=512 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=512 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=512 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=255 -activation=linear - - -[yolo] -mask = 3,4,5 -anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 -classes=80 -num=9 -jitter=.3 -ignore_thresh = .7 -truth_thresh = 1 -random=1 - - - -[route] -layers = -4 - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[upsample] -stride=2 - -[route] -layers = -1, 36 - - - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=256 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=256 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=256 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=255 -activation=linear - - -[yolo] -mask = 0,1,2 -anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 -classes=80 -num=9 -jitter=.3 -ignore_thresh = .7 -truth_thresh = 1 -random=1 - diff --git a/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolov3.cfg b/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolov3.cfg deleted file mode 100755 index e94193b0e..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/cfg/yolov3.cfg +++ /dev/null @@ -1,789 +0,0 @@ -[net] -# Testing -batch=1 -subdivisions=1 -# Training -# batch=64 -# subdivisions=16 -width= 320 -height = 320 -channels=3 -momentum=0.9 -decay=0.0005 -angle=0 -saturation = 1.5 -exposure = 1.5 -hue=.1 - -learning_rate=0.001 -burn_in=1000 -max_batches = 500200 -policy=steps -steps=400000,450000 -scales=.1,.1 - -[convolutional] -batch_normalize=1 -filters=32 -size=3 -stride=1 -pad=1 -activation=leaky - -# Downsample - -[convolutional] -batch_normalize=1 -filters=64 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=32 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=64 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=64 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=64 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -# Downsample - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=2 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=1024 -size=3 -stride=1 -pad=1 -activation=leaky - -[shortcut] -from=-3 -activation=linear - -###################### - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=512 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=1024 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=255 -activation=linear - - -[yolo] -mask = 6,7,8 -anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 -classes=80 -num=9 -jitter=.3 -ignore_thresh = .5 -truth_thresh = 1 -random=1 - - -[route] -layers = -4 - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[upsample] -stride=2 - -[route] -layers = -1, 61 - - - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=512 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=512 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=256 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=512 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=255 -activation=linear - - -[yolo] -mask = 3,4,5 -anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 -classes=80 -num=9 -jitter=.3 -ignore_thresh = .5 -truth_thresh = 1 -random=1 - - - -[route] -layers = -4 - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[upsample] -stride=2 - -[route] -layers = -1, 36 - - - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=256 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=256 -activation=leaky - -[convolutional] -batch_normalize=1 -filters=128 -size=1 -stride=1 -pad=1 -activation=leaky - -[convolutional] -batch_normalize=1 -size=3 -stride=1 -pad=1 -filters=256 -activation=leaky - -[convolutional] -size=1 -stride=1 -pad=1 -filters=255 -activation=linear - - -[yolo] -mask = 0,1,2 -anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 -classes=80 -num=9 -jitter=.3 -ignore_thresh = .5 -truth_thresh = 1 -random=1 - diff --git a/cv/pose/alphapose/pytorch/detector/yolo/darknet.py b/cv/pose/alphapose/pytorch/detector/yolo/darknet.py deleted file mode 100755 index 88ec3547e..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/darknet.py +++ /dev/null @@ -1,548 +0,0 @@ -from __future__ import division - -import torch -import torch.nn as nn -import torch.nn.functional as F -from torch.autograd import Variable -import numpy as np -import cv2 -import matplotlib.pyplot as plt -try: - from util import count_parameters as count - from util import convert2cpu as cpu - from util import predict_transform -except ImportError: - from yolo.util import count_parameters as count - from yolo.util import convert2cpu as cpu - from yolo.util import predict_transform - -class test_net(nn.Module): - def __init__(self, num_layers, input_size): - super(test_net, self).__init__() - self.num_layers= num_layers - self.linear_1 = nn.Linear(input_size, 5) - self.middle = nn.ModuleList([nn.Linear(5,5) for x in range(num_layers)]) - self.output = nn.Linear(5,2) - - def forward(self, x): - x = x.view(-1) - fwd = nn.Sequential(self.linear_1, *self.middle, self.output) - return fwd(x) - -def get_test_input(): - img = cv2.imread("dog-cycle-car.png") - img = cv2.resize(img, (416,416)) - img_ = img[:,:,::-1].transpose((2,0,1)) - img_ = img_[np.newaxis,:,:,:]/255.0 - img_ = torch.from_numpy(img_).float() - img_ = Variable(img_) - return img_ - - -def parse_cfg(cfgfile): - """ - Takes a configuration file - - Returns a list of blocks. Each blocks describes a block in the neural - network to be built. Block is represented as a dictionary in the list - - """ - file = open(cfgfile, 'r') - lines = file.read().split('\n') #store the lines in a list - lines = [x for x in lines if len(x) > 0] #get read of the empty lines - lines = [x for x in lines if x[0] != '#'] - lines = [x.rstrip().lstrip() for x in lines] - - - block = {} - blocks = [] - - for line in lines: - if line[0] == "[": #This marks the start of a new block - if len(block) != 0: - blocks.append(block) - block = {} - block["type"] = line[1:-1].rstrip() - else: - key,value = line.split("=") - block[key.rstrip()] = value.lstrip() - blocks.append(block) - - return blocks -# print('\n\n'.join([repr(x) for x in blocks])) - -import pickle as pkl - -class MaxPoolStride1(nn.Module): - def __init__(self, kernel_size): - super(MaxPoolStride1, self).__init__() - self.kernel_size = kernel_size - self.pad = kernel_size - 1 - - def forward(self, x): - padding = int(self.pad / 2) - #padded_x = F.pad(x, (0,self.pad,0,self.pad), mode="replicate") - #pooled_x = nn.MaxPool2d(self.kernel_size, self.pad)(padded_x) - #padded_x = F.pad(x, (0, self.pad, 0, self.pad), mode="replicate") - padded_x = F.pad(x, (padding, padding, padding, padding), mode="constant", value=0) - pooled_x = nn.MaxPool2d(self.kernel_size, 1)(padded_x) - return pooled_x - - -class EmptyLayer(nn.Module): - def __init__(self): - super(EmptyLayer, self).__init__() - - -class DetectionLayer(nn.Module): - def __init__(self, anchors): - super(DetectionLayer, self).__init__() - self.anchors = anchors - - def forward(self, x, inp_dim, num_classes, confidence): - x = x.data - global args - prediction = x.to(args.device) - prediction = predict_transform(prediction, inp_dim, self.anchors, num_classes, confidence, args) - return prediction - - - - - -class Upsample(nn.Module): - def __init__(self, stride=2): - super(Upsample, self).__init__() - self.stride = stride - - def forward(self, x): - stride = self.stride - assert(x.data.dim() == 4) - B = x.data.size(0) - C = x.data.size(1) - H = x.data.size(2) - W = x.data.size(3) - ws = stride - hs = stride - x = x.view(B, C, H, 1, W, 1).expand(B, C, H, stride, W, stride).contiguous().view(B, C, H*stride, W*stride) - return x -# - -class ReOrgLayer(nn.Module): - def __init__(self, stride = 2): - super(ReOrgLayer, self).__init__() - self.stride= stride - - def forward(self,x): - assert(x.data.dim() == 4) - B,C,H,W = x.data.shape - hs = self.stride - ws = self.stride - assert(H % hs == 0), "The stride " + str(self.stride) + " is not a proper divisor of height " + str(H) - assert(W % ws == 0), "The stride " + str(self.stride) + " is not a proper divisor of height " + str(W) - x = x.view(B,C, H // hs, hs, W // ws, ws).transpose(-2,-3).contiguous() - x = x.view(B,C, H // hs * W // ws, hs, ws) - x = x.view(B,C, H // hs * W // ws, hs*ws).transpose(-1,-2).contiguous() - x = x.view(B, C, ws*hs, H // ws, W // ws).transpose(1,2).contiguous() - x = x.view(B, C*ws*hs, H // ws, W // ws) - return x - - -def create_modules(blocks): - net_info = blocks[0] #Captures the information about the input and pre-processing - - module_list = nn.ModuleList() - - index = 0 #indexing blocks helps with implementing route layers (skip connections) - - - prev_filters = 3 - - output_filters = [] - - for x in blocks: - module = nn.Sequential() - - if (x["type"] == "net"): - continue - - #If it's a convolutional layer - if (x["type"] == "convolutional"): - #Get the info about the layer - activation = x["activation"] - try: - batch_normalize = int(x["batch_normalize"]) - bias = False - except: - batch_normalize = 0 - bias = True - - filters= int(x["filters"]) - padding = int(x["pad"]) - kernel_size = int(x["size"]) - stride = int(x["stride"]) - - if padding: - pad = (kernel_size - 1) // 2 - else: - pad = 0 - - #Add the convolutional layer - conv = nn.Conv2d(prev_filters, filters, kernel_size, stride, pad, bias=bias) - module.add_module("conv_{0}".format(index), conv) - - #Add the Batch Norm Layer - if batch_normalize: - bn = nn.BatchNorm2d(filters) - module.add_module("batch_norm_{0}".format(index), bn) - - #Check the activation. - #It is either Linear or a Leaky ReLU for YOLO - if activation == "leaky": - activn = nn.LeakyReLU(0.1, inplace = True) - module.add_module("leaky_{0}".format(index), activn) - - - - #If it's an upsampling layer - #We use Bilinear2dUpsampling - - elif (x["type"] == "upsample"): - stride = int(x["stride"]) -# upsample = Upsample(stride) - upsample = nn.Upsample(scale_factor = 2, mode = "nearest") - module.add_module("upsample_{}".format(index), upsample) - - #If it is a route layer - elif (x["type"] == "route"): - x["layers"] = x["layers"].split(',') - - #Start of a route - start = int(x["layers"][0]) - if len(x["layers"]) <= 2: - #end, if there exists one. - try: - end = int(x["layers"][1]) - except: - end = 0 - - #Positive anotation - if start > 0: - start = start - index - - if end > 0: - end = end - index - - - route = EmptyLayer() - module.add_module("route_{0}".format(index), route) - - - - if end < 0: - filters = output_filters[index + start] + output_filters[index + end] - else: - filters= output_filters[index + start] - else: #SPP-route - assert len(x["layers"]) == 4 - - round = EmptyLayer() - module.add_module("route_{0}".format(index), route) - - filters = output_filters[index + start] + output_filters[index + int(x["layers"][1])] \ - + output_filters[index + int(x["layers"][2])] + output_filters[index + int(x["layers"][3])] - - #shortcut corresponds to skip connection - elif x["type"] == "shortcut": - from_ = int(x["from"]) - shortcut = EmptyLayer() - module.add_module("shortcut_{}".format(index), shortcut) - - - elif x["type"] == "maxpool": - stride = int(x["stride"]) - size = int(x["size"]) - if stride != 1: - maxpool = nn.MaxPool2d(size, stride) - else: - maxpool = MaxPoolStride1(size) - #maxpool = nn.MaxPool2d(size, stride=1, padding=size-1) - - module.add_module("maxpool_{}".format(index), maxpool) - - #Yolo is the detection layer - elif x["type"] == "yolo": - mask = x["mask"].split(",") - mask = [int(x) for x in mask] - - - anchors = x["anchors"].split(",") - anchors = [int(a) for a in anchors] - anchors = [(anchors[i], anchors[i+1]) for i in range(0, len(anchors),2)] - anchors = [anchors[i] for i in mask] - - detection = DetectionLayer(anchors) - module.add_module("Detection_{}".format(index), detection) - - - - else: - print("Something I dunno") - assert False - - module_list.append(module) - prev_filters = filters - output_filters.append(filters) - index += 1 - - - return (net_info, module_list) - - - -class Darknet(nn.Module): - def __init__(self, cfgfile): - super(Darknet, self).__init__() - self.blocks = parse_cfg(cfgfile) - self.net_info, self.module_list = create_modules(self.blocks) - self.header = torch.IntTensor([0,0,0,0]) - self.seen = 0 - - - - def get_blocks(self): - return self.blocks - - def get_module_list(self): - return self.module_list - - - def forward(self, x, args): - detections = [] - modules = self.blocks[1:] - outputs = {} #We cache the outputs for the route layer - - - write = 0 - for i in range(len(modules)): - - module_type = (modules[i]["type"]) - if module_type == "convolutional" or module_type == "upsample" or module_type == "maxpool": - - x = self.module_list[i](x) - outputs[i] = x - - - elif module_type == "route": - layers = modules[i]["layers"] - layers = [int(a) for a in layers] - - if (layers[0]) > 0: - layers[0] = layers[0] - i - - if len(layers) == 1: - x = outputs[i + (layers[0])] - - elif len(layers) == 2: - if (layers[1]) > 0: - layers[1] = layers[1] - i - - map1 = outputs[i + layers[0]] - map2 = outputs[i + layers[1]] - - x = torch.cat((map1, map2), 1) - elif len(layers) == 4: # SPP - map1 = outputs[i + layers[0]] - map2 = outputs[i + layers[1]] - map3 = outputs[i + layers[2]] - map4 = outputs[i + layers[3]] - - x = torch.cat((map1, map2, map3, map4), 1) - outputs[i] = x - - elif module_type == "shortcut": - from_ = int(modules[i]["from"]) - x = outputs[i-1] + outputs[i+from_] - outputs[i] = x - - - - elif module_type == 'yolo': - - anchors = self.module_list[i][0].anchors - #Get the input dimensions - inp_dim = int (self.net_info["height"]) - - #Get the number of classes - num_classes = int (modules[i]["classes"]) - - #Output the result - x = x.data.to(args.device) - x = predict_transform(x, inp_dim, anchors, num_classes, args) - - if type(x) == int: - continue - - - if not write: - detections = x - write = 1 - - else: - detections = torch.cat((detections, x), 1) - - outputs[i] = outputs[i-1] - - - - try: - return detections - except: - return 0 - - - def load_weights(self, weightfile): - - #Open the weights file - fp = open(weightfile, "rb") - - #The first 4 values are header information - # 1. Major version number - # 2. Minor Version Number - # 3. Subversion number - # 4. IMages seen - header = np.fromfile(fp, dtype = np.int32, count = 5) - self.header = torch.from_numpy(header) - self.seen = self.header[3] - - #The rest of the values are the weights - # Let's load them up - weights = np.fromfile(fp, dtype = np.float32) - - ptr = 0 - for i in range(len(self.module_list)): - module_type = self.blocks[i + 1]["type"] - - if module_type == "convolutional": - model = self.module_list[i] - try: - batch_normalize = int(self.blocks[i+1]["batch_normalize"]) - except: - batch_normalize = 0 - - conv = model[0] - - if (batch_normalize): - bn = model[1] - - #Get the number of weights of Batch Norm Layer - num_bn_biases = bn.bias.numel() - - #Load the weights - bn_biases = torch.from_numpy(weights[ptr:ptr + num_bn_biases]) - ptr += num_bn_biases - - bn_weights = torch.from_numpy(weights[ptr: ptr + num_bn_biases]) - ptr += num_bn_biases - - bn_running_mean = torch.from_numpy(weights[ptr: ptr + num_bn_biases]) - ptr += num_bn_biases - - bn_running_var = torch.from_numpy(weights[ptr: ptr + num_bn_biases]) - ptr += num_bn_biases - - #Cast the loaded weights into dims of model weights. - bn_biases = bn_biases.view_as(bn.bias.data) - bn_weights = bn_weights.view_as(bn.weight.data) - bn_running_mean = bn_running_mean.view_as(bn.running_mean) - bn_running_var = bn_running_var.view_as(bn.running_var) - - #Copy the data to model - bn.bias.data.copy_(bn_biases) - bn.weight.data.copy_(bn_weights) - bn.running_mean.copy_(bn_running_mean) - bn.running_var.copy_(bn_running_var) - - else: - #Number of biases - num_biases = conv.bias.numel() - - #Load the weights - conv_biases = torch.from_numpy(weights[ptr: ptr + num_biases]) - ptr = ptr + num_biases - - #reshape the loaded weights according to the dims of the model weights - conv_biases = conv_biases.view_as(conv.bias.data) - - #Finally copy the data - conv.bias.data.copy_(conv_biases) - - - #Let us load the weights for the Convolutional layers - num_weights = conv.weight.numel() - - #Do the same as above for weights - conv_weights = torch.from_numpy(weights[ptr:ptr+num_weights]) - ptr = ptr + num_weights - - conv_weights = conv_weights.view_as(conv.weight.data) - conv.weight.data.copy_(conv_weights) - - def save_weights(self, savedfile, cutoff = 0): - - if cutoff <= 0: - cutoff = len(self.blocks) - 1 - - fp = open(savedfile, 'wb') - - # Attach the header at the top of the file - self.header[3] = self.seen - header = self.header - - header = header.numpy() - header.tofile(fp) - - # Now, let us save the weights - for i in range(len(self.module_list)): - module_type = self.blocks[i+1]["type"] - - if (module_type) == "convolutional": - model = self.module_list[i] - try: - batch_normalize = int(self.blocks[i+1]["batch_normalize"]) - except: - batch_normalize = 0 - - conv = model[0] - - if (batch_normalize): - bn = model[1] - - #If the parameters are on GPU, convert them back to CPU - #We don't convert the parameter to GPU - #Instead. we copy the parameter and then convert it to CPU - #This is done as weight are need to be saved during training - cpu(bn.bias.data).numpy().tofile(fp) - cpu(bn.weight.data).numpy().tofile(fp) - cpu(bn.running_mean).numpy().tofile(fp) - cpu(bn.running_var).numpy().tofile(fp) - - - else: - cpu(conv.bias.data).numpy().tofile(fp) - - - #Let us save the weights for the Convolutional layers - cpu(conv.weight.data).numpy().tofile(fp) - - - - - -# -#dn = Darknet('cfg/yolov3.cfg') -#dn.load_weights("yolov3.weights") -#inp = get_test_input() -#a, interms = dn(inp) -#dn.eval() -#a_i, interms_i = dn(inp) diff --git a/cv/pose/alphapose/pytorch/detector/yolo/detect.py b/cv/pose/alphapose/pytorch/detector/yolo/detect.py deleted file mode 100755 index ebdbbd2b3..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/detect.py +++ /dev/null @@ -1,103 +0,0 @@ -from __future__ import division -import time -import torch -import torch.nn as nn -from torch.autograd import Variable -import numpy as np -import cv2 -from util import * -import argparse -import os -import os.path as osp -from darknet import Darknet -from preprocess import prep_image, inp_to_image -import pandas as pd -import random -import pickle as pkl -import itertools - - -if __name__ == '__main__': - - scales = "1,2,3" - images = "imgs/messi.jpg" - batch_size = 1 - confidence = 0.5 - nms_thesh = 0.4 - - CUDA = torch.cuda.is_available() - - num_classes = 80 - classes = load_classes('data/coco.names') - - #Set up the neural network - print("Loading network.....") - model = Darknet("cfg/yolov3-spp.cfg") - model.load_weights("yolov3-spp.weights") - print("Network successfully loaded") - - model.net_info["height"] = "608" - inp_dim = int(model.net_info["height"]) - assert inp_dim % 32 == 0 - assert inp_dim > 32 - - #If there's a GPU availible, put the model on GPU - if CUDA: - model.cuda() - - #Set the model in evaluation mode - model.eval() - - #Detection phase - try: - imlist = [] - imlist.append(osp.join(osp.realpath('.'), images)) - except FileNotFoundError: - print ("No file or directory with the name {}".format(images)) - exit() - - batches = list(map(prep_image, imlist, [inp_dim for x in range(len(imlist))])) - im_batches = [x[0] for x in batches] - orig_ims = [x[1] for x in batches] - im_dim_list = [x[2] for x in batches] - im_dim_list = torch.FloatTensor(im_dim_list).repeat(1, 2) - - if CUDA: - im_dim_list = im_dim_list.cuda() - - - for batch in im_batches: - #load the image - if CUDA: - batch = batch.cuda() - with torch.no_grad(): - prediction = model(Variable(batch), CUDA) - - prediction = write_results(prediction, confidence, num_classes, nms=True, nms_conf=nms_thesh) - output = prediction - - if CUDA: - torch.cuda.synchronize() - - try: - output - except NameError: - print("No detections were made") - exit() - print(im_dim_list.shape) - im_dim_list = torch.index_select(im_dim_list, 0, output[:,0].long()) - - scaling_factor = torch.min(inp_dim/im_dim_list,1)[0].view(-1,1) - - - output[:,[1,3]] -= (inp_dim - scaling_factor*im_dim_list[:,0].view(-1,1))/2 - output[:,[2,4]] -= (inp_dim - scaling_factor*im_dim_list[:,1].view(-1,1))/2 - - output[:,1:5] /= scaling_factor - - for i in range(output.shape[0]): - output[i, [1,3]] = torch.clamp(output[i, [1,3]], 0.0, im_dim_list[i,0]) - output[i, [2,4]] = torch.clamp(output[i, [2,4]], 0.0, im_dim_list[i,1]) - - print(output) - print(output.shape) diff --git a/cv/pose/alphapose/pytorch/detector/yolo/pallete b/cv/pose/alphapose/pytorch/detector/yolo/pallete deleted file mode 100755 index 25f0143e9c80c98923dac550f6cd52e20a9dbbe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 908 zcmW-f`%lni9EBCU;1xwQHN1dwTx{U`jfSs2i&K}s$iUdxMi(iNzC?Il`N*2c55Zea;w@} z#W{NT#d?NvuF`3(rkW@GY^~uherKb#mKsz9d^QeEja9|=>?O`RzG4&qS?ig{uasFE zxIiE0tc}UpPMcL78Df;Tt%kf=M4$BnUuW#U))saq`yH#1HdgSR)fDrm8L_sqCCU%17gJny(c!j0 zx?L=q*-Iy%SugQL#tv95T#Ee`YkSZhpuuX5&h;Wr8>_fUv$Z2co2j&RQj)#<*2~=B z6lbkntV|nu)tdNsNg z%(eDp_PzpK4-e^L)Y{92pbYMP$?!kH{Y=JBh1HwSR$kaR5L$a^wMcRA73TZ67`Pu> zujTpGg5W`Rr@9ZVLv%#2#5$b+GsT})e-;;uk2JuKQU2RH!WHT$wT`BiVZN~jb7z=( zYbfA4xMU5}%V5#`vGBUa1#5(LEGSSO=U&nW+-M-(qstoOk6^lKji=?u#s4{xz~>7a k6Oo%{(wa<}rTk!>WLB(BSg)t>$|Czz2-Y%VojTq06m_^a82|tP diff --git a/cv/pose/alphapose/pytorch/detector/yolo/preprocess.py b/cv/pose/alphapose/pytorch/detector/yolo/preprocess.py deleted file mode 100755 index b03650908..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/preprocess.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -from __future__ import division - -import torch -import torch.nn as nn -import torch.nn.functional as F -from torch.autograd import Variable -import numpy as np -import cv2 -import matplotlib.pyplot as plt - -""" -try: - from util import count_parameters as count - from util import convert2cpu as cpu -except ImportError: - from yolo.util import count_parameters as count - from yolo.util import convert2cpu as cpu -""" -from .util import count_parameters as count -from .util import convert2cpu as cpu - -from PIL import Image, ImageDraw - - -def letterbox_image(img, inp_dim): - '''resize image with unchanged aspect ratio using padding''' - img_w, img_h = img.shape[1], img.shape[0] - w, h = inp_dim - new_w = int(img_w * min(w / img_w, h / img_h)) - new_h = int(img_h * min(w / img_w, h / img_h)) - resized_image = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_CUBIC) - - canvas = np.full((inp_dim[1], inp_dim[0], 3), 128) - - canvas[(h - new_h) // 2:(h - new_h) // 2 + new_h, (w - new_w) // 2:(w - new_w) // 2 + new_w, :] = resized_image - - return canvas - - -def prep_image(img, inp_dim): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = cv2.imread(img) - dim = orig_im.shape[1], orig_im.shape[0] - img = (letterbox_image(orig_im, (inp_dim, inp_dim))) - img_ = img[:, :, ::-1].transpose((2, 0, 1)).copy() - img_ = torch.from_numpy(img_).float().div(255.0).unsqueeze(0) - return img_, orig_im, dim - - -def prep_frame(img, inp_dim): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = img - dim = orig_im.shape[1], orig_im.shape[0] - img = (letterbox_image(orig_im, (inp_dim, inp_dim))) - img_ = img[:, :, ::-1].transpose((2, 0, 1)).copy() - img_ = torch.from_numpy(img_).float().div(255.0).unsqueeze(0) - return img_, orig_im, dim - - -def prep_image_pil(img, network_dim): - orig_im = Image.open(img) - img = orig_im.convert('RGB') - dim = img.size - img = img.resize(network_dim) - img = torch.ByteTensor(torch.ByteStorage.from_buffer(img.tobytes())) - img = img.view(*network_dim, 3).transpose(0, 1).transpose(0, 2).contiguous() - img = img.view(1, 3, *network_dim) - img = img.float().div(255.0) - return (img, orig_im, dim) - - -def inp_to_image(inp): - inp = inp.cpu().squeeze() - inp = inp * 255 - try: - inp = inp.data.numpy() - except RuntimeError: - inp = inp.numpy() - inp = inp.transpose(1, 2, 0) - - inp = inp[:, :, ::-1] - return inp diff --git a/cv/pose/alphapose/pytorch/detector/yolo/util.py b/cv/pose/alphapose/pytorch/detector/yolo/util.py deleted file mode 100755 index 2833bbfb3..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/util.py +++ /dev/null @@ -1,403 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. - -from __future__ import division - -import torch -import torch.nn as nn -import torch.nn.functional as F -from torch.autograd import Variable -import numpy as np -import cv2 -import matplotlib.pyplot as plt - -""" -try: - from bbox import bbox_iou -except ImportError: - from yolo.bbox import bbox_iou -""" -from .bbox import bbox_iou - - -def count_parameters(model): - return sum(p.numel() for p in model.parameters()) - -def count_learnable_parameters(model): - return sum(p.numel() for p in model.parameters() if p.requires_grad) - -def convert2cpu(matrix): - if matrix.is_cuda: - return torch.FloatTensor(matrix.size()).copy_(matrix) - else: - return matrix - -def predict_transform(prediction, inp_dim, anchors, num_classes, args): - batch_size = prediction.size(0) - stride = inp_dim // prediction.size(2) - grid_size = inp_dim // stride - bbox_attrs = 5 + num_classes - num_anchors = len(anchors) - - anchors = [(a[0]/stride, a[1]/stride) for a in anchors] - - - - prediction = prediction.view(batch_size, bbox_attrs*num_anchors, grid_size*grid_size) - prediction = prediction.transpose(1,2).contiguous() - prediction = prediction.view(batch_size, grid_size*grid_size*num_anchors, bbox_attrs) - - - #Sigmoid the centre_X, centre_Y. and object confidencce - prediction[:,:,0] = torch.sigmoid(prediction[:,:,0]) - prediction[:,:,1] = torch.sigmoid(prediction[:,:,1]) - prediction[:,:,4] = torch.sigmoid(prediction[:,:,4]) - - - - #Add the center offsets - grid_len = np.arange(grid_size) - a,b = np.meshgrid(grid_len, grid_len) - - x_offset = torch.FloatTensor(a).view(-1,1) - y_offset = torch.FloatTensor(b).view(-1,1) - - if args: - x_offset = x_offset.to(args.device) - y_offset = y_offset.to(args.device) - else: - x_offset = x_offset.cuda() - y_offset = y_offset.cuda() - - x_y_offset = torch.cat((x_offset, y_offset), 1).repeat(1,num_anchors).view(-1,2).unsqueeze(0) - - prediction[:,:,:2] += x_y_offset - - #log space transform height and the width - anchors = torch.FloatTensor(anchors) - - if args: - anchors = anchors.to(args.device) - else: - anchors = anchors.cuda() - - anchors = anchors.repeat(grid_size*grid_size, 1).unsqueeze(0) - prediction[:,:,2:4] = torch.exp(prediction[:,:,2:4])*anchors - - #Softmax the class scores - prediction[:,:,5: 5 + num_classes] = torch.sigmoid((prediction[:,:, 5 : 5 + num_classes])) - - prediction[:,:,:4] *= stride - - - return prediction - -def load_classes(namesfile): - fp = open(namesfile, "r") - names = fp.read().split("\n")[:-1] - return names - -def get_im_dim(im): - im = cv2.imread(im) - w,h = im.shape[1], im.shape[0] - return w,h - -def unique(tensor): - tensor_np = tensor.cpu().numpy() - unique_np = np.unique(tensor_np) - unique_tensor = torch.from_numpy(unique_np) - - tensor_res = tensor.new(unique_tensor.shape) - tensor_res.copy_(unique_tensor) - return tensor_res - - -def dynamic_write_results(prediction, confidence, num_classes, nms=True, nms_conf=0.4): - prediction_bak = prediction.clone() - dets = write_results(prediction.clone(), confidence, num_classes, nms, nms_conf) - if isinstance(dets, int): - return dets - - if dets.shape[0] > 100: - nms_conf -= 0.05 - dets = write_results(prediction_bak.clone(), confidence, num_classes, nms, nms_conf) - - return dets - - -def write_results(prediction, confidence, num_classes, nms=True, nms_conf=0.4): - conf_mask = (prediction[:, :, 4] > confidence).float().float().unsqueeze(2) - prediction = prediction * conf_mask - - try: - ind_nz = torch.nonzero(prediction[:,:,4]).transpose(0,1).contiguous() - except: - return 0 - - box_a = prediction.new(prediction.shape) - box_a[:,:,0] = (prediction[:,:,0] - prediction[:,:,2]/2) - box_a[:,:,1] = (prediction[:,:,1] - prediction[:,:,3]/2) - box_a[:,:,2] = (prediction[:,:,0] + prediction[:,:,2]/2) - box_a[:,:,3] = (prediction[:,:,1] + prediction[:,:,3]/2) - prediction[:,:,:4] = box_a[:,:,:4] - - batch_size = prediction.size(0) - - output = prediction.new(1, prediction.size(2) + 1) - write = False - num = 0 - for ind in range(batch_size): - #select the image from the batch - image_pred = prediction[ind] - - #Get the class having maximum score, and the index of that class - #Get rid of num_classes softmax scores - #Add the class index and the class score of class having maximum score - max_conf, max_conf_score = torch.max(image_pred[:,5:5+ num_classes], 1) - max_conf = max_conf.float().unsqueeze(1) - max_conf_score = max_conf_score.float().unsqueeze(1) - seq = (image_pred[:,:5], max_conf, max_conf_score) - image_pred = torch.cat(seq, 1) - - #Get rid of the zero entries - non_zero_ind = (torch.nonzero(image_pred[:,4])) - - image_pred_ = image_pred[non_zero_ind.squeeze(),:].view(-1,7) - - #Get the various classes detected in the image - try: - img_classes = unique(image_pred_[:,-1]) - except: - continue - - #WE will do NMS classwise - #print(img_classes) - for cls in img_classes: - if cls != 0: - continue - #get the detections with one particular class - cls_mask = image_pred_*(image_pred_[:,-1] == cls).float().unsqueeze(1) - class_mask_ind = torch.nonzero(cls_mask[:,-2]).squeeze() - - image_pred_class = image_pred_[class_mask_ind].view(-1,7) - - #sort the detections such that the entry with the maximum objectness - #confidence is at the top - conf_sort_index = torch.sort(image_pred_class[:,4], descending = True )[1] - image_pred_class = image_pred_class[conf_sort_index] - idx = image_pred_class.size(0) - - #if nms has to be done - if nms: - # Perform non-maximum suppression - max_detections = [] - while image_pred_class.size(0): - # Get detection with highest confidence and save as max detection - max_detections.append(image_pred_class[0].unsqueeze(0)) - # Stop if we're at the last detection - if len(image_pred_class) == 1: - break - # Get the IOUs for all boxes with lower confidence - ious = bbox_iou(max_detections[-1], image_pred_class[1:]) - # Remove detections with IoU >= NMS threshold - image_pred_class = image_pred_class[1:][ious < nms_conf] - - image_pred_class = torch.cat(max_detections).data - - - #Concatenate the batch_id of the image to the detection - #this helps us identify which image does the detection correspond to - #We use a linear straucture to hold ALL the detections from the batch - #the batch_dim is flattened - #batch is identified by extra batch column - - batch_ind = image_pred_class.new(image_pred_class.size(0), 1).fill_(ind) - seq = batch_ind, image_pred_class - if not write: - output = torch.cat(seq,1) - write = True - else: - out = torch.cat(seq,1) - output = torch.cat((output,out)) - num += 1 - - if not num: - return 0 - - return output - -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Sat Mar 24 00:12:16 2018 - -@author: ayooshmac -""" - -def predict_transform_half(prediction, inp_dim, anchors, num_classes, args): - batch_size = prediction.size(0) - stride = inp_dim // prediction.size(2) - - bbox_attrs = 5 + num_classes - num_anchors = len(anchors) - grid_size = inp_dim // stride - - - prediction = prediction.view(batch_size, bbox_attrs*num_anchors, grid_size*grid_size) - prediction = prediction.transpose(1,2).contiguous() - prediction = prediction.view(batch_size, grid_size*grid_size*num_anchors, bbox_attrs) - - - #Sigmoid the centre_X, centre_Y. and object confidencce - prediction[:,:,0] = torch.sigmoid(prediction[:,:,0]) - prediction[:,:,1] = torch.sigmoid(prediction[:,:,1]) - prediction[:,:,4] = torch.sigmoid(prediction[:,:,4]) - - - #Add the center offsets - grid_len = np.arange(grid_size) - a,b = np.meshgrid(grid_len, grid_len) - - x_offset = torch.FloatTensor(a).view(-1,1) - y_offset = torch.FloatTensor(b).view(-1,1) - - if args: - x_offset = x_offset.to(args.device).half() - y_offset = y_offset.to(args.device).half() - else: - x_offset = x_offset.cuda().half() - y_offset = y_offset.cuda().half() - - x_y_offset = torch.cat((x_offset, y_offset), 1).repeat(1,num_anchors).view(-1,2).unsqueeze(0) - - prediction[:,:,:2] += x_y_offset - - #log space transform height and the width - anchors = torch.HalfTensor(anchors) - - if args: - anchors = anchors.to(args.device) - else: - anchors = anchors.cuda() - - anchors = anchors.repeat(grid_size*grid_size, 1).unsqueeze(0) - prediction[:,:,2:4] = torch.exp(prediction[:,:,2:4])*anchors - - #Softmax the class scores - prediction[:,:,5: 5 + num_classes] = nn.Softmax(-1)(Variable(prediction[:,:, 5 : 5 + num_classes])).data - - prediction[:,:,:4] *= stride - - - return prediction - - -def write_results_half(prediction, confidence, num_classes, nms = True, nms_conf = 0.4): - conf_mask = (prediction[:,:,4] > confidence).half().unsqueeze(2) - prediction = prediction*conf_mask - - try: - ind_nz = torch.nonzero(prediction[:,:,4]).transpose(0,1).contiguous() - except: - return 0 - - - - box_a = prediction.new(prediction.shape) - box_a[:,:,0] = (prediction[:,:,0] - prediction[:,:,2]/2) - box_a[:,:,1] = (prediction[:,:,1] - prediction[:,:,3]/2) - box_a[:,:,2] = (prediction[:,:,0] + prediction[:,:,2]/2) - box_a[:,:,3] = (prediction[:,:,1] + prediction[:,:,3]/2) - prediction[:,:,:4] = box_a[:,:,:4] - - - - batch_size = prediction.size(0) - - output = prediction.new(1, prediction.size(2) + 1) - write = False - - for ind in range(batch_size): - #select the image from the batch - image_pred = prediction[ind] - - - #Get the class having maximum score, and the index of that class - #Get rid of num_classes softmax scores - #Add the class index and the class score of class having maximum score - max_conf, max_conf_score = torch.max(image_pred[:,5:5+ num_classes], 1) - max_conf = max_conf.half().unsqueeze(1) - max_conf_score = max_conf_score.half().unsqueeze(1) - seq = (image_pred[:,:5], max_conf, max_conf_score) - image_pred = torch.cat(seq, 1) - - - #Get rid of the zero entries - non_zero_ind = (torch.nonzero(image_pred[:,4])) - try: - image_pred_ = image_pred[non_zero_ind.squeeze(),:] - except: - continue - - #Get the various classes detected in the image - img_classes = unique(image_pred_[:,-1].long()).half() - - - - - #WE will do NMS classwise - for cls in img_classes: - #get the detections with one particular class - cls_mask = image_pred_*(image_pred_[:,-1] == cls).half().unsqueeze(1) - class_mask_ind = torch.nonzero(cls_mask[:,-2]).squeeze() - - - image_pred_class = image_pred_[class_mask_ind] - - - #sort the detections such that the entry with the maximum objectness - #confidence is at the top - conf_sort_index = torch.sort(image_pred_class[:,4], descending = True )[1] - image_pred_class = image_pred_class[conf_sort_index] - idx = image_pred_class.size(0) - - #if nms has to be done - if nms: - #For each detection - for i in range(idx): - #Get the IOUs of all boxes that come after the one we are looking at - #in the loop - try: - ious = bbox_iou(image_pred_class[i].unsqueeze(0), image_pred_class[i+1:]) - except ValueError: - break - - except IndexError: - break - - #Zero out all the detections that have IoU > treshhold - iou_mask = (ious < nms_conf).half().unsqueeze(1) - image_pred_class[i+1:] *= iou_mask - - #Remove the non-zero entries - non_zero_ind = torch.nonzero(image_pred_class[:,4]).squeeze() - image_pred_class = image_pred_class[non_zero_ind] - - - - #Concatenate the batch_id of the image to the detection - #this helps us identify which image does the detection correspond to - #We use a linear straucture to hold ALL the detections from the batch - #the batch_dim is flattened - #batch is identified by extra batch column - batch_ind = image_pred_class.new(image_pred_class.size(0), 1).fill_(ind) - seq = batch_ind, image_pred_class - - if not write: - output = torch.cat(seq,1) - write = True - else: - out = torch.cat(seq,1) - output = torch.cat((output,out)) - - return output diff --git a/cv/pose/alphapose/pytorch/detector/yolo/video_demo.py b/cv/pose/alphapose/pytorch/detector/yolo/video_demo.py deleted file mode 100755 index 637aa7972..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/video_demo.py +++ /dev/null @@ -1,186 +0,0 @@ -from __future__ import division -import time -import torch -import torch.nn as nn -from torch.autograd import Variable -import numpy as np -import cv2 -from util import * -from darknet import Darknet -from preprocess import prep_image, inp_to_image, letterbox_image -import pandas as pd -import random -import pickle as pkl -import argparse - - -def get_test_input(input_dim, CUDA): - img = cv2.imread("dog-cycle-car.png") - img = cv2.resize(img, (input_dim, input_dim)) - img_ = img[:,:,::-1].transpose((2,0,1)) - img_ = img_[np.newaxis,:,:,:]/255.0 - img_ = torch.from_numpy(img_).float() - img_ = Variable(img_) - - if CUDA: - img_ = img_.cuda() - - return img_ - -def prep_image(img, inp_dim): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = img - dim = orig_im.shape[1], orig_im.shape[0] - img = (letterbox_image(orig_im, (inp_dim, inp_dim))) - img_ = img[:,:,::-1].transpose((2,0,1)).copy() - img_ = torch.from_numpy(img_).float().div(255.0).unsqueeze(0) - return img_, orig_im, dim - -def write(x, img): - c1 = tuple(x[1:3].int()) - c2 = tuple(x[3:5].int()) - cls = int(x[-1]) - label = "{0}".format(classes[cls]) - color = random.choice(colors) - cv2.rectangle(img, c1, c2,color, 1) - t_size = cv2.getTextSize(label, cv2.FONT_HERSHEY_PLAIN, 1 , 1)[0] - c2 = c1[0] + t_size[0] + 3, c1[1] + t_size[1] + 4 - cv2.rectangle(img, c1, c2,color, -1) - cv2.putText(img, label, (c1[0], c1[1] + t_size[1] + 4), cv2.FONT_HERSHEY_PLAIN, 1, [225,255,255], 1); - return img - -def arg_parse(): - """ - Parse arguements to the detect module - - """ - - - parser = argparse.ArgumentParser(description='YOLO v3 Video Detection Module') - - parser.add_argument("--video", dest = 'video', help = - "Video to run detection upon", - default = "video.avi", type = str) - parser.add_argument("--dataset", dest = "dataset", help = "Dataset on which the network has been trained", default = "pascal") - parser.add_argument("--confidence", dest = "confidence", help = "Object Confidence to filter predictions", default = 0.5) - parser.add_argument("--nms_thresh", dest = "nms_thresh", help = "NMS Threshhold", default = 0.4) - parser.add_argument("--cfg", dest = 'cfgfile', help = - "Config file", - default = "cfg/yolov3-spp.cfg", type = str) - parser.add_argument("--weights", dest = 'weightsfile', help = - "weightsfile", - default = "yolov3-spp.weights", type = str) - parser.add_argument("--reso", dest = 'reso', help = - "Input resolution of the network. Increase to increase accuracy. Decrease to increase speed", - default = "416", type = str) - return parser.parse_args() - - -if __name__ == '__main__': - args = arg_parse() - confidence = float(args.confidence) - nms_thesh = float(args.nms_thresh) - start = 0 - - CUDA = torch.cuda.is_available() - - num_classes = 80 - - CUDA = torch.cuda.is_available() - - bbox_attrs = 5 + num_classes - - print("Loading network.....") - model = Darknet(args.cfgfile) - model.load_weights(args.weightsfile) - print("Network successfully loaded") - - model.net_info["height"] = args.reso - inp_dim = int(model.net_info["height"]) - assert inp_dim % 32 == 0 - assert inp_dim > 32 - - if CUDA: - model.cuda() - - model(get_test_input(inp_dim, CUDA), CUDA) - - model.eval() - - videofile = args.video - - cap = cv2.VideoCapture(videofile) - - assert cap.isOpened(), 'Cannot capture source' - - frames = 0 - start = time.time() - while cap.isOpened(): - - ret, frame = cap.read() - if ret: - - - img, orig_im, dim = prep_image(frame, inp_dim) - - im_dim = torch.FloatTensor(dim).repeat(1,2) - - - if CUDA: - im_dim = im_dim.cuda() - img = img.cuda() - - with torch.no_grad(): - output = model(Variable(img), CUDA) - output = write_results(output, confidence, num_classes, nms = True, nms_conf = nms_thesh) - - if type(output) == int: - frames += 1 - print("FPS of the video is {:5.2f}".format( frames / (time.time() - start))) - cv2.imshow("frame", orig_im) - key = cv2.waitKey(1) - if key & 0xFF == ord('q'): - break - continue - - - - - im_dim = im_dim.repeat(output.size(0), 1) - scaling_factor = torch.min(inp_dim/im_dim,1)[0].view(-1,1) - - output[:,[1,3]] -= (inp_dim - scaling_factor*im_dim[:,0].view(-1,1))/2 - output[:,[2,4]] -= (inp_dim - scaling_factor*im_dim[:,1].view(-1,1))/2 - - output[:,1:5] /= scaling_factor - - for i in range(output.shape[0]): - output[i, [1,3]] = torch.clamp(output[i, [1,3]], 0.0, im_dim[i,0]) - output[i, [2,4]] = torch.clamp(output[i, [2,4]], 0.0, im_dim[i,1]) - - classes = load_classes('data/coco.names') - colors = pkl.load(open("pallete", "rb")) - - list(map(lambda x: write(x, orig_im), output)) - - - cv2.imshow("frame", orig_im) - key = cv2.waitKey(1) - if key & 0xFF == ord('q'): - break - frames += 1 - print("FPS of the video is {:5.2f}".format( frames / (time.time() - start))) - - - else: - break - - - - - diff --git a/cv/pose/alphapose/pytorch/detector/yolo/video_demo_half.py b/cv/pose/alphapose/pytorch/detector/yolo/video_demo_half.py deleted file mode 100755 index 7054ffad1..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo/video_demo_half.py +++ /dev/null @@ -1,189 +0,0 @@ -from __future__ import division -import time -import torch -import torch.nn as nn -from torch.autograd import Variable -import numpy as np -import cv2 -from util import * -from darknet import Darknet -from preprocess import prep_image, inp_to_image, letterbox_image -import pandas as pd -import random -import pickle as pkl -import argparse - - -def get_test_input(input_dim, CUDA): - img = cv2.imread("dog-cycle-car.png") - img = cv2.resize(img, (input_dim, input_dim)) - img_ = img[:,:,::-1].transpose((2,0,1)) - img_ = img_[np.newaxis,:,:,:]/255.0 - img_ = torch.from_numpy(img_).float() - img_ = Variable(img_) - - if CUDA: - img_ = img_.cuda() - - return img_ - -def prep_image(img, inp_dim): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = img - dim = orig_im.shape[1], orig_im.shape[0] - img = (letterbox_image(orig_im, (inp_dim, inp_dim))) - img_ = img[:,:,::-1].transpose((2,0,1)).copy() - img_ = torch.from_numpy(img_).float().div(255.0).unsqueeze(0) - return img_, orig_im, dim - -def write(x, img): - c1 = tuple(x[1:3].int()) - c2 = tuple(x[3:5].int()) - cls = int(x[-1]) - label = "{0}".format(classes[cls]) - color = random.choice(colors) - cv2.rectangle(img, c1, c2,color, 1) - t_size = cv2.getTextSize(label, cv2.FONT_HERSHEY_PLAIN, 1 , 1)[0] - c2 = c1[0] + t_size[0] + 3, c1[1] + t_size[1] + 4 - cv2.rectangle(img, c1, c2,color, -1) - cv2.putText(img, label, (c1[0], c1[1] + t_size[1] + 4), cv2.FONT_HERSHEY_PLAIN, 1, [225,255,255], 1); - return img - -def arg_parse(): - """ - Parse arguements to the detect module - - """ - - - parser = argparse.ArgumentParser(description='YOLO v2 Video Detection Module') - - parser.add_argument("--video", dest = 'video', help = - "Video to run detection upon", - default = "video.avi", type = str) - parser.add_argument("--dataset", dest = "dataset", help = "Dataset on which the network has been trained", default = "pascal") - parser.add_argument("--confidence", dest = "confidence", help = "Object Confidence to filter predictions", default = 0.5) - parser.add_argument("--nms_thresh", dest = "nms_thresh", help = "NMS Threshhold", default = 0.4) - parser.add_argument("--cfg", dest = 'cfgfile', help = - "Config file", - default = "cfg/yolov3-spp.cfg", type = str) - parser.add_argument("--weights", dest = 'weightsfile', help = - "weightsfile", - default = "yolov3-spp.weights", type = str) - parser.add_argument("--reso", dest = 'reso', help = - "Input resolution of the network. Increase to increase accuracy. Decrease to increase speed", - default = "416", type = str) - return parser.parse_args() - - -if __name__ == '__main__': - args = arg_parse() - confidence = float(args.confidence) - nms_thesh = float(args.nms_thresh) - start = 0 - - CUDA = torch.cuda.is_available() - - - - CUDA = torch.cuda.is_available() - num_classes = 80 - bbox_attrs = 5 + num_classes - - print("Loading network.....") - model = Darknet(args.cfgfile) - model.load_weights(args.weightsfile) - print("Network successfully loaded") - - model.net_info["height"] = args.reso - inp_dim = int(model.net_info["height"]) - assert inp_dim % 32 == 0 - assert inp_dim > 32 - - - if CUDA: - model.cuda().half() - - model(get_test_input(inp_dim, CUDA), CUDA) - - model.eval() - - videofile = 'video.avi' - - cap = cv2.VideoCapture(videofile) - - assert cap.isOpened(), 'Cannot capture source' - - frames = 0 - start = time.time() - while cap.isOpened(): - - ret, frame = cap.read() - if ret: - - - img, orig_im, dim = prep_image(frame, inp_dim) - - im_dim = torch.FloatTensor(dim).repeat(1,2) - - - if CUDA: - img = img.cuda().half() - im_dim = im_dim.half().cuda() - write_results = write_results_half - predict_transform = predict_transform_half - - - output = model(Variable(img, volatile = True), CUDA) - output = write_results(output, confidence, num_classes, nms = True, nms_conf = nms_thesh) - - - if type(output) == int: - frames += 1 - print("FPS of the video is {:5.2f}".format( frames / (time.time() - start))) - cv2.imshow("frame", orig_im) - key = cv2.waitKey(1) - if key & 0xFF == ord('q'): - break - continue - - - im_dim = im_dim.repeat(output.size(0), 1) - scaling_factor = torch.min(inp_dim/im_dim,1)[0].view(-1,1) - - output[:,[1,3]] -= (inp_dim - scaling_factor*im_dim[:,0].view(-1,1))/2 - output[:,[2,4]] -= (inp_dim - scaling_factor*im_dim[:,1].view(-1,1))/2 - - output[:,1:5] /= scaling_factor - - for i in range(output.shape[0]): - output[i, [1,3]] = torch.clamp(output[i, [1,3]], 0.0, im_dim[i,0]) - output[i, [2,4]] = torch.clamp(output[i, [2,4]], 0.0, im_dim[i,1]) - - - classes = load_classes('data/coco.names') - colors = pkl.load(open("pallete", "rb")) - - list(map(lambda x: write(x, orig_im), output)) - - - cv2.imshow("frame", orig_im) - key = cv2.waitKey(1) - if key & 0xFF == ord('q'): - break - frames += 1 - print("FPS of the video is {:5.2f}".format( frames / (time.time() - start))) - - - else: - break - - - - - diff --git a/cv/pose/alphapose/pytorch/detector/yolo_api.py b/cv/pose/alphapose/pytorch/detector/yolo_api.py deleted file mode 100755 index 7c1b66856..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo_api.py +++ /dev/null @@ -1,307 +0,0 @@ -# ----------------------------------------------------- -# Copyright (c) Shanghai Jiao Tong University. All rights reserved. -# Written by Chao Xu (xuchao.19962007@sjtu.edu.cn) -# ----------------------------------------------------- -# Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -"""API of yolo detector""" -import os -import sys -sys.path.insert(0, os.path.dirname(__file__)) -from abc import ABC, abstractmethod -import platform - -import torch -import numpy as np - -from yolo.preprocess import prep_image, prep_frame -from yolo.darknet import Darknet -from yolo.util import unique -from yolo.bbox import bbox_iou - -from detector.apis import BaseDetector - -#only windows visual studio 2013 ~2017 support compile c/cuda extensions -#If you force to compile extension on Windows and ensure appropriate visual studio -#is intalled, you can try to use these ext_modules. -# if platform.system() != 'Windows': -# from detector.nms import nms_wrapper - -from detector.nms import nms - - -class YOLODetector(BaseDetector): - def __init__(self, cfg, opt=None): - super(YOLODetector, self).__init__() - - self.detector_cfg = cfg - self.detector_opt = opt - self.model_cfg = cfg.get('CONFIG', 'detector/yolo/cfg/yolov3-spp.cfg') - self.model_weights = cfg.get('WEIGHTS', 'detector/yolo/data/yolov3-spp.weights') - self.inp_dim = cfg.get('INP_DIM', 608) - self.nms_thres = cfg.get('NMS_THRES', 0.6) - self.confidence = 0.3 if (False if not hasattr(opt, 'tracking') else opt.tracking) else cfg.get('CONFIDENCE', 0.05) - self.num_classes = cfg.get('NUM_CLASSES', 80) - self.model = None - - def load_model(self): - args = self.detector_opt - - print('Loading YOLO model..') - self.model = Darknet(self.model_cfg) - self.model.load_weights(self.model_weights) - self.model.net_info['height'] = self.inp_dim - - - if args: - if len(args.gpus) > 1: - self.model = torch.nn.DataParallel(self.model, device_ids=args.gpus).to(args.device) - else: - self.model.to(args.device) - else: - self.model.cuda() - self.model.eval() - - def image_preprocess(self, img_source): - """ - Pre-process the img before fed to the object detection network - Input: image name(str) or raw image data(ndarray or torch.Tensor,channel GBR) - Output: pre-processed image data(torch.FloatTensor,(1,3,h,w)) - """ - if isinstance(img_source, str): - img, orig_img, im_dim_list = prep_image(img_source, self.inp_dim) - elif isinstance(img_source, torch.Tensor) or isinstance(img_source, np.ndarray): - img, orig_img, im_dim_list = prep_frame(img_source, self.inp_dim) - else: - raise IOError('Unknown image source type: {}'.format(type(img_source))) - - return img - - def images_detection(self, imgs, orig_dim_list): - """ - Feed the img data into object detection network and - collect bbox w.r.t original image size - Input: imgs(torch.FloatTensor,(b,3,h,w)): pre-processed mini-batch image input - orig_dim_list(torch.FloatTensor, (b,(w,h,w,h))): original mini-batch image size - Output: dets(torch.cuda.FloatTensor,(n,(batch_idx,x1,y1,x2,y2,c,s,idx of cls))): human detection results - """ - args = self.detector_opt - _CUDA = True - if args: - if args.gpus[0] < 0: - _CUDA = False - if not self.model: - self.load_model() - with torch.no_grad(): - imgs = imgs.to(args.device) if args else imgs.cuda() - prediction = self.model(imgs, args=args) - #do nms to the detection results, only human category is left - # dets = self.dynamic_write_results(prediction, self.confidence, - # self.num_classes, nms=True, - # nms_conf=self.nms_thres) - - dets = self.dynamic_write_results(prediction, self.confidence, - self.num_classes, nms=False, - nms_conf=self.nms_thres) - - if isinstance(dets, int) or dets.shape[0] == 0: - return 0 - dets = dets.cpu() - - orig_dim_list = torch.index_select(orig_dim_list, 0, dets[:, 0].long()) - scaling_factor = torch.min(self.inp_dim / orig_dim_list, 1)[0].view(-1, 1) - dets[:, [1, 3]] -= (self.inp_dim - scaling_factor * orig_dim_list[:, 0].view(-1, 1)) / 2 - dets[:, [2, 4]] -= (self.inp_dim - scaling_factor * orig_dim_list[:, 1].view(-1, 1)) / 2 - dets[:, 1:5] /= scaling_factor - for i in range(dets.shape[0]): - dets[i, [1, 3]] = torch.clamp(dets[i, [1, 3]], 0.0, orig_dim_list[i, 0]) - dets[i, [2, 4]] = torch.clamp(dets[i, [2, 4]], 0.0, orig_dim_list[i, 1]) - - return dets - - def dynamic_write_results(self, prediction, confidence, num_classes, nms=True, nms_conf=0.4): - prediction_bak = prediction.clone() - dets = self.write_results(prediction.clone(), confidence, num_classes, nms, nms_conf) - if isinstance(dets, int): - return dets - - if dets.shape[0] > 100: - nms_conf -= 0.05 - dets = self.write_results(prediction_bak.clone(), confidence, num_classes, nms, nms_conf) - - return dets - - def write_results(self, prediction, confidence, num_classes, nms=True, nms_conf=0.4): - args = self.detector_opt - #prediction: (batchsize, num of objects, (xc,yc,w,h,box confidence, 80 class scores)) - conf_mask = (prediction[:, :, 4] > confidence).float().float().unsqueeze(2) - prediction = prediction * conf_mask - - try: - ind_nz = torch.nonzero(prediction[:,:,4]).transpose(0,1).contiguous() - except: - return 0 - - #the 3rd channel of prediction: (xc,yc,w,h)->(x1,y1,x2,y2) - box_a = prediction.new(prediction.shape) - box_a[:,:,0] = (prediction[:,:,0] - prediction[:,:,2]/2) - box_a[:,:,1] = (prediction[:,:,1] - prediction[:,:,3]/2) - box_a[:,:,2] = (prediction[:,:,0] + prediction[:,:,2]/2) - box_a[:,:,3] = (prediction[:,:,1] + prediction[:,:,3]/2) - prediction[:,:,:4] = box_a[:,:,:4] - - batch_size = prediction.size(0) - - output = prediction.new(1, prediction.size(2) + 1) - write = False - num = 0 - for ind in range(batch_size): - #select the image from the batch - image_pred = prediction[ind] - - #Get the class having maximum score, and the index of that class - #Get rid of num_classes softmax scores - #Add the class index and the class score of class having maximum score - max_conf, max_conf_score = torch.max(image_pred[:,5:5+ num_classes], 1) - max_conf = max_conf.float().unsqueeze(1) - max_conf_score = max_conf_score.float().unsqueeze(1) - seq = (image_pred[:,:5], max_conf, max_conf_score) - #image_pred:(n,(x1,y1,x2,y2,c,s,idx of cls)) - image_pred = torch.cat(seq, 1) - - #Get rid of the zero entries - non_zero_ind = (torch.nonzero(image_pred[:,4])) - - image_pred_ = image_pred[non_zero_ind.squeeze(),:].view(-1,7) - - #Get the various classes detected in the image - try: - img_classes = unique(image_pred_[:,-1]) - except: - continue - - #WE will do NMS classwise - #print(img_classes) - for cls in img_classes: - if cls != 0: - continue - #get the detections with one particular class - cls_mask = image_pred_*(image_pred_[:,-1] == cls).float().unsqueeze(1) - class_mask_ind = torch.nonzero(cls_mask[:,-2]).squeeze() - - image_pred_class = image_pred_[class_mask_ind].view(-1,7) - - #sort the detections such that the entry with the maximum objectness - #confidence is at the top - conf_sort_index = torch.sort(image_pred_class[:,4], descending = True )[1] - image_pred_class = image_pred_class[conf_sort_index] - idx = image_pred_class.size(0) - - #if nms has to be done - if nms: - if platform.system() != 'Windows': - #We use faster rcnn implementation of nms (soft nms is optional) - # nms_op = getattr(nms_wrapper, 'nms') - nms_op = nms - #nms_op input:(n,(x1,y1,x2,y2,c)) - #nms_op output: input[inds,:], inds - # _, inds = nms_op(image_pred_class[:,:5], nms_conf) - _, inds = nms_op(image_pred_class[:,:4], image_pred_class[:, 4], nms_conf) - - image_pred_class = image_pred_class[inds] - else: - # Perform non-maximum suppression - max_detections = [] - while image_pred_class.size(0): - # Get detection with highest confidence and save as max detection - max_detections.append(image_pred_class[0].unsqueeze(0)) - # Stop if we're at the last detection - if len(image_pred_class) == 1: - break - # Get the IOUs for all boxes with lower confidence - ious = bbox_iou(max_detections[-1], image_pred_class[1:], args) - # Remove detections with IoU >= NMS threshold - image_pred_class = image_pred_class[1:][ious < nms_conf] - - image_pred_class = torch.cat(max_detections).data - - #Concatenate the batch_id of the image to the detection - #this helps us identify which image does the detection correspond to - #We use a linear straucture to hold ALL the detections from the batch - #the batch_dim is flattened - #batch is identified by extra batch column - - batch_ind = image_pred_class.new(image_pred_class.size(0), 1).fill_(ind) - seq = batch_ind, image_pred_class - if not write: - output = torch.cat(seq,1) - write = True - else: - out = torch.cat(seq,1) - output = torch.cat((output,out)) - num += 1 - - if not num: - return 0 - #output:(n,(batch_ind,x1,y1,x2,y2,c,s,idx of cls)) - return output - - def detect_one_img(self, img_name): - """ - Detect bboxs in one image - Input: 'str', full path of image - Output: '[{"category_id":1,"score":float,"bbox":[x,y,w,h],"image_id":str},...]', - The output results are similar with coco results type, except that image_id uses full path str - instead of coco %012d id for generalization. - """ - args = self.detector_opt - _CUDA = True - if args: - if args.gpus[0] < 0: - _CUDA = False - if not self.model: - self.load_model() - if isinstance(self.model, torch.nn.DataParallel): - self.model = self.model.module - dets_results = [] - #pre-process(scale, normalize, ...) the image - img, orig_img, img_dim_list = prep_image(img_name, self.inp_dim) - with torch.no_grad(): - img_dim_list = torch.FloatTensor([img_dim_list]).repeat(1, 2) - img = img.to(args.device) if args else img.cuda() - prediction = self.model(img, args=args) - #do nms to the detection results, only human category is left - # dets = self.dynamic_write_results(prediction, self.confidence, - # self.num_classes, nms=True, - # nms_conf=self.nms_thres) - - dets = self.dynamic_write_results(prediction, self.confidence, - self.num_classes, nms=False, - nms_conf=self.nms_thres) - - if isinstance(dets, int) or dets.shape[0] == 0: - return None - dets = dets.cpu() - - img_dim_list = torch.index_select(img_dim_list, 0, dets[:, 0].long()) - scaling_factor = torch.min(self.inp_dim / img_dim_list, 1)[0].view(-1, 1) - dets[:, [1, 3]] -= (self.inp_dim - scaling_factor * img_dim_list[:, 0].view(-1, 1)) / 2 - dets[:, [2, 4]] -= (self.inp_dim - scaling_factor * img_dim_list[:, 1].view(-1, 1)) / 2 - dets[:, 1:5] /= scaling_factor - for i in range(dets.shape[0]): - dets[i, [1, 3]] = torch.clamp(dets[i, [1, 3]], 0.0, img_dim_list[i, 0]) - dets[i, [2, 4]] = torch.clamp(dets[i, [2, 4]], 0.0, img_dim_list[i, 1]) - - #write results - det_dict = {} - x = float(dets[i, 1]) - y = float(dets[i, 2]) - w = float(dets[i, 3] - dets[i, 1]) - h = float(dets[i, 4] - dets[i, 2]) - det_dict["category_id"] = 1 - det_dict["score"] = float(dets[i, 5]) - det_dict["bbox"] = [x, y, w, h] - det_dict["image_id"] = int(os.path.basename(img_name).split('.')[0]) - dets_results.append(det_dict) - - return dets_results diff --git a/cv/pose/alphapose/pytorch/detector/yolo_cfg.py b/cv/pose/alphapose/pytorch/detector/yolo_cfg.py deleted file mode 100755 index f0adf357e..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolo_cfg.py +++ /dev/null @@ -1,9 +0,0 @@ -from easydict import EasyDict as edict - -cfg = edict() -cfg.CONFIG = 'detector/yolo/cfg/yolov3-spp.cfg' -cfg.WEIGHTS = 'detector/yolo/data/yolov3-spp.weights' -cfg.INP_DIM = 608 -cfg.NMS_THRES = 0.6 -cfg.CONFIDENCE = 0.1 -cfg.NUM_CLASSES = 80 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/common.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/common.py deleted file mode 100755 index b12fec3ca..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/common.py +++ /dev/null @@ -1,641 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Common modules -""" - -import json -import math -import platform -import warnings -from collections import OrderedDict, namedtuple -from copy import copy -from pathlib import Path - -import cv2 -import numpy as np -import pandas as pd -import requests -import torch -import torch.nn as nn -from PIL import Image -from torch.cuda import amp - -from .utils.datasets import exif_transpose, letterbox -from .utils.general import (LOGGER, check_requirements, check_suffix, colorstr, increment_path, make_divisible, - non_max_suppression, scale_coords, xywh2xyxy, xyxy2xywh) -from .utils.plots import Annotator, colors, save_one_box -from .utils.torch_utils import copy_attr, time_sync - - -def autopad(k, p=None): # kernel, padding - # Pad to 'same' - if p is None: - p = k // 2 if isinstance(k, int) else [x // 2 for x in k] # auto-pad - return p - - -class Conv(nn.Module): - # Standard convolution - def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True): # ch_in, ch_out, kernel, stride, padding, groups - super().__init__() - self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False) - self.bn = nn.BatchNorm2d(c2) - self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity()) - - def forward(self, x): - return self.act(self.bn(self.conv(x))) - - def forward_fuse(self, x): - return self.act(self.conv(x)) - - -class DWConv(Conv): - # Depth-wise convolution class - def __init__(self, c1, c2, k=1, s=1, act=True): # ch_in, ch_out, kernel, stride, padding, groups - super().__init__(c1, c2, k, s, g=math.gcd(c1, c2), act=act) - - -class TransformerLayer(nn.Module): - # Transformer layer https://arxiv.org/abs/2010.11929 (LayerNorm layers removed for better performance) - def __init__(self, c, num_heads): - super().__init__() - self.q = nn.Linear(c, c, bias=False) - self.k = nn.Linear(c, c, bias=False) - self.v = nn.Linear(c, c, bias=False) - self.ma = nn.MultiheadAttention(embed_dim=c, num_heads=num_heads) - self.fc1 = nn.Linear(c, c, bias=False) - self.fc2 = nn.Linear(c, c, bias=False) - - def forward(self, x): - x = self.ma(self.q(x), self.k(x), self.v(x))[0] + x - x = self.fc2(self.fc1(x)) + x - return x - - -class TransformerBlock(nn.Module): - # Vision Transformer https://arxiv.org/abs/2010.11929 - def __init__(self, c1, c2, num_heads, num_layers): - super().__init__() - self.conv = None - if c1 != c2: - self.conv = Conv(c1, c2) - self.linear = nn.Linear(c2, c2) # learnable position embedding - self.tr = nn.Sequential(*(TransformerLayer(c2, num_heads) for _ in range(num_layers))) - self.c2 = c2 - - def forward(self, x): - if self.conv is not None: - x = self.conv(x) - b, _, w, h = x.shape - p = x.flatten(2).permute(2, 0, 1) - return self.tr(p + self.linear(p)).permute(1, 2, 0).reshape(b, self.c2, w, h) - - -class Bottleneck(nn.Module): - # Standard bottleneck - def __init__(self, c1, c2, shortcut=True, g=1, e=0.5): # ch_in, ch_out, shortcut, groups, expansion - super().__init__() - c_ = int(c2 * e) # hidden channels - self.cv1 = Conv(c1, c_, 1, 1) - self.cv2 = Conv(c_, c2, 3, 1, g=g) - self.add = shortcut and c1 == c2 - - def forward(self, x): - return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x)) - - -class BottleneckCSP(nn.Module): - # CSP Bottleneck https://github.com/WongKinYiu/CrossStagePartialNetworks - def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion - super().__init__() - c_ = int(c2 * e) # hidden channels - self.cv1 = Conv(c1, c_, 1, 1) - self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False) - self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False) - self.cv4 = Conv(2 * c_, c2, 1, 1) - self.bn = nn.BatchNorm2d(2 * c_) # applied to cat(cv2, cv3) - self.act = nn.SiLU() - self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n))) - - def forward(self, x): - y1 = self.cv3(self.m(self.cv1(x))) - y2 = self.cv2(x) - return self.cv4(self.act(self.bn(torch.cat((y1, y2), dim=1)))) - - -class C3(nn.Module): - # CSP Bottleneck with 3 convolutions - def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion - super().__init__() - c_ = int(c2 * e) # hidden channels - self.cv1 = Conv(c1, c_, 1, 1) - self.cv2 = Conv(c1, c_, 1, 1) - self.cv3 = Conv(2 * c_, c2, 1) # act=FReLU(c2) - self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n))) - # self.m = nn.Sequential(*[CrossConv(c_, c_, 3, 1, g, 1.0, shortcut) for _ in range(n)]) - - def forward(self, x): - return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1)) - - -class C3TR(C3): - # C3 module with TransformerBlock() - def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): - super().__init__(c1, c2, n, shortcut, g, e) - c_ = int(c2 * e) - self.m = TransformerBlock(c_, c_, 4, n) - - -class C3SPP(C3): - # C3 module with SPP() - def __init__(self, c1, c2, k=(5, 9, 13), n=1, shortcut=True, g=1, e=0.5): - super().__init__(c1, c2, n, shortcut, g, e) - c_ = int(c2 * e) - self.m = SPP(c_, c_, k) - - -class C3Ghost(C3): - # C3 module with GhostBottleneck() - def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): - super().__init__(c1, c2, n, shortcut, g, e) - c_ = int(c2 * e) # hidden channels - self.m = nn.Sequential(*(GhostBottleneck(c_, c_) for _ in range(n))) - - -class SPP(nn.Module): - # Spatial Pyramid Pooling (SPP) layer https://arxiv.org/abs/1406.4729 - def __init__(self, c1, c2, k=(5, 9, 13)): - super().__init__() - c_ = c1 // 2 # hidden channels - self.cv1 = Conv(c1, c_, 1, 1) - self.cv2 = Conv(c_ * (len(k) + 1), c2, 1, 1) - self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k]) - - def forward(self, x): - x = self.cv1(x) - with warnings.catch_warnings(): - warnings.simplefilter('ignore') # suppress torch 1.9.0 max_pool2d() warning - return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1)) - - -class SPPF(nn.Module): - # Spatial Pyramid Pooling - Fast (SPPF) layer for YOLOv5 by Glenn Jocher - def __init__(self, c1, c2, k=5): # equivalent to SPP(k=(5, 9, 13)) - super().__init__() - c_ = c1 // 2 # hidden channels - self.cv1 = Conv(c1, c_, 1, 1) - self.cv2 = Conv(c_ * 4, c2, 1, 1) - self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2) - - def forward(self, x): - x = self.cv1(x) - with warnings.catch_warnings(): - warnings.simplefilter('ignore') # suppress torch 1.9.0 max_pool2d() warning - y1 = self.m(x) - y2 = self.m(y1) - return self.cv2(torch.cat([x, y1, y2, self.m(y2)], 1)) - - -class Focus(nn.Module): - # Focus wh information into c-space - def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True): # ch_in, ch_out, kernel, stride, padding, groups - super().__init__() - self.conv = Conv(c1 * 4, c2, k, s, p, g, act) - # self.contract = Contract(gain=2) - - def forward(self, x): # x(b,c,w,h) -> y(b,4c,w/2,h/2) - return self.conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1)) - # return self.conv(self.contract(x)) - - -class GhostConv(nn.Module): - # Ghost Convolution https://github.com/huawei-noah/ghostnet - def __init__(self, c1, c2, k=1, s=1, g=1, act=True): # ch_in, ch_out, kernel, stride, groups - super().__init__() - c_ = c2 // 2 # hidden channels - self.cv1 = Conv(c1, c_, k, s, None, g, act) - self.cv2 = Conv(c_, c_, 5, 1, None, c_, act) - - def forward(self, x): - y = self.cv1(x) - return torch.cat([y, self.cv2(y)], 1) - - -class GhostBottleneck(nn.Module): - # Ghost Bottleneck https://github.com/huawei-noah/ghostnet - def __init__(self, c1, c2, k=3, s=1): # ch_in, ch_out, kernel, stride - super().__init__() - c_ = c2 // 2 - self.conv = nn.Sequential(GhostConv(c1, c_, 1, 1), # pw - DWConv(c_, c_, k, s, act=False) if s == 2 else nn.Identity(), # dw - GhostConv(c_, c2, 1, 1, act=False)) # pw-linear - self.shortcut = nn.Sequential(DWConv(c1, c1, k, s, act=False), - Conv(c1, c2, 1, 1, act=False)) if s == 2 else nn.Identity() - - def forward(self, x): - return self.conv(x) + self.shortcut(x) - - -class Contract(nn.Module): - # Contract width-height into channels, i.e. x(1,64,80,80) to x(1,256,40,40) - def __init__(self, gain=2): - super().__init__() - self.gain = gain - - def forward(self, x): - b, c, h, w = x.size() # assert (h / s == 0) and (W / s == 0), 'Indivisible gain' - s = self.gain - x = x.view(b, c, h // s, s, w // s, s) # x(1,64,40,2,40,2) - x = x.permute(0, 3, 5, 1, 2, 4).contiguous() # x(1,2,2,64,40,40) - return x.view(b, c * s * s, h // s, w // s) # x(1,256,40,40) - - -class Expand(nn.Module): - # Expand channels into width-height, i.e. x(1,64,80,80) to x(1,16,160,160) - def __init__(self, gain=2): - super().__init__() - self.gain = gain - - def forward(self, x): - b, c, h, w = x.size() # assert C / s ** 2 == 0, 'Indivisible gain' - s = self.gain - x = x.view(b, s, s, c // s ** 2, h, w) # x(1,2,2,16,80,80) - x = x.permute(0, 3, 4, 1, 5, 2).contiguous() # x(1,16,80,2,80,2) - return x.view(b, c // s ** 2, h * s, w * s) # x(1,16,160,160) - - -class Concat(nn.Module): - # Concatenate a list of tensors along dimension - def __init__(self, dimension=1): - super().__init__() - self.d = dimension - - def forward(self, x): - return torch.cat(x, self.d) - - -class DetectMultiBackend(nn.Module): - # YOLOv5 MultiBackend class for python inference on various backends - def __init__(self, weights='yolov5s.pt', device=None, dnn=False): - # Usage: - # PyTorch: weights = *.pt - # TorchScript: *.torchscript - # CoreML: *.mlmodel - # TensorFlow: *_saved_model - # TensorFlow: *.pb - # TensorFlow Lite: *.tflite - # ONNX Runtime: *.onnx - # OpenCV DNN: *.onnx with dnn=True - # TensorRT: *.engine - from .experimental import attempt_download, attempt_load # scoped to avoid circular import - - super().__init__() - w = str(weights[0] if isinstance(weights, list) else weights) - suffix = Path(w).suffix.lower() - suffixes = ['.pt', '.torchscript', '.onnx', '.engine', '.tflite', '.pb', '', '.mlmodel'] - check_suffix(w, suffixes) # check weights have acceptable suffix - pt, jit, onnx, engine, tflite, pb, saved_model, coreml = (suffix == x for x in suffixes) # backend booleans - stride, names = 64, [f'class{i}' for i in range(1000)] # assign defaults - attempt_download(w) # download if not local - - if jit: # TorchScript - LOGGER.info(f'Loading {w} for TorchScript inference...') - extra_files = {'config.txt': ''} # model metadata - model = torch.jit.load(w, _extra_files=extra_files) - if extra_files['config.txt']: - d = json.loads(extra_files['config.txt']) # extra_files dict - stride, names = int(d['stride']), d['names'] - elif pt: # PyTorch - model = attempt_load(weights, map_location=device) - stride = int(model.stride.max()) # model stride - names = model.module.names if hasattr(model, 'module') else model.names # get class names - self.model = model # explicitly assign for to(), cpu(), cuda(), half() - elif coreml: # CoreML - LOGGER.info(f'Loading {w} for CoreML inference...') - import coremltools as ct - model = ct.models.MLModel(w) - elif dnn: # ONNX OpenCV DNN - LOGGER.info(f'Loading {w} for ONNX OpenCV DNN inference...') - check_requirements(('opencv-python>=4.5.4',)) - net = cv2.dnn.readNetFromONNX(w) - elif onnx: # ONNX Runtime - LOGGER.info(f'Loading {w} for ONNX Runtime inference...') - cuda = torch.cuda.is_available() - check_requirements(('onnx', 'onnxruntime-gpu' if cuda else 'onnxruntime')) - import onnxruntime - providers = ['CUDAExecutionProvider', 'CPUExecutionProvider'] if cuda else ['CPUExecutionProvider'] - session = onnxruntime.InferenceSession(w, providers=providers) - elif engine: # TensorRT - LOGGER.info(f'Loading {w} for TensorRT inference...') - import tensorrt as trt # https://developer.nvidia.com/nvidia-tensorrt-download - Binding = namedtuple('Binding', ('name', 'dtype', 'shape', 'data', 'ptr')) - logger = trt.Logger(trt.Logger.INFO) - with open(w, 'rb') as f, trt.Runtime(logger) as runtime: - model = runtime.deserialize_cuda_engine(f.read()) - bindings = OrderedDict() - for index in range(model.num_bindings): - name = model.get_binding_name(index) - dtype = trt.nptype(model.get_binding_dtype(index)) - shape = tuple(model.get_binding_shape(index)) - data = torch.from_numpy(np.empty(shape, dtype=np.dtype(dtype))).to(device) - bindings[name] = Binding(name, dtype, shape, data, int(data.data_ptr())) - binding_addrs = OrderedDict((n, d.ptr) for n, d in bindings.items()) - context = model.create_execution_context() - batch_size = bindings['images'].shape[0] - else: # TensorFlow model (TFLite, pb, saved_model) - if pb: # https://www.tensorflow.org/guide/migrate#a_graphpb_or_graphpbtxt - LOGGER.info(f'Loading {w} for TensorFlow *.pb inference...') - import tensorflow as tf - - def wrap_frozen_graph(gd, inputs, outputs): - x = tf.compat.v1.wrap_function(lambda: tf.compat.v1.import_graph_def(gd, name=""), []) # wrapped - return x.prune(tf.nest.map_structure(x.graph.as_graph_element, inputs), - tf.nest.map_structure(x.graph.as_graph_element, outputs)) - - graph_def = tf.Graph().as_graph_def() - graph_def.ParseFromString(open(w, 'rb').read()) - frozen_func = wrap_frozen_graph(gd=graph_def, inputs="x:0", outputs="Identity:0") - elif saved_model: - LOGGER.info(f'Loading {w} for TensorFlow saved_model inference...') - import tensorflow as tf - model = tf.keras.models.load_model(w) - elif tflite: # https://www.tensorflow.org/lite/guide/python#install_tensorflow_lite_for_python - if 'edgetpu' in w.lower(): - LOGGER.info(f'Loading {w} for TensorFlow Lite Edge TPU inference...') - import tflite_runtime.interpreter as tfli - delegate = {'Linux': 'libedgetpu.so.1', # install https://coral.ai/software/#edgetpu-runtime - 'Darwin': 'libedgetpu.1.dylib', - 'Windows': 'edgetpu.dll'}[platform.system()] - interpreter = tfli.Interpreter(model_path=w, experimental_delegates=[tfli.load_delegate(delegate)]) - else: - LOGGER.info(f'Loading {w} for TensorFlow Lite inference...') - import tensorflow as tf - interpreter = tf.lite.Interpreter(model_path=w) # load TFLite model - interpreter.allocate_tensors() # allocate - input_details = interpreter.get_input_details() # inputs - output_details = interpreter.get_output_details() # outputs - self.__dict__.update(locals()) # assign all variables to self - - def forward(self, im, augment=False, visualize=False, val=False): - """ - # YOLOv5 MultiBackend inference - b, ch, h, w = im.shape # batch, channel, height, width - if self.pt: # PyTorch - y = self.model(im) if self.jit else self.model(im, augment=augment, visualize=visualize) - return y if val else y[0] - elif self.coreml: # CoreML - im = im.permute(0, 2, 3, 1).cpu().numpy() # torch BCHW to numpy BHWC shape(1,320,192,3) - im = Image.fromarray((im[0] * 255).astype('uint8')) - # im = im.resize((192, 320), Image.ANTIALIAS) - y = self.model.predict({'image': im}) # coordinates are xywh normalized - box = xywh2xyxy(y['coordinates'] * [[w, h, w, h]]) # xyxy pixels - conf, cls = y['confidence'].max(1), y['confidence'].argmax(1).astype(np.float) - y = np.concatenate((box, conf.reshape(-1, 1), cls.reshape(-1, 1)), 1) - elif self.onnx: # ONNX - im = im.cpu().numpy() # torch to numpy - if self.dnn: # ONNX OpenCV DNN - self.net.setInput(im) - y = self.net.forward() - else: # ONNX Runtime - y = self.session.run([self.session.get_outputs()[0].name], {self.session.get_inputs()[0].name: im})[0] - elif self.engine: # TensorRT - assert im.shape == self.bindings['images'].shape, (im.shape, self.bindings['images'].shape) - self.binding_addrs['images'] = int(im.data_ptr()) - self.context.execute_v2(list(self.binding_addrs.values())) - y = self.bindings['output'].data - else: # TensorFlow model (TFLite, pb, saved_model) - im = im.permute(0, 2, 3, 1).cpu().numpy() # torch BCHW to numpy BHWC shape(1,320,192,3) - if self.pb: - y = self.frozen_func(x=self.tf.constant(im)).numpy() - elif self.saved_model: - y = self.model(im, training=False).numpy() - elif self.tflite: - input, output = self.input_details[0], self.output_details[0] - int8 = input['dtype'] == np.uint8 # is TFLite quantized uint8 model - if int8: - scale, zero_point = input['quantization'] - im = (im / scale + zero_point).astype(np.uint8) # de-scale - self.interpreter.set_tensor(input['index'], im) - self.interpreter.invoke() - y = self.interpreter.get_tensor(output['index']) - if int8: - scale, zero_point = output['quantization'] - y = (y.astype(np.float32) - zero_point) * scale # re-scale - y[..., 0] *= w # x - y[..., 1] *= h # y - y[..., 2] *= w # w - y[..., 3] *= h # h - y = torch.tensor(y) if isinstance(y, np.ndarray) else y - return (y, []) if val else y - """ - y = self.model(im) - return y[0] - - def warmup(self, imgsz=(1, 3, 640, 640), half=False): - # Warmup model by running inference once - if self.pt or self.engine or self.onnx: # warmup types - if isinstance(self.device, torch.device) and self.device.type != 'cpu': # only warmup GPU models - im = torch.zeros(*imgsz).to(self.device).type(torch.half if half else torch.float) # input image - self.forward(im) # warmup - - -class AutoShape(nn.Module): - # YOLOv5 input-robust model wrapper for passing cv2/np/PIL/torch inputs. Includes preprocessing, inference and NMS - conf = 0.25 # NMS confidence threshold - iou = 0.45 # NMS IoU threshold - agnostic = False # NMS class-agnostic - multi_label = False # NMS multiple labels per box - classes = None # (optional list) filter by class, i.e. = [0, 15, 16] for COCO persons, cats and dogs - max_det = 1000 # maximum number of detections per image - amp = False # Automatic Mixed Precision (AMP) inference - - def __init__(self, model): - super().__init__() - LOGGER.info('Adding AutoShape... ') - copy_attr(self, model, include=('yaml', 'nc', 'hyp', 'names', 'stride', 'abc'), exclude=()) # copy attributes - self.dmb = isinstance(model, DetectMultiBackend) # DetectMultiBackend() instance - self.pt = not self.dmb or model.pt # PyTorch model - self.model = model.eval() - - def _apply(self, fn): - # Apply to(), cpu(), cuda(), half() to model tensors that are not parameters or registered buffers - self = super()._apply(fn) - if self.pt: - m = self.model.model.model[-1] if self.dmb else self.model.model[-1] # Detect() - m.stride = fn(m.stride) - m.grid = list(map(fn, m.grid)) - if isinstance(m.anchor_grid, list): - m.anchor_grid = list(map(fn, m.anchor_grid)) - return self - - @torch.no_grad() - def forward(self, imgs, size=640, augment=False, profile=False): - # Inference from various sources. For height=640, width=1280, RGB images example inputs are: - # file: imgs = 'data/images/zidane.jpg' # str or PosixPath - # URI: = 'https://ultralytics.com/images/zidane.jpg' - # OpenCV: = cv2.imread('image.jpg')[:,:,::-1] # HWC BGR to RGB x(640,1280,3) - # PIL: = Image.open('image.jpg') or ImageGrab.grab() # HWC x(640,1280,3) - # numpy: = np.zeros((640,1280,3)) # HWC - # torch: = torch.zeros(16,3,320,640) # BCHW (scaled to size=640, 0-1 values) - # multiple: = [Image.open('image1.jpg'), Image.open('image2.jpg'), ...] # list of images - - t = [time_sync()] - p = next(self.model.parameters()) if self.pt else torch.zeros(1) # for device and type - autocast = self.amp and (p.device.type != 'cpu') # Automatic Mixed Precision (AMP) inference - if isinstance(imgs, torch.Tensor): # torch - with amp.autocast(enabled=autocast): - return self.model(imgs.to(p.device).type_as(p), augment, profile) # inference - - # Pre-process - n, imgs = (len(imgs), imgs) if isinstance(imgs, list) else (1, [imgs]) # number of images, list of images - shape0, shape1, files = [], [], [] # image and inference shapes, filenames - for i, im in enumerate(imgs): - f = f'image{i}' # filename - if isinstance(im, (str, Path)): # filename or uri - im, f = Image.open(requests.get(im, stream=True).raw if str(im).startswith('http') else im), im - im = np.asarray(exif_transpose(im)) - elif isinstance(im, Image.Image): # PIL Image - im, f = np.asarray(exif_transpose(im)), getattr(im, 'filename', f) or f - files.append(Path(f).with_suffix('.jpg').name) - if im.shape[0] < 5: # image in CHW - im = im.transpose((1, 2, 0)) # reverse dataloader .transpose(2, 0, 1) - im = im[..., :3] if im.ndim == 3 else np.tile(im[..., None], 3) # enforce 3ch input - s = im.shape[:2] # HWC - shape0.append(s) # image shape - g = (size / max(s)) # gain - shape1.append([y * g for y in s]) - imgs[i] = im if im.data.contiguous else np.ascontiguousarray(im) # update - shape1 = [make_divisible(x, self.stride) for x in np.stack(shape1, 0).max(0)] # inference shape - x = [letterbox(im, new_shape=shape1 if self.pt else size, auto=False)[0] for im in imgs] # pad - x = np.stack(x, 0) if n > 1 else x[0][None] # stack - x = np.ascontiguousarray(x.transpose((0, 3, 1, 2))) # BHWC to BCHW - x = torch.from_numpy(x).to(p.device).type_as(p) / 255 # uint8 to fp16/32 - t.append(time_sync()) - - with amp.autocast(enabled=autocast): - # Inference - y = self.model(x, augment, profile) # forward - t.append(time_sync()) - - # Post-process - y = non_max_suppression(y if self.dmb else y[0], self.conf, iou_thres=self.iou, classes=self.classes, - agnostic=self.agnostic, multi_label=self.multi_label, max_det=self.max_det) # NMS - for i in range(n): - scale_coords(shape1, y[i][:, :4], shape0[i]) - - t.append(time_sync()) - return Detections(imgs, y, files, t, self.names, x.shape) - - -class Detections: - # YOLOv5 detections class for inference results - def __init__(self, imgs, pred, files, times=(0, 0, 0, 0), names=None, shape=None): - super().__init__() - d = pred[0].device # device - gn = [torch.tensor([*(im.shape[i] for i in [1, 0, 1, 0]), 1, 1], device=d) for im in imgs] # normalizations - self.imgs = imgs # list of images as numpy arrays - self.pred = pred # list of tensors pred[0] = (xyxy, conf, cls) - self.names = names # class names - self.files = files # image filenames - self.times = times # profiling times - self.xyxy = pred # xyxy pixels - self.xywh = [xyxy2xywh(x) for x in pred] # xywh pixels - self.xyxyn = [x / g for x, g in zip(self.xyxy, gn)] # xyxy normalized - self.xywhn = [x / g for x, g in zip(self.xywh, gn)] # xywh normalized - self.n = len(self.pred) # number of images (batch size) - self.t = tuple((times[i + 1] - times[i]) * 1000 / self.n for i in range(3)) # timestamps (ms) - self.s = shape # inference BCHW shape - - def display(self, pprint=False, show=False, save=False, crop=False, render=False, save_dir=Path('')): - crops = [] - for i, (im, pred) in enumerate(zip(self.imgs, self.pred)): - s = f'image {i + 1}/{len(self.pred)}: {im.shape[0]}x{im.shape[1]} ' # string - if pred.shape[0]: - for c in pred[:, -1].unique(): - n = (pred[:, -1] == c).sum() # detections per class - s += f"{n} {self.names[int(c)]}{'s' * (n > 1)}, " # add to string - if show or save or render or crop: - annotator = Annotator(im, example=str(self.names)) - for *box, conf, cls in reversed(pred): # xyxy, confidence, class - label = f'{self.names[int(cls)]} {conf:.2f}' - if crop: - file = save_dir / 'crops' / self.names[int(cls)] / self.files[i] if save else None - crops.append({'box': box, 'conf': conf, 'cls': cls, 'label': label, - 'im': save_one_box(box, im, file=file, save=save)}) - else: # all others - annotator.box_label(box, label, color=colors(cls)) - im = annotator.im - else: - s += '(no detections)' - - im = Image.fromarray(im.astype(np.uint8)) if isinstance(im, np.ndarray) else im # from np - if pprint: - LOGGER.info(s.rstrip(', ')) - if show: - im.show(self.files[i]) # show - if save: - f = self.files[i] - im.save(save_dir / f) # save - if i == self.n - 1: - LOGGER.info(f"Saved {self.n} image{'s' * (self.n > 1)} to {colorstr('bold', save_dir)}") - if render: - self.imgs[i] = np.asarray(im) - if crop: - if save: - LOGGER.info(f'Saved results to {save_dir}\n') - return crops - - def print(self): - self.display(pprint=True) # print results - LOGGER.info(f'Speed: %.1fms pre-process, %.1fms inference, %.1fms NMS per image at shape {tuple(self.s)}' % - self.t) - - def show(self): - self.display(show=True) # show results - - def save(self, save_dir='runs/detect/exp'): - save_dir = increment_path(save_dir, exist_ok=save_dir != 'runs/detect/exp', mkdir=True) # increment save_dir - self.display(save=True, save_dir=save_dir) # save results - - def crop(self, save=True, save_dir='runs/detect/exp'): - save_dir = increment_path(save_dir, exist_ok=save_dir != 'runs/detect/exp', mkdir=True) if save else None - return self.display(crop=True, save=save, save_dir=save_dir) # crop results - - def render(self): - self.display(render=True) # render results - return self.imgs - - def pandas(self): - # return detections as pandas DataFrames, i.e. print(results.pandas().xyxy[0]) - new = copy(self) # return copy - ca = 'xmin', 'ymin', 'xmax', 'ymax', 'confidence', 'class', 'name' # xyxy columns - cb = 'xcenter', 'ycenter', 'width', 'height', 'confidence', 'class', 'name' # xywh columns - for k, c in zip(['xyxy', 'xyxyn', 'xywh', 'xywhn'], [ca, ca, cb, cb]): - a = [[x[:5] + [int(x[5]), self.names[int(x[5])]] for x in x.tolist()] for x in getattr(self, k)] # update - setattr(new, k, [pd.DataFrame(x, columns=c) for x in a]) - return new - - def tolist(self): - # return a list of Detections objects, i.e. 'for result in results.tolist():' - r = range(self.n) # iterable - x = [Detections([self.imgs[i]], [self.pred[i]], [self.files[i]], self.times, self.names, self.s) for i in r] - # for d in x: - # for k in ['imgs', 'pred', 'xyxy', 'xyxyn', 'xywh', 'xywhn']: - # setattr(d, k, getattr(d, k)[0]) # pop out of list - return x - - def __len__(self): - return self.n - - -class Classify(nn.Module): - # Classification head, i.e. x(b,c1,20,20) to x(b,c2) - def __init__(self, c1, c2, k=1, s=1, p=None, g=1): # ch_in, ch_out, kernel, stride, padding, groups - super().__init__() - self.aap = nn.AdaptiveAvgPool2d(1) # to x(b,c1,1,1) - self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g) # to x(b,c2,1,1) - self.flat = nn.Flatten() - - def forward(self, x): - z = torch.cat([self.aap(y) for y in (x if isinstance(x, list) else [x])], 1) # cat if list - return self.flat(self.conv(z)) # flatten to x(b,c2) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/Makefile b/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/Makefile deleted file mode 100755 index 0457ba04b..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -build: - @python setup.py build - @mkdir -p _ext - @mv $$(ls build/lib*/cuda_impl/*.so) _ext - @rm -rf build - -install: - @python setup.py install - @rm -rf build - @rm -rf dist - @rm -rf cuda_impl.egg-info diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/__init__.py deleted file mode 100755 index de4fe27d2..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .yolov5_decode import yolov5_decode diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/cuda/yolov5_decode.cu b/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/cuda/yolov5_decode.cu deleted file mode 100755 index d85765325..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/cuda/yolov5_decode.cu +++ /dev/null @@ -1,59 +0,0 @@ -#include "pytorch_cuda_helper.h" -#include "yolov5_decode_kernel.cuh" - - -namespace cudaImpl { - -namespace { - -at::Tensor YoloV5DecodeForwardKernelLauncher( - const at::Tensor& pred_map, - const at::Tensor& anchors, - int64_t stride) -{ - TORCH_CHECK(pred_map.is_cuda(), "pred_map must be a CUDA tensor"); - TORCH_CHECK(anchors.is_cuda(), "anchors must be a CUDA tensor"); - - int batch_size = pred_map.size(0); - int num_anchors = pred_map.size(1); - int height = pred_map.size(2); - int width = pred_map.size(3); - int num_classes = pred_map.size(4) - 5; - int total_bboxes = batch_size * height * width * num_anchors; - - at::cuda::CUDAGuard device_guard(pred_map.device()); - - TORCH_CHECK(pred_map.is_contiguous() && anchors.is_contiguous(), - "Tensor must be contiguous") - - at::Tensor decoded_bboxes = at::zeros( - {batch_size, int(height*width*num_anchors), 6}, pred_map.options()); - - cudaStream_t stream = at::cuda::getCurrentCUDAStream(); - AT_DISPATCH_FLOATING_TYPES_AND_HALF( - pred_map.scalar_type(), "YoloV5DecodeForwardKernel", [&] { - YoloV5DecodeForwardKernel - <<>>( - pred_map.data_ptr(), - anchors.data_ptr(), - decoded_bboxes.data_ptr(), - stride, - batch_size, - height, - width, - num_classes, - num_anchors); - }); - AT_CUDA_CHECK(cudaGetLastError()); - return decoded_bboxes; -} - -} // namespace - -TORCH_LIBRARY_IMPL(cudaImpl, CUDA, m) { - m.impl( - TORCH_SELECTIVE_NAME("cudaImpl::yolov5_decode_forward"), - TORCH_FN(YoloV5DecodeForwardKernelLauncher)); - } - -} // namespace cudaImpl diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/cuda/yolov5_decode_kernel.cuh b/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/cuda/yolov5_decode_kernel.cuh deleted file mode 100755 index fce3d22ba..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/cuda/yolov5_decode_kernel.cuh +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef CUDA_IMPL_YOLOV5_DECODE_KERNEL_H_ -#define CUDA_IMPL_YOLOV5_DECODE_KERNEL_H_ - -#include - -template -inline __device__ T devExp(T x) { return expf(x); } - -template -inline __device__ T devSigmoid(T x) { return 1.0f / (1.0f + devExp(-x)); } - - -/* pred_map: (batch_size, height, width, num_anchors, 5+num_classes) */ -template -__global__ void YoloV5DecodeForwardKernel( - const T* pred_map, - const T* anchors, - T* decoded_bboxes, - int stride, - int batch_size, - int height, - int width, - int num_classes, - int num_anchors) -{ - int fm_area = height * width; - int num_attrib = 5 + num_classes; - int total_bboxes = batch_size * fm_area * num_anchors; - - int thd_idx = blockIdx.x * blockDim.x + threadIdx.x; - if (thd_idx >= total_bboxes) - return; - - // 计算某个维度的 idx 时, 先把该维度变成 inner most dim(除以其右边的所有维度的 dim 值的积) - // 然后对该维度的 dim 值取余(避免 idx 超过 dim 值) - //int batch_idx = thd_idx / (fm_area * num_anchors) % batch_size; - int anchor_idx = thd_idx / fm_area % num_anchors; - int h_idx = thd_idx / width % height; - int w_idx = thd_idx % width; - - T* pred_attribs = (T*)(pred_map + thd_idx * num_attrib); - - T cx = (devSigmoid(pred_attribs[0]) * 2 - 0.5 + w_idx) * stride; - T cy = (devSigmoid(pred_attribs[1]) * 2 - 0.5 + h_idx) * stride; - T w_tmp = devSigmoid(pred_attribs[2]) * 2; - T w = w_tmp * w_tmp * anchors[2*anchor_idx] * stride; - T h_tmp = devSigmoid(pred_attribs[3]) * 2; - T h = h_tmp * h_tmp * anchors[2*anchor_idx+1] * stride; - T conf = devSigmoid(pred_attribs[4]); - - int class_id = 0; - T max_prob = 0.0; - T* pred_probs = (T*)(pred_attribs + 5); -#pragma unroll - for (int k = 0; k < num_classes; ++k) { - T prob = devSigmoid(pred_probs[k]); - if (prob > max_prob) { - max_prob = prob; - class_id = k + 1; - } - } - T* decoded_bbox = (T*)(decoded_bboxes + thd_idx * 6); - T x1 = cx - 0.5 * w; - T y1 = cy - 0.5 * h; - decoded_bbox[0] = x1; - decoded_bbox[1] = y1; - decoded_bbox[2] = x1 + w; - decoded_bbox[3] = y1 + h; - decoded_bbox[4] = max_prob * conf; - decoded_bbox[5] = (T)class_id; -} - -#endif // CUDA_IMPL_YOLOV5_DECODE_KERNEL_H_ diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/include/cuda_helper.h b/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/include/cuda_helper.h deleted file mode 100755 index 2b0a6a187..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/include/cuda_helper.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef CUDA_IMPL_COMMON_CUDA_HELPER_H_ -#define CUDA_IMPL_COMMON_CUDA_HELPER_H_ - -#include - -#ifndef warpSize -#ifdef __ILUVATAR__ -#define warpSize 64 -#else -#define warpSize 32 -#endif -#endif - -#ifndef THREADS_PER_BLOCK -#ifdef __ILUVATAR__ -#define THREADS_PER_BLOCK 4096 -#else -#define THREADS_PER_BLOCK 1024 -#endif -#endif - -#ifndef MAX_BLOCKS -#define MAX_BLOCKS 1024 -#endif - -#define CUDA_1D_KERNEL_LOOP(i, n) \ - for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < (n); \ - i += blockDim.x * gridDim.x) - -#define CUDA_2D_KERNEL_LOOP(i, n, j, m) \ - for (size_t i = blockIdx.x * blockDim.x + threadIdx.x; i < (n); \ - i += blockDim.x * gridDim.x) \ - for (size_t j = blockIdx.y * blockDim.y + threadIdx.y; j < (m); \ - j += blockDim.y * gridDim.y) - -#define CUDA_2D_KERNEL_BLOCK_LOOP(i, n, j, m) \ - for (size_t i = blockIdx.x; i < (n); i += gridDim.x) \ - for (size_t j = blockIdx.y; j < (m); j += gridDim.y) - -inline int GET_BLOCKS(const int N, const int num_threads = THREADS_PER_BLOCK) { - int optimal_block_num = (N + num_threads - 1) / num_threads; - return std::min(optimal_block_num, MAX_BLOCKS); -} - -#endif // CUDA_IMPL_COMMON_CUDA_HELPER_H_ diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/include/pytorch_cuda_helper.h b/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/include/pytorch_cuda_helper.h deleted file mode 100755 index 799fc9e2a..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/include/pytorch_cuda_helper.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CUDA_IMPL_COMMON_PYTORCH_CUDA_HELPER_H_ -#define CUDA_IMPL_COMMON_PYTORCH_CUDA_HELPER_H_ - -#include -#include -#include -#include - -#include "cuda_helper.h" - -using at::Half; -using at::Tensor; -using phalf = at::Half; - -#define __PHALF(x) (x) - -#endif // CUDA_IMPL_COMMON_PYTORCH_CUDA_HELPER_H_ diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/yolov5_decode.cpp b/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/yolov5_decode.cpp deleted file mode 100755 index fea6291fe..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/csrc/yolov5_decode.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include - - -namespace cudaImpl { - -at::Tensor yolov5_decode_forward( - const at::Tensor& pred_map, - const at::Tensor& anchors, - int64_t stride) -{ - static auto op = c10::Dispatcher::singleton() - .findSchemaOrThrow("cudaImpl::yolov5_decode_forward", "") - .typed(); - return op.call( - pred_map, anchors, stride - ); -} - -TORCH_LIBRARY_FRAGMENT(cudaImpl, m) { - m.def(TORCH_SELECTIVE_SCHEMA( - "cudaImpl::yolov5_decode_forward(Tensor pred_map, Tensor anchors, int stride) -> Tensor")); -} - -PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { - m.def("yolov5_decode_forward", &yolov5_decode_forward, "yolov5_decode_forward kernel warpper"); -} - -} // namespace cudaImpl diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/setup.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/setup.py deleted file mode 100755 index a830f657e..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/setup.py +++ /dev/null @@ -1,40 +0,0 @@ -import glob -import os -from setuptools import setup -import torch -from torch.utils.cpp_extension import BuildExtension, CUDAExtension - - -def get_sources(): - cur_dir = os.path.dirname(os.path.abspath(__file__)) - csrc_dir = os.path.join(cur_dir, "csrc") - sources = glob.glob(os.path.join(csrc_dir, "*.cpp")) - cuda_sources = glob.glob(os.path.join(csrc_dir, "**", "*.cu")) - - if torch.cuda.is_available(): - sources += cuda_sources - - return sources - - -def get_include_dirs(): - cur_dir = os.path.dirname(os.path.abspath(__file__)) - csrc_dir = os.path.join(cur_dir, "csrc") - return [os.path.join(csrc_dir, "include")] - - -setup( - name='cuda_impl', - ext_modules=[ - CUDAExtension( - name="cuda_impl.yolov5_decode", - sources=get_sources(), - include_dirs=get_include_dirs() - ) - ], - cmdclass={ - "build_ext": BuildExtension - }, - include_package_data=False, - zip_safe=False -) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/yolov5_decode.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/yolov5_decode.py deleted file mode 100755 index 6a1435fa3..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/cuda_impl/yolov5_decode.py +++ /dev/null @@ -1,26 +0,0 @@ -import torch - -try: - from cuda_impl.yolov5_decode import yolov5_decode_forward -except: - from ._ext.yolov5_decode import yolov5_decode_forward - - -class YoloV5DecodeForwardFunction(torch.autograd.Function): - @staticmethod - def forward(ctx, pred_map, anchors, stride): - return yolov5_decode_forward(pred_map, anchors, stride) - - -def yolov5_decode(pred_map, anchors, stride): - num_anchors = len(anchors) // 2 - fm_shape = pred_map.shape - W = fm_shape[-1] - H = fm_shape[-2] - B = fm_shape[0] - if len(fm_shape) == 4: - pred_map = pred_map.view(B, num_anchors, -1, H, W) - # (B, num_anchors, 5+num_classses, H, W) -> (B, num_anchors, H, W, 5+num_classses) - pred_map = pred_map.permute(0, 1, 3, 4, 2).contiguous() - anchors = torch.FloatTensor(anchors).to(pred_map.device).type_as(pred_map) - return YoloV5DecodeForwardFunction.apply(pred_map, anchors, stride) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/experimental.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/experimental.py deleted file mode 100755 index dbd844dbc..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/experimental.py +++ /dev/null @@ -1,121 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Experimental modules -""" -import math - -import numpy as np -import torch -import torch.nn as nn - -from .common import Conv -from .utils.downloads import attempt_download - - -class CrossConv(nn.Module): - # Cross Convolution Downsample - def __init__(self, c1, c2, k=3, s=1, g=1, e=1.0, shortcut=False): - # ch_in, ch_out, kernel, stride, groups, expansion, shortcut - super().__init__() - c_ = int(c2 * e) # hidden channels - self.cv1 = Conv(c1, c_, (1, k), (1, s)) - self.cv2 = Conv(c_, c2, (k, 1), (s, 1), g=g) - self.add = shortcut and c1 == c2 - - def forward(self, x): - return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x)) - - -class Sum(nn.Module): - # Weighted sum of 2 or more layers https://arxiv.org/abs/1911.09070 - def __init__(self, n, weight=False): # n: number of inputs - super().__init__() - self.weight = weight # apply weights boolean - self.iter = range(n - 1) # iter object - if weight: - self.w = nn.Parameter(-torch.arange(1.0, n) / 2, requires_grad=True) # layer weights - - def forward(self, x): - y = x[0] # no weight - if self.weight: - w = torch.sigmoid(self.w) * 2 - for i in self.iter: - y = y + x[i + 1] * w[i] - else: - for i in self.iter: - y = y + x[i + 1] - return y - - -class MixConv2d(nn.Module): - # Mixed Depth-wise Conv https://arxiv.org/abs/1907.09595 - def __init__(self, c1, c2, k=(1, 3), s=1, equal_ch=True): # ch_in, ch_out, kernel, stride, ch_strategy - super().__init__() - n = len(k) # number of convolutions - if equal_ch: # equal c_ per group - i = torch.linspace(0, n - 1E-6, c2).floor() # c2 indices - c_ = [(i == g).sum() for g in range(n)] # intermediate channels - else: # equal weight.numel() per group - b = [c2] + [0] * n - a = np.eye(n + 1, n, k=-1) - a -= np.roll(a, 1, axis=1) - a *= np.array(k) ** 2 - a[0] = 1 - c_ = np.linalg.lstsq(a, b, rcond=None)[0].round() # solve for equal weight indices, ax = b - - self.m = nn.ModuleList( - [nn.Conv2d(c1, int(c_), k, s, k // 2, groups=math.gcd(c1, int(c_)), bias=False) for k, c_ in zip(k, c_)]) - self.bn = nn.BatchNorm2d(c2) - self.act = nn.SiLU() - - def forward(self, x): - return self.act(self.bn(torch.cat([m(x) for m in self.m], 1))) - - -class Ensemble(nn.ModuleList): - # Ensemble of models - def __init__(self): - super().__init__() - - def forward(self, x, augment=False, profile=False, visualize=False): - y = [] - for module in self: - y.append(module(x, augment, profile, visualize)[0]) - # y = torch.stack(y).max(0)[0] # max ensemble - # y = torch.stack(y).mean(0) # mean ensemble - y = torch.cat(y, 1) # nms ensemble - return y, None # inference, train output - - -def attempt_load(weights, map_location=None, inplace=True, fuse=True): - from .yolo import Detect, Model - - # Loads an ensemble of models weights=[a,b,c] or a single model weights=[a] or weights=a - model = Ensemble() - for w in weights if isinstance(weights, list) else [weights]: - ckpt = torch.load(attempt_download(w), map_location=map_location) # load - if fuse: - model.append(ckpt['ema' if ckpt.get('ema') else 'model'].float().fuse().eval()) # FP32 model - else: - model.append(ckpt['ema' if ckpt.get('ema') else 'model'].float().eval()) # without layer fuse - - # Compatibility updates - for m in model.modules(): - name = type(m).__name__ - # if type(m) in [nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU, Detect, Model]: - if name in ["Hardswish", "LeakyReLU", "ReLU", "ReLU6", "SiLU", "Detect", "Model"]: - m.inplace = inplace # pytorch 1.7.0 compatibility - if name == "Detect": - if not isinstance(m.anchor_grid, list): # new Detect Layer compatibility - delattr(m, 'anchor_grid') - setattr(m, 'anchor_grid', [torch.zeros(1)] * m.nl) - elif type(m) is Conv: - m._non_persistent_buffers_set = set() # pytorch 1.6.0 compatibility - if len(model) == 1: - return model[-1] # return model - else: - print(f'Ensemble created with {weights}\n') - for k in ['names']: - setattr(model, k, getattr(model[-1], k)) - model.stride = model[torch.argmax(torch.tensor([m.stride.max() for m in model])).int()].stride # max stride - return model # return ensemble diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/anchors.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/anchors.yaml deleted file mode 100755 index e4d7beb06..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/anchors.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -# Default anchors for COCO data - - -# P5 ------------------------------------------------------------------------------------------------------------------- -# P5-640: -anchors_p5_640: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - - -# P6 ------------------------------------------------------------------------------------------------------------------- -# P6-640: thr=0.25: 0.9964 BPR, 5.54 anchors past thr, n=12, img_size=640, metric_all=0.281/0.716-mean/best, past_thr=0.469-mean: 9,11, 21,19, 17,41, 43,32, 39,70, 86,64, 65,131, 134,130, 120,265, 282,180, 247,354, 512,387 -anchors_p6_640: - - [9,11, 21,19, 17,41] # P3/8 - - [43,32, 39,70, 86,64] # P4/16 - - [65,131, 134,130, 120,265] # P5/32 - - [282,180, 247,354, 512,387] # P6/64 - -# P6-1280: thr=0.25: 0.9950 BPR, 5.55 anchors past thr, n=12, img_size=1280, metric_all=0.281/0.714-mean/best, past_thr=0.468-mean: 19,27, 44,40, 38,94, 96,68, 86,152, 180,137, 140,301, 303,264, 238,542, 436,615, 739,380, 925,792 -anchors_p6_1280: - - [19,27, 44,40, 38,94] # P3/8 - - [96,68, 86,152, 180,137] # P4/16 - - [140,301, 303,264, 238,542] # P5/32 - - [436,615, 739,380, 925,792] # P6/64 - -# P6-1920: thr=0.25: 0.9950 BPR, 5.55 anchors past thr, n=12, img_size=1920, metric_all=0.281/0.714-mean/best, past_thr=0.468-mean: 28,41, 67,59, 57,141, 144,103, 129,227, 270,205, 209,452, 455,396, 358,812, 653,922, 1109,570, 1387,1187 -anchors_p6_1920: - - [28,41, 67,59, 57,141] # P3/8 - - [144,103, 129,227, 270,205] # P4/16 - - [209,452, 455,396, 358,812] # P5/32 - - [653,922, 1109,570, 1387,1187] # P6/64 - - -# P7 ------------------------------------------------------------------------------------------------------------------- -# P7-640: thr=0.25: 0.9962 BPR, 6.76 anchors past thr, n=15, img_size=640, metric_all=0.275/0.733-mean/best, past_thr=0.466-mean: 11,11, 13,30, 29,20, 30,46, 61,38, 39,92, 78,80, 146,66, 79,163, 149,150, 321,143, 157,303, 257,402, 359,290, 524,372 -anchors_p7_640: - - [11,11, 13,30, 29,20] # P3/8 - - [30,46, 61,38, 39,92] # P4/16 - - [78,80, 146,66, 79,163] # P5/32 - - [149,150, 321,143, 157,303] # P6/64 - - [257,402, 359,290, 524,372] # P7/128 - -# P7-1280: thr=0.25: 0.9968 BPR, 6.71 anchors past thr, n=15, img_size=1280, metric_all=0.273/0.732-mean/best, past_thr=0.463-mean: 19,22, 54,36, 32,77, 70,83, 138,71, 75,173, 165,159, 148,334, 375,151, 334,317, 251,626, 499,474, 750,326, 534,814, 1079,818 -anchors_p7_1280: - - [19,22, 54,36, 32,77] # P3/8 - - [70,83, 138,71, 75,173] # P4/16 - - [165,159, 148,334, 375,151] # P5/32 - - [334,317, 251,626, 499,474] # P6/64 - - [750,326, 534,814, 1079,818] # P7/128 - -# P7-1920: thr=0.25: 0.9968 BPR, 6.71 anchors past thr, n=15, img_size=1920, metric_all=0.273/0.732-mean/best, past_thr=0.463-mean: 29,34, 81,55, 47,115, 105,124, 207,107, 113,259, 247,238, 222,500, 563,227, 501,476, 376,939, 749,711, 1126,489, 801,1222, 1618,1227 -anchors_p7_1920: - - [29,34, 81,55, 47,115] # P3/8 - - [105,124, 207,107, 113,259] # P4/16 - - [247,238, 222,500, 563,227] # P5/32 - - [501,476, 376,939, 749,711] # P6/64 - - [1126,489, 801,1222, 1618,1227] # P7/128 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3-spp.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3-spp.yaml deleted file mode 100755 index c66982158..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3-spp.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# darknet53 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [32, 3, 1]], # 0 - [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 - [-1, 1, Bottleneck, [64]], - [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 - [-1, 2, Bottleneck, [128]], - [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 - [-1, 8, Bottleneck, [256]], - [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 - [-1, 8, Bottleneck, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 - [-1, 4, Bottleneck, [1024]], # 10 - ] - -# YOLOv3-SPP head -head: - [[-1, 1, Bottleneck, [1024, False]], - [-1, 1, SPP, [512, [5, 9, 13]]], - [-1, 1, Conv, [1024, 3, 1]], - [-1, 1, Conv, [512, 1, 1]], - [-1, 1, Conv, [1024, 3, 1]], # 15 (P5/32-large) - - [-2, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P4 - [-1, 1, Bottleneck, [512, False]], - [-1, 1, Bottleneck, [512, False]], - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, Conv, [512, 3, 1]], # 22 (P4/16-medium) - - [-2, 1, Conv, [128, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P3 - [-1, 1, Bottleneck, [256, False]], - [-1, 2, Bottleneck, [256, False]], # 27 (P3/8-small) - - [[27, 22, 15], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3-tiny.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3-tiny.yaml deleted file mode 100755 index b28b44315..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3-tiny.yaml +++ /dev/null @@ -1,41 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: - - [10,14, 23,27, 37,58] # P4/16 - - [81,82, 135,169, 344,319] # P5/32 - -# YOLOv3-tiny backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [16, 3, 1]], # 0 - [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 1-P1/2 - [-1, 1, Conv, [32, 3, 1]], - [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 3-P2/4 - [-1, 1, Conv, [64, 3, 1]], - [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 5-P3/8 - [-1, 1, Conv, [128, 3, 1]], - [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 7-P4/16 - [-1, 1, Conv, [256, 3, 1]], - [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 9-P5/32 - [-1, 1, Conv, [512, 3, 1]], - [-1, 1, nn.ZeroPad2d, [[0, 1, 0, 1]]], # 11 - [-1, 1, nn.MaxPool2d, [2, 1, 0]], # 12 - ] - -# YOLOv3-tiny head -head: - [[-1, 1, Conv, [1024, 3, 1]], - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, Conv, [512, 3, 1]], # 15 (P5/32-large) - - [-2, 1, Conv, [128, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P4 - [-1, 1, Conv, [256, 3, 1]], # 19 (P4/16-medium) - - [[19, 15], 1, Detect, [nc, anchors]], # Detect(P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3.yaml deleted file mode 100755 index 4f4b240e6..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov3.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# darknet53 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [32, 3, 1]], # 0 - [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 - [-1, 1, Bottleneck, [64]], - [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 - [-1, 2, Bottleneck, [128]], - [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 - [-1, 8, Bottleneck, [256]], - [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 - [-1, 8, Bottleneck, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 - [-1, 4, Bottleneck, [1024]], # 10 - ] - -# YOLOv3 head -head: - [[-1, 1, Bottleneck, [1024, False]], - [-1, 1, Conv, [512, [1, 1]]], - [-1, 1, Conv, [1024, 3, 1]], - [-1, 1, Conv, [512, 1, 1]], - [-1, 1, Conv, [1024, 3, 1]], # 15 (P5/32-large) - - [-2, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P4 - [-1, 1, Bottleneck, [512, False]], - [-1, 1, Bottleneck, [512, False]], - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, Conv, [512, 3, 1]], # 22 (P4/16-medium) - - [-2, 1, Conv, [128, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P3 - [-1, 1, Bottleneck, [256, False]], - [-1, 2, Bottleneck, [256, False]], # 27 (P3/8-small) - - [[27, 22, 15], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-bifpn.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-bifpn.yaml deleted file mode 100755 index 504815f5c..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-bifpn.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 BiFPN head -head: - [[-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 13 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 17 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 14, 6], 1, Concat, [1]], # cat P4 <--- BiFPN change - [-1, 3, C3, [512, False]], # 20 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [1024, False]], # 23 (P5/32-large) - - [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-fpn.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-fpn.yaml deleted file mode 100755 index a23e9c6fb..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-fpn.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 FPN head -head: - [[-1, 3, C3, [1024, False]], # 10 (P5/32-large) - - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 1, Conv, [512, 1, 1]], - [-1, 3, C3, [512, False]], # 14 (P4/16-medium) - - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 1, Conv, [256, 1, 1]], - [-1, 3, C3, [256, False]], # 18 (P3/8-small) - - [[18, 14, 10], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p2.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p2.yaml deleted file mode 100755 index ffe26ebad..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p2.yaml +++ /dev/null @@ -1,54 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: 3 # auto-anchor evolves 3 anchors per P output layer - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 13 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 17 (P3/8-small) - - [-1, 1, Conv, [128, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 2], 1, Concat, [1]], # cat backbone P2 - [-1, 1, C3, [128, False]], # 21 (P2/4-xsmall) - - [-1, 1, Conv, [128, 3, 2]], - [[-1, 18], 1, Concat, [1]], # cat head P3 - [-1, 3, C3, [256, False]], # 24 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 27 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [1024, False]], # 30 (P5/32-large) - - [[21, 24, 27, 30], 1, Detect, [nc, anchors]], # Detect(P2, P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p6.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p6.yaml deleted file mode 100755 index 28f3e439c..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p6.yaml +++ /dev/null @@ -1,56 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: 3 # auto-anchor 3 anchors per P output layer - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 - [-1, 3, C3, [768]], - [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 11 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [768, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P5 - [-1, 3, C3, [768, False]], # 15 - - [-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 19 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 23 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 20], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 26 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 16], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [768, False]], # 29 (P5/32-large) - - [-1, 1, Conv, [768, 3, 2]], - [[-1, 12], 1, Concat, [1]], # cat head P6 - [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) - - [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p7.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p7.yaml deleted file mode 100755 index bd2f5845f..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-p7.yaml +++ /dev/null @@ -1,67 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: 3 # auto-anchor 3 anchors per P output layer - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 - [-1, 3, C3, [768]], - [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 - [-1, 3, C3, [1024]], - [-1, 1, Conv, [1280, 3, 2]], # 11-P7/128 - [-1, 3, C3, [1280]], - [-1, 1, SPPF, [1280, 5]], # 13 - ] - -# YOLOv5 head -head: - [[-1, 1, Conv, [1024, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 10], 1, Concat, [1]], # cat backbone P6 - [-1, 3, C3, [1024, False]], # 17 - - [-1, 1, Conv, [768, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P5 - [-1, 3, C3, [768, False]], # 21 - - [-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 25 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 29 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 26], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 32 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 22], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [768, False]], # 35 (P5/32-large) - - [-1, 1, Conv, [768, 3, 2]], - [[-1, 18], 1, Concat, [1]], # cat head P6 - [-1, 3, C3, [1024, False]], # 38 (P6/64-xlarge) - - [-1, 1, Conv, [1024, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P7 - [-1, 3, C3, [1280, False]], # 41 (P7/128-xxlarge) - - [[29, 32, 35, 38, 41], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6, P7) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-panet.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-panet.yaml deleted file mode 100755 index ccfbf9006..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5-panet.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 PANet head -head: - [[-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 13 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 17 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 20 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [1024, False]], # 23 (P5/32-large) - - [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5l6.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5l6.yaml deleted file mode 100755 index 632c2cb69..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5l6.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: - - [19,27, 44,40, 38,94] # P3/8 - - [96,68, 86,152, 180,137] # P4/16 - - [140,301, 303,264, 238,542] # P5/32 - - [436,615, 739,380, 925,792] # P6/64 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 - [-1, 3, C3, [768]], - [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 11 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [768, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P5 - [-1, 3, C3, [768, False]], # 15 - - [-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 19 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 23 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 20], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 26 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 16], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [768, False]], # 29 (P5/32-large) - - [-1, 1, Conv, [768, 3, 2]], - [[-1, 12], 1, Concat, [1]], # cat head P6 - [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) - - [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5m6.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5m6.yaml deleted file mode 100755 index ecc53fd68..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5m6.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 0.67 # model depth multiple -width_multiple: 0.75 # layer channel multiple -anchors: - - [19,27, 44,40, 38,94] # P3/8 - - [96,68, 86,152, 180,137] # P4/16 - - [140,301, 303,264, 238,542] # P5/32 - - [436,615, 739,380, 925,792] # P6/64 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 - [-1, 3, C3, [768]], - [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 11 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [768, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P5 - [-1, 3, C3, [768, False]], # 15 - - [-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 19 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 23 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 20], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 26 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 16], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [768, False]], # 29 (P5/32-large) - - [-1, 1, Conv, [768, 3, 2]], - [[-1, 12], 1, Concat, [1]], # cat head P6 - [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) - - [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5n6.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5n6.yaml deleted file mode 100755 index 0c0c71d32..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5n6.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 0.33 # model depth multiple -width_multiple: 0.25 # layer channel multiple -anchors: - - [19,27, 44,40, 38,94] # P3/8 - - [96,68, 86,152, 180,137] # P4/16 - - [140,301, 303,264, 238,542] # P5/32 - - [436,615, 739,380, 925,792] # P6/64 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 - [-1, 3, C3, [768]], - [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 11 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [768, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P5 - [-1, 3, C3, [768, False]], # 15 - - [-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 19 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 23 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 20], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 26 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 16], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [768, False]], # 29 (P5/32-large) - - [-1, 1, Conv, [768, 3, 2]], - [[-1, 12], 1, Concat, [1]], # cat head P6 - [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) - - [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s-ghost.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s-ghost.yaml deleted file mode 100755 index ff9519c3f..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s-ghost.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 0.33 # model depth multiple -width_multiple: 0.50 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, GhostConv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3Ghost, [128]], - [-1, 1, GhostConv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3Ghost, [256]], - [-1, 1, GhostConv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3Ghost, [512]], - [-1, 1, GhostConv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3Ghost, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, GhostConv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3Ghost, [512, False]], # 13 - - [-1, 1, GhostConv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3Ghost, [256, False]], # 17 (P3/8-small) - - [-1, 1, GhostConv, [256, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P4 - [-1, 3, C3Ghost, [512, False]], # 20 (P4/16-medium) - - [-1, 1, GhostConv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3Ghost, [1024, False]], # 23 (P5/32-large) - - [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s-transformer.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s-transformer.yaml deleted file mode 100755 index 100d7c447..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s-transformer.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 0.33 # model depth multiple -width_multiple: 0.50 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3TR, [1024]], # 9 <--- C3TR() Transformer module - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 13 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 17 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 20 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [1024, False]], # 23 (P5/32-large) - - [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s6.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s6.yaml deleted file mode 100755 index a28fb5594..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5s6.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 0.33 # model depth multiple -width_multiple: 0.50 # layer channel multiple -anchors: - - [19,27, 44,40, 38,94] # P3/8 - - [96,68, 86,152, 180,137] # P4/16 - - [140,301, 303,264, 238,542] # P5/32 - - [436,615, 739,380, 925,792] # P6/64 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 - [-1, 3, C3, [768]], - [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 11 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [768, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P5 - [-1, 3, C3, [768, False]], # 15 - - [-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 19 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 23 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 20], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 26 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 16], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [768, False]], # 29 (P5/32-large) - - [-1, 1, Conv, [768, 3, 2]], - [[-1, 12], 1, Concat, [1]], # cat head P6 - [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) - - [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5x6.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5x6.yaml deleted file mode 100755 index ba795c4aa..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/hub/yolov5x6.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.33 # model depth multiple -width_multiple: 1.25 # layer channel multiple -anchors: - - [19,27, 44,40, 38,94] # P3/8 - - [96,68, 86,152, 180,137] # P4/16 - - [140,301, 303,264, 238,542] # P5/32 - - [436,615, 739,380, 925,792] # P6/64 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 - [-1, 3, C3, [768]], - [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 11 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [768, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 8], 1, Concat, [1]], # cat backbone P5 - [-1, 3, C3, [768, False]], # 15 - - [-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 19 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 23 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 20], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 26 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 16], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [768, False]], # 29 (P5/32-large) - - [-1, 1, Conv, [768, 3, 2]], - [[-1, 12], 1, Concat, [1]], # cat head P6 - [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) - - [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/tf.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/tf.py deleted file mode 100755 index 84359c445..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/tf.py +++ /dev/null @@ -1,464 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -TensorFlow, Keras and TFLite versions of YOLOv5 -Authored by https://github.com/zldrobit in PR https://github.com/ultralytics/yolov5/pull/1127 - -Usage: - $ python models/tf.py --weights yolov5s.pt - -Export: - $ python path/to/export.py --weights yolov5s.pt --include saved_model pb tflite tfjs -""" - -import argparse -import sys -from copy import deepcopy -from pathlib import Path - -FILE = Path(__file__).resolve() -ROOT = FILE.parents[1] # YOLOv5 root directory -if str(ROOT) not in sys.path: - sys.path.append(str(ROOT)) # add ROOT to PATH -# ROOT = ROOT.relative_to(Path.cwd()) # relative - -import numpy as np -import tensorflow as tf -import torch -import torch.nn as nn -from tensorflow import keras - -from models.common import C3, SPP, SPPF, Bottleneck, BottleneckCSP, Concat, Conv, DWConv, Focus, autopad -from models.experimental import CrossConv, MixConv2d, attempt_load -from models.yolo import Detect -from utils.activations import SiLU -from utils.general import LOGGER, make_divisible, print_args - - -class TFBN(keras.layers.Layer): - # TensorFlow BatchNormalization wrapper - def __init__(self, w=None): - super().__init__() - self.bn = keras.layers.BatchNormalization( - beta_initializer=keras.initializers.Constant(w.bias.numpy()), - gamma_initializer=keras.initializers.Constant(w.weight.numpy()), - moving_mean_initializer=keras.initializers.Constant(w.running_mean.numpy()), - moving_variance_initializer=keras.initializers.Constant(w.running_var.numpy()), - epsilon=w.eps) - - def call(self, inputs): - return self.bn(inputs) - - -class TFPad(keras.layers.Layer): - def __init__(self, pad): - super().__init__() - self.pad = tf.constant([[0, 0], [pad, pad], [pad, pad], [0, 0]]) - - def call(self, inputs): - return tf.pad(inputs, self.pad, mode='constant', constant_values=0) - - -class TFConv(keras.layers.Layer): - # Standard convolution - def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True, w=None): - # ch_in, ch_out, weights, kernel, stride, padding, groups - super().__init__() - assert g == 1, "TF v2.2 Conv2D does not support 'groups' argument" - assert isinstance(k, int), "Convolution with multiple kernels are not allowed." - # TensorFlow convolution padding is inconsistent with PyTorch (e.g. k=3 s=2 'SAME' padding) - # see https://stackoverflow.com/questions/52975843/comparing-conv2d-with-padding-between-tensorflow-and-pytorch - - conv = keras.layers.Conv2D( - c2, k, s, 'SAME' if s == 1 else 'VALID', use_bias=False if hasattr(w, 'bn') else True, - kernel_initializer=keras.initializers.Constant(w.conv.weight.permute(2, 3, 1, 0).numpy()), - bias_initializer='zeros' if hasattr(w, 'bn') else keras.initializers.Constant(w.conv.bias.numpy())) - self.conv = conv if s == 1 else keras.Sequential([TFPad(autopad(k, p)), conv]) - self.bn = TFBN(w.bn) if hasattr(w, 'bn') else tf.identity - - # YOLOv5 activations - if isinstance(w.act, nn.LeakyReLU): - self.act = (lambda x: keras.activations.relu(x, alpha=0.1)) if act else tf.identity - elif isinstance(w.act, nn.Hardswish): - self.act = (lambda x: x * tf.nn.relu6(x + 3) * 0.166666667) if act else tf.identity - elif isinstance(w.act, (nn.SiLU, SiLU)): - self.act = (lambda x: keras.activations.swish(x)) if act else tf.identity - else: - raise Exception(f'no matching TensorFlow activation found for {w.act}') - - def call(self, inputs): - return self.act(self.bn(self.conv(inputs))) - - -class TFFocus(keras.layers.Layer): - # Focus wh information into c-space - def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True, w=None): - # ch_in, ch_out, kernel, stride, padding, groups - super().__init__() - self.conv = TFConv(c1 * 4, c2, k, s, p, g, act, w.conv) - - def call(self, inputs): # x(b,w,h,c) -> y(b,w/2,h/2,4c) - # inputs = inputs / 255 # normalize 0-255 to 0-1 - return self.conv(tf.concat([inputs[:, ::2, ::2, :], - inputs[:, 1::2, ::2, :], - inputs[:, ::2, 1::2, :], - inputs[:, 1::2, 1::2, :]], 3)) - - -class TFBottleneck(keras.layers.Layer): - # Standard bottleneck - def __init__(self, c1, c2, shortcut=True, g=1, e=0.5, w=None): # ch_in, ch_out, shortcut, groups, expansion - super().__init__() - c_ = int(c2 * e) # hidden channels - self.cv1 = TFConv(c1, c_, 1, 1, w=w.cv1) - self.cv2 = TFConv(c_, c2, 3, 1, g=g, w=w.cv2) - self.add = shortcut and c1 == c2 - - def call(self, inputs): - return inputs + self.cv2(self.cv1(inputs)) if self.add else self.cv2(self.cv1(inputs)) - - -class TFConv2d(keras.layers.Layer): - # Substitution for PyTorch nn.Conv2D - def __init__(self, c1, c2, k, s=1, g=1, bias=True, w=None): - super().__init__() - assert g == 1, "TF v2.2 Conv2D does not support 'groups' argument" - self.conv = keras.layers.Conv2D( - c2, k, s, 'VALID', use_bias=bias, - kernel_initializer=keras.initializers.Constant(w.weight.permute(2, 3, 1, 0).numpy()), - bias_initializer=keras.initializers.Constant(w.bias.numpy()) if bias else None, ) - - def call(self, inputs): - return self.conv(inputs) - - -class TFBottleneckCSP(keras.layers.Layer): - # CSP Bottleneck https://github.com/WongKinYiu/CrossStagePartialNetworks - def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5, w=None): - # ch_in, ch_out, number, shortcut, groups, expansion - super().__init__() - c_ = int(c2 * e) # hidden channels - self.cv1 = TFConv(c1, c_, 1, 1, w=w.cv1) - self.cv2 = TFConv2d(c1, c_, 1, 1, bias=False, w=w.cv2) - self.cv3 = TFConv2d(c_, c_, 1, 1, bias=False, w=w.cv3) - self.cv4 = TFConv(2 * c_, c2, 1, 1, w=w.cv4) - self.bn = TFBN(w.bn) - self.act = lambda x: keras.activations.relu(x, alpha=0.1) - self.m = keras.Sequential([TFBottleneck(c_, c_, shortcut, g, e=1.0, w=w.m[j]) for j in range(n)]) - - def call(self, inputs): - y1 = self.cv3(self.m(self.cv1(inputs))) - y2 = self.cv2(inputs) - return self.cv4(self.act(self.bn(tf.concat((y1, y2), axis=3)))) - - -class TFC3(keras.layers.Layer): - # CSP Bottleneck with 3 convolutions - def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5, w=None): - # ch_in, ch_out, number, shortcut, groups, expansion - super().__init__() - c_ = int(c2 * e) # hidden channels - self.cv1 = TFConv(c1, c_, 1, 1, w=w.cv1) - self.cv2 = TFConv(c1, c_, 1, 1, w=w.cv2) - self.cv3 = TFConv(2 * c_, c2, 1, 1, w=w.cv3) - self.m = keras.Sequential([TFBottleneck(c_, c_, shortcut, g, e=1.0, w=w.m[j]) for j in range(n)]) - - def call(self, inputs): - return self.cv3(tf.concat((self.m(self.cv1(inputs)), self.cv2(inputs)), axis=3)) - - -class TFSPP(keras.layers.Layer): - # Spatial pyramid pooling layer used in YOLOv3-SPP - def __init__(self, c1, c2, k=(5, 9, 13), w=None): - super().__init__() - c_ = c1 // 2 # hidden channels - self.cv1 = TFConv(c1, c_, 1, 1, w=w.cv1) - self.cv2 = TFConv(c_ * (len(k) + 1), c2, 1, 1, w=w.cv2) - self.m = [keras.layers.MaxPool2D(pool_size=x, strides=1, padding='SAME') for x in k] - - def call(self, inputs): - x = self.cv1(inputs) - return self.cv2(tf.concat([x] + [m(x) for m in self.m], 3)) - - -class TFSPPF(keras.layers.Layer): - # Spatial pyramid pooling-Fast layer - def __init__(self, c1, c2, k=5, w=None): - super().__init__() - c_ = c1 // 2 # hidden channels - self.cv1 = TFConv(c1, c_, 1, 1, w=w.cv1) - self.cv2 = TFConv(c_ * 4, c2, 1, 1, w=w.cv2) - self.m = keras.layers.MaxPool2D(pool_size=k, strides=1, padding='SAME') - - def call(self, inputs): - x = self.cv1(inputs) - y1 = self.m(x) - y2 = self.m(y1) - return self.cv2(tf.concat([x, y1, y2, self.m(y2)], 3)) - - -class TFDetect(keras.layers.Layer): - def __init__(self, nc=80, anchors=(), ch=(), imgsz=(640, 640), w=None): # detection layer - super().__init__() - self.stride = tf.convert_to_tensor(w.stride.numpy(), dtype=tf.float32) - self.nc = nc # number of classes - self.no = nc + 5 # number of outputs per anchor - self.nl = len(anchors) # number of detection layers - self.na = len(anchors[0]) // 2 # number of anchors - self.grid = [tf.zeros(1)] * self.nl # init grid - self.anchors = tf.convert_to_tensor(w.anchors.numpy(), dtype=tf.float32) - self.anchor_grid = tf.reshape(self.anchors * tf.reshape(self.stride, [self.nl, 1, 1]), - [self.nl, 1, -1, 1, 2]) - self.m = [TFConv2d(x, self.no * self.na, 1, w=w.m[i]) for i, x in enumerate(ch)] - self.training = False # set to False after building model - self.imgsz = imgsz - for i in range(self.nl): - ny, nx = self.imgsz[0] // self.stride[i], self.imgsz[1] // self.stride[i] - self.grid[i] = self._make_grid(nx, ny) - - def call(self, inputs): - z = [] # inference output - x = [] - for i in range(self.nl): - x.append(self.m[i](inputs[i])) - # x(bs,20,20,255) to x(bs,3,20,20,85) - ny, nx = self.imgsz[0] // self.stride[i], self.imgsz[1] // self.stride[i] - x[i] = tf.transpose(tf.reshape(x[i], [-1, ny * nx, self.na, self.no]), [0, 2, 1, 3]) - - if not self.training: # inference - y = tf.sigmoid(x[i]) - xy = (y[..., 0:2] * 2 - 0.5 + self.grid[i]) * self.stride[i] # xy - wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] - # Normalize xywh to 0-1 to reduce calibration error - xy /= tf.constant([[self.imgsz[1], self.imgsz[0]]], dtype=tf.float32) - wh /= tf.constant([[self.imgsz[1], self.imgsz[0]]], dtype=tf.float32) - y = tf.concat([xy, wh, y[..., 4:]], -1) - z.append(tf.reshape(y, [-1, self.na * ny * nx, self.no])) - - return x if self.training else (tf.concat(z, 1), x) - - @staticmethod - def _make_grid(nx=20, ny=20): - # yv, xv = torch.meshgrid([torch.arange(ny), torch.arange(nx)]) - # return torch.stack((xv, yv), 2).view((1, 1, ny, nx, 2)).float() - xv, yv = tf.meshgrid(tf.range(nx), tf.range(ny)) - return tf.cast(tf.reshape(tf.stack([xv, yv], 2), [1, 1, ny * nx, 2]), dtype=tf.float32) - - -class TFUpsample(keras.layers.Layer): - def __init__(self, size, scale_factor, mode, w=None): # warning: all arguments needed including 'w' - super().__init__() - assert scale_factor == 2, "scale_factor must be 2" - self.upsample = lambda x: tf.image.resize(x, (x.shape[1] * 2, x.shape[2] * 2), method=mode) - # self.upsample = keras.layers.UpSampling2D(size=scale_factor, interpolation=mode) - # with default arguments: align_corners=False, half_pixel_centers=False - # self.upsample = lambda x: tf.raw_ops.ResizeNearestNeighbor(images=x, - # size=(x.shape[1] * 2, x.shape[2] * 2)) - - def call(self, inputs): - return self.upsample(inputs) - - -class TFConcat(keras.layers.Layer): - def __init__(self, dimension=1, w=None): - super().__init__() - assert dimension == 1, "convert only NCHW to NHWC concat" - self.d = 3 - - def call(self, inputs): - return tf.concat(inputs, self.d) - - -def parse_model(d, ch, model, imgsz): # model_dict, input_channels(3) - LOGGER.info(f"\n{'':>3}{'from':>18}{'n':>3}{'params':>10} {'module':<40}{'arguments':<30}") - anchors, nc, gd, gw = d['anchors'], d['nc'], d['depth_multiple'], d['width_multiple'] - na = (len(anchors[0]) // 2) if isinstance(anchors, list) else anchors # number of anchors - no = na * (nc + 5) # number of outputs = anchors * (classes + 5) - - layers, save, c2 = [], [], ch[-1] # layers, savelist, ch out - for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']): # from, number, module, args - m_str = m - m = eval(m) if isinstance(m, str) else m # eval strings - for j, a in enumerate(args): - try: - args[j] = eval(a) if isinstance(a, str) else a # eval strings - except NameError: - pass - - n = max(round(n * gd), 1) if n > 1 else n # depth gain - if m in [nn.Conv2d, Conv, Bottleneck, SPP, SPPF, DWConv, MixConv2d, Focus, CrossConv, BottleneckCSP, C3]: - c1, c2 = ch[f], args[0] - c2 = make_divisible(c2 * gw, 8) if c2 != no else c2 - - args = [c1, c2, *args[1:]] - if m in [BottleneckCSP, C3]: - args.insert(2, n) - n = 1 - elif m is nn.BatchNorm2d: - args = [ch[f]] - elif m is Concat: - c2 = sum(ch[-1 if x == -1 else x + 1] for x in f) - elif m is Detect: - args.append([ch[x + 1] for x in f]) - if isinstance(args[1], int): # number of anchors - args[1] = [list(range(args[1] * 2))] * len(f) - args.append(imgsz) - else: - c2 = ch[f] - - tf_m = eval('TF' + m_str.replace('nn.', '')) - m_ = keras.Sequential([tf_m(*args, w=model.model[i][j]) for j in range(n)]) if n > 1 \ - else tf_m(*args, w=model.model[i]) # module - - torch_m_ = nn.Sequential(*(m(*args) for _ in range(n))) if n > 1 else m(*args) # module - t = str(m)[8:-2].replace('__main__.', '') # module type - np = sum(x.numel() for x in torch_m_.parameters()) # number params - m_.i, m_.f, m_.type, m_.np = i, f, t, np # attach index, 'from' index, type, number params - LOGGER.info(f'{i:>3}{str(f):>18}{str(n):>3}{np:>10} {t:<40}{str(args):<30}') # print - save.extend(x % i for x in ([f] if isinstance(f, int) else f) if x != -1) # append to savelist - layers.append(m_) - ch.append(c2) - return keras.Sequential(layers), sorted(save) - - -class TFModel: - def __init__(self, cfg='yolov5s.yaml', ch=3, nc=None, model=None, imgsz=(640, 640)): # model, channels, classes - super().__init__() - if isinstance(cfg, dict): - self.yaml = cfg # model dict - else: # is *.yaml - import yaml # for torch hub - self.yaml_file = Path(cfg).name - with open(cfg) as f: - self.yaml = yaml.load(f, Loader=yaml.FullLoader) # model dict - - # Define model - if nc and nc != self.yaml['nc']: - LOGGER.info(f"Overriding {cfg} nc={self.yaml['nc']} with nc={nc}") - self.yaml['nc'] = nc # override yaml value - self.model, self.savelist = parse_model(deepcopy(self.yaml), ch=[ch], model=model, imgsz=imgsz) - - def predict(self, inputs, tf_nms=False, agnostic_nms=False, topk_per_class=100, topk_all=100, iou_thres=0.45, - conf_thres=0.25): - y = [] # outputs - x = inputs - for i, m in enumerate(self.model.layers): - if m.f != -1: # if not from previous layer - x = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f] # from earlier layers - - x = m(x) # run - y.append(x if m.i in self.savelist else None) # save output - - # Add TensorFlow NMS - if tf_nms: - boxes = self._xywh2xyxy(x[0][..., :4]) - probs = x[0][:, :, 4:5] - classes = x[0][:, :, 5:] - scores = probs * classes - if agnostic_nms: - nms = AgnosticNMS()((boxes, classes, scores), topk_all, iou_thres, conf_thres) - return nms, x[1] - else: - boxes = tf.expand_dims(boxes, 2) - nms = tf.image.combined_non_max_suppression( - boxes, scores, topk_per_class, topk_all, iou_thres, conf_thres, clip_boxes=False) - return nms, x[1] - - return x[0] # output only first tensor [1,6300,85] = [xywh, conf, class0, class1, ...] - # x = x[0][0] # [x(1,6300,85), ...] to x(6300,85) - # xywh = x[..., :4] # x(6300,4) boxes - # conf = x[..., 4:5] # x(6300,1) confidences - # cls = tf.reshape(tf.cast(tf.argmax(x[..., 5:], axis=1), tf.float32), (-1, 1)) # x(6300,1) classes - # return tf.concat([conf, cls, xywh], 1) - - @staticmethod - def _xywh2xyxy(xywh): - # Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right - x, y, w, h = tf.split(xywh, num_or_size_splits=4, axis=-1) - return tf.concat([x - w / 2, y - h / 2, x + w / 2, y + h / 2], axis=-1) - - -class AgnosticNMS(keras.layers.Layer): - # TF Agnostic NMS - def call(self, input, topk_all, iou_thres, conf_thres): - # wrap map_fn to avoid TypeSpec related error https://stackoverflow.com/a/65809989/3036450 - return tf.map_fn(lambda x: self._nms(x, topk_all, iou_thres, conf_thres), input, - fn_output_signature=(tf.float32, tf.float32, tf.float32, tf.int32), - name='agnostic_nms') - - @staticmethod - def _nms(x, topk_all=100, iou_thres=0.45, conf_thres=0.25): # agnostic NMS - boxes, classes, scores = x - class_inds = tf.cast(tf.argmax(classes, axis=-1), tf.float32) - scores_inp = tf.reduce_max(scores, -1) - selected_inds = tf.image.non_max_suppression( - boxes, scores_inp, max_output_size=topk_all, iou_threshold=iou_thres, score_threshold=conf_thres) - selected_boxes = tf.gather(boxes, selected_inds) - padded_boxes = tf.pad(selected_boxes, - paddings=[[0, topk_all - tf.shape(selected_boxes)[0]], [0, 0]], - mode="CONSTANT", constant_values=0.0) - selected_scores = tf.gather(scores_inp, selected_inds) - padded_scores = tf.pad(selected_scores, - paddings=[[0, topk_all - tf.shape(selected_boxes)[0]]], - mode="CONSTANT", constant_values=-1.0) - selected_classes = tf.gather(class_inds, selected_inds) - padded_classes = tf.pad(selected_classes, - paddings=[[0, topk_all - tf.shape(selected_boxes)[0]]], - mode="CONSTANT", constant_values=-1.0) - valid_detections = tf.shape(selected_inds)[0] - return padded_boxes, padded_scores, padded_classes, valid_detections - - -def representative_dataset_gen(dataset, ncalib=100): - # Representative dataset generator for use with converter.representative_dataset, returns a generator of np arrays - for n, (path, img, im0s, vid_cap, string) in enumerate(dataset): - input = np.transpose(img, [1, 2, 0]) - input = np.expand_dims(input, axis=0).astype(np.float32) - input /= 255 - yield [input] - if n >= ncalib: - break - - -def run(weights=ROOT / 'yolov5s.pt', # weights path - imgsz=(640, 640), # inference size h,w - batch_size=1, # batch size - dynamic=False, # dynamic batch size - ): - # PyTorch model - im = torch.zeros((batch_size, 3, *imgsz)) # BCHW image - model = attempt_load(weights, map_location=torch.device('cpu'), inplace=True, fuse=False) - y = model(im) # inference - model.info() - - # TensorFlow model - im = tf.zeros((batch_size, *imgsz, 3)) # BHWC image - tf_model = TFModel(cfg=model.yaml, model=model, nc=model.nc, imgsz=imgsz) - y = tf_model.predict(im) # inference - - # Keras model - im = keras.Input(shape=(*imgsz, 3), batch_size=None if dynamic else batch_size) - keras_model = keras.Model(inputs=im, outputs=tf_model.predict(im)) - keras_model.summary() - - LOGGER.info('PyTorch, TensorFlow and Keras models successfully verified.\nUse export.py for TF model export.') - - -def parse_opt(): - parser = argparse.ArgumentParser() - parser.add_argument('--weights', type=str, default=ROOT / 'yolov5s.pt', help='weights path') - parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[640], help='inference size h,w') - parser.add_argument('--batch-size', type=int, default=1, help='batch size') - parser.add_argument('--dynamic', action='store_true', help='dynamic batch size') - opt = parser.parse_args() - opt.imgsz *= 2 if len(opt.imgsz) == 1 else 1 # expand - print_args(FILE.stem, opt) - return opt - - -def main(opt): - run(**vars(opt)) - - -if __name__ == "__main__": - opt = parse_opt() - main(opt) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/__init__.py deleted file mode 100755 index 295aebfbc..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/__init__.py +++ /dev/null @@ -1,37 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -utils/initialization -""" - - -def notebook_init(verbose=True): - # Check system software and hardware - print('Checking setup...') - - import os - import shutil - - from utils.general import check_requirements, emojis, is_colab - from utils.torch_utils import select_device # imports - - check_requirements(('psutil', 'IPython')) - import psutil - from IPython import display # to display images and clear console output - - if is_colab(): - shutil.rmtree('/content/sample_data', ignore_errors=True) # remove colab /sample_data directory - - if verbose: - # System info - # gb = 1 / 1000 ** 3 # bytes to GB - gib = 1 / 1024 ** 3 # bytes to GiB - ram = psutil.virtual_memory().total - total, used, free = shutil.disk_usage("/") - display.clear_output() - s = f'({os.cpu_count()} CPUs, {ram * gib:.1f} GB RAM, {(total - free) * gib:.1f}/{total * gib:.1f} GB disk)' - else: - s = '' - - select_device(newline=False) - print(emojis(f'Setup complete ✅ {s}')) - return display diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/activations.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/activations.py deleted file mode 100755 index a4ff789cf..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/activations.py +++ /dev/null @@ -1,101 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Activation functions -""" - -import torch -import torch.nn as nn -import torch.nn.functional as F - - -# SiLU https://arxiv.org/pdf/1606.08415.pdf ---------------------------------------------------------------------------- -class SiLU(nn.Module): # export-friendly version of nn.SiLU() - @staticmethod - def forward(x): - return x * torch.sigmoid(x) - - -class Hardswish(nn.Module): # export-friendly version of nn.Hardswish() - @staticmethod - def forward(x): - # return x * F.hardsigmoid(x) # for TorchScript and CoreML - return x * F.hardtanh(x + 3, 0.0, 6.0) / 6.0 # for TorchScript, CoreML and ONNX - - -# Mish https://github.com/digantamisra98/Mish -------------------------------------------------------------------------- -class Mish(nn.Module): - @staticmethod - def forward(x): - return x * F.softplus(x).tanh() - - -class MemoryEfficientMish(nn.Module): - class F(torch.autograd.Function): - @staticmethod - def forward(ctx, x): - ctx.save_for_backward(x) - return x.mul(torch.tanh(F.softplus(x))) # x * tanh(ln(1 + exp(x))) - - @staticmethod - def backward(ctx, grad_output): - x = ctx.saved_tensors[0] - sx = torch.sigmoid(x) - fx = F.softplus(x).tanh() - return grad_output * (fx + x * sx * (1 - fx * fx)) - - def forward(self, x): - return self.F.apply(x) - - -# FReLU https://arxiv.org/abs/2007.11824 ------------------------------------------------------------------------------- -class FReLU(nn.Module): - def __init__(self, c1, k=3): # ch_in, kernel - super().__init__() - self.conv = nn.Conv2d(c1, c1, k, 1, 1, groups=c1, bias=False) - self.bn = nn.BatchNorm2d(c1) - - def forward(self, x): - return torch.max(x, self.bn(self.conv(x))) - - -# ACON https://arxiv.org/pdf/2009.04759.pdf ---------------------------------------------------------------------------- -class AconC(nn.Module): - r""" ACON activation (activate or not). - AconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is a learnable parameter - according to "Activate or Not: Learning Customized Activation" . - """ - - def __init__(self, c1): - super().__init__() - self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1)) - self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1)) - self.beta = nn.Parameter(torch.ones(1, c1, 1, 1)) - - def forward(self, x): - dpx = (self.p1 - self.p2) * x - return dpx * torch.sigmoid(self.beta * dpx) + self.p2 * x - - -class MetaAconC(nn.Module): - r""" ACON activation (activate or not). - MetaAconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is generated by a small network - according to "Activate or Not: Learning Customized Activation" . - """ - - def __init__(self, c1, k=1, s=1, r=16): # ch_in, kernel, stride, r - super().__init__() - c2 = max(r, c1 // r) - self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1)) - self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1)) - self.fc1 = nn.Conv2d(c1, c2, k, s, bias=True) - self.fc2 = nn.Conv2d(c2, c1, k, s, bias=True) - # self.bn1 = nn.BatchNorm2d(c2) - # self.bn2 = nn.BatchNorm2d(c1) - - def forward(self, x): - y = x.mean(dim=2, keepdims=True).mean(dim=3, keepdims=True) - # batch-size 1 bug/instabilities https://github.com/ultralytics/yolov5/issues/2891 - # beta = torch.sigmoid(self.bn2(self.fc2(self.bn1(self.fc1(y))))) # bug/unstable - beta = torch.sigmoid(self.fc2(self.fc1(y))) # bug patch BN layers removed - dpx = (self.p1 - self.p2) * x - return dpx * torch.sigmoid(beta * dpx) + self.p2 * x diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/augmentations.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/augmentations.py deleted file mode 100755 index 7b5b7785f..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/augmentations.py +++ /dev/null @@ -1,277 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Image augmentation functions -""" - -import math -import random - -import cv2 -import numpy as np - -from .general import LOGGER, check_version, colorstr, resample_segments, segment2box -from .metrics import bbox_ioa - - -class Albumentations: - # YOLOv5 Albumentations class (optional, only used if package is installed) - def __init__(self): - self.transform = None - try: - import albumentations as A - check_version(A.__version__, '1.0.3', hard=True) # version requirement - - self.transform = A.Compose([ - A.Blur(p=0.01), - A.MedianBlur(p=0.01), - A.ToGray(p=0.01), - A.CLAHE(p=0.01), - A.RandomBrightnessContrast(p=0.0), - A.RandomGamma(p=0.0), - A.ImageCompression(quality_lower=75, p=0.0)], - bbox_params=A.BboxParams(format='yolo', label_fields=['class_labels'])) - - LOGGER.info(colorstr('albumentations: ') + ', '.join(f'{x}' for x in self.transform.transforms if x.p)) - except ImportError: # package not installed, skip - pass - except Exception as e: - LOGGER.info(colorstr('albumentations: ') + f'{e}') - - def __call__(self, im, labels, p=1.0): - if self.transform and random.random() < p: - new = self.transform(image=im, bboxes=labels[:, 1:], class_labels=labels[:, 0]) # transformed - im, labels = new['image'], np.array([[c, *b] for c, b in zip(new['class_labels'], new['bboxes'])]) - return im, labels - - -def augment_hsv(im, hgain=0.5, sgain=0.5, vgain=0.5): - # HSV color-space augmentation - if hgain or sgain or vgain: - r = np.random.uniform(-1, 1, 3) * [hgain, sgain, vgain] + 1 # random gains - hue, sat, val = cv2.split(cv2.cvtColor(im, cv2.COLOR_BGR2HSV)) - dtype = im.dtype # uint8 - - x = np.arange(0, 256, dtype=r.dtype) - lut_hue = ((x * r[0]) % 180).astype(dtype) - lut_sat = np.clip(x * r[1], 0, 255).astype(dtype) - lut_val = np.clip(x * r[2], 0, 255).astype(dtype) - - im_hsv = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val))) - cv2.cvtColor(im_hsv, cv2.COLOR_HSV2BGR, dst=im) # no return needed - - -def hist_equalize(im, clahe=True, bgr=False): - # Equalize histogram on BGR image 'im' with im.shape(n,m,3) and range 0-255 - yuv = cv2.cvtColor(im, cv2.COLOR_BGR2YUV if bgr else cv2.COLOR_RGB2YUV) - if clahe: - c = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) - yuv[:, :, 0] = c.apply(yuv[:, :, 0]) - else: - yuv[:, :, 0] = cv2.equalizeHist(yuv[:, :, 0]) # equalize Y channel histogram - return cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR if bgr else cv2.COLOR_YUV2RGB) # convert YUV image to RGB - - -def replicate(im, labels): - # Replicate labels - h, w = im.shape[:2] - boxes = labels[:, 1:].astype(int) - x1, y1, x2, y2 = boxes.T - s = ((x2 - x1) + (y2 - y1)) / 2 # side length (pixels) - for i in s.argsort()[:round(s.size * 0.5)]: # smallest indices - x1b, y1b, x2b, y2b = boxes[i] - bh, bw = y2b - y1b, x2b - x1b - yc, xc = int(random.uniform(0, h - bh)), int(random.uniform(0, w - bw)) # offset x, y - x1a, y1a, x2a, y2a = [xc, yc, xc + bw, yc + bh] - im[y1a:y2a, x1a:x2a] = im[y1b:y2b, x1b:x2b] # im4[ymin:ymax, xmin:xmax] - labels = np.append(labels, [[labels[i, 0], x1a, y1a, x2a, y2a]], axis=0) - - return im, labels - - -def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32): - # Resize and pad image while meeting stride-multiple constraints - shape = im.shape[:2] # current shape [height, width] - if isinstance(new_shape, int): - new_shape = (new_shape, new_shape) - - # Scale ratio (new / old) - r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) - if not scaleup: # only scale down, do not scale up (for better val mAP) - r = min(r, 1.0) - - # Compute padding - ratio = r, r # width, height ratios - new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) - dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding - if auto: # minimum rectangle - dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding - elif scaleFill: # stretch - dw, dh = 0.0, 0.0 - new_unpad = (new_shape[1], new_shape[0]) - ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios - - dw /= 2 # divide padding into 2 sides - dh /= 2 - - if shape[::-1] != new_unpad: # resize - im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR) - top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) - left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) - im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border - return im, ratio, (dw, dh) - - -def random_perspective(im, targets=(), segments=(), degrees=10, translate=.1, scale=.1, shear=10, perspective=0.0, - border=(0, 0)): - # torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(0.1, 0.1), scale=(0.9, 1.1), shear=(-10, 10)) - # targets = [cls, xyxy] - - height = im.shape[0] + border[0] * 2 # shape(h,w,c) - width = im.shape[1] + border[1] * 2 - - # Center - C = np.eye(3) - C[0, 2] = -im.shape[1] / 2 # x translation (pixels) - C[1, 2] = -im.shape[0] / 2 # y translation (pixels) - - # Perspective - P = np.eye(3) - P[2, 0] = random.uniform(-perspective, perspective) # x perspective (about y) - P[2, 1] = random.uniform(-perspective, perspective) # y perspective (about x) - - # Rotation and Scale - R = np.eye(3) - a = random.uniform(-degrees, degrees) - # a += random.choice([-180, -90, 0, 90]) # add 90deg rotations to small rotations - s = random.uniform(1 - scale, 1 + scale) - # s = 2 ** random.uniform(-scale, scale) - R[:2] = cv2.getRotationMatrix2D(angle=a, center=(0, 0), scale=s) - - # Shear - S = np.eye(3) - S[0, 1] = math.tan(random.uniform(-shear, shear) * math.pi / 180) # x shear (deg) - S[1, 0] = math.tan(random.uniform(-shear, shear) * math.pi / 180) # y shear (deg) - - # Translation - T = np.eye(3) - T[0, 2] = random.uniform(0.5 - translate, 0.5 + translate) * width # x translation (pixels) - T[1, 2] = random.uniform(0.5 - translate, 0.5 + translate) * height # y translation (pixels) - - # Combined rotation matrix - M = T @ S @ R @ P @ C # order of operations (right to left) is IMPORTANT - if (border[0] != 0) or (border[1] != 0) or (M != np.eye(3)).any(): # image changed - if perspective: - im = cv2.warpPerspective(im, M, dsize=(width, height), borderValue=(114, 114, 114)) - else: # affine - im = cv2.warpAffine(im, M[:2], dsize=(width, height), borderValue=(114, 114, 114)) - - # Visualize - # import matplotlib.pyplot as plt - # ax = plt.subplots(1, 2, figsize=(12, 6))[1].ravel() - # ax[0].imshow(im[:, :, ::-1]) # base - # ax[1].imshow(im2[:, :, ::-1]) # warped - - # Transform label coordinates - n = len(targets) - if n: - use_segments = any(x.any() for x in segments) - new = np.zeros((n, 4)) - if use_segments: # warp segments - segments = resample_segments(segments) # upsample - for i, segment in enumerate(segments): - xy = np.ones((len(segment), 3)) - xy[:, :2] = segment - xy = xy @ M.T # transform - xy = xy[:, :2] / xy[:, 2:3] if perspective else xy[:, :2] # perspective rescale or affine - - # clip - new[i] = segment2box(xy, width, height) - - else: # warp boxes - xy = np.ones((n * 4, 3)) - xy[:, :2] = targets[:, [1, 2, 3, 4, 1, 4, 3, 2]].reshape(n * 4, 2) # x1y1, x2y2, x1y2, x2y1 - xy = xy @ M.T # transform - xy = (xy[:, :2] / xy[:, 2:3] if perspective else xy[:, :2]).reshape(n, 8) # perspective rescale or affine - - # create new boxes - x = xy[:, [0, 2, 4, 6]] - y = xy[:, [1, 3, 5, 7]] - new = np.concatenate((x.min(1), y.min(1), x.max(1), y.max(1))).reshape(4, n).T - - # clip - new[:, [0, 2]] = new[:, [0, 2]].clip(0, width) - new[:, [1, 3]] = new[:, [1, 3]].clip(0, height) - - # filter candidates - i = box_candidates(box1=targets[:, 1:5].T * s, box2=new.T, area_thr=0.01 if use_segments else 0.10) - targets = targets[i] - targets[:, 1:5] = new[i] - - return im, targets - - -def copy_paste(im, labels, segments, p=0.5): - # Implement Copy-Paste augmentation https://arxiv.org/abs/2012.07177, labels as nx5 np.array(cls, xyxy) - n = len(segments) - if p and n: - h, w, c = im.shape # height, width, channels - im_new = np.zeros(im.shape, np.uint8) - for j in random.sample(range(n), k=round(p * n)): - l, s = labels[j], segments[j] - box = w - l[3], l[2], w - l[1], l[4] - ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area - if (ioa < 0.30).all(): # allow 30% obscuration of existing labels - labels = np.concatenate((labels, [[l[0], *box]]), 0) - segments.append(np.concatenate((w - s[:, 0:1], s[:, 1:2]), 1)) - cv2.drawContours(im_new, [segments[j].astype(np.int32)], -1, (255, 255, 255), cv2.FILLED) - - result = cv2.bitwise_and(src1=im, src2=im_new) - result = cv2.flip(result, 1) # augment segments (flip left-right) - i = result > 0 # pixels to replace - # i[:, :] = result.max(2).reshape(h, w, 1) # act over ch - im[i] = result[i] # cv2.imwrite('debug.jpg', im) # debug - - return im, labels, segments - - -def cutout(im, labels, p=0.5): - # Applies image cutout augmentation https://arxiv.org/abs/1708.04552 - if random.random() < p: - h, w = im.shape[:2] - scales = [0.5] * 1 + [0.25] * 2 + [0.125] * 4 + [0.0625] * 8 + [0.03125] * 16 # image size fraction - for s in scales: - mask_h = random.randint(1, int(h * s)) # create random masks - mask_w = random.randint(1, int(w * s)) - - # box - xmin = max(0, random.randint(0, w) - mask_w // 2) - ymin = max(0, random.randint(0, h) - mask_h // 2) - xmax = min(w, xmin + mask_w) - ymax = min(h, ymin + mask_h) - - # apply random color mask - im[ymin:ymax, xmin:xmax] = [random.randint(64, 191) for _ in range(3)] - - # return unobscured labels - if len(labels) and s > 0.03: - box = np.array([xmin, ymin, xmax, ymax], dtype=np.float32) - ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area - labels = labels[ioa < 0.60] # remove >60% obscured labels - - return labels - - -def mixup(im, labels, im2, labels2): - # Applies MixUp augmentation https://arxiv.org/pdf/1710.09412.pdf - r = np.random.beta(32.0, 32.0) # mixup ratio, alpha=beta=32.0 - im = (im * r + im2 * (1 - r)).astype(np.uint8) - labels = np.concatenate((labels, labels2), 0) - return im, labels - - -def box_candidates(box1, box2, wh_thr=2, ar_thr=20, area_thr=0.1, eps=1e-16): # box1(4,n), box2(4,n) - # Compute candidate boxes: box1 before augment, box2 after augment, wh_thr (pixels), aspect_ratio_thr, area_ratio - w1, h1 = box1[2] - box1[0], box1[3] - box1[1] - w2, h2 = box2[2] - box2[0], box2[3] - box2[1] - ar = np.maximum(w2 / (h2 + eps), h2 / (w2 + eps)) # aspect ratio - return (w2 > wh_thr) & (h2 > wh_thr) & (w2 * h2 / (w1 * h1 + eps) > area_thr) & (ar < ar_thr) # candidates diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/autoanchor.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/autoanchor.py deleted file mode 100755 index 169faf118..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/autoanchor.py +++ /dev/null @@ -1,164 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Auto-anchor utils -""" - -import random - -import numpy as np -import torch -import yaml -from tqdm import tqdm - -from .general import LOGGER, colorstr, emojis - -PREFIX = colorstr('AutoAnchor: ') - - -def check_anchor_order(m): - # Check anchor order against stride order for YOLOv5 Detect() module m, and correct if necessary - a = m.anchors.prod(-1).view(-1) # anchor area - da = a[-1] - a[0] # delta a - ds = m.stride[-1] - m.stride[0] # delta s - if da.sign() != ds.sign(): # same order - LOGGER.info(f'{PREFIX}Reversing anchor order') - m.anchors[:] = m.anchors.flip(0) - - -def check_anchors(dataset, model, thr=4.0, imgsz=640): - # Check anchor fit to data, recompute if necessary - m = model.module.model[-1] if hasattr(model, 'module') else model.model[-1] # Detect() - shapes = imgsz * dataset.shapes / dataset.shapes.max(1, keepdims=True) - scale = np.random.uniform(0.9, 1.1, size=(shapes.shape[0], 1)) # augment scale - wh = torch.tensor(np.concatenate([l[:, 3:5] * s for s, l in zip(shapes * scale, dataset.labels)])).float() # wh - - def metric(k): # compute metric - r = wh[:, None] / k[None] - x = torch.min(r, 1 / r).min(2)[0] # ratio metric - best = x.max(1)[0] # best_x - aat = (x > 1 / thr).float().sum(1).mean() # anchors above threshold - bpr = (best > 1 / thr).float().mean() # best possible recall - return bpr, aat - - anchors = m.anchors.clone() * m.stride.to(m.anchors.device).view(-1, 1, 1) # current anchors - bpr, aat = metric(anchors.cpu().view(-1, 2)) - s = f'\n{PREFIX}{aat:.2f} anchors/target, {bpr:.3f} Best Possible Recall (BPR). ' - if bpr > 0.98: # threshold to recompute - LOGGER.info(emojis(f'{s}Current anchors are a good fit to dataset ✅')) - else: - LOGGER.info(emojis(f'{s}Anchors are a poor fit to dataset ⚠️, attempting to improve...')) - na = m.anchors.numel() // 2 # number of anchors - try: - anchors = kmean_anchors(dataset, n=na, img_size=imgsz, thr=thr, gen=1000, verbose=False) - except Exception as e: - LOGGER.info(f'{PREFIX}ERROR: {e}') - new_bpr = metric(anchors)[0] - if new_bpr > bpr: # replace anchors - anchors = torch.tensor(anchors, device=m.anchors.device).type_as(m.anchors) - m.anchors[:] = anchors.clone().view_as(m.anchors) / m.stride.to(m.anchors.device).view(-1, 1, 1) # loss - check_anchor_order(m) - LOGGER.info(f'{PREFIX}New anchors saved to model. Update model *.yaml to use these anchors in the future.') - else: - LOGGER.info(f'{PREFIX}Original anchors better than new anchors. Proceeding with original anchors.') - - -def kmean_anchors(dataset='./data/coco128.yaml', n=9, img_size=640, thr=4.0, gen=1000, verbose=True): - """ Creates kmeans-evolved anchors from training dataset - - Arguments: - dataset: path to data.yaml, or a loaded dataset - n: number of anchors - img_size: image size used for training - thr: anchor-label wh ratio threshold hyperparameter hyp['anchor_t'] used for training, default=4.0 - gen: generations to evolve anchors using genetic algorithm - verbose: print all results - - Return: - k: kmeans evolved anchors - - Usage: - from utils.autoanchor import *; _ = kmean_anchors() - """ - from scipy.cluster.vq import kmeans - - thr = 1 / thr - - def metric(k, wh): # compute metrics - r = wh[:, None] / k[None] - x = torch.min(r, 1 / r).min(2)[0] # ratio metric - # x = wh_iou(wh, torch.tensor(k)) # iou metric - return x, x.max(1)[0] # x, best_x - - def anchor_fitness(k): # mutation fitness - _, best = metric(torch.tensor(k, dtype=torch.float32), wh) - return (best * (best > thr).float()).mean() # fitness - - def print_results(k, verbose=True): - k = k[np.argsort(k.prod(1))] # sort small to large - x, best = metric(k, wh0) - bpr, aat = (best > thr).float().mean(), (x > thr).float().mean() * n # best possible recall, anch > thr - s = f'{PREFIX}thr={thr:.2f}: {bpr:.4f} best possible recall, {aat:.2f} anchors past thr\n' \ - f'{PREFIX}n={n}, img_size={img_size}, metric_all={x.mean():.3f}/{best.mean():.3f}-mean/best, ' \ - f'past_thr={x[x > thr].mean():.3f}-mean: ' - for i, x in enumerate(k): - s += '%i,%i, ' % (round(x[0]), round(x[1])) - if verbose: - LOGGER.info(s[:-2]) - return k - - if isinstance(dataset, str): # *.yaml file - with open(dataset, errors='ignore') as f: - data_dict = yaml.safe_load(f) # model dict - from utils.datasets import LoadImagesAndLabels - dataset = LoadImagesAndLabels(data_dict['train'], augment=True, rect=True) - - # Get label wh - shapes = img_size * dataset.shapes / dataset.shapes.max(1, keepdims=True) - wh0 = np.concatenate([l[:, 3:5] * s for s, l in zip(shapes, dataset.labels)]) # wh - - # Filter - i = (wh0 < 3.0).any(1).sum() - if i: - LOGGER.info(f'{PREFIX}WARNING: Extremely small objects found. {i} of {len(wh0)} labels are < 3 pixels in size.') - wh = wh0[(wh0 >= 2.0).any(1)] # filter > 2 pixels - # wh = wh * (np.random.rand(wh.shape[0], 1) * 0.9 + 0.1) # multiply by random scale 0-1 - - # Kmeans calculation - LOGGER.info(f'{PREFIX}Running kmeans for {n} anchors on {len(wh)} points...') - s = wh.std(0) # sigmas for whitening - k, dist = kmeans(wh / s, n, iter=30) # points, mean distance - assert len(k) == n, f'{PREFIX}ERROR: scipy.cluster.vq.kmeans requested {n} points but returned only {len(k)}' - k *= s - wh = torch.tensor(wh, dtype=torch.float32) # filtered - wh0 = torch.tensor(wh0, dtype=torch.float32) # unfiltered - k = print_results(k, verbose=False) - - # Plot - # k, d = [None] * 20, [None] * 20 - # for i in tqdm(range(1, 21)): - # k[i-1], d[i-1] = kmeans(wh / s, i) # points, mean distance - # fig, ax = plt.subplots(1, 2, figsize=(14, 7), tight_layout=True) - # ax = ax.ravel() - # ax[0].plot(np.arange(1, 21), np.array(d) ** 2, marker='.') - # fig, ax = plt.subplots(1, 2, figsize=(14, 7)) # plot wh - # ax[0].hist(wh[wh[:, 0]<100, 0],400) - # ax[1].hist(wh[wh[:, 1]<100, 1],400) - # fig.savefig('wh.png', dpi=200) - - # Evolve - npr = np.random - f, sh, mp, s = anchor_fitness(k), k.shape, 0.9, 0.1 # fitness, generations, mutation prob, sigma - pbar = tqdm(range(gen), desc=f'{PREFIX}Evolving anchors with Genetic Algorithm:') # progress bar - for _ in pbar: - v = np.ones(sh) - while (v == 1).all(): # mutate until a change occurs (prevent duplicates) - v = ((npr.random(sh) < mp) * random.random() * npr.randn(*sh) * s + 1).clip(0.3, 3.0) - kg = (k.copy() * v).clip(min=2.0) - fg = anchor_fitness(kg) - if fg > f: - f, k = fg, kg.copy() - pbar.desc = f'{PREFIX}Evolving anchors with Genetic Algorithm: fitness = {f:.4f}' - if verbose: - print_results(k, verbose) - - return print_results(k) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/autobatch.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/autobatch.py deleted file mode 100755 index f1e38fcf0..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/autobatch.py +++ /dev/null @@ -1,57 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Auto-batch utils -""" - -from copy import deepcopy - -import numpy as np -import torch -from torch.cuda import amp - -from .general import LOGGER, colorstr -from .torch_utils import profile - - -def check_train_batch_size(model, imgsz=640): - # Check YOLOv5 training batch size - with amp.autocast(): - return autobatch(deepcopy(model).train(), imgsz) # compute optimal batch size - - -def autobatch(model, imgsz=640, fraction=0.9, batch_size=16): - # Automatically estimate best batch size to use `fraction` of available CUDA memory - # Usage: - # import torch - # from utils.autobatch import autobatch - # model = torch.hub.load('ultralytics/yolov5', 'yolov5s', autoshape=False) - # print(autobatch(model)) - - prefix = colorstr('AutoBatch: ') - LOGGER.info(f'{prefix}Computing optimal batch size for --imgsz {imgsz}') - device = next(model.parameters()).device # get model device - if device.type == 'cpu': - LOGGER.info(f'{prefix}CUDA not detected, using default CPU batch-size {batch_size}') - return batch_size - - d = str(device).upper() # 'CUDA:0' - properties = torch.cuda.get_device_properties(device) # device properties - t = properties.total_memory / 1024 ** 3 # (GiB) - r = torch.cuda.memory_reserved(device) / 1024 ** 3 # (GiB) - a = torch.cuda.memory_allocated(device) / 1024 ** 3 # (GiB) - f = t - (r + a) # free inside reserved - LOGGER.info(f'{prefix}{d} ({properties.name}) {t:.2f}G total, {r:.2f}G reserved, {a:.2f}G allocated, {f:.2f}G free') - - batch_sizes = [1, 2, 4, 8, 16] - try: - img = [torch.zeros(b, 3, imgsz, imgsz) for b in batch_sizes] - y = profile(img, model, n=3, device=device) - except Exception as e: - LOGGER.warning(f'{prefix}{e}') - - y = [x[2] for x in y if x] # memory [2] - batch_sizes = batch_sizes[:len(y)] - p = np.polyfit(batch_sizes, y, deg=1) # first degree polynomial fit - b = int((f * fraction - p[1]) / p[0]) # y intercept (optimal batch size) - LOGGER.info(f'{prefix}Using batch-size {b} for {d} {t * fraction:.2f}G/{t:.2f}G ({fraction * 100:.0f}%)') - return b diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/mime.sh b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/mime.sh deleted file mode 100755 index c319a83cf..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/mime.sh +++ /dev/null @@ -1,26 +0,0 @@ -# AWS EC2 instance startup 'MIME' script https://aws.amazon.com/premiumsupport/knowledge-center/execute-user-data-ec2/ -# This script will run on every instance restart, not only on first start -# --- DO NOT COPY ABOVE COMMENTS WHEN PASTING INTO USERDATA --- - -Content-Type: multipart/mixed; boundary="//" -MIME-Version: 1.0 - ---// -Content-Type: text/cloud-config; charset="us-ascii" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Disposition: attachment; filename="cloud-config.txt" - -#cloud-config -cloud_final_modules: -- [scripts-user, always] - ---// -Content-Type: text/x-shellscript; charset="us-ascii" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Disposition: attachment; filename="userdata.txt" - -#!/bin/bash -# --- paste contents of userdata.sh here --- ---// diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/resume.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/resume.py deleted file mode 100755 index b21731c97..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/resume.py +++ /dev/null @@ -1,40 +0,0 @@ -# Resume all interrupted trainings in yolov5/ dir including DDP trainings -# Usage: $ python utils/aws/resume.py - -import os -import sys -from pathlib import Path - -import torch -import yaml - -FILE = Path(__file__).resolve() -ROOT = FILE.parents[2] # YOLOv5 root directory -if str(ROOT) not in sys.path: - sys.path.append(str(ROOT)) # add ROOT to PATH - -port = 0 # --master_port -path = Path('').resolve() -for last in path.rglob('*/**/last.pt'): - ckpt = torch.load(last) - if ckpt['optimizer'] is None: - continue - - # Load opt.yaml - with open(last.parent.parent / 'opt.yaml', errors='ignore') as f: - opt = yaml.safe_load(f) - - # Get device count - d = opt['device'].split(',') # devices - nd = len(d) # number of devices - ddp = nd > 1 or (nd == 0 and torch.cuda.device_count() > 1) # distributed data parallel - - if ddp: # multi-GPU - port += 1 - cmd = f'python -m torch.distributed.run --nproc_per_node {nd} --master_port {port} train.py --resume {last}' - else: # single-GPU - cmd = f'python train.py --resume {last}' - - cmd += ' > /dev/null 2>&1 &' # redirect output to dev/null and run in daemon thread - print(cmd) - os.system(cmd) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/userdata.sh b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/userdata.sh deleted file mode 100755 index 5fc1332ac..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/aws/userdata.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -# AWS EC2 instance startup script https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html -# This script will run only once on first instance start (for a re-start script see mime.sh) -# /home/ubuntu (ubuntu) or /home/ec2-user (amazon-linux) is working dir -# Use >300 GB SSD - -cd home/ubuntu -if [ ! -d yolov5 ]; then - echo "Running first-time script." # install dependencies, download COCO, pull Docker - git clone https://github.com/ultralytics/yolov5 -b master && sudo chmod -R 777 yolov5 - cd yolov5 - bash data/scripts/get_coco.sh && echo "COCO done." & - sudo docker pull ultralytics/yolov5:latest && echo "Docker done." & - python -m pip install --upgrade pip && pip install -r requirements.txt && python detect.py && echo "Requirements done." & - wait && echo "All tasks done." # finish background tasks -else - echo "Running re-start script." # resume interrupted runs - i=0 - list=$(sudo docker ps -qa) # container list i.e. $'one\ntwo\nthree\nfour' - while IFS= read -r id; do - ((i++)) - echo "restarting container $i: $id" - sudo docker start $id - # sudo docker exec -it $id python train.py --resume # single-GPU - sudo docker exec -d $id python utils/aws/resume.py # multi-scenario - done <<<"$list" -fi diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/callbacks.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/callbacks.py deleted file mode 100755 index c9d936ef0..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/callbacks.py +++ /dev/null @@ -1,77 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Callback utils -""" - - -class Callbacks: - """" - Handles all registered callbacks for YOLOv5 Hooks - """ - - def __init__(self): - # Define the available callbacks - self._callbacks = { - 'on_pretrain_routine_start': [], - 'on_pretrain_routine_end': [], - - 'on_train_start': [], - 'on_train_epoch_start': [], - 'on_train_batch_start': [], - 'optimizer_step': [], - 'on_before_zero_grad': [], - 'on_train_batch_end': [], - 'on_train_epoch_end': [], - - 'on_val_start': [], - 'on_val_batch_start': [], - 'on_val_image_end': [], - 'on_val_batch_end': [], - 'on_val_end': [], - - 'on_fit_epoch_end': [], # fit = train + val - 'on_model_save': [], - 'on_train_end': [], - - 'teardown': [], - } - - def register_action(self, hook, name='', callback=None): - """ - Register a new action to a callback hook - - Args: - hook The callback hook name to register the action to - name The name of the action for later reference - callback The callback to fire - """ - assert hook in self._callbacks, f"hook '{hook}' not found in callbacks {self._callbacks}" - assert callable(callback), f"callback '{callback}' is not callable" - self._callbacks[hook].append({'name': name, 'callback': callback}) - - def get_registered_actions(self, hook=None): - """" - Returns all the registered actions by callback hook - - Args: - hook The name of the hook to check, defaults to all - """ - if hook: - return self._callbacks[hook] - else: - return self._callbacks - - def run(self, hook, *args, **kwargs): - """ - Loop through the registered actions and fire all callbacks - - Args: - hook The name of the hook to check, defaults to all - args Arguments to receive from YOLOv5 - kwargs Keyword Arguments to receive from YOLOv5 - """ - - assert hook in self._callbacks, f"hook '{hook}' not found in callbacks {self._callbacks}" - - for logger in self._callbacks[hook]: - logger['callback'](*args, **kwargs) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/datasets.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/datasets.py deleted file mode 100755 index a388a4ddf..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/datasets.py +++ /dev/null @@ -1,1036 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Dataloaders and dataset utils -""" - -import glob -import hashlib -import json -import os -import random -import shutil -import time -from itertools import repeat -from multiprocessing.pool import Pool, ThreadPool -from pathlib import Path -from threading import Thread -from zipfile import ZipFile - -import cv2 -import numpy as np -import torch -import torch.nn.functional as F -import yaml -from PIL import ExifTags, Image, ImageOps -from torch.utils.data import DataLoader, Dataset, dataloader, distributed -from tqdm import tqdm - -from .augmentations import Albumentations, augment_hsv, copy_paste, letterbox, mixup, random_perspective -from .general import (LOGGER, NUM_THREADS, check_dataset, check_requirements, check_yaml, clean_str, - segments2boxes, xyn2xy, xywh2xyxy, xywhn2xyxy, xyxy2xywhn) -from .torch_utils import torch_distributed_zero_first - -# Parameters -HELP_URL = 'https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data' -IMG_FORMATS = ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'tiff', 'dng', 'webp', 'mpo'] # acceptable image suffixes -VID_FORMATS = ['mov', 'avi', 'mp4', 'mpg', 'mpeg', 'm4v', 'wmv', 'mkv'] # acceptable video suffixes -WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1)) # DPP - -# Get orientation exif tag -for orientation in ExifTags.TAGS.keys(): - if ExifTags.TAGS[orientation] == 'Orientation': - break - - -def get_hash(paths): - # Returns a single hash value of a list of paths (files or dirs) - size = sum(os.path.getsize(p) for p in paths if os.path.exists(p)) # sizes - h = hashlib.md5(str(size).encode()) # hash sizes - h.update(''.join(paths).encode()) # hash paths - return h.hexdigest() # return hash - - -def exif_size(img): - # Returns exif-corrected PIL size - s = img.size # (width, height) - try: - rotation = dict(img._getexif().items())[orientation] - if rotation == 6: # rotation 270 - s = (s[1], s[0]) - elif rotation == 8: # rotation 90 - s = (s[1], s[0]) - except: - pass - - return s - - -def exif_transpose(image): - """ - Transpose a PIL image accordingly if it has an EXIF Orientation tag. - Inplace version of https://github.com/python-pillow/Pillow/blob/master/src/PIL/ImageOps.py exif_transpose() - - :param image: The image to transpose. - :return: An image. - """ - exif = image.getexif() - orientation = exif.get(0x0112, 1) # default 1 - if orientation > 1: - method = {2: Image.FLIP_LEFT_RIGHT, - 3: Image.ROTATE_180, - 4: Image.FLIP_TOP_BOTTOM, - 5: Image.TRANSPOSE, - 6: Image.ROTATE_270, - 7: Image.TRANSVERSE, - 8: Image.ROTATE_90, - }.get(orientation) - if method is not None: - image = image.transpose(method) - del exif[0x0112] - image.info["exif"] = exif.tobytes() - return image - - -def create_dataloader(path, imgsz, batch_size, stride, single_cls=False, hyp=None, augment=False, cache=False, pad=0.0, - rect=False, rank=-1, workers=8, image_weights=False, quad=False, prefix='', shuffle=False): - if rect and shuffle: - LOGGER.warning('WARNING: --rect is incompatible with DataLoader shuffle, setting shuffle=False') - shuffle = False - with torch_distributed_zero_first(rank): # init dataset *.cache only once if DDP - dataset = LoadImagesAndLabels(path, imgsz, batch_size, - augment=augment, # augmentation - hyp=hyp, # hyperparameters - rect=rect, # rectangular batches - cache_images=cache, - single_cls=single_cls, - stride=int(stride), - pad=pad, - image_weights=image_weights, - prefix=prefix) - - batch_size = min(batch_size, len(dataset)) - nw = min([os.cpu_count() // WORLD_SIZE, batch_size if batch_size > 1 else 0, workers]) # number of workers - sampler = None if rank == -1 else distributed.DistributedSampler(dataset, shuffle=shuffle) - loader = DataLoader if image_weights else InfiniteDataLoader # only DataLoader allows for attribute updates - return loader(dataset, - batch_size=batch_size, - shuffle=shuffle and sampler is None, - num_workers=nw, - sampler=sampler, - pin_memory=True, - collate_fn=LoadImagesAndLabels.collate_fn4 if quad else LoadImagesAndLabels.collate_fn), dataset - - -class InfiniteDataLoader(dataloader.DataLoader): - """ Dataloader that reuses workers - - Uses same syntax as vanilla DataLoader - """ - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - object.__setattr__(self, 'batch_sampler', _RepeatSampler(self.batch_sampler)) - self.iterator = super().__iter__() - - def __len__(self): - return len(self.batch_sampler.sampler) - - def __iter__(self): - for i in range(len(self)): - yield next(self.iterator) - - -class _RepeatSampler: - """ Sampler that repeats forever - - Args: - sampler (Sampler) - """ - - def __init__(self, sampler): - self.sampler = sampler - - def __iter__(self): - while True: - yield from iter(self.sampler) - - -class LoadImages: - # YOLOv5 image/video dataloader, i.e. `python detect.py --source image.jpg/vid.mp4` - def __init__(self, path, img_size=640, stride=32, auto=True): - p = str(Path(path).resolve()) # os-agnostic absolute path - if '*' in p: - files = sorted(glob.glob(p, recursive=True)) # glob - elif os.path.isdir(p): - files = sorted(glob.glob(os.path.join(p, '*.*'))) # dir - elif os.path.isfile(p): - files = [p] # files - else: - raise Exception(f'ERROR: {p} does not exist') - - images = [x for x in files if x.split('.')[-1].lower() in IMG_FORMATS] - videos = [x for x in files if x.split('.')[-1].lower() in VID_FORMATS] - ni, nv = len(images), len(videos) - - self.img_size = img_size - self.stride = stride - self.files = images + videos - self.nf = ni + nv # number of files - self.video_flag = [False] * ni + [True] * nv - self.mode = 'image' - self.auto = auto - if any(videos): - self.new_video(videos[0]) # new video - else: - self.cap = None - assert self.nf > 0, f'No images or videos found in {p}. ' \ - f'Supported formats are:\nimages: {IMG_FORMATS}\nvideos: {VID_FORMATS}' - - def __iter__(self): - self.count = 0 - return self - - def __next__(self): - if self.count == self.nf: - raise StopIteration - path = self.files[self.count] - - if self.video_flag[self.count]: - # Read video - self.mode = 'video' - ret_val, img0 = self.cap.read() - while not ret_val: - self.count += 1 - self.cap.release() - if self.count == self.nf: # last video - raise StopIteration - else: - path = self.files[self.count] - self.new_video(path) - ret_val, img0 = self.cap.read() - - self.frame += 1 - s = f'video {self.count + 1}/{self.nf} ({self.frame}/{self.frames}) {path}: ' - - else: - # Read image - self.count += 1 - img0 = cv2.imread(path) # BGR - assert img0 is not None, f'Image Not Found {path}' - s = f'image {self.count}/{self.nf} {path}: ' - - # Padded resize - img = letterbox(img0, self.img_size, stride=self.stride, auto=self.auto)[0] - - # Convert - img = img.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - img = np.ascontiguousarray(img) - - return path, img, img0, self.cap, s - - def new_video(self, path): - self.frame = 0 - self.cap = cv2.VideoCapture(path) - self.frames = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT)) - - def __len__(self): - return self.nf # number of files - - -class LoadWebcam: # for inference - # YOLOv5 local webcam dataloader, i.e. `python detect.py --source 0` - def __init__(self, pipe='0', img_size=640, stride=32): - self.img_size = img_size - self.stride = stride - self.pipe = eval(pipe) if pipe.isnumeric() else pipe - self.cap = cv2.VideoCapture(self.pipe) # video capture object - self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 3) # set buffer size - - def __iter__(self): - self.count = -1 - return self - - def __next__(self): - self.count += 1 - if cv2.waitKey(1) == ord('q'): # q to quit - self.cap.release() - cv2.destroyAllWindows() - raise StopIteration - - # Read frame - ret_val, img0 = self.cap.read() - img0 = cv2.flip(img0, 1) # flip left-right - - # Print - assert ret_val, f'Camera Error {self.pipe}' - img_path = 'webcam.jpg' - s = f'webcam {self.count}: ' - - # Padded resize - img = letterbox(img0, self.img_size, stride=self.stride)[0] - - # Convert - img = img.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - img = np.ascontiguousarray(img) - - return img_path, img, img0, None, s - - def __len__(self): - return 0 - - -class LoadStreams: - # YOLOv5 streamloader, i.e. `python detect.py --source 'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP streams` - def __init__(self, sources='streams.txt', img_size=640, stride=32, auto=True): - self.mode = 'stream' - self.img_size = img_size - self.stride = stride - - if os.path.isfile(sources): - with open(sources) as f: - sources = [x.strip() for x in f.read().strip().splitlines() if len(x.strip())] - else: - sources = [sources] - - n = len(sources) - self.imgs, self.fps, self.frames, self.threads = [None] * n, [0] * n, [0] * n, [None] * n - self.sources = [clean_str(x) for x in sources] # clean source names for later - self.auto = auto - for i, s in enumerate(sources): # index, source - # Start thread to read frames from video stream - st = f'{i + 1}/{n}: {s}... ' - if 'youtube.com/' in s or 'youtu.be/' in s: # if source is YouTube video - check_requirements(('pafy', 'youtube_dl')) - import pafy - s = pafy.new(s).getbest(preftype="mp4").url # YouTube URL - s = eval(s) if s.isnumeric() else s # i.e. s = '0' local webcam - cap = cv2.VideoCapture(s) - assert cap.isOpened(), f'{st}Failed to open {s}' - w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) - h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) - self.fps[i] = max(cap.get(cv2.CAP_PROP_FPS) % 100, 0) or 30.0 # 30 FPS fallback - self.frames[i] = max(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)), 0) or float('inf') # infinite stream fallback - - _, self.imgs[i] = cap.read() # guarantee first frame - self.threads[i] = Thread(target=self.update, args=([i, cap, s]), daemon=True) - LOGGER.info(f"{st} Success ({self.frames[i]} frames {w}x{h} at {self.fps[i]:.2f} FPS)") - self.threads[i].start() - LOGGER.info('') # newline - - # check for common shapes - s = np.stack([letterbox(x, self.img_size, stride=self.stride, auto=self.auto)[0].shape for x in self.imgs]) - self.rect = np.unique(s, axis=0).shape[0] == 1 # rect inference if all shapes equal - if not self.rect: - LOGGER.warning('WARNING: Stream shapes differ. For optimal performance supply similarly-shaped streams.') - - def update(self, i, cap, stream): - # Read stream `i` frames in daemon thread - n, f, read = 0, self.frames[i], 1 # frame number, frame array, inference every 'read' frame - while cap.isOpened() and n < f: - n += 1 - # _, self.imgs[index] = cap.read() - cap.grab() - if n % read == 0: - success, im = cap.retrieve() - if success: - self.imgs[i] = im - else: - LOGGER.warning('WARNING: Video stream unresponsive, please check your IP camera connection.') - self.imgs[i] = np.zeros_like(self.imgs[i]) - cap.open(stream) # re-open stream if signal was lost - time.sleep(1 / self.fps[i]) # wait time - - def __iter__(self): - self.count = -1 - return self - - def __next__(self): - self.count += 1 - if not all(x.is_alive() for x in self.threads) or cv2.waitKey(1) == ord('q'): # q to quit - cv2.destroyAllWindows() - raise StopIteration - - # Letterbox - img0 = self.imgs.copy() - img = [letterbox(x, self.img_size, stride=self.stride, auto=self.rect and self.auto)[0] for x in img0] - - # Stack - img = np.stack(img, 0) - - # Convert - img = img[..., ::-1].transpose((0, 3, 1, 2)) # BGR to RGB, BHWC to BCHW - img = np.ascontiguousarray(img) - - return self.sources, img, img0, None, '' - - def __len__(self): - return len(self.sources) # 1E12 frames = 32 streams at 30 FPS for 30 years - - -def img2label_paths(img_paths): - # Define label paths as a function of image paths - sa, sb = os.sep + 'images' + os.sep, os.sep + 'labels' + os.sep # /images/, /labels/ substrings - return [sb.join(x.rsplit(sa, 1)).rsplit('.', 1)[0] + '.txt' for x in img_paths] - - -class LoadImagesAndLabels(Dataset): - # YOLOv5 train_loader/val_loader, loads images and labels for training and validation - cache_version = 0.6 # dataset labels *.cache version - - def __init__(self, path, img_size=640, batch_size=16, augment=False, hyp=None, rect=False, image_weights=False, - cache_images=False, single_cls=False, stride=32, pad=0.0, prefix=''): - self.img_size = img_size - self.augment = augment - self.hyp = hyp - self.image_weights = image_weights - self.rect = False if image_weights else rect - self.mosaic = self.augment and not self.rect # load 4 images at a time into a mosaic (only during training) - self.mosaic_border = [-img_size // 2, -img_size // 2] - self.stride = stride - self.path = path - self.albumentations = Albumentations() if augment else None - - try: - f = [] # image files - for p in path if isinstance(path, list) else [path]: - p = Path(p) # os-agnostic - if p.is_dir(): # dir - f += glob.glob(str(p / '**' / '*.*'), recursive=True) - # f = list(p.rglob('*.*')) # pathlib - elif p.is_file(): # file - with open(p) as t: - t = t.read().strip().splitlines() - parent = str(p.parent) + os.sep - f += [x.replace('./', parent) if x.startswith('./') else x for x in t] # local to global path - # f += [p.parent / x.lstrip(os.sep) for x in t] # local to global path (pathlib) - else: - raise Exception(f'{prefix}{p} does not exist') - self.img_files = sorted(x.replace('/', os.sep) for x in f if x.split('.')[-1].lower() in IMG_FORMATS) - # self.img_files = sorted([x for x in f if x.suffix[1:].lower() in IMG_FORMATS]) # pathlib - assert self.img_files, f'{prefix}No images found' - except Exception as e: - raise Exception(f'{prefix}Error loading data from {path}: {e}\nSee {HELP_URL}') - - # Check cache - self.label_files = img2label_paths(self.img_files) # labels - cache_path = (p if p.is_file() else Path(self.label_files[0]).parent).with_suffix('.cache') - try: - cache, exists = np.load(cache_path, allow_pickle=True).item(), True # load dict - assert cache['version'] == self.cache_version # same version - assert cache['hash'] == get_hash(self.label_files + self.img_files) # same hash - except: - cache, exists = self.cache_labels(cache_path, prefix), False # cache - - # Display cache - nf, nm, ne, nc, n = cache.pop('results') # found, missing, empty, corrupted, total - if exists: - d = f"Scanning '{cache_path}' images and labels... {nf} found, {nm} missing, {ne} empty, {nc} corrupted" - tqdm(None, desc=prefix + d, total=n, initial=n) # display cache results - if cache['msgs']: - LOGGER.info('\n'.join(cache['msgs'])) # display warnings - assert nf > 0 or not augment, f'{prefix}No labels in {cache_path}. Can not train without labels. See {HELP_URL}' - - # Read cache - [cache.pop(k) for k in ('hash', 'version', 'msgs')] # remove items - labels, shapes, self.segments = zip(*cache.values()) - self.labels = list(labels) - self.shapes = np.array(shapes, dtype=np.float64) - self.img_files = list(cache.keys()) # update - self.label_files = img2label_paths(cache.keys()) # update - n = len(shapes) # number of images - bi = np.floor(np.arange(n) / batch_size).astype(np.int) # batch index - nb = bi[-1] + 1 # number of batches - self.batch = bi # batch index of image - self.n = n - self.indices = range(n) - - # Update labels - include_class = [] # filter labels to include only these classes (optional) - include_class_array = np.array(include_class).reshape(1, -1) - for i, (label, segment) in enumerate(zip(self.labels, self.segments)): - if include_class: - j = (label[:, 0:1] == include_class_array).any(1) - self.labels[i] = label[j] - if segment: - self.segments[i] = segment[j] - if single_cls: # single-class training, merge all classes into 0 - self.labels[i][:, 0] = 0 - if segment: - self.segments[i][:, 0] = 0 - - # Rectangular Training - if self.rect: - # Sort by aspect ratio - s = self.shapes # wh - ar = s[:, 1] / s[:, 0] # aspect ratio - irect = ar.argsort() - self.img_files = [self.img_files[i] for i in irect] - self.label_files = [self.label_files[i] for i in irect] - self.labels = [self.labels[i] for i in irect] - self.shapes = s[irect] # wh - ar = ar[irect] - - # Set training image shapes - shapes = [[1, 1]] * nb - for i in range(nb): - ari = ar[bi == i] - mini, maxi = ari.min(), ari.max() - if maxi < 1: - shapes[i] = [maxi, 1] - elif mini > 1: - shapes[i] = [1, 1 / mini] - - self.batch_shapes = np.ceil(np.array(shapes) * img_size / stride + pad).astype(np.int) * stride - - # Cache images into memory for faster training (WARNING: large datasets may exceed system RAM) - self.imgs, self.img_npy = [None] * n, [None] * n - if cache_images: - if cache_images == 'disk': - self.im_cache_dir = Path(Path(self.img_files[0]).parent.as_posix() + '_npy') - self.img_npy = [self.im_cache_dir / Path(f).with_suffix('.npy').name for f in self.img_files] - self.im_cache_dir.mkdir(parents=True, exist_ok=True) - gb = 0 # Gigabytes of cached images - self.img_hw0, self.img_hw = [None] * n, [None] * n - results = ThreadPool(NUM_THREADS).imap(lambda x: load_image(*x), zip(repeat(self), range(n))) - pbar = tqdm(enumerate(results), total=n) - for i, x in pbar: - if cache_images == 'disk': - if not self.img_npy[i].exists(): - np.save(self.img_npy[i].as_posix(), x[0]) - gb += self.img_npy[i].stat().st_size - else: - self.imgs[i], self.img_hw0[i], self.img_hw[i] = x # im, hw_orig, hw_resized = load_image(self, i) - gb += self.imgs[i].nbytes - pbar.desc = f'{prefix}Caching images ({gb / 1E9:.1f}GB {cache_images})' - pbar.close() - - def cache_labels(self, path=Path('./labels.cache'), prefix=''): - # Cache dataset labels, check images and read shapes - x = {} # dict - nm, nf, ne, nc, msgs = 0, 0, 0, 0, [] # number missing, found, empty, corrupt, messages - desc = f"{prefix}Scanning '{path.parent / path.stem}' images and labels..." - with Pool(NUM_THREADS) as pool: - pbar = tqdm(pool.imap(verify_image_label, zip(self.img_files, self.label_files, repeat(prefix))), - desc=desc, total=len(self.img_files)) - for im_file, l, shape, segments, nm_f, nf_f, ne_f, nc_f, msg in pbar: - nm += nm_f - nf += nf_f - ne += ne_f - nc += nc_f - if im_file: - x[im_file] = [l, shape, segments] - if msg: - msgs.append(msg) - pbar.desc = f"{desc}{nf} found, {nm} missing, {ne} empty, {nc} corrupted" - - pbar.close() - if msgs: - LOGGER.info('\n'.join(msgs)) - if nf == 0: - LOGGER.warning(f'{prefix}WARNING: No labels found in {path}. See {HELP_URL}') - x['hash'] = get_hash(self.label_files + self.img_files) - x['results'] = nf, nm, ne, nc, len(self.img_files) - x['msgs'] = msgs # warnings - x['version'] = self.cache_version # cache version - try: - np.save(path, x) # save cache for next time - path.with_suffix('.cache.npy').rename(path) # remove .npy suffix - LOGGER.info(f'{prefix}New cache created: {path}') - except Exception as e: - LOGGER.warning(f'{prefix}WARNING: Cache directory {path.parent} is not writeable: {e}') # not writeable - return x - - def __len__(self): - return len(self.img_files) - - # def __iter__(self): - # self.count = -1 - # print('ran dataset iter') - # #self.shuffled_vector = np.random.permutation(self.nF) if self.augment else np.arange(self.nF) - # return self - - def __getitem__(self, index): - index = self.indices[index] # linear, shuffled, or image_weights - - hyp = self.hyp - mosaic = self.mosaic and random.random() < hyp['mosaic'] - if mosaic: - # Load mosaic - img, labels = load_mosaic(self, index) - shapes = None - - # MixUp augmentation - if random.random() < hyp['mixup']: - img, labels = mixup(img, labels, *load_mosaic(self, random.randint(0, self.n - 1))) - - else: - # Load image - img, (h0, w0), (h, w) = load_image(self, index) - - # Letterbox - shape = self.batch_shapes[self.batch[index]] if self.rect else self.img_size # final letterboxed shape - img, ratio, pad = letterbox(img, shape, auto=False, scaleup=self.augment) - shapes = (h0, w0), ((h / h0, w / w0), pad) # for COCO mAP rescaling - - labels = self.labels[index].copy() - if labels.size: # normalized xywh to pixel xyxy format - labels[:, 1:] = xywhn2xyxy(labels[:, 1:], ratio[0] * w, ratio[1] * h, padw=pad[0], padh=pad[1]) - - if self.augment: - img, labels = random_perspective(img, labels, - degrees=hyp['degrees'], - translate=hyp['translate'], - scale=hyp['scale'], - shear=hyp['shear'], - perspective=hyp['perspective']) - - nl = len(labels) # number of labels - if nl: - labels[:, 1:5] = xyxy2xywhn(labels[:, 1:5], w=img.shape[1], h=img.shape[0], clip=True, eps=1E-3) - - if self.augment: - # Albumentations - img, labels = self.albumentations(img, labels) - nl = len(labels) # update after albumentations - - # HSV color-space - augment_hsv(img, hgain=hyp['hsv_h'], sgain=hyp['hsv_s'], vgain=hyp['hsv_v']) - - # Flip up-down - if random.random() < hyp['flipud']: - img = np.flipud(img) - if nl: - labels[:, 2] = 1 - labels[:, 2] - - # Flip left-right - if random.random() < hyp['fliplr']: - img = np.fliplr(img) - if nl: - labels[:, 1] = 1 - labels[:, 1] - - # Cutouts - # labels = cutout(img, labels, p=0.5) - # nl = len(labels) # update after cutout - - labels_out = torch.zeros((nl, 6)) - if nl: - labels_out[:, 1:] = torch.from_numpy(labels) - - # Convert - img = img.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - img = np.ascontiguousarray(img) - - return torch.from_numpy(img), labels_out, self.img_files[index], shapes - - @staticmethod - def collate_fn(batch): - img, label, path, shapes = zip(*batch) # transposed - for i, l in enumerate(label): - l[:, 0] = i # add target image index for build_targets() - return torch.stack(img, 0), torch.cat(label, 0), path, shapes - - @staticmethod - def collate_fn4(batch): - img, label, path, shapes = zip(*batch) # transposed - n = len(shapes) // 4 - img4, label4, path4, shapes4 = [], [], path[:n], shapes[:n] - - ho = torch.tensor([[0.0, 0, 0, 1, 0, 0]]) - wo = torch.tensor([[0.0, 0, 1, 0, 0, 0]]) - s = torch.tensor([[1, 1, 0.5, 0.5, 0.5, 0.5]]) # scale - for i in range(n): # zidane torch.zeros(16,3,720,1280) # BCHW - i *= 4 - if random.random() < 0.5: - im = F.interpolate(img[i].unsqueeze(0).float(), scale_factor=2.0, mode='bilinear', align_corners=False)[ - 0].type(img[i].type()) - l = label[i] - else: - im = torch.cat((torch.cat((img[i], img[i + 1]), 1), torch.cat((img[i + 2], img[i + 3]), 1)), 2) - l = torch.cat((label[i], label[i + 1] + ho, label[i + 2] + wo, label[i + 3] + ho + wo), 0) * s - img4.append(im) - label4.append(l) - - for i, l in enumerate(label4): - l[:, 0] = i # add target image index for build_targets() - - return torch.stack(img4, 0), torch.cat(label4, 0), path4, shapes4 - - -# Ancillary functions -------------------------------------------------------------------------------------------------- -def load_image(self, i): - # loads 1 image from dataset index 'i', returns im, original hw, resized hw - im = self.imgs[i] - if im is None: # not cached in ram - npy = self.img_npy[i] - if npy and npy.exists(): # load npy - im = np.load(npy) - else: # read image - path = self.img_files[i] - im = cv2.imread(path) # BGR - assert im is not None, f'Image Not Found {path}' - h0, w0 = im.shape[:2] # orig hw - r = self.img_size / max(h0, w0) # ratio - if r != 1: # if sizes are not equal - im = cv2.resize(im, (int(w0 * r), int(h0 * r)), - interpolation=cv2.INTER_AREA if r < 1 and not self.augment else cv2.INTER_LINEAR) - return im, (h0, w0), im.shape[:2] # im, hw_original, hw_resized - else: - return self.imgs[i], self.img_hw0[i], self.img_hw[i] # im, hw_original, hw_resized - - -def load_mosaic(self, index): - # YOLOv5 4-mosaic loader. Loads 1 image + 3 random images into a 4-image mosaic - labels4, segments4 = [], [] - s = self.img_size - yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in self.mosaic_border) # mosaic center x, y - indices = [index] + random.choices(self.indices, k=3) # 3 additional image indices - random.shuffle(indices) - for i, index in enumerate(indices): - # Load image - img, _, (h, w) = load_image(self, index) - - # place img in img4 - if i == 0: # top left - img4 = np.full((s * 2, s * 2, img.shape[2]), 114, dtype=np.uint8) # base image with 4 tiles - x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc # xmin, ymin, xmax, ymax (large image) - x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h # xmin, ymin, xmax, ymax (small image) - elif i == 1: # top right - x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc - x1b, y1b, x2b, y2b = 0, h - (y2a - y1a), min(w, x2a - x1a), h - elif i == 2: # bottom left - x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h) - x1b, y1b, x2b, y2b = w - (x2a - x1a), 0, w, min(y2a - y1a, h) - elif i == 3: # bottom right - x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h) - x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h) - - img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b] # img4[ymin:ymax, xmin:xmax] - padw = x1a - x1b - padh = y1a - y1b - - # Labels - labels, segments = self.labels[index].copy(), self.segments[index].copy() - if labels.size: - labels[:, 1:] = xywhn2xyxy(labels[:, 1:], w, h, padw, padh) # normalized xywh to pixel xyxy format - segments = [xyn2xy(x, w, h, padw, padh) for x in segments] - labels4.append(labels) - segments4.extend(segments) - - # Concat/clip labels - labels4 = np.concatenate(labels4, 0) - for x in (labels4[:, 1:], *segments4): - np.clip(x, 0, 2 * s, out=x) # clip when using random_perspective() - # img4, labels4 = replicate(img4, labels4) # replicate - - # Augment - img4, labels4, segments4 = copy_paste(img4, labels4, segments4, p=self.hyp['copy_paste']) - img4, labels4 = random_perspective(img4, labels4, segments4, - degrees=self.hyp['degrees'], - translate=self.hyp['translate'], - scale=self.hyp['scale'], - shear=self.hyp['shear'], - perspective=self.hyp['perspective'], - border=self.mosaic_border) # border to remove - - return img4, labels4 - - -def load_mosaic9(self, index): - # YOLOv5 9-mosaic loader. Loads 1 image + 8 random images into a 9-image mosaic - labels9, segments9 = [], [] - s = self.img_size - indices = [index] + random.choices(self.indices, k=8) # 8 additional image indices - random.shuffle(indices) - for i, index in enumerate(indices): - # Load image - img, _, (h, w) = load_image(self, index) - - # place img in img9 - if i == 0: # center - img9 = np.full((s * 3, s * 3, img.shape[2]), 114, dtype=np.uint8) # base image with 4 tiles - h0, w0 = h, w - c = s, s, s + w, s + h # xmin, ymin, xmax, ymax (base) coordinates - elif i == 1: # top - c = s, s - h, s + w, s - elif i == 2: # top right - c = s + wp, s - h, s + wp + w, s - elif i == 3: # right - c = s + w0, s, s + w0 + w, s + h - elif i == 4: # bottom right - c = s + w0, s + hp, s + w0 + w, s + hp + h - elif i == 5: # bottom - c = s + w0 - w, s + h0, s + w0, s + h0 + h - elif i == 6: # bottom left - c = s + w0 - wp - w, s + h0, s + w0 - wp, s + h0 + h - elif i == 7: # left - c = s - w, s + h0 - h, s, s + h0 - elif i == 8: # top left - c = s - w, s + h0 - hp - h, s, s + h0 - hp - - padx, pady = c[:2] - x1, y1, x2, y2 = (max(x, 0) for x in c) # allocate coords - - # Labels - labels, segments = self.labels[index].copy(), self.segments[index].copy() - if labels.size: - labels[:, 1:] = xywhn2xyxy(labels[:, 1:], w, h, padx, pady) # normalized xywh to pixel xyxy format - segments = [xyn2xy(x, w, h, padx, pady) for x in segments] - labels9.append(labels) - segments9.extend(segments) - - # Image - img9[y1:y2, x1:x2] = img[y1 - pady:, x1 - padx:] # img9[ymin:ymax, xmin:xmax] - hp, wp = h, w # height, width previous - - # Offset - yc, xc = (int(random.uniform(0, s)) for _ in self.mosaic_border) # mosaic center x, y - img9 = img9[yc:yc + 2 * s, xc:xc + 2 * s] - - # Concat/clip labels - labels9 = np.concatenate(labels9, 0) - labels9[:, [1, 3]] -= xc - labels9[:, [2, 4]] -= yc - c = np.array([xc, yc]) # centers - segments9 = [x - c for x in segments9] - - for x in (labels9[:, 1:], *segments9): - np.clip(x, 0, 2 * s, out=x) # clip when using random_perspective() - # img9, labels9 = replicate(img9, labels9) # replicate - - # Augment - img9, labels9 = random_perspective(img9, labels9, segments9, - degrees=self.hyp['degrees'], - translate=self.hyp['translate'], - scale=self.hyp['scale'], - shear=self.hyp['shear'], - perspective=self.hyp['perspective'], - border=self.mosaic_border) # border to remove - - return img9, labels9 - - -def create_folder(path='./new'): - # Create folder - if os.path.exists(path): - shutil.rmtree(path) # delete output folder - os.makedirs(path) # make new output folder - - -def flatten_recursive(path='../datasets/coco128'): - # Flatten a recursive directory by bringing all files to top level - new_path = Path(path + '_flat') - create_folder(new_path) - for file in tqdm(glob.glob(str(Path(path)) + '/**/*.*', recursive=True)): - shutil.copyfile(file, new_path / Path(file).name) - - -def extract_boxes(path='../datasets/coco128'): # from utils.datasets import *; extract_boxes() - # Convert detection dataset into classification dataset, with one directory per class - path = Path(path) # images dir - shutil.rmtree(path / 'classifier') if (path / 'classifier').is_dir() else None # remove existing - files = list(path.rglob('*.*')) - n = len(files) # number of files - for im_file in tqdm(files, total=n): - if im_file.suffix[1:] in IMG_FORMATS: - # image - im = cv2.imread(str(im_file))[..., ::-1] # BGR to RGB - h, w = im.shape[:2] - - # labels - lb_file = Path(img2label_paths([str(im_file)])[0]) - if Path(lb_file).exists(): - with open(lb_file) as f: - lb = np.array([x.split() for x in f.read().strip().splitlines()], dtype=np.float32) # labels - - for j, x in enumerate(lb): - c = int(x[0]) # class - f = (path / 'classifier') / f'{c}' / f'{path.stem}_{im_file.stem}_{j}.jpg' # new filename - if not f.parent.is_dir(): - f.parent.mkdir(parents=True) - - b = x[1:] * [w, h, w, h] # box - # b[2:] = b[2:].max() # rectangle to square - b[2:] = b[2:] * 1.2 + 3 # pad - b = xywh2xyxy(b.reshape(-1, 4)).ravel().astype(np.int) - - b[[0, 2]] = np.clip(b[[0, 2]], 0, w) # clip boxes outside of image - b[[1, 3]] = np.clip(b[[1, 3]], 0, h) - assert cv2.imwrite(str(f), im[b[1]:b[3], b[0]:b[2]]), f'box failure in {f}' - - -def autosplit(path='../datasets/coco128/images', weights=(0.9, 0.1, 0.0), annotated_only=False): - """ Autosplit a dataset into train/val/test splits and save path/autosplit_*.txt files - Usage: from utils.datasets import *; autosplit() - Arguments - path: Path to images directory - weights: Train, val, test weights (list, tuple) - annotated_only: Only use images with an annotated txt file - """ - path = Path(path) # images dir - files = sorted(x for x in path.rglob('*.*') if x.suffix[1:].lower() in IMG_FORMATS) # image files only - n = len(files) # number of files - random.seed(0) # for reproducibility - indices = random.choices([0, 1, 2], weights=weights, k=n) # assign each image to a split - - txt = ['autosplit_train.txt', 'autosplit_val.txt', 'autosplit_test.txt'] # 3 txt files - [(path.parent / x).unlink(missing_ok=True) for x in txt] # remove existing - - print(f'Autosplitting images from {path}' + ', using *.txt labeled images only' * annotated_only) - for i, img in tqdm(zip(indices, files), total=n): - if not annotated_only or Path(img2label_paths([str(img)])[0]).exists(): # check label - with open(path.parent / txt[i], 'a') as f: - f.write('./' + img.relative_to(path.parent).as_posix() + '\n') # add image to txt file - - -def verify_image_label(args): - # Verify one image-label pair - im_file, lb_file, prefix = args - nm, nf, ne, nc, msg, segments = 0, 0, 0, 0, '', [] # number (missing, found, empty, corrupt), message, segments - try: - # verify images - im = Image.open(im_file) - im.verify() # PIL verify - shape = exif_size(im) # image size - assert (shape[0] > 9) & (shape[1] > 9), f'image size {shape} <10 pixels' - assert im.format.lower() in IMG_FORMATS, f'invalid image format {im.format}' - if im.format.lower() in ('jpg', 'jpeg'): - with open(im_file, 'rb') as f: - f.seek(-2, 2) - if f.read() != b'\xff\xd9': # corrupt JPEG - ImageOps.exif_transpose(Image.open(im_file)).save(im_file, 'JPEG', subsampling=0, quality=100) - msg = f'{prefix}WARNING: {im_file}: corrupt JPEG restored and saved' - - # verify labels - if os.path.isfile(lb_file): - nf = 1 # label found - with open(lb_file) as f: - l = [x.split() for x in f.read().strip().splitlines() if len(x)] - if any([len(x) > 8 for x in l]): # is segment - classes = np.array([x[0] for x in l], dtype=np.float32) - segments = [np.array(x[1:], dtype=np.float32).reshape(-1, 2) for x in l] # (cls, xy1...) - l = np.concatenate((classes.reshape(-1, 1), segments2boxes(segments)), 1) # (cls, xywh) - l = np.array(l, dtype=np.float32) - nl = len(l) - if nl: - assert l.shape[1] == 5, f'labels require 5 columns, {l.shape[1]} columns detected' - assert (l >= 0).all(), f'negative label values {l[l < 0]}' - assert (l[:, 1:] <= 1).all(), f'non-normalized or out of bounds coordinates {l[:, 1:][l[:, 1:] > 1]}' - _, i = np.unique(l, axis=0, return_index=True) - if len(i) < nl: # duplicate row check - l = l[i] # remove duplicates - if segments: - segments = segments[i] - msg = f'{prefix}WARNING: {im_file}: {nl - len(i)} duplicate labels removed' - else: - ne = 1 # label empty - l = np.zeros((0, 5), dtype=np.float32) - else: - nm = 1 # label missing - l = np.zeros((0, 5), dtype=np.float32) - return im_file, l, shape, segments, nm, nf, ne, nc, msg - except Exception as e: - nc = 1 - msg = f'{prefix}WARNING: {im_file}: ignoring corrupt image/label: {e}' - return [None, None, None, None, nm, nf, ne, nc, msg] - - -def dataset_stats(path='coco128.yaml', autodownload=False, verbose=False, profile=False, hub=False): - """ Return dataset statistics dictionary with images and instances counts per split per class - To run in parent directory: export PYTHONPATH="$PWD/yolov5" - Usage1: from utils.datasets import *; dataset_stats('coco128.yaml', autodownload=True) - Usage2: from utils.datasets import *; dataset_stats('../datasets/coco128_with_yaml.zip') - Arguments - path: Path to data.yaml or data.zip (with data.yaml inside data.zip) - autodownload: Attempt to download dataset if not found locally - verbose: Print stats dictionary - """ - - def round_labels(labels): - # Update labels to integer class and 6 decimal place floats - return [[int(c), *(round(x, 4) for x in points)] for c, *points in labels] - - def unzip(path): - # Unzip data.zip TODO: CONSTRAINT: path/to/abc.zip MUST unzip to 'path/to/abc/' - if str(path).endswith('.zip'): # path is data.zip - assert Path(path).is_file(), f'Error unzipping {path}, file not found' - ZipFile(path).extractall(path=path.parent) # unzip - dir = path.with_suffix('') # dataset directory == zip name - return True, str(dir), next(dir.rglob('*.yaml')) # zipped, data_dir, yaml_path - else: # path is data.yaml - return False, None, path - - def hub_ops(f, max_dim=1920): - # HUB ops for 1 image 'f': resize and save at reduced quality in /dataset-hub for web/app viewing - f_new = im_dir / Path(f).name # dataset-hub image filename - try: # use PIL - im = Image.open(f) - r = max_dim / max(im.height, im.width) # ratio - if r < 1.0: # image too large - im = im.resize((int(im.width * r), int(im.height * r))) - im.save(f_new, 'JPEG', quality=75, optimize=True) # save - except Exception as e: # use OpenCV - print(f'WARNING: HUB ops PIL failure {f}: {e}') - im = cv2.imread(f) - im_height, im_width = im.shape[:2] - r = max_dim / max(im_height, im_width) # ratio - if r < 1.0: # image too large - im = cv2.resize(im, (int(im_width * r), int(im_height * r)), interpolation=cv2.INTER_AREA) - cv2.imwrite(str(f_new), im) - - zipped, data_dir, yaml_path = unzip(Path(path)) - with open(check_yaml(yaml_path), errors='ignore') as f: - data = yaml.safe_load(f) # data dict - if zipped: - data['path'] = data_dir # TODO: should this be dir.resolve()? - check_dataset(data, autodownload) # download dataset if missing - hub_dir = Path(data['path'] + ('-hub' if hub else '')) - stats = {'nc': data['nc'], 'names': data['names']} # statistics dictionary - for split in 'train', 'val', 'test': - if data.get(split) is None: - stats[split] = None # i.e. no test set - continue - x = [] - dataset = LoadImagesAndLabels(data[split]) # load dataset - for label in tqdm(dataset.labels, total=dataset.n, desc='Statistics'): - x.append(np.bincount(label[:, 0].astype(int), minlength=data['nc'])) - x = np.array(x) # shape(128x80) - stats[split] = {'instance_stats': {'total': int(x.sum()), 'per_class': x.sum(0).tolist()}, - 'image_stats': {'total': dataset.n, 'unlabelled': int(np.all(x == 0, 1).sum()), - 'per_class': (x > 0).sum(0).tolist()}, - 'labels': [{str(Path(k).name): round_labels(v.tolist())} for k, v in - zip(dataset.img_files, dataset.labels)]} - - if hub: - im_dir = hub_dir / 'images' - im_dir.mkdir(parents=True, exist_ok=True) - for _ in tqdm(ThreadPool(NUM_THREADS).imap(hub_ops, dataset.img_files), total=dataset.n, desc='HUB Ops'): - pass - - # Profile - stats_path = hub_dir / 'stats.json' - if profile: - for _ in range(1): - file = stats_path.with_suffix('.npy') - t1 = time.time() - np.save(file, stats) - t2 = time.time() - x = np.load(file, allow_pickle=True) - print(f'stats.npy times: {time.time() - t2:.3f}s read, {t2 - t1:.3f}s write') - - file = stats_path.with_suffix('.json') - t1 = time.time() - with open(file, 'w') as f: - json.dump(stats, f) # save stats *.json - t2 = time.time() - with open(file) as f: - x = json.load(f) # load hyps dict - print(f'stats.json times: {time.time() - t2:.3f}s read, {t2 - t1:.3f}s write') - - # Save, print and return - if hub: - print(f'Saving {stats_path.resolve()}...') - with open(stats_path, 'w') as f: - json.dump(stats, f) # save stats.json - if verbose: - print(json.dumps(stats, indent=2, sort_keys=False)) - return stats diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/downloads.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/downloads.py deleted file mode 100755 index 998a7a582..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/downloads.py +++ /dev/null @@ -1,150 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Download utils -""" - -import os -import platform -import subprocess -import time -import urllib -from pathlib import Path -from zipfile import ZipFile - -import requests -import torch - - -def gsutil_getsize(url=''): - # gs://bucket/file size https://cloud.google.com/storage/docs/gsutil/commands/du - s = subprocess.check_output(f'gsutil du {url}', shell=True).decode('utf-8') - return eval(s.split(' ')[0]) if len(s) else 0 # bytes - - -def safe_download(file, url, url2=None, min_bytes=1E0, error_msg=''): - # Attempts to download file from url or url2, checks and removes incomplete downloads < min_bytes - file = Path(file) - assert_msg = f"Downloaded file '{file}' does not exist or size is < min_bytes={min_bytes}" - try: # url1 - print(f'Downloading {url} to {file}...') - torch.hub.download_url_to_file(url, str(file)) - assert file.exists() and file.stat().st_size > min_bytes, assert_msg # check - except Exception as e: # url2 - file.unlink(missing_ok=True) # remove partial downloads - print(f'ERROR: {e}\nRe-attempting {url2 or url} to {file}...') - os.system(f"curl -L '{url2 or url}' -o '{file}' --retry 3 -C -") # curl download, retry and resume on fail - finally: - if not file.exists() or file.stat().st_size < min_bytes: # check - file.unlink(missing_ok=True) # remove partial downloads - print(f"ERROR: {assert_msg}\n{error_msg}") - print('') - - -def attempt_download(file, repo='ultralytics/yolov5'): # from utils.downloads import *; attempt_download() - # Attempt file download if does not exist - file = Path(str(file).strip().replace("'", '')) - - if not file.exists(): - # URL specified - name = Path(urllib.parse.unquote(str(file))).name # decode '%2F' to '/' etc. - if str(file).startswith(('http:/', 'https:/')): # download - url = str(file).replace(':/', '://') # Pathlib turns :// -> :/ - name = name.split('?')[0] # parse authentication https://url.com/file.txt?auth... - safe_download(file=name, url=url, min_bytes=1E5) - return name - - # GitHub assets - file.parent.mkdir(parents=True, exist_ok=True) # make parent dir (if required) - try: - response = requests.get(f'https://api.github.com/repos/{repo}/releases/latest').json() # github api - assets = [x['name'] for x in response['assets']] # release assets, i.e. ['yolov5s.pt', 'yolov5m.pt', ...] - tag = response['tag_name'] # i.e. 'v1.0' - except: # fallback plan - assets = ['yolov5n.pt', 'yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt', - 'yolov5n6.pt', 'yolov5s6.pt', 'yolov5m6.pt', 'yolov5l6.pt', 'yolov5x6.pt'] - try: - tag = subprocess.check_output('git tag', shell=True, stderr=subprocess.STDOUT).decode().split()[-1] - except: - tag = 'v6.0' # current release - - if name in assets: - safe_download(file, - url=f'https://github.com/{repo}/releases/download/{tag}/{name}', - # url2=f'https://storage.googleapis.com/{repo}/ckpt/{name}', # backup url (optional) - min_bytes=1E5, - error_msg=f'{file} missing, try downloading from https://github.com/{repo}/releases/') - - return str(file) - - -def gdrive_download(id='16TiPfZj7htmTyhntwcZyEEAejOUxuT6m', file='tmp.zip'): - # Downloads a file from Google Drive. from yolov5.utils.downloads import *; gdrive_download() - t = time.time() - file = Path(file) - cookie = Path('cookie') # gdrive cookie - print(f'Downloading https://drive.google.com/uc?export=download&id={id} as {file}... ', end='') - file.unlink(missing_ok=True) # remove existing file - cookie.unlink(missing_ok=True) # remove existing cookie - - # Attempt file download - out = "NUL" if platform.system() == "Windows" else "/dev/null" - os.system(f'curl -c ./cookie -s -L "drive.google.com/uc?export=download&id={id}" > {out}') - if os.path.exists('cookie'): # large file - s = f'curl -Lb ./cookie "drive.google.com/uc?export=download&confirm={get_token()}&id={id}" -o {file}' - else: # small file - s = f'curl -s -L -o {file} "drive.google.com/uc?export=download&id={id}"' - r = os.system(s) # execute, capture return - cookie.unlink(missing_ok=True) # remove existing cookie - - # Error check - if r != 0: - file.unlink(missing_ok=True) # remove partial - print('Download error ') # raise Exception('Download error') - return r - - # Unzip if archive - if file.suffix == '.zip': - print('unzipping... ', end='') - ZipFile(file).extractall(path=file.parent) # unzip - file.unlink() # remove zip - - print(f'Done ({time.time() - t:.1f}s)') - return r - - -def get_token(cookie="./cookie"): - with open(cookie) as f: - for line in f: - if "download" in line: - return line.split()[-1] - return "" - -# Google utils: https://cloud.google.com/storage/docs/reference/libraries ---------------------------------------------- -# -# -# def upload_blob(bucket_name, source_file_name, destination_blob_name): -# # Uploads a file to a bucket -# # https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-python -# -# storage_client = storage.Client() -# bucket = storage_client.get_bucket(bucket_name) -# blob = bucket.blob(destination_blob_name) -# -# blob.upload_from_filename(source_file_name) -# -# print('File {} uploaded to {}.'.format( -# source_file_name, -# destination_blob_name)) -# -# -# def download_blob(bucket_name, source_blob_name, destination_file_name): -# # Uploads a blob from a bucket -# storage_client = storage.Client() -# bucket = storage_client.get_bucket(bucket_name) -# blob = bucket.blob(source_blob_name) -# -# blob.download_to_filename(destination_file_name) -# -# print('Blob {} downloaded to {}.'.format( -# source_blob_name, -# destination_file_name)) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/README.md b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/README.md deleted file mode 100755 index a726acbd9..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Flask REST API - -[REST](https://en.wikipedia.org/wiki/Representational_state_transfer) [API](https://en.wikipedia.org/wiki/API)s are -commonly used to expose Machine Learning (ML) models to other services. This folder contains an example REST API -created using Flask to expose the YOLOv5s model from [PyTorch Hub](https://pytorch.org/hub/ultralytics_yolov5/). - -## Requirements - -[Flask](https://palletsprojects.com/p/flask/) is required. Install with: - -```shell -$ pip install Flask -``` - -## Run - -After Flask installation run: - -```shell -$ python3 restapi.py --port 5000 -``` - -Then use [curl](https://curl.se/) to perform a request: - -```shell -$ curl -X POST -F image=@zidane.jpg 'http://localhost:5000/v1/object-detection/yolov5s' -``` - -The model inference results are returned as a JSON response: - -```json -[ - { - "class": 0, - "confidence": 0.8900438547, - "height": 0.9318675399, - "name": "person", - "width": 0.3264600933, - "xcenter": 0.7438579798, - "ycenter": 0.5207948685 - }, - { - "class": 0, - "confidence": 0.8440024257, - "height": 0.7155083418, - "name": "person", - "width": 0.6546785235, - "xcenter": 0.427829951, - "ycenter": 0.6334488392 - }, - { - "class": 27, - "confidence": 0.3771208823, - "height": 0.3902671337, - "name": "tie", - "width": 0.0696444362, - "xcenter": 0.3675483763, - "ycenter": 0.7991207838 - }, - { - "class": 27, - "confidence": 0.3527112305, - "height": 0.1540903747, - "name": "tie", - "width": 0.0336618312, - "xcenter": 0.7814827561, - "ycenter": 0.5065554976 - } -] -``` - -An example python script to perform inference using [requests](https://docs.python-requests.org/en/master/) is given -in `example_request.py` diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/example_request.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/example_request.py deleted file mode 100755 index ff21f30f9..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/example_request.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Perform test request""" -import pprint - -import requests - -DETECTION_URL = "http://localhost:5000/v1/object-detection/yolov5s" -TEST_IMAGE = "zidane.jpg" - -image_data = open(TEST_IMAGE, "rb").read() - -response = requests.post(DETECTION_URL, files={"image": image_data}).json() - -pprint.pprint(response) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/restapi.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/restapi.py deleted file mode 100755 index b93ad16a0..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/flask_rest_api/restapi.py +++ /dev/null @@ -1,37 +0,0 @@ -""" -Run a rest API exposing the yolov5s object detection model -""" -import argparse -import io - -import torch -from flask import Flask, request -from PIL import Image - -app = Flask(__name__) - -DETECTION_URL = "/v1/object-detection/yolov5s" - - -@app.route(DETECTION_URL, methods=["POST"]) -def predict(): - if not request.method == "POST": - return - - if request.files.get("image"): - image_file = request.files["image"] - image_bytes = image_file.read() - - img = Image.open(io.BytesIO(image_bytes)) - - results = model(img, size=640) # reduce size=320 for faster inference - return results.pandas().xyxy[0].to_json(orient="records") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Flask API exposing YOLOv5 model") - parser.add_argument("--port", default=5000, type=int, help="port number") - args = parser.parse_args() - - model = torch.hub.load("ultralytics/yolov5", "yolov5s", force_reload=True) # force_reload to recache - app.run(host="0.0.0.0", port=args.port) # debug=True causes Restarting with stat diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/general.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/general.py deleted file mode 100755 index 81fbfe0b7..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/general.py +++ /dev/null @@ -1,843 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -General utils -""" - -import contextlib -import glob -import logging -import math -import os -import platform -import random -import re -import shutil -import signal -import time -import urllib -from itertools import repeat -from multiprocessing.pool import ThreadPool -from pathlib import Path -from subprocess import check_output -from zipfile import ZipFile - -import cv2 -import numpy as np -import pandas as pd -import pkg_resources as pkg -import torch -import torchvision -import yaml - -from .downloads import gsutil_getsize -from .metrics import box_iou, fitness - -# Settings -FILE = Path(__file__).resolve() -ROOT = FILE.parents[1] # YOLOv5 root directory -NUM_THREADS = min(8, max(1, os.cpu_count() - 1)) # number of YOLOv5 multiprocessing threads - -torch.set_printoptions(linewidth=320, precision=5, profile='long') -np.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format}) # format short g, %precision=5 -pd.options.display.max_columns = 10 -cv2.setNumThreads(0) # prevent OpenCV from multithreading (incompatible with PyTorch DataLoader) -os.environ['NUMEXPR_MAX_THREADS'] = str(NUM_THREADS) # NumExpr max threads - - -def set_logging(name=None, verbose=True): - # Sets level and returns logger - rank = int(os.getenv('RANK', -1)) # rank in world for Multi-GPU trainings - logging.basicConfig(format="%(message)s", level=logging.INFO if (verbose and rank in (-1, 0)) else logging.WARNING) - return logging.getLogger(name) - - -LOGGER = set_logging(__name__) # define globally (used in train.py, val.py, detect.py, etc.) - - -class Profile(contextlib.ContextDecorator): - # Usage: @Profile() decorator or 'with Profile():' context manager - def __enter__(self): - self.start = time.time() - - def __exit__(self, type, value, traceback): - print(f'Profile results: {time.time() - self.start:.5f}s') - - -class Timeout(contextlib.ContextDecorator): - # Usage: @Timeout(seconds) decorator or 'with Timeout(seconds):' context manager - def __init__(self, seconds, *, timeout_msg='', suppress_timeout_errors=True): - self.seconds = int(seconds) - self.timeout_message = timeout_msg - self.suppress = bool(suppress_timeout_errors) - - def _timeout_handler(self, signum, frame): - raise TimeoutError(self.timeout_message) - - def __enter__(self): - signal.signal(signal.SIGALRM, self._timeout_handler) # Set handler for SIGALRM - signal.alarm(self.seconds) # start countdown for SIGALRM to be raised - - def __exit__(self, exc_type, exc_val, exc_tb): - signal.alarm(0) # Cancel SIGALRM if it's scheduled - if self.suppress and exc_type is TimeoutError: # Suppress TimeoutError - return True - - -class WorkingDirectory(contextlib.ContextDecorator): - # Usage: @WorkingDirectory(dir) decorator or 'with WorkingDirectory(dir):' context manager - def __init__(self, new_dir): - self.dir = new_dir # new dir - self.cwd = Path.cwd().resolve() # current dir - - def __enter__(self): - os.chdir(self.dir) - - def __exit__(self, exc_type, exc_val, exc_tb): - os.chdir(self.cwd) - - -def try_except(func): - # try-except function. Usage: @try_except decorator - def handler(*args, **kwargs): - try: - func(*args, **kwargs) - except Exception as e: - print(e) - - return handler - - -def methods(instance): - # Get class/instance methods - return [f for f in dir(instance) if callable(getattr(instance, f)) and not f.startswith("__")] - - -def print_args(name, opt): - # Print argparser arguments - LOGGER.info(colorstr(f'{name}: ') + ', '.join(f'{k}={v}' for k, v in vars(opt).items())) - - -def init_seeds(seed=0): - # Initialize random number generator (RNG) seeds https://pytorch.org/docs/stable/notes/randomness.html - # cudnn seed 0 settings are slower and more reproducible, else faster and less reproducible - import torch.backends.cudnn as cudnn - random.seed(seed) - np.random.seed(seed) - torch.manual_seed(seed) - cudnn.benchmark, cudnn.deterministic = (False, True) if seed == 0 else (True, False) - - -def intersect_dicts(da, db, exclude=()): - # Dictionary intersection of matching keys and shapes, omitting 'exclude' keys, using da values - return {k: v for k, v in da.items() if k in db and not any(x in k for x in exclude) and v.shape == db[k].shape} - - -def get_latest_run(search_dir='.'): - # Return path to most recent 'last.pt' in /runs (i.e. to --resume from) - last_list = glob.glob(f'{search_dir}/**/last*.pt', recursive=True) - return max(last_list, key=os.path.getctime) if last_list else '' - - -def user_config_dir(dir='Ultralytics', env_var='YOLOV5_CONFIG_DIR'): - # Return path of user configuration directory. Prefer environment variable if exists. Make dir if required. - env = os.getenv(env_var) - if env: - path = Path(env) # use environment variable - else: - cfg = {'Windows': 'AppData/Roaming', 'Linux': '.config', 'Darwin': 'Library/Application Support'} # 3 OS dirs - path = Path.home() / cfg.get(platform.system(), '') # OS-specific config dir - path = (path if is_writeable(path) else Path('/tmp')) / dir # GCP and AWS lambda fix, only /tmp is writeable - path.mkdir(exist_ok=True) # make if required - return path - - -def is_writeable(dir, test=False): - # Return True if directory has write permissions, test opening a file with write permissions if test=True - if test: # method 1 - file = Path(dir) / 'tmp.txt' - try: - with open(file, 'w'): # open file with write permissions - pass - file.unlink() # remove file - return True - except OSError: - return False - else: # method 2 - return os.access(dir, os.R_OK) # possible issues on Windows - - -def is_docker(): - # Is environment a Docker container? - return Path('/workspace').exists() # or Path('/.dockerenv').exists() - - -def is_colab(): - # Is environment a Google Colab instance? - try: - import google.colab - return True - except ImportError: - return False - - -def is_pip(): - # Is file in a pip package? - return 'site-packages' in Path(__file__).resolve().parts - - -def is_ascii(s=''): - # Is string composed of all ASCII (no UTF) characters? (note str().isascii() introduced in python 3.7) - s = str(s) # convert list, tuple, None, etc. to str - return len(s.encode().decode('ascii', 'ignore')) == len(s) - - -def is_chinese(s='人工智能'): - # Is string composed of any Chinese characters? - return re.search('[\u4e00-\u9fff]', s) - - -def emojis(str=''): - # Return platform-dependent emoji-safe version of string - return str.encode().decode('ascii', 'ignore') if platform.system() == 'Windows' else str - - -def file_size(path): - # Return file/dir size (MB) - path = Path(path) - if path.is_file(): - return path.stat().st_size / 1E6 - elif path.is_dir(): - return sum(f.stat().st_size for f in path.glob('**/*') if f.is_file()) / 1E6 - else: - return 0.0 - - -def check_online(): - # Check internet connectivity - import socket - try: - socket.create_connection(("1.1.1.1", 443), 5) # check host accessibility - return True - except OSError: - return False - - -@try_except -@WorkingDirectory(ROOT) -def check_git_status(): - # Recommend 'git pull' if code is out of date - msg = ', for updates see https://github.com/ultralytics/yolov5' - print(colorstr('github: '), end='') - assert Path('.git').exists(), 'skipping check (not a git repository)' + msg - assert not is_docker(), 'skipping check (Docker image)' + msg - assert check_online(), 'skipping check (offline)' + msg - - cmd = 'git fetch && git config --get remote.origin.url' - url = check_output(cmd, shell=True, timeout=5).decode().strip().rstrip('.git') # git fetch - branch = check_output('git rev-parse --abbrev-ref HEAD', shell=True).decode().strip() # checked out - n = int(check_output(f'git rev-list {branch}..origin/master --count', shell=True)) # commits behind - if n > 0: - s = f"⚠️ YOLOv5 is out of date by {n} commit{'s' * (n > 1)}. Use `git pull` or `git clone {url}` to update." - else: - s = f'up to date with {url} ✅' - print(emojis(s)) # emoji-safe - - -def check_python(minimum='3.6.2'): - # Check current python version vs. required python version - check_version(platform.python_version(), minimum, name='Python ', hard=True) - - -def check_version(current='0.0.0', minimum='0.0.0', name='version ', pinned=False, hard=False): - # Check version vs. required version - current, minimum = (pkg.parse_version(x) for x in (current, minimum)) - result = (current == minimum) if pinned else (current >= minimum) # bool - if hard: # assert min requirements met - assert result, f'{name}{minimum} required by YOLOv5, but {name}{current} is currently installed' - else: - return result - - -@try_except -def check_requirements(requirements=ROOT / 'requirements.txt', exclude=(), install=True): - # Check installed dependencies meet requirements (pass *.txt file or list of packages) - prefix = colorstr('red', 'bold', 'requirements:') - check_python() # check python version - if isinstance(requirements, (str, Path)): # requirements.txt file - file = Path(requirements) - assert file.exists(), f"{prefix} {file.resolve()} not found, check failed." - with file.open() as f: - requirements = [f'{x.name}{x.specifier}' for x in pkg.parse_requirements(f) if x.name not in exclude] - else: # list or tuple of packages - requirements = [x for x in requirements if x not in exclude] - - n = 0 # number of packages updates - for r in requirements: - try: - pkg.require(r) - except Exception as e: # DistributionNotFound or VersionConflict if requirements not met - s = f"{prefix} {r} not found and is required by YOLOv5" - if install: - print(f"{s}, attempting auto-update...") - try: - assert check_online(), f"'pip install {r}' skipped (offline)" - print(check_output(f"pip install '{r}'", shell=True).decode()) - n += 1 - except Exception as e: - print(f'{prefix} {e}') - else: - print(f'{s}. Please install and rerun your command.') - - if n: # if packages updated - source = file.resolve() if 'file' in locals() else requirements - s = f"{prefix} {n} package{'s' * (n > 1)} updated per {source}\n" \ - f"{prefix} ⚠️ {colorstr('bold', 'Restart runtime or rerun command for updates to take effect')}\n" - print(emojis(s)) - - -def check_img_size(imgsz, s=32, floor=0): - # Verify image size is a multiple of stride s in each dimension - if isinstance(imgsz, int): # integer i.e. img_size=640 - new_size = max(make_divisible(imgsz, int(s)), floor) - else: # list i.e. img_size=[640, 480] - new_size = [max(make_divisible(x, int(s)), floor) for x in imgsz] - if new_size != imgsz: - print(f'WARNING: --img-size {imgsz} must be multiple of max stride {s}, updating to {new_size}') - return new_size - - -def check_imshow(): - # Check if environment supports image displays - try: - assert not is_docker(), 'cv2.imshow() is disabled in Docker environments' - assert not is_colab(), 'cv2.imshow() is disabled in Google Colab environments' - cv2.imshow('test', np.zeros((1, 1, 3))) - cv2.waitKey(1) - cv2.destroyAllWindows() - cv2.waitKey(1) - return True - except Exception as e: - print(f'WARNING: Environment does not support cv2.imshow() or PIL Image.show() image displays\n{e}') - return False - - -def check_suffix(file='yolov5s.pt', suffix=('.pt',), msg=''): - # Check file(s) for acceptable suffix - if file and suffix: - if isinstance(suffix, str): - suffix = [suffix] - for f in file if isinstance(file, (list, tuple)) else [file]: - s = Path(f).suffix.lower() # file suffix - if len(s): - assert s in suffix, f"{msg}{f} acceptable suffix is {suffix}" - - -def check_yaml(file, suffix=('.yaml', '.yml')): - # Search/download YAML file (if necessary) and return path, checking suffix - return check_file(file, suffix) - - -def check_file(file, suffix=''): - # Search/download file (if necessary) and return path - check_suffix(file, suffix) # optional - file = str(file) # convert to str() - if Path(file).is_file() or file == '': # exists - return file - elif file.startswith(('http:/', 'https:/')): # download - url = str(Path(file)).replace(':/', '://') # Pathlib turns :// -> :/ - file = Path(urllib.parse.unquote(file).split('?')[0]).name # '%2F' to '/', split https://url.com/file.txt?auth - if Path(file).is_file(): - print(f'Found {url} locally at {file}') # file already exists - else: - print(f'Downloading {url} to {file}...') - torch.hub.download_url_to_file(url, file) - assert Path(file).exists() and Path(file).stat().st_size > 0, f'File download failed: {url}' # check - return file - else: # search - files = [] - for d in 'data', 'models', 'utils': # search directories - files.extend(glob.glob(str(ROOT / d / '**' / file), recursive=True)) # find file - assert len(files), f'File not found: {file}' # assert file was found - assert len(files) == 1, f"Multiple files match '{file}', specify exact path: {files}" # assert unique - return files[0] # return file - - -def check_dataset(data, autodownload=True): - # Download and/or unzip dataset if not found locally - # Usage: https://github.com/ultralytics/yolov5/releases/download/v1.0/coco128_with_yaml.zip - - # Download (optional) - extract_dir = '' - if isinstance(data, (str, Path)) and str(data).endswith('.zip'): # i.e. gs://bucket/dir/coco128.zip - download(data, dir='../datasets', unzip=True, delete=False, curl=False, threads=1) - data = next((Path('../datasets') / Path(data).stem).rglob('*.yaml')) - extract_dir, autodownload = data.parent, False - - # Read yaml (optional) - if isinstance(data, (str, Path)): - with open(data, errors='ignore') as f: - data = yaml.safe_load(f) # dictionary - - # Parse yaml - path = extract_dir or Path(data.get('path') or '') # optional 'path' default to '.' - for k in 'train', 'val', 'test': - if data.get(k): # prepend path - data[k] = str(path / data[k]) if isinstance(data[k], str) else [str(path / x) for x in data[k]] - - assert 'nc' in data, "Dataset 'nc' key missing." - if 'names' not in data: - data['names'] = [f'class{i}' for i in range(data['nc'])] # assign class names if missing - train, val, test, s = (data.get(x) for x in ('train', 'val', 'test', 'download')) - if val: - val = [Path(x).resolve() for x in (val if isinstance(val, list) else [val])] # val path - if not all(x.exists() for x in val): - print('\nWARNING: Dataset not found, nonexistent paths: %s' % [str(x) for x in val if not x.exists()]) - if s and autodownload: # download script - root = path.parent if 'path' in data else '..' # unzip directory i.e. '../' - if s.startswith('http') and s.endswith('.zip'): # URL - f = Path(s).name # filename - print(f'Downloading {s} to {f}...') - torch.hub.download_url_to_file(s, f) - Path(root).mkdir(parents=True, exist_ok=True) # create root - ZipFile(f).extractall(path=root) # unzip - Path(f).unlink() # remove zip - r = None # success - elif s.startswith('bash '): # bash script - print(f'Running {s} ...') - r = os.system(s) - else: # python script - r = exec(s, {'yaml': data}) # return None - print(f"Dataset autodownload {f'success, saved to {root}' if r in (0, None) else 'failure'}\n") - else: - raise Exception('Dataset not found.') - - return data # dictionary - - -def url2file(url): - # Convert URL to filename, i.e. https://url.com/file.txt?auth -> file.txt - url = str(Path(url)).replace(':/', '://') # Pathlib turns :// -> :/ - file = Path(urllib.parse.unquote(url)).name.split('?')[0] # '%2F' to '/', split https://url.com/file.txt?auth - return file - - -def download(url, dir='.', unzip=True, delete=True, curl=False, threads=1): - # Multi-threaded file download and unzip function, used in data.yaml for autodownload - def download_one(url, dir): - # Download 1 file - f = dir / Path(url).name # filename - if Path(url).is_file(): # exists in current path - Path(url).rename(f) # move to dir - elif not f.exists(): - print(f'Downloading {url} to {f}...') - if curl: - os.system(f"curl -L '{url}' -o '{f}' --retry 9 -C -") # curl download, retry and resume on fail - else: - torch.hub.download_url_to_file(url, f, progress=True) # torch download - if unzip and f.suffix in ('.zip', '.gz'): - print(f'Unzipping {f}...') - if f.suffix == '.zip': - ZipFile(f).extractall(path=dir) # unzip - elif f.suffix == '.gz': - os.system(f'tar xfz {f} --directory {f.parent}') # unzip - if delete: - f.unlink() # remove zip - - dir = Path(dir) - dir.mkdir(parents=True, exist_ok=True) # make directory - if threads > 1: - pool = ThreadPool(threads) - pool.imap(lambda x: download_one(*x), zip(url, repeat(dir))) # multi-threaded - pool.close() - pool.join() - else: - for u in [url] if isinstance(url, (str, Path)) else url: - download_one(u, dir) - - -def make_divisible(x, divisor): - # Returns nearest x divisible by divisor - if isinstance(divisor, torch.Tensor): - divisor = int(divisor.max()) # to int - return math.ceil(x / divisor) * divisor - - -def clean_str(s): - # Cleans a string by replacing special characters with underscore _ - return re.sub(pattern="[|@#!¡·$€%&()=?¿^*;:,¨´><+]", repl="_", string=s) - - -def one_cycle(y1=0.0, y2=1.0, steps=100): - # lambda function for sinusoidal ramp from y1 to y2 https://arxiv.org/pdf/1812.01187.pdf - return lambda x: ((1 - math.cos(x * math.pi / steps)) / 2) * (y2 - y1) + y1 - - -def colorstr(*input): - # Colors a string https://en.wikipedia.org/wiki/ANSI_escape_code, i.e. colorstr('blue', 'hello world') - *args, string = input if len(input) > 1 else ('blue', 'bold', input[0]) # color arguments, string - colors = {'black': '\033[30m', # basic colors - 'red': '\033[31m', - 'green': '\033[32m', - 'yellow': '\033[33m', - 'blue': '\033[34m', - 'magenta': '\033[35m', - 'cyan': '\033[36m', - 'white': '\033[37m', - 'bright_black': '\033[90m', # bright colors - 'bright_red': '\033[91m', - 'bright_green': '\033[92m', - 'bright_yellow': '\033[93m', - 'bright_blue': '\033[94m', - 'bright_magenta': '\033[95m', - 'bright_cyan': '\033[96m', - 'bright_white': '\033[97m', - 'end': '\033[0m', # misc - 'bold': '\033[1m', - 'underline': '\033[4m'} - return ''.join(colors[x] for x in args) + f'{string}' + colors['end'] - - -def labels_to_class_weights(labels, nc=80): - # Get class weights (inverse frequency) from training labels - if labels[0] is None: # no labels loaded - return torch.Tensor() - - labels = np.concatenate(labels, 0) # labels.shape = (866643, 5) for COCO - classes = labels[:, 0].astype(np.int) # labels = [class xywh] - weights = np.bincount(classes, minlength=nc) # occurrences per class - - # Prepend gridpoint count (for uCE training) - # gpi = ((320 / 32 * np.array([1, 2, 4])) ** 2 * 3).sum() # gridpoints per image - # weights = np.hstack([gpi * len(labels) - weights.sum() * 9, weights * 9]) ** 0.5 # prepend gridpoints to start - - weights[weights == 0] = 1 # replace empty bins with 1 - weights = 1 / weights # number of targets per class - weights /= weights.sum() # normalize - return torch.from_numpy(weights) - - -def labels_to_image_weights(labels, nc=80, class_weights=np.ones(80)): - # Produces image weights based on class_weights and image contents - class_counts = np.array([np.bincount(x[:, 0].astype(np.int), minlength=nc) for x in labels]) - image_weights = (class_weights.reshape(1, nc) * class_counts).sum(1) - # index = random.choices(range(n), weights=image_weights, k=1) # weight image sample - return image_weights - - -def coco80_to_coco91_class(): # converts 80-index (val2014) to 91-index (paper) - # https://tech.amikelive.com/node-718/what-object-categories-labels-are-in-coco-dataset/ - # a = np.loadtxt('data/coco.names', dtype='str', delimiter='\n') - # b = np.loadtxt('data/coco_paper.names', dtype='str', delimiter='\n') - # x1 = [list(a[i] == b).index(True) + 1 for i in range(80)] # darknet to coco - # x2 = [list(b[i] == a).index(True) if any(b[i] == a) else None for i in range(91)] # coco to darknet - x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90] - return x - - -def xyxy2xywh(x): - # Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] where xy1=top-left, xy2=bottom-right - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = (x[:, 0] + x[:, 2]) / 2 # x center - y[:, 1] = (x[:, 1] + x[:, 3]) / 2 # y center - y[:, 2] = x[:, 2] - x[:, 0] # width - y[:, 3] = x[:, 3] - x[:, 1] # height - return y - - -def xywh2xyxy(x): - # Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = x[:, 0] - x[:, 2] / 2 # top left x - y[:, 1] = x[:, 1] - x[:, 3] / 2 # top left y - y[:, 2] = x[:, 0] + x[:, 2] / 2 # bottom right x - y[:, 3] = x[:, 1] + x[:, 3] / 2 # bottom right y - return y - - -def xywhn2xyxy(x, w=640, h=640, padw=0, padh=0): - # Convert nx4 boxes from [x, y, w, h] normalized to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = w * (x[:, 0] - x[:, 2] / 2) + padw # top left x - y[:, 1] = h * (x[:, 1] - x[:, 3] / 2) + padh # top left y - y[:, 2] = w * (x[:, 0] + x[:, 2] / 2) + padw # bottom right x - y[:, 3] = h * (x[:, 1] + x[:, 3] / 2) + padh # bottom right y - return y - - -def xyxy2xywhn(x, w=640, h=640, clip=False, eps=0.0): - # Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] normalized where xy1=top-left, xy2=bottom-right - if clip: - clip_coords(x, (h - eps, w - eps)) # warning: inplace clip - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = ((x[:, 0] + x[:, 2]) / 2) / w # x center - y[:, 1] = ((x[:, 1] + x[:, 3]) / 2) / h # y center - y[:, 2] = (x[:, 2] - x[:, 0]) / w # width - y[:, 3] = (x[:, 3] - x[:, 1]) / h # height - return y - - -def xyn2xy(x, w=640, h=640, padw=0, padh=0): - # Convert normalized segments into pixel segments, shape (n,2) - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = w * x[:, 0] + padw # top left x - y[:, 1] = h * x[:, 1] + padh # top left y - return y - - -def segment2box(segment, width=640, height=640): - # Convert 1 segment label to 1 box label, applying inside-image constraint, i.e. (xy1, xy2, ...) to (xyxy) - x, y = segment.T # segment xy - inside = (x >= 0) & (y >= 0) & (x <= width) & (y <= height) - x, y, = x[inside], y[inside] - return np.array([x.min(), y.min(), x.max(), y.max()]) if any(x) else np.zeros((1, 4)) # xyxy - - -def segments2boxes(segments): - # Convert segment labels to box labels, i.e. (cls, xy1, xy2, ...) to (cls, xywh) - boxes = [] - for s in segments: - x, y = s.T # segment xy - boxes.append([x.min(), y.min(), x.max(), y.max()]) # cls, xyxy - return xyxy2xywh(np.array(boxes)) # cls, xywh - - -def resample_segments(segments, n=1000): - # Up-sample an (n,2) segment - for i, s in enumerate(segments): - x = np.linspace(0, len(s) - 1, n) - xp = np.arange(len(s)) - segments[i] = np.concatenate([np.interp(x, xp, s[:, i]) for i in range(2)]).reshape(2, -1).T # segment xy - return segments - - -def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None): - # Rescale coords (xyxy) from img1_shape to img0_shape - if ratio_pad is None: # calculate from img0_shape - gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1]) # gain = old / new - pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2 # wh padding - else: - gain = ratio_pad[0][0] - pad = ratio_pad[1] - - coords[:, [0, 2]] -= pad[0] # x padding - coords[:, [1, 3]] -= pad[1] # y padding - coords[:, :4] /= gain - clip_coords(coords, img0_shape) - return coords - - -def clip_coords(boxes, shape): - # Clip bounding xyxy bounding boxes to image shape (height, width) - if isinstance(boxes, torch.Tensor): # faster individually - boxes[:, 0].clamp_(0, shape[1]) # x1 - boxes[:, 1].clamp_(0, shape[0]) # y1 - boxes[:, 2].clamp_(0, shape[1]) # x2 - boxes[:, 3].clamp_(0, shape[0]) # y2 - else: # np.array (faster grouped) - boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1]) # x1, x2 - boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2 - - -def non_max_suppression(prediction, conf_thres=0.25, iou_thres=0.45, classes=None, agnostic=False, multi_label=False, - labels=(), max_det=300): - """Runs Non-Maximum Suppression (NMS) on inference results - - Returns: - list of detections, on (n,6) tensor per image [xyxy, conf, cls] - """ - nc = prediction.shape[2] - 5 # number of classes - xc = prediction[..., 4] > conf_thres # candidates - - # Checks - assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0' - assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0' - - # Settings - min_wh, max_wh = 2, 4096 # (pixels) minimum and maximum box width and height - max_nms = 30000 # maximum number of boxes into torchvision.ops.nms() - time_limit = 10.0 # seconds to quit after - redundant = True # require redundant detections - multi_label &= nc > 1 # multiple labels per box (adds 0.5ms/img) - merge = False # use merge-NMS - - t = time.time() - output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0] - for xi, x in enumerate(prediction): # image index, image inference - # Apply constraints - # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0 # width-height - x = x[xc[xi]] # confidence - - # Cat apriori labels if autolabelling - if labels and len(labels[xi]): - l = labels[xi] - v = torch.zeros((len(l), nc + 5), device=x.device) - v[:, :4] = l[:, 1:5] # box - v[:, 4] = 1.0 # conf - v[range(len(l)), l[:, 0].long() + 5] = 1.0 # cls - x = torch.cat((x, v), 0) - - # If none remain process next image - if not x.shape[0]: - continue - - # Compute conf - x[:, 5:] *= x[:, 4:5] # conf = obj_conf * cls_conf - - # Box (center x, center y, width, height) to (x1, y1, x2, y2) - box = xywh2xyxy(x[:, :4]) - - # Detections matrix nx6 (xyxy, conf, cls) - if multi_label: - i, j = (x[:, 5:] > conf_thres).nonzero(as_tuple=False).T - x = torch.cat((box[i], x[i, j + 5, None], j[:, None].float()), 1) - else: # best class only - conf, j = x[:, 5:].max(1, keepdim=True) - x = torch.cat((box, conf, j.float()), 1)[conf.view(-1) > conf_thres] - - # Filter by class - if classes is not None: - x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)] - - # Apply finite constraint - # if not torch.isfinite(x).all(): - # x = x[torch.isfinite(x).all(1)] - - # Check shape - n = x.shape[0] # number of boxes - if not n: # no boxes - continue - elif n > max_nms: # excess boxes - x = x[x[:, 4].argsort(descending=True)[:max_nms]] # sort by confidence - - # Batched NMS - c = x[:, 5:6] * (0 if agnostic else max_wh) # classes - boxes, scores = x[:, :4] + c, x[:, 4] # boxes (offset by class), scores - i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS - if i.shape[0] > max_det: # limit detections - i = i[:max_det] - if merge and (1 < n < 3E3): # Merge NMS (boxes merged using weighted mean) - # update boxes as boxes(i,4) = weights(i,n) * boxes(n,4) - iou = box_iou(boxes[i], boxes) > iou_thres # iou matrix - weights = iou * scores[None] # box weights - x[i, :4] = torch.mm(weights, x[:, :4]).float() / weights.sum(1, keepdim=True) # merged boxes - if redundant: - i = i[iou.sum(1) > 1] # require redundancy - - output[xi] = x[i] - if (time.time() - t) > time_limit: - print(f'WARNING: NMS time limit {time_limit}s exceeded') - break # time limit exceeded - - return output - - -def strip_optimizer(f='best.pt', s=''): # from utils.general import *; strip_optimizer() - # Strip optimizer from 'f' to finalize training, optionally save as 's' - x = torch.load(f, map_location=torch.device('cpu')) - if x.get('ema'): - x['model'] = x['ema'] # replace model with ema - for k in 'optimizer', 'best_fitness', 'wandb_id', 'ema', 'updates': # keys - x[k] = None - x['epoch'] = -1 - x['model'].half() # to FP16 - for p in x['model'].parameters(): - p.requires_grad = False - torch.save(x, s or f) - mb = os.path.getsize(s or f) / 1E6 # filesize - print(f"Optimizer stripped from {f},{(' saved as %s,' % s) if s else ''} {mb:.1f}MB") - - -def print_mutation(results, hyp, save_dir, bucket): - evolve_csv, results_csv, evolve_yaml = save_dir / 'evolve.csv', save_dir / 'results.csv', save_dir / 'hyp_evolve.yaml' - keys = ('metrics/precision', 'metrics/recall', 'metrics/mAP_0.5', 'metrics/mAP_0.5:0.95', - 'val/box_loss', 'val/obj_loss', 'val/cls_loss') + tuple(hyp.keys()) # [results + hyps] - keys = tuple(x.strip() for x in keys) - vals = results + tuple(hyp.values()) - n = len(keys) - - # Download (optional) - if bucket: - url = f'gs://{bucket}/evolve.csv' - if gsutil_getsize(url) > (os.path.getsize(evolve_csv) if os.path.exists(evolve_csv) else 0): - os.system(f'gsutil cp {url} {save_dir}') # download evolve.csv if larger than local - - # Log to evolve.csv - s = '' if evolve_csv.exists() else (('%20s,' * n % keys).rstrip(',') + '\n') # add header - with open(evolve_csv, 'a') as f: - f.write(s + ('%20.5g,' * n % vals).rstrip(',') + '\n') - - # Print to screen - print(colorstr('evolve: ') + ', '.join(f'{x.strip():>20s}' for x in keys)) - print(colorstr('evolve: ') + ', '.join(f'{x:20.5g}' for x in vals), end='\n\n\n') - - # Save yaml - with open(evolve_yaml, 'w') as f: - data = pd.read_csv(evolve_csv) - data = data.rename(columns=lambda x: x.strip()) # strip keys - i = np.argmax(fitness(data.values[:, :7])) # - f.write('# YOLOv5 Hyperparameter Evolution Results\n' + - f'# Best generation: {i}\n' + - f'# Last generation: {len(data) - 1}\n' + - '# ' + ', '.join(f'{x.strip():>20s}' for x in keys[:7]) + '\n' + - '# ' + ', '.join(f'{x:>20.5g}' for x in data.values[i, :7]) + '\n\n') - yaml.safe_dump(hyp, f, sort_keys=False) - - if bucket: - os.system(f'gsutil cp {evolve_csv} {evolve_yaml} gs://{bucket}') # upload - - -def apply_classifier(x, model, img, im0): - # Apply a second stage classifier to YOLO outputs - # Example model = torchvision.models.__dict__['efficientnet_b0'](pretrained=True).to(device).eval() - im0 = [im0] if isinstance(im0, np.ndarray) else im0 - for i, d in enumerate(x): # per image - if d is not None and len(d): - d = d.clone() - - # Reshape and pad cutouts - b = xyxy2xywh(d[:, :4]) # boxes - b[:, 2:] = b[:, 2:].max(1)[0].unsqueeze(1) # rectangle to square - b[:, 2:] = b[:, 2:] * 1.3 + 30 # pad - d[:, :4] = xywh2xyxy(b).long() - - # Rescale boxes from img_size to im0 size - scale_coords(img.shape[2:], d[:, :4], im0[i].shape) - - # Classes - pred_cls1 = d[:, 5].long() - ims = [] - for j, a in enumerate(d): # per item - cutout = im0[i][int(a[1]):int(a[3]), int(a[0]):int(a[2])] - im = cv2.resize(cutout, (224, 224)) # BGR - # cv2.imwrite('example%i.jpg' % j, cutout) - - im = im[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, to 3x416x416 - im = np.ascontiguousarray(im, dtype=np.float32) # uint8 to float32 - im /= 255 # 0 - 255 to 0.0 - 1.0 - ims.append(im) - - pred_cls2 = model(torch.Tensor(ims).to(d.device)).argmax(1) # classifier prediction - x[i] = x[i][pred_cls1 == pred_cls2] # retain matching class detections - - return x - - -def increment_path(path, exist_ok=False, sep='', mkdir=False): - # Increment file or directory path, i.e. runs/exp --> runs/exp{sep}2, runs/exp{sep}3, ... etc. - path = Path(path) # os-agnostic - if path.exists() and not exist_ok: - path, suffix = (path.with_suffix(''), path.suffix) if path.is_file() else (path, '') - dirs = glob.glob(f"{path}{sep}*") # similar paths - matches = [re.search(rf"%s{sep}(\d+)" % path.stem, d) for d in dirs] - i = [int(m.groups()[0]) for m in matches if m] # indices - n = max(i) + 1 if i else 2 # increment number - path = Path(f"{path}{sep}{n}{suffix}") # increment path - if mkdir: - path.mkdir(parents=True, exist_ok=True) # make directory - return path - - -# Variables -NCOLS = 0 if is_docker() else shutil.get_terminal_size().columns # terminal window size for tqdm diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/Dockerfile b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/Dockerfile deleted file mode 100755 index 0155618f4..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -FROM gcr.io/google-appengine/python - -# Create a virtualenv for dependencies. This isolates these packages from -# system-level packages. -# Use -p python3 or -p python3.7 to select python version. Default is version 2. -RUN virtualenv /env -p python3 - -# Setting these environment variables are the same as running -# source /env/bin/activate. -ENV VIRTUAL_ENV /env -ENV PATH /env/bin:$PATH - -RUN apt-get update && apt-get install -y python-opencv - -# Copy the application's requirements.txt and run pip to install all -# dependencies into the virtualenv. -ADD requirements.txt /app/requirements.txt -RUN pip install -r /app/requirements.txt - -# Add the application source code. -ADD . /app - -# Run a WSGI server to serve the application. gunicorn must be declared as -# a dependency in requirements.txt. -CMD gunicorn -b :$PORT main:app diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/additional_requirements.txt b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/additional_requirements.txt deleted file mode 100755 index 42d7ffc0e..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/additional_requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -# add these requirements in your app on top of the existing ones -pip==21.1 -Flask==1.0.2 -gunicorn==19.9.0 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/app.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/app.yaml deleted file mode 100755 index 5056b7c11..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/google_app_engine/app.yaml +++ /dev/null @@ -1,14 +0,0 @@ -runtime: custom -env: flex - -service: yolov5app - -liveness_check: - initial_delay_sec: 600 - -manual_scaling: - instances: 1 -resources: - cpu: 1 - memory_gb: 4 - disk_size_gb: 20 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/__init__.py deleted file mode 100755 index 2a68d9785..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/__init__.py +++ /dev/null @@ -1,159 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Logging utils -""" - -import os -import warnings -from threading import Thread - -import pkg_resources as pkg -import torch -from torch.utils.tensorboard import SummaryWriter - -from utils.general import colorstr, emojis -from utils.loggers.wandb.wandb_utils import WandbLogger -from utils.plots import plot_images, plot_results -from utils.torch_utils import de_parallel - -LOGGERS = ('csv', 'tb', 'wandb') # text-file, TensorBoard, Weights & Biases -RANK = int(os.getenv('RANK', -1)) - -try: - import wandb - - assert hasattr(wandb, '__version__') # verify package import not local dir - if pkg.parse_version(wandb.__version__) >= pkg.parse_version('0.12.2') and RANK in [0, -1]: - try: - wandb_login_success = wandb.login(timeout=30) - except wandb.errors.UsageError: # known non-TTY terminal issue - wandb_login_success = False - if not wandb_login_success: - wandb = None -except (ImportError, AssertionError): - wandb = None - - -class Loggers(): - # YOLOv5 Loggers class - def __init__(self, save_dir=None, weights=None, opt=None, hyp=None, logger=None, include=LOGGERS): - self.save_dir = save_dir - self.weights = weights - self.opt = opt - self.hyp = hyp - self.logger = logger # for printing results to console - self.include = include - self.keys = ['train/box_loss', 'train/obj_loss', 'train/cls_loss', # train loss - 'metrics/precision', 'metrics/recall', 'metrics/mAP_0.5', 'metrics/mAP_0.5:0.95', # metrics - 'val/box_loss', 'val/obj_loss', 'val/cls_loss', # val loss - 'x/lr0', 'x/lr1', 'x/lr2'] # params - for k in LOGGERS: - setattr(self, k, None) # init empty logger dictionary - self.csv = True # always log to csv - - # Message - if not wandb: - prefix = colorstr('Weights & Biases: ') - s = f"{prefix}run 'pip install wandb' to automatically track and visualize YOLOv5 🚀 runs (RECOMMENDED)" - print(emojis(s)) - - # TensorBoard - s = self.save_dir - if 'tb' in self.include and not self.opt.evolve: - prefix = colorstr('TensorBoard: ') - self.logger.info(f"{prefix}Start with 'tensorboard --logdir {s.parent}', view at http://localhost:6006/") - self.tb = SummaryWriter(str(s)) - - # W&B - if wandb and 'wandb' in self.include: - wandb_artifact_resume = isinstance(self.opt.resume, str) and self.opt.resume.startswith('wandb-artifact://') - run_id = torch.load(self.weights).get('wandb_id') if self.opt.resume and not wandb_artifact_resume else None - self.opt.hyp = self.hyp # add hyperparameters - self.wandb = WandbLogger(self.opt, run_id) - else: - self.wandb = None - - def on_pretrain_routine_end(self): - # Callback runs on pre-train routine end - paths = self.save_dir.glob('*labels*.jpg') # training labels - if self.wandb: - self.wandb.log({"Labels": [wandb.Image(str(x), caption=x.name) for x in paths]}) - - def on_train_batch_end(self, ni, model, imgs, targets, paths, plots, sync_bn): - # Callback runs on train batch end - if plots: - if ni == 0: - if not sync_bn: # tb.add_graph() --sync known issue https://github.com/ultralytics/yolov5/issues/3754 - with warnings.catch_warnings(): - warnings.simplefilter('ignore') # suppress jit trace warning - self.tb.add_graph(torch.jit.trace(de_parallel(model), imgs[0:1], strict=False), []) - if ni < 3: - f = self.save_dir / f'train_batch{ni}.jpg' # filename - Thread(target=plot_images, args=(imgs, targets, paths, f), daemon=True).start() - if self.wandb and ni == 10: - files = sorted(self.save_dir.glob('train*.jpg')) - self.wandb.log({'Mosaics': [wandb.Image(str(f), caption=f.name) for f in files if f.exists()]}) - - def on_train_epoch_end(self, epoch): - # Callback runs on train epoch end - if self.wandb: - self.wandb.current_epoch = epoch + 1 - - def on_val_image_end(self, pred, predn, path, names, im): - # Callback runs on val image end - if self.wandb: - self.wandb.val_one_image(pred, predn, path, names, im) - - def on_val_end(self): - # Callback runs on val end - if self.wandb: - files = sorted(self.save_dir.glob('val*.jpg')) - self.wandb.log({"Validation": [wandb.Image(str(f), caption=f.name) for f in files]}) - - def on_fit_epoch_end(self, vals, epoch, best_fitness, fi): - # Callback runs at the end of each fit (train+val) epoch - x = {k: v for k, v in zip(self.keys, vals)} # dict - if self.csv: - file = self.save_dir / 'results.csv' - n = len(x) + 1 # number of cols - s = '' if file.exists() else (('%20s,' * n % tuple(['epoch'] + self.keys)).rstrip(',') + '\n') # add header - with open(file, 'a') as f: - f.write(s + ('%20.5g,' * n % tuple([epoch] + vals)).rstrip(',') + '\n') - - if self.tb: - for k, v in x.items(): - self.tb.add_scalar(k, v, epoch) - - if self.wandb: - self.wandb.log(x) - self.wandb.end_epoch(best_result=best_fitness == fi) - - def on_model_save(self, last, epoch, final_epoch, best_fitness, fi): - # Callback runs on model save event - if self.wandb: - if ((epoch + 1) % self.opt.save_period == 0 and not final_epoch) and self.opt.save_period != -1: - self.wandb.log_model(last.parent, self.opt, epoch, fi, best_model=best_fitness == fi) - - def on_train_end(self, last, best, plots, epoch, results): - # Callback runs on training end - if plots: - plot_results(file=self.save_dir / 'results.csv') # save results.png - files = ['results.png', 'confusion_matrix.png', *(f'{x}_curve.png' for x in ('F1', 'PR', 'P', 'R'))] - files = [(self.save_dir / f) for f in files if (self.save_dir / f).exists()] # filter - - if self.tb: - import cv2 - for f in files: - self.tb.add_image(f.stem, cv2.imread(str(f))[..., ::-1], epoch, dataformats='HWC') - - if self.wandb: - self.wandb.log({"Results": [wandb.Image(str(f), caption=f.name) for f in files]}) - # Calling wandb.log. TODO: Refactor this into WandbLogger.log_model - if not self.opt.evolve: - wandb.log_artifact(str(best if best.exists() else last), type='model', - name='run_' + self.wandb.wandb_run.id + '_model', - aliases=['latest', 'best', 'stripped']) - self.wandb.finish_run() - else: - self.wandb.finish_run() - self.wandb = WandbLogger(self.opt) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/README.md b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/README.md deleted file mode 100755 index 63d999859..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/README.md +++ /dev/null @@ -1,152 +0,0 @@ -📚 This guide explains how to use **Weights & Biases** (W&B) with YOLOv5 🚀. UPDATED 29 September 2021. -* [About Weights & Biases](#about-weights-&-biases) -* [First-Time Setup](#first-time-setup) -* [Viewing runs](#viewing-runs) -* [Disabling wandb](#disabling-wandb) -* [Advanced Usage: Dataset Versioning and Evaluation](#advanced-usage) -* [Reports: Share your work with the world!](#reports) - -## About Weights & Biases -Think of [W&B](https://wandb.ai/site?utm_campaign=repo_yolo_wandbtutorial) like GitHub for machine learning models. With a few lines of code, save everything you need to debug, compare and reproduce your models — architecture, hyperparameters, git commits, model weights, GPU usage, and even datasets and predictions. - -Used by top researchers including teams at OpenAI, Lyft, Github, and MILA, W&B is part of the new standard of best practices for machine learning. How W&B can help you optimize your machine learning workflows: - - * [Debug](https://wandb.ai/wandb/getting-started/reports/Visualize-Debug-Machine-Learning-Models--VmlldzoyNzY5MDk#Free-2) model performance in real time - * [GPU usage](https://wandb.ai/wandb/getting-started/reports/Visualize-Debug-Machine-Learning-Models--VmlldzoyNzY5MDk#System-4) visualized automatically - * [Custom charts](https://wandb.ai/wandb/customizable-charts/reports/Powerful-Custom-Charts-To-Debug-Model-Peformance--VmlldzoyNzY4ODI) for powerful, extensible visualization - * [Share insights](https://wandb.ai/wandb/getting-started/reports/Visualize-Debug-Machine-Learning-Models--VmlldzoyNzY5MDk#Share-8) interactively with collaborators - * [Optimize hyperparameters](https://docs.wandb.com/sweeps) efficiently - * [Track](https://docs.wandb.com/artifacts) datasets, pipelines, and production models - -## First-Time Setup -
- Toggle Details -When you first train, W&B will prompt you to create a new account and will generate an **API key** for you. If you are an existing user you can retrieve your key from https://wandb.ai/authorize. This key is used to tell W&B where to log your data. You only need to supply your key once, and then it is remembered on the same device. - -W&B will create a cloud **project** (default is 'YOLOv5') for your training runs, and each new training run will be provided a unique run **name** within that project as project/name. You can also manually set your project and run name as: - - ```shell - $ python train.py --project ... --name ... - ``` - -YOLOv5 notebook example: Open In Colab Open In Kaggle -Screen Shot 2021-09-29 at 10 23 13 PM - - -
- -## Viewing Runs -
- Toggle Details -Run information streams from your environment to the W&B cloud console as you train. This allows you to monitor and even cancel runs in realtime . All important information is logged: - - * Training & Validation losses - * Metrics: Precision, Recall, mAP@0.5, mAP@0.5:0.95 - * Learning Rate over time - * A bounding box debugging panel, showing the training progress over time - * GPU: Type, **GPU Utilization**, power, temperature, **CUDA memory usage** - * System: Disk I/0, CPU utilization, RAM memory usage - * Your trained model as W&B Artifact - * Environment: OS and Python types, Git repository and state, **training command** - -

Weights & Biases dashboard

-
- - ## Disabling wandb -* training after running `wandb disabled` inside that directory creates no wandb run -![Screenshot (84)](https://user-images.githubusercontent.com/15766192/143441777-c780bdd7-7cb4-4404-9559-b4316030a985.png) - -* To enable wandb again, run `wandb online` -![Screenshot (85)](https://user-images.githubusercontent.com/15766192/143441866-7191b2cb-22f0-4e0f-ae64-2dc47dc13078.png) - -## Advanced Usage -You can leverage W&B artifacts and Tables integration to easily visualize and manage your datasets, models and training evaluations. Here are some quick examples to get you started. -
-

1: Train and Log Evaluation simultaneousy

- This is an extension of the previous section, but it'll also training after uploading the dataset. This also evaluation Table - Evaluation table compares your predictions and ground truths across the validation set for each epoch. It uses the references to the already uploaded datasets, - so no images will be uploaded from your system more than once. -
- Usage - Code $ python train.py --upload_data val - -![Screenshot from 2021-11-21 17-40-06](https://user-images.githubusercontent.com/15766192/142761183-c1696d8c-3f38-45ab-991a-bb0dfd98ae7d.png) -
- -

2. Visualize and Version Datasets

- Log, visualize, dynamically query, and understand your data with W&B Tables. You can use the following command to log your dataset as a W&B Table. This will generate a {dataset}_wandb.yaml file which can be used to train from dataset artifact. -
- Usage - Code $ python utils/logger/wandb/log_dataset.py --project ... --name ... --data .. - - ![Screenshot (64)](https://user-images.githubusercontent.com/15766192/128486078-d8433890-98a3-4d12-8986-b6c0e3fc64b9.png) -
- -

3: Train using dataset artifact

- When you upload a dataset as described in the first section, you get a new config file with an added `_wandb` to its name. This file contains the information that - can be used to train a model directly from the dataset artifact. This also logs evaluation -
- Usage - Code $ python train.py --data {data}_wandb.yaml - -![Screenshot (72)](https://user-images.githubusercontent.com/15766192/128979739-4cf63aeb-a76f-483f-8861-1c0100b938a5.png) -
- -

4: Save model checkpoints as artifacts

- To enable saving and versioning checkpoints of your experiment, pass `--save_period n` with the base cammand, where `n` represents checkpoint interval. - You can also log both the dataset and model checkpoints simultaneously. If not passed, only the final model will be logged - -
- Usage - Code $ python train.py --save_period 1 - -![Screenshot (68)](https://user-images.githubusercontent.com/15766192/128726138-ec6c1f60-639d-437d-b4ee-3acd9de47ef3.png) -
- -
- -

5: Resume runs from checkpoint artifacts.

-Any run can be resumed using artifacts if the --resume argument starts with wandb-artifact:// prefix followed by the run path, i.e, wandb-artifact://username/project/runid . This doesn't require the model checkpoint to be present on the local system. - -
- Usage - Code $ python train.py --resume wandb-artifact://{run_path} - -![Screenshot (70)](https://user-images.githubusercontent.com/15766192/128728988-4e84b355-6c87-41ae-a591-14aecf45343e.png) -
- -

6: Resume runs from dataset artifact & checkpoint artifacts.

- Local dataset or model checkpoints are not required. This can be used to resume runs directly on a different device - The syntax is same as the previous section, but you'll need to lof both the dataset and model checkpoints as artifacts, i.e, set bot --upload_dataset or - train from _wandb.yaml file and set --save_period - -
- Usage - Code $ python train.py --resume wandb-artifact://{run_path} - -![Screenshot (70)](https://user-images.githubusercontent.com/15766192/128728988-4e84b355-6c87-41ae-a591-14aecf45343e.png) -
- - - -

Reports

-W&B Reports can be created from your saved runs for sharing online. Once a report is created you will receive a link you can use to publically share your results. Here is an example report created from the COCO128 tutorial trainings of all four YOLOv5 models ([link](https://wandb.ai/glenn-jocher/yolov5_tutorial/reports/YOLOv5-COCO128-Tutorial-Results--VmlldzozMDI5OTY)). - -Weights & Biases Reports - - -## Environments - -YOLOv5 may be run in any of the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): - -- **Google Colab and Kaggle** notebooks with free GPU: Open In Colab Open In Kaggle -- **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](https://github.com/ultralytics/yolov5/wiki/GCP-Quickstart) -- **Amazon** Deep Learning AMI. See [AWS Quickstart Guide](https://github.com/ultralytics/yolov5/wiki/AWS-Quickstart) -- **Docker Image**. See [Docker Quickstart Guide](https://github.com/ultralytics/yolov5/wiki/Docker-Quickstart) Docker Pulls - - -## Status - -![CI CPU testing](https://github.com/ultralytics/yolov5/workflows/CI%20CPU%20testing/badge.svg) - -If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 training ([train.py](https://github.com/ultralytics/yolov5/blob/master/train.py)), validation ([val.py](https://github.com/ultralytics/yolov5/blob/master/val.py)), inference ([detect.py](https://github.com/ultralytics/yolov5/blob/master/detect.py)) and export ([export.py](https://github.com/ultralytics/yolov5/blob/master/export.py)) on MacOS, Windows, and Ubuntu every 24 hours and on every commit. diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/log_dataset.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/log_dataset.py deleted file mode 100755 index 06e81fb69..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/log_dataset.py +++ /dev/null @@ -1,27 +0,0 @@ -import argparse - -from wandb_utils import WandbLogger - -from utils.general import LOGGER - -WANDB_ARTIFACT_PREFIX = 'wandb-artifact://' - - -def create_dataset_artifact(opt): - logger = WandbLogger(opt, None, job_type='Dataset Creation') # TODO: return value unused - if not logger.wandb: - LOGGER.info("install wandb using `pip install wandb` to log the dataset") - - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--data', type=str, default='data/coco128.yaml', help='data.yaml path') - parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset') - parser.add_argument('--project', type=str, default='YOLOv5', help='name of W&B Project') - parser.add_argument('--entity', default=None, help='W&B entity') - parser.add_argument('--name', type=str, default='log dataset', help='name of W&B run') - - opt = parser.parse_args() - opt.resume = False # Explicitly disallow resume check for dataset upload job - - create_dataset_artifact(opt) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/sweep.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/sweep.py deleted file mode 100755 index 206059bc3..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/sweep.py +++ /dev/null @@ -1,41 +0,0 @@ -import sys -from pathlib import Path - -import wandb - -FILE = Path(__file__).resolve() -ROOT = FILE.parents[3] # YOLOv5 root directory -if str(ROOT) not in sys.path: - sys.path.append(str(ROOT)) # add ROOT to PATH - -from train import parse_opt, train -from utils.callbacks import Callbacks -from utils.general import increment_path -from utils.torch_utils import select_device - - -def sweep(): - wandb.init() - # Get hyp dict from sweep agent - hyp_dict = vars(wandb.config).get("_items") - - # Workaround: get necessary opt args - opt = parse_opt(known=True) - opt.batch_size = hyp_dict.get("batch_size") - opt.save_dir = str(increment_path(Path(opt.project) / opt.name, exist_ok=opt.exist_ok or opt.evolve)) - opt.epochs = hyp_dict.get("epochs") - opt.nosave = True - opt.data = hyp_dict.get("data") - opt.weights = str(opt.weights) - opt.cfg = str(opt.cfg) - opt.data = str(opt.data) - opt.hyp = str(opt.hyp) - opt.project = str(opt.project) - device = select_device(opt.device, batch_size=opt.batch_size) - - # train - train(hyp_dict, opt, device, callbacks=Callbacks()) - - -if __name__ == "__main__": - sweep() diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/sweep.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/sweep.yaml deleted file mode 100755 index c7790d75f..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/sweep.yaml +++ /dev/null @@ -1,143 +0,0 @@ -# Hyperparameters for training -# To set range- -# Provide min and max values as: -# parameter: -# -# min: scalar -# max: scalar -# OR -# -# Set a specific list of search space- -# parameter: -# values: [scalar1, scalar2, scalar3...] -# -# You can use grid, bayesian and hyperopt search strategy -# For more info on configuring sweeps visit - https://docs.wandb.ai/guides/sweeps/configuration - -program: utils/loggers/wandb/sweep.py -method: random -metric: - name: metrics/mAP_0.5 - goal: maximize - -parameters: - # hyperparameters: set either min, max range or values list - data: - value: "data/coco128.yaml" - batch_size: - values: [64] - epochs: - values: [10] - - lr0: - distribution: uniform - min: 1e-5 - max: 1e-1 - lrf: - distribution: uniform - min: 0.01 - max: 1.0 - momentum: - distribution: uniform - min: 0.6 - max: 0.98 - weight_decay: - distribution: uniform - min: 0.0 - max: 0.001 - warmup_epochs: - distribution: uniform - min: 0.0 - max: 5.0 - warmup_momentum: - distribution: uniform - min: 0.0 - max: 0.95 - warmup_bias_lr: - distribution: uniform - min: 0.0 - max: 0.2 - box: - distribution: uniform - min: 0.02 - max: 0.2 - cls: - distribution: uniform - min: 0.2 - max: 4.0 - cls_pw: - distribution: uniform - min: 0.5 - max: 2.0 - obj: - distribution: uniform - min: 0.2 - max: 4.0 - obj_pw: - distribution: uniform - min: 0.5 - max: 2.0 - iou_t: - distribution: uniform - min: 0.1 - max: 0.7 - anchor_t: - distribution: uniform - min: 2.0 - max: 8.0 - fl_gamma: - distribution: uniform - min: 0.0 - max: 0.1 - hsv_h: - distribution: uniform - min: 0.0 - max: 0.1 - hsv_s: - distribution: uniform - min: 0.0 - max: 0.9 - hsv_v: - distribution: uniform - min: 0.0 - max: 0.9 - degrees: - distribution: uniform - min: 0.0 - max: 45.0 - translate: - distribution: uniform - min: 0.0 - max: 0.9 - scale: - distribution: uniform - min: 0.0 - max: 0.9 - shear: - distribution: uniform - min: 0.0 - max: 10.0 - perspective: - distribution: uniform - min: 0.0 - max: 0.001 - flipud: - distribution: uniform - min: 0.0 - max: 1.0 - fliplr: - distribution: uniform - min: 0.0 - max: 1.0 - mosaic: - distribution: uniform - min: 0.0 - max: 1.0 - mixup: - distribution: uniform - min: 0.0 - max: 1.0 - copy_paste: - distribution: uniform - min: 0.0 - max: 1.0 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/wandb_utils.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/wandb_utils.py deleted file mode 100755 index 221d3c88c..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loggers/wandb/wandb_utils.py +++ /dev/null @@ -1,560 +0,0 @@ -"""Utilities and tools for tracking runs with Weights & Biases.""" - -import logging -import os -import sys -from contextlib import contextmanager -from pathlib import Path -from typing import Dict - -import yaml -from tqdm import tqdm - -FILE = Path(__file__).resolve() -ROOT = FILE.parents[3] # YOLOv5 root directory -if str(ROOT) not in sys.path: - sys.path.append(str(ROOT)) # add ROOT to PATH - -from utils.datasets import LoadImagesAndLabels, img2label_paths -from utils.general import LOGGER, check_dataset, check_file - -try: - import wandb - - assert hasattr(wandb, '__version__') # verify package import not local dir -except (ImportError, AssertionError): - wandb = None - -RANK = int(os.getenv('RANK', -1)) -WANDB_ARTIFACT_PREFIX = 'wandb-artifact://' - - -def remove_prefix(from_string, prefix=WANDB_ARTIFACT_PREFIX): - return from_string[len(prefix):] - - -def check_wandb_config_file(data_config_file): - wandb_config = '_wandb.'.join(data_config_file.rsplit('.', 1)) # updated data.yaml path - if Path(wandb_config).is_file(): - return wandb_config - return data_config_file - - -def check_wandb_dataset(data_file): - is_trainset_wandb_artifact = False - is_valset_wandb_artifact = False - if check_file(data_file) and data_file.endswith('.yaml'): - with open(data_file, errors='ignore') as f: - data_dict = yaml.safe_load(f) - is_trainset_wandb_artifact = (isinstance(data_dict['train'], str) and - data_dict['train'].startswith(WANDB_ARTIFACT_PREFIX)) - is_valset_wandb_artifact = (isinstance(data_dict['val'], str) and - data_dict['val'].startswith(WANDB_ARTIFACT_PREFIX)) - if is_trainset_wandb_artifact or is_valset_wandb_artifact: - return data_dict - else: - return check_dataset(data_file) - - -def get_run_info(run_path): - run_path = Path(remove_prefix(run_path, WANDB_ARTIFACT_PREFIX)) - run_id = run_path.stem - project = run_path.parent.stem - entity = run_path.parent.parent.stem - model_artifact_name = 'run_' + run_id + '_model' - return entity, project, run_id, model_artifact_name - - -def check_wandb_resume(opt): - process_wandb_config_ddp_mode(opt) if RANK not in [-1, 0] else None - if isinstance(opt.resume, str): - if opt.resume.startswith(WANDB_ARTIFACT_PREFIX): - if RANK not in [-1, 0]: # For resuming DDP runs - entity, project, run_id, model_artifact_name = get_run_info(opt.resume) - api = wandb.Api() - artifact = api.artifact(entity + '/' + project + '/' + model_artifact_name + ':latest') - modeldir = artifact.download() - opt.weights = str(Path(modeldir) / "last.pt") - return True - return None - - -def process_wandb_config_ddp_mode(opt): - with open(check_file(opt.data), errors='ignore') as f: - data_dict = yaml.safe_load(f) # data dict - train_dir, val_dir = None, None - if isinstance(data_dict['train'], str) and data_dict['train'].startswith(WANDB_ARTIFACT_PREFIX): - api = wandb.Api() - train_artifact = api.artifact(remove_prefix(data_dict['train']) + ':' + opt.artifact_alias) - train_dir = train_artifact.download() - train_path = Path(train_dir) / 'data/images/' - data_dict['train'] = str(train_path) - - if isinstance(data_dict['val'], str) and data_dict['val'].startswith(WANDB_ARTIFACT_PREFIX): - api = wandb.Api() - val_artifact = api.artifact(remove_prefix(data_dict['val']) + ':' + opt.artifact_alias) - val_dir = val_artifact.download() - val_path = Path(val_dir) / 'data/images/' - data_dict['val'] = str(val_path) - if train_dir or val_dir: - ddp_data_path = str(Path(val_dir) / 'wandb_local_data.yaml') - with open(ddp_data_path, 'w') as f: - yaml.safe_dump(data_dict, f) - opt.data = ddp_data_path - - -class WandbLogger(): - """Log training runs, datasets, models, and predictions to Weights & Biases. - - This logger sends information to W&B at wandb.ai. By default, this information - includes hyperparameters, system configuration and metrics, model metrics, - and basic data metrics and analyses. - - By providing additional command line arguments to train.py, datasets, - models and predictions can also be logged. - - For more on how this logger is used, see the Weights & Biases documentation: - https://docs.wandb.com/guides/integrations/yolov5 - """ - - def __init__(self, opt, run_id=None, job_type='Training'): - """ - - Initialize WandbLogger instance - - Upload dataset if opt.upload_dataset is True - - Setup trainig processes if job_type is 'Training' - - arguments: - opt (namespace) -- Commandline arguments for this run - run_id (str) -- Run ID of W&B run to be resumed - job_type (str) -- To set the job_type for this run - - """ - # Pre-training routine -- - self.job_type = job_type - self.wandb, self.wandb_run = wandb, None if not wandb else wandb.run - self.val_artifact, self.train_artifact = None, None - self.train_artifact_path, self.val_artifact_path = None, None - self.result_artifact = None - self.val_table, self.result_table = None, None - self.bbox_media_panel_images = [] - self.val_table_path_map = None - self.max_imgs_to_log = 16 - self.wandb_artifact_data_dict = None - self.data_dict = None - # It's more elegant to stick to 1 wandb.init call, - # but useful config data is overwritten in the WandbLogger's wandb.init call - if isinstance(opt.resume, str): # checks resume from artifact - if opt.resume.startswith(WANDB_ARTIFACT_PREFIX): - entity, project, run_id, model_artifact_name = get_run_info(opt.resume) - model_artifact_name = WANDB_ARTIFACT_PREFIX + model_artifact_name - assert wandb, 'install wandb to resume wandb runs' - # Resume wandb-artifact:// runs here| workaround for not overwriting wandb.config - self.wandb_run = wandb.init(id=run_id, - project=project, - entity=entity, - resume='allow', - allow_val_change=True) - opt.resume = model_artifact_name - elif self.wandb: - self.wandb_run = wandb.init(config=opt, - resume="allow", - project='YOLOv5' if opt.project == 'runs/train' else Path(opt.project).stem, - entity=opt.entity, - name=opt.name if opt.name != 'exp' else None, - job_type=job_type, - id=run_id, - allow_val_change=True) if not wandb.run else wandb.run - if self.wandb_run: - if self.job_type == 'Training': - if opt.upload_dataset: - if not opt.resume: - self.wandb_artifact_data_dict = self.check_and_upload_dataset(opt) - - if opt.resume: - # resume from artifact - if isinstance(opt.resume, str) and opt.resume.startswith(WANDB_ARTIFACT_PREFIX): - self.data_dict = dict(self.wandb_run.config.data_dict) - else: # local resume - self.data_dict = check_wandb_dataset(opt.data) - else: - self.data_dict = check_wandb_dataset(opt.data) - self.wandb_artifact_data_dict = self.wandb_artifact_data_dict or self.data_dict - - # write data_dict to config. useful for resuming from artifacts. Do this only when not resuming. - self.wandb_run.config.update({'data_dict': self.wandb_artifact_data_dict}, - allow_val_change=True) - self.setup_training(opt) - - if self.job_type == 'Dataset Creation': - self.wandb_run.config.update({"upload_dataset": True}) - self.data_dict = self.check_and_upload_dataset(opt) - - def check_and_upload_dataset(self, opt): - """ - Check if the dataset format is compatible and upload it as W&B artifact - - arguments: - opt (namespace)-- Commandline arguments for current run - - returns: - Updated dataset info dictionary where local dataset paths are replaced by WAND_ARFACT_PREFIX links. - """ - assert wandb, 'Install wandb to upload dataset' - config_path = self.log_dataset_artifact(opt.data, - opt.single_cls, - 'YOLOv5' if opt.project == 'runs/train' else Path(opt.project).stem) - with open(config_path, errors='ignore') as f: - wandb_data_dict = yaml.safe_load(f) - return wandb_data_dict - - def setup_training(self, opt): - """ - Setup the necessary processes for training YOLO models: - - Attempt to download model checkpoint and dataset artifacts if opt.resume stats with WANDB_ARTIFACT_PREFIX - - Update data_dict, to contain info of previous run if resumed and the paths of dataset artifact if downloaded - - Setup log_dict, initialize bbox_interval - - arguments: - opt (namespace) -- commandline arguments for this run - - """ - self.log_dict, self.current_epoch = {}, 0 - self.bbox_interval = opt.bbox_interval - if isinstance(opt.resume, str): - modeldir, _ = self.download_model_artifact(opt) - if modeldir: - self.weights = Path(modeldir) / "last.pt" - config = self.wandb_run.config - opt.weights, opt.save_period, opt.batch_size, opt.bbox_interval, opt.epochs, opt.hyp = str( - self.weights), config.save_period, config.batch_size, config.bbox_interval, config.epochs, \ - config.hyp - data_dict = self.data_dict - if self.val_artifact is None: # If --upload_dataset is set, use the existing artifact, don't download - self.train_artifact_path, self.train_artifact = self.download_dataset_artifact(data_dict.get('train'), - opt.artifact_alias) - self.val_artifact_path, self.val_artifact = self.download_dataset_artifact(data_dict.get('val'), - opt.artifact_alias) - - if self.train_artifact_path is not None: - train_path = Path(self.train_artifact_path) / 'data/images/' - data_dict['train'] = str(train_path) - if self.val_artifact_path is not None: - val_path = Path(self.val_artifact_path) / 'data/images/' - data_dict['val'] = str(val_path) - - if self.val_artifact is not None: - self.result_artifact = wandb.Artifact("run_" + wandb.run.id + "_progress", "evaluation") - columns = ["epoch", "id", "ground truth", "prediction"] - columns.extend(self.data_dict['names']) - self.result_table = wandb.Table(columns) - self.val_table = self.val_artifact.get("val") - if self.val_table_path_map is None: - self.map_val_table_path() - if opt.bbox_interval == -1: - self.bbox_interval = opt.bbox_interval = (opt.epochs // 10) if opt.epochs > 10 else 1 - train_from_artifact = self.train_artifact_path is not None and self.val_artifact_path is not None - # Update the the data_dict to point to local artifacts dir - if train_from_artifact: - self.data_dict = data_dict - - def download_dataset_artifact(self, path, alias): - """ - download the model checkpoint artifact if the path starts with WANDB_ARTIFACT_PREFIX - - arguments: - path -- path of the dataset to be used for training - alias (str)-- alias of the artifact to be download/used for training - - returns: - (str, wandb.Artifact) -- path of the downladed dataset and it's corresponding artifact object if dataset - is found otherwise returns (None, None) - """ - if isinstance(path, str) and path.startswith(WANDB_ARTIFACT_PREFIX): - artifact_path = Path(remove_prefix(path, WANDB_ARTIFACT_PREFIX) + ":" + alias) - dataset_artifact = wandb.use_artifact(artifact_path.as_posix().replace("\\", "/")) - assert dataset_artifact is not None, "'Error: W&B dataset artifact doesn\'t exist'" - datadir = dataset_artifact.download() - return datadir, dataset_artifact - return None, None - - def download_model_artifact(self, opt): - """ - download the model checkpoint artifact if the resume path starts with WANDB_ARTIFACT_PREFIX - - arguments: - opt (namespace) -- Commandline arguments for this run - """ - if opt.resume.startswith(WANDB_ARTIFACT_PREFIX): - model_artifact = wandb.use_artifact(remove_prefix(opt.resume, WANDB_ARTIFACT_PREFIX) + ":latest") - assert model_artifact is not None, 'Error: W&B model artifact doesn\'t exist' - modeldir = model_artifact.download() - epochs_trained = model_artifact.metadata.get('epochs_trained') - total_epochs = model_artifact.metadata.get('total_epochs') - is_finished = total_epochs is None - assert not is_finished, 'training is finished, can only resume incomplete runs.' - return modeldir, model_artifact - return None, None - - def log_model(self, path, opt, epoch, fitness_score, best_model=False): - """ - Log the model checkpoint as W&B artifact - - arguments: - path (Path) -- Path of directory containing the checkpoints - opt (namespace) -- Command line arguments for this run - epoch (int) -- Current epoch number - fitness_score (float) -- fitness score for current epoch - best_model (boolean) -- Boolean representing if the current checkpoint is the best yet. - """ - model_artifact = wandb.Artifact('run_' + wandb.run.id + '_model', type='model', metadata={ - 'original_url': str(path), - 'epochs_trained': epoch + 1, - 'save period': opt.save_period, - 'project': opt.project, - 'total_epochs': opt.epochs, - 'fitness_score': fitness_score - }) - model_artifact.add_file(str(path / 'last.pt'), name='last.pt') - wandb.log_artifact(model_artifact, - aliases=['latest', 'last', 'epoch ' + str(self.current_epoch), 'best' if best_model else '']) - LOGGER.info(f"Saving model artifact on epoch {epoch + 1}") - - def log_dataset_artifact(self, data_file, single_cls, project, overwrite_config=False): - """ - Log the dataset as W&B artifact and return the new data file with W&B links - - arguments: - data_file (str) -- the .yaml file with information about the dataset like - path, classes etc. - single_class (boolean) -- train multi-class data as single-class - project (str) -- project name. Used to construct the artifact path - overwrite_config (boolean) -- overwrites the data.yaml file if set to true otherwise creates a new - file with _wandb postfix. Eg -> data_wandb.yaml - - returns: - the new .yaml file with artifact links. it can be used to start training directly from artifacts - """ - upload_dataset = self.wandb_run.config.upload_dataset - log_val_only = isinstance(upload_dataset, str) and upload_dataset == 'val' - self.data_dict = check_dataset(data_file) # parse and check - data = dict(self.data_dict) - nc, names = (1, ['item']) if single_cls else (int(data['nc']), data['names']) - names = {k: v for k, v in enumerate(names)} # to index dictionary - - # log train set - if not log_val_only: - self.train_artifact = self.create_dataset_table(LoadImagesAndLabels( - data['train'], rect=True, batch_size=1), names, name='train') if data.get('train') else None - if data.get('train'): - data['train'] = WANDB_ARTIFACT_PREFIX + str(Path(project) / 'train') - - self.val_artifact = self.create_dataset_table(LoadImagesAndLabels( - data['val'], rect=True, batch_size=1), names, name='val') if data.get('val') else None - if data.get('val'): - data['val'] = WANDB_ARTIFACT_PREFIX + str(Path(project) / 'val') - - path = Path(data_file) - # create a _wandb.yaml file with artifacts links if both train and test set are logged - if not log_val_only: - path = (path.stem if overwrite_config else path.stem + '_wandb') + '.yaml' # updated data.yaml path - path = Path('data') / path - data.pop('download', None) - data.pop('path', None) - with open(path, 'w') as f: - yaml.safe_dump(data, f) - LOGGER.info(f"Created dataset config file {path}") - - if self.job_type == 'Training': # builds correct artifact pipeline graph - if not log_val_only: - self.wandb_run.log_artifact( - self.train_artifact) # calling use_artifact downloads the dataset. NOT NEEDED! - self.wandb_run.use_artifact(self.val_artifact) - self.val_artifact.wait() - self.val_table = self.val_artifact.get('val') - self.map_val_table_path() - else: - self.wandb_run.log_artifact(self.train_artifact) - self.wandb_run.log_artifact(self.val_artifact) - return path - - def map_val_table_path(self): - """ - Map the validation dataset Table like name of file -> it's id in the W&B Table. - Useful for - referencing artifacts for evaluation. - """ - self.val_table_path_map = {} - LOGGER.info("Mapping dataset") - for i, data in enumerate(tqdm(self.val_table.data)): - self.val_table_path_map[data[3]] = data[0] - - def create_dataset_table(self, dataset: LoadImagesAndLabels, class_to_id: Dict[int, str], name: str = 'dataset'): - """ - Create and return W&B artifact containing W&B Table of the dataset. - - arguments: - dataset -- instance of LoadImagesAndLabels class used to iterate over the data to build Table - class_to_id -- hash map that maps class ids to labels - name -- name of the artifact - - returns: - dataset artifact to be logged or used - """ - # TODO: Explore multiprocessing to slpit this loop parallely| This is essential for speeding up the the logging - artifact = wandb.Artifact(name=name, type="dataset") - img_files = tqdm([dataset.path]) if isinstance(dataset.path, str) and Path(dataset.path).is_dir() else None - img_files = tqdm(dataset.img_files) if not img_files else img_files - for img_file in img_files: - if Path(img_file).is_dir(): - artifact.add_dir(img_file, name='data/images') - labels_path = 'labels'.join(dataset.path.rsplit('images', 1)) - artifact.add_dir(labels_path, name='data/labels') - else: - artifact.add_file(img_file, name='data/images/' + Path(img_file).name) - label_file = Path(img2label_paths([img_file])[0]) - artifact.add_file(str(label_file), - name='data/labels/' + label_file.name) if label_file.exists() else None - table = wandb.Table(columns=["id", "train_image", "Classes", "name"]) - class_set = wandb.Classes([{'id': id, 'name': name} for id, name in class_to_id.items()]) - for si, (img, labels, paths, shapes) in enumerate(tqdm(dataset)): - box_data, img_classes = [], {} - for cls, *xywh in labels[:, 1:].tolist(): - cls = int(cls) - box_data.append({"position": {"middle": [xywh[0], xywh[1]], "width": xywh[2], "height": xywh[3]}, - "class_id": cls, - "box_caption": "%s" % (class_to_id[cls])}) - img_classes[cls] = class_to_id[cls] - boxes = {"ground_truth": {"box_data": box_data, "class_labels": class_to_id}} # inference-space - table.add_data(si, wandb.Image(paths, classes=class_set, boxes=boxes), list(img_classes.values()), - Path(paths).name) - artifact.add(table, name) - return artifact - - def log_training_progress(self, predn, path, names): - """ - Build evaluation Table. Uses reference from validation dataset table. - - arguments: - predn (list): list of predictions in the native space in the format - [xmin, ymin, xmax, ymax, confidence, class] - path (str): local path of the current evaluation image - names (dict(int, str)): hash map that maps class ids to labels - """ - class_set = wandb.Classes([{'id': id, 'name': name} for id, name in names.items()]) - box_data = [] - avg_conf_per_class = [0] * len(self.data_dict['names']) - pred_class_count = {} - for *xyxy, conf, cls in predn.tolist(): - if conf >= 0.25: - cls = int(cls) - box_data.append( - {"position": {"minX": xyxy[0], "minY": xyxy[1], "maxX": xyxy[2], "maxY": xyxy[3]}, - "class_id": cls, - "box_caption": f"{names[cls]} {conf:.3f}", - "scores": {"class_score": conf}, - "domain": "pixel"}) - avg_conf_per_class[cls] += conf - - if cls in pred_class_count: - pred_class_count[cls] += 1 - else: - pred_class_count[cls] = 1 - - for pred_class in pred_class_count.keys(): - avg_conf_per_class[pred_class] = avg_conf_per_class[pred_class] / pred_class_count[pred_class] - - boxes = {"predictions": {"box_data": box_data, "class_labels": names}} # inference-space - id = self.val_table_path_map[Path(path).name] - self.result_table.add_data(self.current_epoch, - id, - self.val_table.data[id][1], - wandb.Image(self.val_table.data[id][1], boxes=boxes, classes=class_set), - *avg_conf_per_class - ) - - def val_one_image(self, pred, predn, path, names, im): - """ - Log validation data for one image. updates the result Table if validation dataset is uploaded and log bbox media panel - - arguments: - pred (list): list of scaled predictions in the format - [xmin, ymin, xmax, ymax, confidence, class] - predn (list): list of predictions in the native space - [xmin, ymin, xmax, ymax, confidence, class] - path (str): local path of the current evaluation image - """ - if self.val_table and self.result_table: # Log Table if Val dataset is uploaded as artifact - self.log_training_progress(predn, path, names) - - if len(self.bbox_media_panel_images) < self.max_imgs_to_log and self.current_epoch > 0: - if self.current_epoch % self.bbox_interval == 0: - box_data = [{"position": {"minX": xyxy[0], "minY": xyxy[1], "maxX": xyxy[2], "maxY": xyxy[3]}, - "class_id": int(cls), - "box_caption": f"{names[cls]} {conf:.3f}", - "scores": {"class_score": conf}, - "domain": "pixel"} for *xyxy, conf, cls in pred.tolist()] - boxes = {"predictions": {"box_data": box_data, "class_labels": names}} # inference-space - self.bbox_media_panel_images.append(wandb.Image(im, boxes=boxes, caption=path.name)) - - def log(self, log_dict): - """ - save the metrics to the logging dictionary - - arguments: - log_dict (Dict) -- metrics/media to be logged in current step - """ - if self.wandb_run: - for key, value in log_dict.items(): - self.log_dict[key] = value - - def end_epoch(self, best_result=False): - """ - commit the log_dict, model artifacts and Tables to W&B and flush the log_dict. - - arguments: - best_result (boolean): Boolean representing if the result of this evaluation is best or not - """ - if self.wandb_run: - with all_logging_disabled(): - if self.bbox_media_panel_images: - self.log_dict["BoundingBoxDebugger"] = self.bbox_media_panel_images - try: - wandb.log(self.log_dict) - except BaseException as e: - LOGGER.info( - f"An error occurred in wandb logger. The training will proceed without interruption. More info\n{e}") - self.wandb_run.finish() - self.wandb_run = None - - self.log_dict = {} - self.bbox_media_panel_images = [] - if self.result_artifact: - self.result_artifact.add(self.result_table, 'result') - wandb.log_artifact(self.result_artifact, aliases=['latest', 'last', 'epoch ' + str(self.current_epoch), - ('best' if best_result else '')]) - - wandb.log({"evaluation": self.result_table}) - columns = ["epoch", "id", "ground truth", "prediction"] - columns.extend(self.data_dict['names']) - self.result_table = wandb.Table(columns) - self.result_artifact = wandb.Artifact("run_" + wandb.run.id + "_progress", "evaluation") - - def finish_run(self): - """ - Log metrics if any and finish the current W&B run - """ - if self.wandb_run: - if self.log_dict: - with all_logging_disabled(): - wandb.log(self.log_dict) - wandb.run.finish() - - -@contextmanager -def all_logging_disabled(highest_level=logging.CRITICAL): - """ source - https://gist.github.com/simon-weber/7853144 - A context manager that will prevent any logging messages triggered during the body from being processed. - :param highest_level: the maximum logging level in use. - This would only need to be changed if a custom level greater than CRITICAL is defined. - """ - previous_level = logging.root.manager.disable - logging.disable(highest_level) - try: - yield - finally: - logging.disable(previous_level) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loss.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loss.py deleted file mode 100755 index d84287483..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/loss.py +++ /dev/null @@ -1,222 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Loss functions -""" - -import torch -import torch.nn as nn - -from .metrics import bbox_iou -from .torch_utils import is_parallel - - -def smooth_BCE(eps=0.1): # https://github.com/ultralytics/yolov3/issues/238#issuecomment-598028441 - # return positive, negative label smoothing BCE targets - return 1.0 - 0.5 * eps, 0.5 * eps - - -class BCEBlurWithLogitsLoss(nn.Module): - # BCEwithLogitLoss() with reduced missing label effects. - def __init__(self, alpha=0.05): - super().__init__() - self.loss_fcn = nn.BCEWithLogitsLoss(reduction='none') # must be nn.BCEWithLogitsLoss() - self.alpha = alpha - - def forward(self, pred, true): - loss = self.loss_fcn(pred, true) - pred = torch.sigmoid(pred) # prob from logits - dx = pred - true # reduce only missing label effects - # dx = (pred - true).abs() # reduce missing label and false label effects - alpha_factor = 1 - torch.exp((dx - 1) / (self.alpha + 1e-4)) - loss *= alpha_factor - return loss.mean() - - -class FocalLoss(nn.Module): - # Wraps focal loss around existing loss_fcn(), i.e. criteria = FocalLoss(nn.BCEWithLogitsLoss(), gamma=1.5) - def __init__(self, loss_fcn, gamma=1.5, alpha=0.25): - super().__init__() - self.loss_fcn = loss_fcn # must be nn.BCEWithLogitsLoss() - self.gamma = gamma - self.alpha = alpha - self.reduction = loss_fcn.reduction - self.loss_fcn.reduction = 'none' # required to apply FL to each element - - def forward(self, pred, true): - loss = self.loss_fcn(pred, true) - # p_t = torch.exp(-loss) - # loss *= self.alpha * (1.000001 - p_t) ** self.gamma # non-zero power for gradient stability - - # TF implementation https://github.com/tensorflow/addons/blob/v0.7.1/tensorflow_addons/losses/focal_loss.py - pred_prob = torch.sigmoid(pred) # prob from logits - p_t = true * pred_prob + (1 - true) * (1 - pred_prob) - alpha_factor = true * self.alpha + (1 - true) * (1 - self.alpha) - modulating_factor = (1.0 - p_t) ** self.gamma - loss *= alpha_factor * modulating_factor - - if self.reduction == 'mean': - return loss.mean() - elif self.reduction == 'sum': - return loss.sum() - else: # 'none' - return loss - - -class QFocalLoss(nn.Module): - # Wraps Quality focal loss around existing loss_fcn(), i.e. criteria = FocalLoss(nn.BCEWithLogitsLoss(), gamma=1.5) - def __init__(self, loss_fcn, gamma=1.5, alpha=0.25): - super().__init__() - self.loss_fcn = loss_fcn # must be nn.BCEWithLogitsLoss() - self.gamma = gamma - self.alpha = alpha - self.reduction = loss_fcn.reduction - self.loss_fcn.reduction = 'none' # required to apply FL to each element - - def forward(self, pred, true): - loss = self.loss_fcn(pred, true) - - pred_prob = torch.sigmoid(pred) # prob from logits - alpha_factor = true * self.alpha + (1 - true) * (1 - self.alpha) - modulating_factor = torch.abs(true - pred_prob) ** self.gamma - loss *= alpha_factor * modulating_factor - - if self.reduction == 'mean': - return loss.mean() - elif self.reduction == 'sum': - return loss.sum() - else: # 'none' - return loss - - -class ComputeLoss: - # Compute losses - def __init__(self, model, autobalance=False): - self.sort_obj_iou = False - device = next(model.parameters()).device # get model device - h = model.hyp # hyperparameters - - # Define criteria - BCEcls = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([h['cls_pw']], device=device)) - BCEobj = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([h['obj_pw']], device=device)) - - # Class label smoothing https://arxiv.org/pdf/1902.04103.pdf eqn 3 - self.cp, self.cn = smooth_BCE(eps=h.get('label_smoothing', 0.0)) # positive, negative BCE targets - - # Focal loss - g = h['fl_gamma'] # focal loss gamma - if g > 0: - BCEcls, BCEobj = FocalLoss(BCEcls, g), FocalLoss(BCEobj, g) - - det = model.module.model[-1] if is_parallel(model) else model.model[-1] # Detect() module - self.balance = {3: [4.0, 1.0, 0.4]}.get(det.nl, [4.0, 1.0, 0.25, 0.06, 0.02]) # P3-P7 - self.ssi = list(det.stride).index(16) if autobalance else 0 # stride 16 index - self.BCEcls, self.BCEobj, self.gr, self.hyp, self.autobalance = BCEcls, BCEobj, 1.0, h, autobalance - for k in 'na', 'nc', 'nl', 'anchors': - setattr(self, k, getattr(det, k)) - - def __call__(self, p, targets): # predictions, targets, model - device = targets.device - lcls, lbox, lobj = torch.zeros(1, device=device), torch.zeros(1, device=device), torch.zeros(1, device=device) - tcls, tbox, indices, anchors = self.build_targets(p, targets) # targets - - # Losses - for i, pi in enumerate(p): # layer index, layer predictions - b, a, gj, gi = indices[i] # image, anchor, gridy, gridx - tobj = torch.zeros_like(pi[..., 0], device=device) # target obj - - n = b.shape[0] # number of targets - if n: - ps = pi[b, a, gj, gi] # prediction subset corresponding to targets - - # Regression - pxy = ps[:, :2].sigmoid() * 2 - 0.5 - pwh = (ps[:, 2:4].sigmoid() * 2) ** 2 * anchors[i] - pbox = torch.cat((pxy, pwh), 1) # predicted box - iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True) # iou(prediction, target) - lbox += (1.0 - iou).mean() # iou loss - - # Objectness - score_iou = iou.detach().clamp(0).type(tobj.dtype) - if self.sort_obj_iou: - sort_id = torch.argsort(score_iou) - b, a, gj, gi, score_iou = b[sort_id], a[sort_id], gj[sort_id], gi[sort_id], score_iou[sort_id] - tobj[b, a, gj, gi] = (1.0 - self.gr) + self.gr * score_iou # iou ratio - - # Classification - if self.nc > 1: # cls loss (only if multiple classes) - t = torch.full_like(ps[:, 5:], self.cn, device=device) # targets - t[range(n), tcls[i]] = self.cp - lcls += self.BCEcls(ps[:, 5:], t) # BCE - - # Append targets to text file - # with open('targets.txt', 'a') as file: - # [file.write('%11.5g ' * 4 % tuple(x) + '\n') for x in torch.cat((txy[i], twh[i]), 1)] - - obji = self.BCEobj(pi[..., 4], tobj) - lobj += obji * self.balance[i] # obj loss - if self.autobalance: - self.balance[i] = self.balance[i] * 0.9999 + 0.0001 / obji.detach().item() - - if self.autobalance: - self.balance = [x / self.balance[self.ssi] for x in self.balance] - lbox *= self.hyp['box'] - lobj *= self.hyp['obj'] - lcls *= self.hyp['cls'] - bs = tobj.shape[0] # batch size - - return (lbox + lobj + lcls) * bs, torch.cat((lbox, lobj, lcls)).detach() - - def build_targets(self, p, targets): - # Build targets for compute_loss(), input targets(image,class,x,y,w,h) - na, nt = self.na, targets.shape[0] # number of anchors, targets - tcls, tbox, indices, anch = [], [], [], [] - gain = torch.ones(7, device=targets.device) # normalized to gridspace gain - ai = torch.arange(na, device=targets.device).float().view(na, 1).repeat(1, nt) # same as .repeat_interleave(nt) - targets = torch.cat((targets.repeat(na, 1, 1), ai[:, :, None]), 2) # append anchor indices - - g = 0.5 # bias - off = torch.tensor([[0, 0], - [1, 0], [0, 1], [-1, 0], [0, -1], # j,k,l,m - # [1, 1], [1, -1], [-1, 1], [-1, -1], # jk,jm,lk,lm - ], device=targets.device).float() * g # offsets - - for i in range(self.nl): - anchors = self.anchors[i] - gain[2:6] = torch.tensor(p[i].shape)[[3, 2, 3, 2]] # xyxy gain - - # Match targets to anchors - t = targets * gain - if nt: - # Matches - r = t[:, :, 4:6] / anchors[:, None] # wh ratio - j = torch.max(r, 1 / r).max(2)[0] < self.hyp['anchor_t'] # compare - # j = wh_iou(anchors, t[:, 4:6]) > model.hyp['iou_t'] # iou(3,n)=wh_iou(anchors(3,2), gwh(n,2)) - t = t[j] # filter - - # Offsets - gxy = t[:, 2:4] # grid xy - gxi = gain[[2, 3]] - gxy # inverse - j, k = ((gxy % 1 < g) & (gxy > 1)).T - l, m = ((gxi % 1 < g) & (gxi > 1)).T - j = torch.stack((torch.ones_like(j), j, k, l, m)) - t = t.repeat((5, 1, 1))[j] - offsets = (torch.zeros_like(gxy)[None] + off[:, None])[j] - else: - t = targets[0] - offsets = 0 - - # Define - b, c = t[:, :2].long().T # image, class - gxy = t[:, 2:4] # grid xy - gwh = t[:, 4:6] # grid wh - gij = (gxy - offsets).long() - gi, gj = gij.T # grid xy indices - - # Append - a = t[:, 6].long() # anchor indices - indices.append((b, a, gj.clamp_(0, gain[3] - 1), gi.clamp_(0, gain[2] - 1))) # image, anchor, grid indices - tbox.append(torch.cat((gxy - gij, gwh), 1)) # box - anch.append(anchors[a]) # anchors - tcls.append(c) # class - - return tcls, tbox, indices, anch diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/metrics.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/metrics.py deleted file mode 100755 index 3f1dc559c..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/metrics.py +++ /dev/null @@ -1,344 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Model validation metrics -""" - -import math -import warnings -from pathlib import Path - -import matplotlib.pyplot as plt -import numpy as np -import torch - - -def fitness(x): - # Model fitness as a weighted combination of metrics - w = [0.0, 0.0, 0.1, 0.9] # weights for [P, R, mAP@0.5, mAP@0.5:0.95] - return (x[:, :4] * w).sum(1) - - -def ap_per_class(tp, conf, pred_cls, target_cls, plot=False, save_dir='.', names=(), eps=1e-16): - """ Compute the average precision, given the recall and precision curves. - Source: https://github.com/rafaelpadilla/Object-Detection-Metrics. - # Arguments - tp: True positives (nparray, nx1 or nx10). - conf: Objectness value from 0-1 (nparray). - pred_cls: Predicted object classes (nparray). - target_cls: True object classes (nparray). - plot: Plot precision-recall curve at mAP@0.5 - save_dir: Plot save directory - # Returns - The average precision as computed in py-faster-rcnn. - """ - - # Sort by objectness - i = np.argsort(-conf) - tp, conf, pred_cls = tp[i], conf[i], pred_cls[i] - - # Find unique classes - unique_classes, nt = np.unique(target_cls, return_counts=True) - nc = unique_classes.shape[0] # number of classes, number of detections - - # Create Precision-Recall curve and compute AP for each class - px, py = np.linspace(0, 1, 1000), [] # for plotting - ap, p, r = np.zeros((nc, tp.shape[1])), np.zeros((nc, 1000)), np.zeros((nc, 1000)) - for ci, c in enumerate(unique_classes): - i = pred_cls == c - n_l = nt[ci] # number of labels - n_p = i.sum() # number of predictions - - if n_p == 0 or n_l == 0: - continue - else: - # Accumulate FPs and TPs - fpc = (1 - tp[i]).cumsum(0) - tpc = tp[i].cumsum(0) - - # Recall - recall = tpc / (n_l + eps) # recall curve - r[ci] = np.interp(-px, -conf[i], recall[:, 0], left=0) # negative x, xp because xp decreases - - # Precision - precision = tpc / (tpc + fpc) # precision curve - p[ci] = np.interp(-px, -conf[i], precision[:, 0], left=1) # p at pr_score - - # AP from recall-precision curve - for j in range(tp.shape[1]): - ap[ci, j], mpre, mrec = compute_ap(recall[:, j], precision[:, j]) - if plot and j == 0: - py.append(np.interp(px, mrec, mpre)) # precision at mAP@0.5 - - # Compute F1 (harmonic mean of precision and recall) - f1 = 2 * p * r / (p + r + eps) - names = [v for k, v in names.items() if k in unique_classes] # list: only classes that have data - names = {i: v for i, v in enumerate(names)} # to dict - if plot: - plot_pr_curve(px, py, ap, Path(save_dir) / 'PR_curve.png', names) - plot_mc_curve(px, f1, Path(save_dir) / 'F1_curve.png', names, ylabel='F1') - plot_mc_curve(px, p, Path(save_dir) / 'P_curve.png', names, ylabel='Precision') - plot_mc_curve(px, r, Path(save_dir) / 'R_curve.png', names, ylabel='Recall') - - i = f1.mean(0).argmax() # max F1 index - p, r, f1 = p[:, i], r[:, i], f1[:, i] - tp = (r * nt).round() # true positives - fp = (tp / (p + eps) - tp).round() # false positives - return tp, fp, p, r, f1, ap, unique_classes.astype('int32') - - -def compute_ap(recall, precision): - """ Compute the average precision, given the recall and precision curves - # Arguments - recall: The recall curve (list) - precision: The precision curve (list) - # Returns - Average precision, precision curve, recall curve - """ - - # Append sentinel values to beginning and end - mrec = np.concatenate(([0.0], recall, [1.0])) - mpre = np.concatenate(([1.0], precision, [0.0])) - - # Compute the precision envelope - mpre = np.flip(np.maximum.accumulate(np.flip(mpre))) - - # Integrate area under curve - method = 'interp' # methods: 'continuous', 'interp' - if method == 'interp': - x = np.linspace(0, 1, 101) # 101-point interp (COCO) - ap = np.trapz(np.interp(x, mrec, mpre), x) # integrate - else: # 'continuous' - i = np.where(mrec[1:] != mrec[:-1])[0] # points where x axis (recall) changes - ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) # area under curve - - return ap, mpre, mrec - - -class ConfusionMatrix: - # Updated version of https://github.com/kaanakan/object_detection_confusion_matrix - def __init__(self, nc, conf=0.25, iou_thres=0.45): - self.matrix = np.zeros((nc + 1, nc + 1)) - self.nc = nc # number of classes - self.conf = conf - self.iou_thres = iou_thres - - def process_batch(self, detections, labels): - """ - Return intersection-over-union (Jaccard index) of boxes. - Both sets of boxes are expected to be in (x1, y1, x2, y2) format. - Arguments: - detections (Array[N, 6]), x1, y1, x2, y2, conf, class - labels (Array[M, 5]), class, x1, y1, x2, y2 - Returns: - None, updates confusion matrix accordingly - """ - detections = detections[detections[:, 4] > self.conf] - gt_classes = labels[:, 0].int() - detection_classes = detections[:, 5].int() - iou = box_iou(labels[:, 1:], detections[:, :4]) - - x = torch.where(iou > self.iou_thres) - if x[0].shape[0]: - matches = torch.cat((torch.stack(x, 1), iou[x[0], x[1]][:, None]), 1).cpu().numpy() - if x[0].shape[0] > 1: - matches = matches[matches[:, 2].argsort()[::-1]] - matches = matches[np.unique(matches[:, 1], return_index=True)[1]] - matches = matches[matches[:, 2].argsort()[::-1]] - matches = matches[np.unique(matches[:, 0], return_index=True)[1]] - else: - matches = np.zeros((0, 3)) - - n = matches.shape[0] > 0 - m0, m1, _ = matches.transpose().astype(np.int16) - for i, gc in enumerate(gt_classes): - j = m0 == i - if n and sum(j) == 1: - self.matrix[detection_classes[m1[j]], gc] += 1 # correct - else: - self.matrix[self.nc, gc] += 1 # background FP - - if n: - for i, dc in enumerate(detection_classes): - if not any(m1 == i): - self.matrix[dc, self.nc] += 1 # background FN - - def matrix(self): - return self.matrix - - def tp_fp(self): - tp = self.matrix.diagonal() # true positives - fp = self.matrix.sum(1) - tp # false positives - # fn = self.matrix.sum(0) - tp # false negatives (missed detections) - return tp[:-1], fp[:-1] # remove background class - - def plot(self, normalize=True, save_dir='', names=()): - try: - import seaborn as sn - - array = self.matrix / ((self.matrix.sum(0).reshape(1, -1) + 1E-6) if normalize else 1) # normalize columns - array[array < 0.005] = np.nan # don't annotate (would appear as 0.00) - - fig = plt.figure(figsize=(12, 9), tight_layout=True) - sn.set(font_scale=1.0 if self.nc < 50 else 0.8) # for label size - labels = (0 < len(names) < 99) and len(names) == self.nc # apply names to ticklabels - with warnings.catch_warnings(): - warnings.simplefilter('ignore') # suppress empty matrix RuntimeWarning: All-NaN slice encountered - sn.heatmap(array, annot=self.nc < 30, annot_kws={"size": 8}, cmap='Blues', fmt='.2f', square=True, - xticklabels=names + ['background FP'] if labels else "auto", - yticklabels=names + ['background FN'] if labels else "auto").set_facecolor((1, 1, 1)) - fig.axes[0].set_xlabel('True') - fig.axes[0].set_ylabel('Predicted') - fig.savefig(Path(save_dir) / 'confusion_matrix.png', dpi=250) - plt.close() - except Exception as e: - print(f'WARNING: ConfusionMatrix plot failure: {e}') - - def print(self): - for i in range(self.nc + 1): - print(' '.join(map(str, self.matrix[i]))) - - -def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, eps=1e-7): - # Returns the IoU of box1 to box2. box1 is 4, box2 is nx4 - box2 = box2.T - - # Get the coordinates of bounding boxes - if x1y1x2y2: # x1, y1, x2, y2 = box1 - b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3] - b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3] - else: # transform from xywh to xyxy - b1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2 - b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2 - b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2 - b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2 - - # Intersection area - inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \ - (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0) - - # Union Area - w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps - w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps - union = w1 * h1 + w2 * h2 - inter + eps - - iou = inter / union - if GIoU or DIoU or CIoU: - cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1) # convex (smallest enclosing box) width - ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1) # convex height - if CIoU or DIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1 - c2 = cw ** 2 + ch ** 2 + eps # convex diagonal squared - rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + - (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # center distance squared - if DIoU: - return iou - rho2 / c2 # DIoU - elif CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47 - v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2) - with torch.no_grad(): - alpha = v / (v - iou + (1 + eps)) - return iou - (rho2 / c2 + v * alpha) # CIoU - else: # GIoU https://arxiv.org/pdf/1902.09630.pdf - c_area = cw * ch + eps # convex area - return iou - (c_area - union) / c_area # GIoU - else: - return iou # IoU - - -def box_iou(box1, box2): - # https://github.com/pytorch/vision/blob/master/torchvision/ops/boxes.py - """ - Return intersection-over-union (Jaccard index) of boxes. - Both sets of boxes are expected to be in (x1, y1, x2, y2) format. - Arguments: - box1 (Tensor[N, 4]) - box2 (Tensor[M, 4]) - Returns: - iou (Tensor[N, M]): the NxM matrix containing the pairwise - IoU values for every element in boxes1 and boxes2 - """ - - def box_area(box): - # box = 4xn - return (box[2] - box[0]) * (box[3] - box[1]) - - area1 = box_area(box1.T) - area2 = box_area(box2.T) - - # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2) - inter = (torch.min(box1[:, None, 2:], box2[:, 2:]) - torch.max(box1[:, None, :2], box2[:, :2])).clamp(0).prod(2) - return inter / (area1[:, None] + area2 - inter) # iou = inter / (area1 + area2 - inter) - - -def bbox_ioa(box1, box2, eps=1E-7): - """ Returns the intersection over box2 area given box1, box2. Boxes are x1y1x2y2 - box1: np.array of shape(4) - box2: np.array of shape(nx4) - returns: np.array of shape(n) - """ - - box2 = box2.transpose() - - # Get the coordinates of bounding boxes - b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3] - b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3] - - # Intersection area - inter_area = (np.minimum(b1_x2, b2_x2) - np.maximum(b1_x1, b2_x1)).clip(0) * \ - (np.minimum(b1_y2, b2_y2) - np.maximum(b1_y1, b2_y1)).clip(0) - - # box2 area - box2_area = (b2_x2 - b2_x1) * (b2_y2 - b2_y1) + eps - - # Intersection over box2 area - return inter_area / box2_area - - -def wh_iou(wh1, wh2): - # Returns the nxm IoU matrix. wh1 is nx2, wh2 is mx2 - wh1 = wh1[:, None] # [N,1,2] - wh2 = wh2[None] # [1,M,2] - inter = torch.min(wh1, wh2).prod(2) # [N,M] - return inter / (wh1.prod(2) + wh2.prod(2) - inter) # iou = inter / (area1 + area2 - inter) - - -# Plots ---------------------------------------------------------------------------------------------------------------- - -def plot_pr_curve(px, py, ap, save_dir='pr_curve.png', names=()): - # Precision-recall curve - fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True) - py = np.stack(py, axis=1) - - if 0 < len(names) < 21: # display per-class legend if < 21 classes - for i, y in enumerate(py.T): - ax.plot(px, y, linewidth=1, label=f'{names[i]} {ap[i, 0]:.3f}') # plot(recall, precision) - else: - ax.plot(px, py, linewidth=1, color='grey') # plot(recall, precision) - - ax.plot(px, py.mean(1), linewidth=3, color='blue', label='all classes %.3f mAP@0.5' % ap[:, 0].mean()) - ax.set_xlabel('Recall') - ax.set_ylabel('Precision') - ax.set_xlim(0, 1) - ax.set_ylim(0, 1) - plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left") - fig.savefig(Path(save_dir), dpi=250) - plt.close() - - -def plot_mc_curve(px, py, save_dir='mc_curve.png', names=(), xlabel='Confidence', ylabel='Metric'): - # Metric-confidence curve - fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True) - - if 0 < len(names) < 21: # display per-class legend if < 21 classes - for i, y in enumerate(py): - ax.plot(px, y, linewidth=1, label=f'{names[i]}') # plot(confidence, metric) - else: - ax.plot(px, py.T, linewidth=1, color='grey') # plot(confidence, metric) - - y = py.mean(0) - ax.plot(px, y, linewidth=3, color='blue', label=f'all classes {y.max():.2f} at {px[y.argmax()]:.3f}') - ax.set_xlabel(xlabel) - ax.set_ylabel(ylabel) - ax.set_xlim(0, 1) - ax.set_ylim(0, 1) - plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left") - fig.savefig(Path(save_dir), dpi=250) - plt.close() diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/plots.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/plots.py deleted file mode 100755 index 6df0efd4a..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/plots.py +++ /dev/null @@ -1,470 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Plotting utils -""" - -import math -import os -from copy import copy -from pathlib import Path - -import cv2 -import matplotlib -import matplotlib.pyplot as plt -import numpy as np -import pandas as pd -import seaborn as sn -import torch -from PIL import Image, ImageDraw, ImageFont - -from .general import (LOGGER, Timeout, check_requirements, clip_coords, increment_path, is_ascii, is_chinese, - try_except, user_config_dir, xywh2xyxy, xyxy2xywh) -from .metrics import fitness - -# Settings -CONFIG_DIR = user_config_dir() # Ultralytics settings dir -RANK = int(os.getenv('RANK', -1)) -matplotlib.rc('font', **{'size': 11}) -matplotlib.use('Agg') # for writing to files only - - -class Colors: - # Ultralytics color palette https://ultralytics.com/ - def __init__(self): - # hex = matplotlib.colors.TABLEAU_COLORS.values() - hex = ('FF3838', 'FF9D97', 'FF701F', 'FFB21D', 'CFD231', '48F90A', '92CC17', '3DDB86', '1A9334', '00D4BB', - '2C99A8', '00C2FF', '344593', '6473FF', '0018EC', '8438FF', '520085', 'CB38FF', 'FF95C8', 'FF37C7') - self.palette = [self.hex2rgb('#' + c) for c in hex] - self.n = len(self.palette) - - def __call__(self, i, bgr=False): - c = self.palette[int(i) % self.n] - return (c[2], c[1], c[0]) if bgr else c - - @staticmethod - def hex2rgb(h): # rgb order (PIL) - return tuple(int(h[1 + i:1 + i + 2], 16) for i in (0, 2, 4)) - - -colors = Colors() # create instance for 'from utils.plots import colors' - - -def check_font(font='Arial.ttf', size=10): - # Return a PIL TrueType Font, downloading to CONFIG_DIR if necessary - font = Path(font) - font = font if font.exists() else (CONFIG_DIR / font.name) - try: - return ImageFont.truetype(str(font) if font.exists() else font.name, size) - except Exception as e: # download if missing - url = "https://ultralytics.com/assets/" + font.name - print(f'Downloading {url} to {font}...') - torch.hub.download_url_to_file(url, str(font), progress=False) - try: - return ImageFont.truetype(str(font), size) - except TypeError: - check_requirements('Pillow>=8.4.0') # known issue https://github.com/ultralytics/yolov5/issues/5374 - - -class Annotator: - if RANK in (-1, 0): - check_font() # download TTF if necessary - - # YOLOv5 Annotator for train/val mosaics and jpgs and detect/hub inference annotations - def __init__(self, im, line_width=None, font_size=None, font='Arial.ttf', pil=False, example='abc'): - assert im.data.contiguous, 'Image not contiguous. Apply np.ascontiguousarray(im) to Annotator() input images.' - self.pil = pil or not is_ascii(example) or is_chinese(example) - if self.pil: # use PIL - self.im = im if isinstance(im, Image.Image) else Image.fromarray(im) - self.draw = ImageDraw.Draw(self.im) - self.font = check_font(font='Arial.Unicode.ttf' if is_chinese(example) else font, - size=font_size or max(round(sum(self.im.size) / 2 * 0.035), 12)) - else: # use cv2 - self.im = im - self.lw = line_width or max(round(sum(im.shape) / 2 * 0.003), 2) # line width - - def box_label(self, box, label='', color=(128, 128, 128), txt_color=(255, 255, 255)): - # Add one xyxy box to image with label - if self.pil or not is_ascii(label): - self.draw.rectangle(box, width=self.lw, outline=color) # box - if label: - w, h = self.font.getsize(label) # text width, height - outside = box[1] - h >= 0 # label fits outside box - self.draw.rectangle([box[0], - box[1] - h if outside else box[1], - box[0] + w + 1, - box[1] + 1 if outside else box[1] + h + 1], fill=color) - # self.draw.text((box[0], box[1]), label, fill=txt_color, font=self.font, anchor='ls') # for PIL>8.0 - self.draw.text((box[0], box[1] - h if outside else box[1]), label, fill=txt_color, font=self.font) - else: # cv2 - p1, p2 = (int(box[0]), int(box[1])), (int(box[2]), int(box[3])) - cv2.rectangle(self.im, p1, p2, color, thickness=self.lw, lineType=cv2.LINE_AA) - if label: - tf = max(self.lw - 1, 1) # font thickness - w, h = cv2.getTextSize(label, 0, fontScale=self.lw / 3, thickness=tf)[0] # text width, height - outside = p1[1] - h - 3 >= 0 # label fits outside box - p2 = p1[0] + w, p1[1] - h - 3 if outside else p1[1] + h + 3 - cv2.rectangle(self.im, p1, p2, color, -1, cv2.LINE_AA) # filled - cv2.putText(self.im, label, (p1[0], p1[1] - 2 if outside else p1[1] + h + 2), 0, self.lw / 3, txt_color, - thickness=tf, lineType=cv2.LINE_AA) - - def rectangle(self, xy, fill=None, outline=None, width=1): - # Add rectangle to image (PIL-only) - self.draw.rectangle(xy, fill, outline, width) - - def text(self, xy, text, txt_color=(255, 255, 255)): - # Add text to image (PIL-only) - w, h = self.font.getsize(text) # text width, height - self.draw.text((xy[0], xy[1] - h + 1), text, fill=txt_color, font=self.font) - - def result(self): - # Return annotated image as array - return np.asarray(self.im) - - -def feature_visualization(x, module_type, stage, n=32, save_dir=Path('runs/detect/exp')): - """ - x: Features to be visualized - module_type: Module type - stage: Module stage within model - n: Maximum number of feature maps to plot - save_dir: Directory to save results - """ - if 'Detect' not in module_type: - batch, channels, height, width = x.shape # batch, channels, height, width - if height > 1 and width > 1: - f = save_dir / f"stage{stage}_{module_type.split('.')[-1]}_features.png" # filename - - blocks = torch.chunk(x[0].cpu(), channels, dim=0) # select batch index 0, block by channels - n = min(n, channels) # number of plots - fig, ax = plt.subplots(math.ceil(n / 8), 8, tight_layout=True) # 8 rows x n/8 cols - ax = ax.ravel() - plt.subplots_adjust(wspace=0.05, hspace=0.05) - for i in range(n): - ax[i].imshow(blocks[i].squeeze()) # cmap='gray' - ax[i].axis('off') - - print(f'Saving {f}... ({n}/{channels})') - plt.savefig(f, dpi=300, bbox_inches='tight') - plt.close() - np.save(str(f.with_suffix('.npy')), x[0].cpu().numpy()) # npy save - - -def hist2d(x, y, n=100): - # 2d histogram used in labels.png and evolve.png - xedges, yedges = np.linspace(x.min(), x.max(), n), np.linspace(y.min(), y.max(), n) - hist, xedges, yedges = np.histogram2d(x, y, (xedges, yedges)) - xidx = np.clip(np.digitize(x, xedges) - 1, 0, hist.shape[0] - 1) - yidx = np.clip(np.digitize(y, yedges) - 1, 0, hist.shape[1] - 1) - return np.log(hist[xidx, yidx]) - - -def butter_lowpass_filtfilt(data, cutoff=1500, fs=50000, order=5): - from scipy.signal import butter, filtfilt - - # https://stackoverflow.com/questions/28536191/how-to-filter-smooth-with-scipy-numpy - def butter_lowpass(cutoff, fs, order): - nyq = 0.5 * fs - normal_cutoff = cutoff / nyq - return butter(order, normal_cutoff, btype='low', analog=False) - - b, a = butter_lowpass(cutoff, fs, order=order) - return filtfilt(b, a, data) # forward-backward filter - - -def output_to_target(output): - # Convert model output to target format [batch_id, class_id, x, y, w, h, conf] - targets = [] - for i, o in enumerate(output): - for *box, conf, cls in o.cpu().numpy(): - targets.append([i, cls, *list(*xyxy2xywh(np.array(box)[None])), conf]) - return np.array(targets) - - -def plot_images(images, targets, paths=None, fname='images.jpg', names=None, max_size=1920, max_subplots=16): - # Plot image grid with labels - if isinstance(images, torch.Tensor): - images = images.cpu().float().numpy() - if isinstance(targets, torch.Tensor): - targets = targets.cpu().numpy() - if np.max(images[0]) <= 1: - images *= 255 # de-normalise (optional) - bs, _, h, w = images.shape # batch size, _, height, width - bs = min(bs, max_subplots) # limit plot images - ns = np.ceil(bs ** 0.5) # number of subplots (square) - - # Build Image - mosaic = np.full((int(ns * h), int(ns * w), 3), 255, dtype=np.uint8) # init - for i, im in enumerate(images): - if i == max_subplots: # if last batch has fewer images than we expect - break - x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin - im = im.transpose(1, 2, 0) - mosaic[y:y + h, x:x + w, :] = im - - # Resize (optional) - scale = max_size / ns / max(h, w) - if scale < 1: - h = math.ceil(scale * h) - w = math.ceil(scale * w) - mosaic = cv2.resize(mosaic, tuple(int(x * ns) for x in (w, h))) - - # Annotate - fs = int((h + w) * ns * 0.01) # font size - annotator = Annotator(mosaic, line_width=round(fs / 10), font_size=fs, pil=True) - for i in range(i + 1): - x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin - annotator.rectangle([x, y, x + w, y + h], None, (255, 255, 255), width=2) # borders - if paths: - annotator.text((x + 5, y + 5 + h), text=Path(paths[i]).name[:40], txt_color=(220, 220, 220)) # filenames - if len(targets) > 0: - ti = targets[targets[:, 0] == i] # image targets - boxes = xywh2xyxy(ti[:, 2:6]).T - classes = ti[:, 1].astype('int') - labels = ti.shape[1] == 6 # labels if no conf column - conf = None if labels else ti[:, 6] # check for confidence presence (label vs pred) - - if boxes.shape[1]: - if boxes.max() <= 1.01: # if normalized with tolerance 0.01 - boxes[[0, 2]] *= w # scale to pixels - boxes[[1, 3]] *= h - elif scale < 1: # absolute coords need scale if image scales - boxes *= scale - boxes[[0, 2]] += x - boxes[[1, 3]] += y - for j, box in enumerate(boxes.T.tolist()): - cls = classes[j] - color = colors(cls) - cls = names[cls] if names else cls - if labels or conf[j] > 0.25: # 0.25 conf thresh - label = f'{cls}' if labels else f'{cls} {conf[j]:.1f}' - annotator.box_label(box, label, color=color) - annotator.im.save(fname) # save - - -def plot_lr_scheduler(optimizer, scheduler, epochs=300, save_dir=''): - # Plot LR simulating training for full epochs - optimizer, scheduler = copy(optimizer), copy(scheduler) # do not modify originals - y = [] - for _ in range(epochs): - scheduler.step() - y.append(optimizer.param_groups[0]['lr']) - plt.plot(y, '.-', label='LR') - plt.xlabel('epoch') - plt.ylabel('LR') - plt.grid() - plt.xlim(0, epochs) - plt.ylim(0) - plt.savefig(Path(save_dir) / 'LR.png', dpi=200) - plt.close() - - -def plot_val_txt(): # from utils.plots import *; plot_val() - # Plot val.txt histograms - x = np.loadtxt('val.txt', dtype=np.float32) - box = xyxy2xywh(x[:, :4]) - cx, cy = box[:, 0], box[:, 1] - - fig, ax = plt.subplots(1, 1, figsize=(6, 6), tight_layout=True) - ax.hist2d(cx, cy, bins=600, cmax=10, cmin=0) - ax.set_aspect('equal') - plt.savefig('hist2d.png', dpi=300) - - fig, ax = plt.subplots(1, 2, figsize=(12, 6), tight_layout=True) - ax[0].hist(cx, bins=600) - ax[1].hist(cy, bins=600) - plt.savefig('hist1d.png', dpi=200) - - -def plot_targets_txt(): # from utils.plots import *; plot_targets_txt() - # Plot targets.txt histograms - x = np.loadtxt('targets.txt', dtype=np.float32).T - s = ['x targets', 'y targets', 'width targets', 'height targets'] - fig, ax = plt.subplots(2, 2, figsize=(8, 8), tight_layout=True) - ax = ax.ravel() - for i in range(4): - ax[i].hist(x[i], bins=100, label=f'{x[i].mean():.3g} +/- {x[i].std():.3g}') - ax[i].legend() - ax[i].set_title(s[i]) - plt.savefig('targets.jpg', dpi=200) - - -def plot_val_study(file='', dir='', x=None): # from utils.plots import *; plot_val_study() - # Plot file=study.txt generated by val.py (or plot all study*.txt in dir) - save_dir = Path(file).parent if file else Path(dir) - plot2 = False # plot additional results - if plot2: - ax = plt.subplots(2, 4, figsize=(10, 6), tight_layout=True)[1].ravel() - - fig2, ax2 = plt.subplots(1, 1, figsize=(8, 4), tight_layout=True) - # for f in [save_dir / f'study_coco_{x}.txt' for x in ['yolov5n6', 'yolov5s6', 'yolov5m6', 'yolov5l6', 'yolov5x6']]: - for f in sorted(save_dir.glob('study*.txt')): - y = np.loadtxt(f, dtype=np.float32, usecols=[0, 1, 2, 3, 7, 8, 9], ndmin=2).T - x = np.arange(y.shape[1]) if x is None else np.array(x) - if plot2: - s = ['P', 'R', 'mAP@.5', 'mAP@.5:.95', 't_preprocess (ms/img)', 't_inference (ms/img)', 't_NMS (ms/img)'] - for i in range(7): - ax[i].plot(x, y[i], '.-', linewidth=2, markersize=8) - ax[i].set_title(s[i]) - - j = y[3].argmax() + 1 - ax2.plot(y[5, 1:j], y[3, 1:j] * 1E2, '.-', linewidth=2, markersize=8, - label=f.stem.replace('study_coco_', '').replace('yolo', 'YOLO')) - - ax2.plot(1E3 / np.array([209, 140, 97, 58, 35, 18]), [34.6, 40.5, 43.0, 47.5, 49.7, 51.5], - 'k.-', linewidth=2, markersize=8, alpha=.25, label='EfficientDet') - - ax2.grid(alpha=0.2) - ax2.set_yticks(np.arange(20, 60, 5)) - ax2.set_xlim(0, 57) - ax2.set_ylim(25, 55) - ax2.set_xlabel('GPU Speed (ms/img)') - ax2.set_ylabel('COCO AP val') - ax2.legend(loc='lower right') - f = save_dir / 'study.png' - print(f'Saving {f}...') - plt.savefig(f, dpi=300) - - -@try_except # known issue https://github.com/ultralytics/yolov5/issues/5395 -@Timeout(30) # known issue https://github.com/ultralytics/yolov5/issues/5611 -def plot_labels(labels, names=(), save_dir=Path('')): - # plot dataset labels - LOGGER.info(f"Plotting labels to {save_dir / 'labels.jpg'}... ") - c, b = labels[:, 0], labels[:, 1:].transpose() # classes, boxes - nc = int(c.max() + 1) # number of classes - x = pd.DataFrame(b.transpose(), columns=['x', 'y', 'width', 'height']) - - # seaborn correlogram - sn.pairplot(x, corner=True, diag_kind='auto', kind='hist', diag_kws=dict(bins=50), plot_kws=dict(pmax=0.9)) - plt.savefig(save_dir / 'labels_correlogram.jpg', dpi=200) - plt.close() - - # matplotlib labels - matplotlib.use('svg') # faster - ax = plt.subplots(2, 2, figsize=(8, 8), tight_layout=True)[1].ravel() - y = ax[0].hist(c, bins=np.linspace(0, nc, nc + 1) - 0.5, rwidth=0.8) - # [y[2].patches[i].set_color([x / 255 for x in colors(i)]) for i in range(nc)] # update colors bug #3195 - ax[0].set_ylabel('instances') - if 0 < len(names) < 30: - ax[0].set_xticks(range(len(names))) - ax[0].set_xticklabels(names, rotation=90, fontsize=10) - else: - ax[0].set_xlabel('classes') - sn.histplot(x, x='x', y='y', ax=ax[2], bins=50, pmax=0.9) - sn.histplot(x, x='width', y='height', ax=ax[3], bins=50, pmax=0.9) - - # rectangles - labels[:, 1:3] = 0.5 # center - labels[:, 1:] = xywh2xyxy(labels[:, 1:]) * 2000 - img = Image.fromarray(np.ones((2000, 2000, 3), dtype=np.uint8) * 255) - for cls, *box in labels[:1000]: - ImageDraw.Draw(img).rectangle(box, width=1, outline=colors(cls)) # plot - ax[1].imshow(img) - ax[1].axis('off') - - for a in [0, 1, 2, 3]: - for s in ['top', 'right', 'left', 'bottom']: - ax[a].spines[s].set_visible(False) - - plt.savefig(save_dir / 'labels.jpg', dpi=200) - matplotlib.use('Agg') - plt.close() - - -def plot_evolve(evolve_csv='path/to/evolve.csv'): # from utils.plots import *; plot_evolve() - # Plot evolve.csv hyp evolution results - evolve_csv = Path(evolve_csv) - data = pd.read_csv(evolve_csv) - keys = [x.strip() for x in data.columns] - x = data.values - f = fitness(x) - j = np.argmax(f) # max fitness index - plt.figure(figsize=(10, 12), tight_layout=True) - matplotlib.rc('font', **{'size': 8}) - for i, k in enumerate(keys[7:]): - v = x[:, 7 + i] - mu = v[j] # best single result - plt.subplot(6, 5, i + 1) - plt.scatter(v, f, c=hist2d(v, f, 20), cmap='viridis', alpha=.8, edgecolors='none') - plt.plot(mu, f.max(), 'k+', markersize=15) - plt.title(f'{k} = {mu:.3g}', fontdict={'size': 9}) # limit to 40 characters - if i % 5 != 0: - plt.yticks([]) - print(f'{k:>15}: {mu:.3g}') - f = evolve_csv.with_suffix('.png') # filename - plt.savefig(f, dpi=200) - plt.close() - print(f'Saved {f}') - - -def plot_results(file='path/to/results.csv', dir=''): - # Plot training results.csv. Usage: from utils.plots import *; plot_results('path/to/results.csv') - save_dir = Path(file).parent if file else Path(dir) - fig, ax = plt.subplots(2, 5, figsize=(12, 6), tight_layout=True) - ax = ax.ravel() - files = list(save_dir.glob('results*.csv')) - assert len(files), f'No results.csv files found in {save_dir.resolve()}, nothing to plot.' - for fi, f in enumerate(files): - try: - data = pd.read_csv(f) - s = [x.strip() for x in data.columns] - x = data.values[:, 0] - for i, j in enumerate([1, 2, 3, 4, 5, 8, 9, 10, 6, 7]): - y = data.values[:, j] - # y[y == 0] = np.nan # don't show zero values - ax[i].plot(x, y, marker='.', label=f.stem, linewidth=2, markersize=8) - ax[i].set_title(s[j], fontsize=12) - # if j in [8, 9, 10]: # share train and val loss y axes - # ax[i].get_shared_y_axes().join(ax[i], ax[i - 5]) - except Exception as e: - print(f'Warning: Plotting error for {f}: {e}') - ax[1].legend() - fig.savefig(save_dir / 'results.png', dpi=200) - plt.close() - - -def profile_idetection(start=0, stop=0, labels=(), save_dir=''): - # Plot iDetection '*.txt' per-image logs. from utils.plots import *; profile_idetection() - ax = plt.subplots(2, 4, figsize=(12, 6), tight_layout=True)[1].ravel() - s = ['Images', 'Free Storage (GB)', 'RAM Usage (GB)', 'Battery', 'dt_raw (ms)', 'dt_smooth (ms)', 'real-world FPS'] - files = list(Path(save_dir).glob('frames*.txt')) - for fi, f in enumerate(files): - try: - results = np.loadtxt(f, ndmin=2).T[:, 90:-30] # clip first and last rows - n = results.shape[1] # number of rows - x = np.arange(start, min(stop, n) if stop else n) - results = results[:, x] - t = (results[0] - results[0].min()) # set t0=0s - results[0] = x - for i, a in enumerate(ax): - if i < len(results): - label = labels[fi] if len(labels) else f.stem.replace('frames_', '') - a.plot(t, results[i], marker='.', label=label, linewidth=1, markersize=5) - a.set_title(s[i]) - a.set_xlabel('time (s)') - # if fi == len(files) - 1: - # a.set_ylim(bottom=0) - for side in ['top', 'right']: - a.spines[side].set_visible(False) - else: - a.remove() - except Exception as e: - print(f'Warning: Plotting error for {f}; {e}') - ax[1].legend() - plt.savefig(Path(save_dir) / 'idetection_profile.png', dpi=200) - - -def save_one_box(xyxy, im, file='image.jpg', gain=1.02, pad=10, square=False, BGR=False, save=True): - # Save image crop as {file} with crop size multiple {gain} and {pad} pixels. Save and/or return crop - xyxy = torch.tensor(xyxy).view(-1, 4) - b = xyxy2xywh(xyxy) # boxes - if square: - b[:, 2:] = b[:, 2:].max(1)[0].unsqueeze(1) # attempt rectangle to square - b[:, 2:] = b[:, 2:] * gain + pad # box wh * gain + pad - xyxy = xywh2xyxy(b).long() - clip_coords(xyxy, im.shape) - crop = im[int(xyxy[0, 1]):int(xyxy[0, 3]), int(xyxy[0, 0]):int(xyxy[0, 2]), ::(1 if BGR else -1)] - if save: - file.parent.mkdir(parents=True, exist_ok=True) # make directory - cv2.imwrite(str(increment_path(file).with_suffix('.jpg')), crop) - return crop diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/torch_utils.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/torch_utils.py deleted file mode 100755 index e61830e3c..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/utils/torch_utils.py +++ /dev/null @@ -1,318 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -PyTorch utils -""" - -import datetime -import math -import os -import platform -import subprocess -import time -from contextlib import contextmanager -from copy import deepcopy -from pathlib import Path - -import torch -import torch.distributed as dist -import torch.nn as nn -import torch.nn.functional as F - -from .general import LOGGER - -try: - import thop # for FLOPs computation -except ImportError: - thop = None - - -@contextmanager -def torch_distributed_zero_first(local_rank: int): - """ - Decorator to make all processes in distributed training wait for each local_master to do something. - """ - if local_rank not in [-1, 0]: - dist.barrier(device_ids=[local_rank]) - yield - if local_rank == 0: - dist.barrier(device_ids=[0]) - - -def date_modified(path=__file__): - # return human-readable file modification date, i.e. '2021-3-26' - t = datetime.datetime.fromtimestamp(Path(path).stat().st_mtime) - return f'{t.year}-{t.month}-{t.day}' - - -def git_describe(path=Path(__file__).parent): # path must be a directory - # return human-readable git description, i.e. v5.0-5-g3e25f1e https://git-scm.com/docs/git-describe - s = f'git -C {path} describe --tags --long --always' - try: - return subprocess.check_output(s, shell=True, stderr=subprocess.STDOUT).decode()[:-1] - except subprocess.CalledProcessError as e: - return '' # not a git repository - - -def select_device(device='', batch_size=0, newline=True): - # device = 'cpu' or '0' or '0,1,2,3' - s = f'YOLOv5 🚀 {git_describe() or date_modified()} torch {torch.__version__} ' # string - device = str(device).strip().lower().replace('cuda:', '') # to string, 'cuda:0' to '0' - cpu = device == 'cpu' - if cpu: - os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # force torch.cuda.is_available() = False - elif device: # non-cpu device requested - os.environ['CUDA_VISIBLE_DEVICES'] = device # set environment variable - assert torch.cuda.is_available(), f'CUDA unavailable, invalid device {device} requested' # check availability - - cuda = not cpu and torch.cuda.is_available() - if cuda: - devices = device.split(',') if device else '0' # range(torch.cuda.device_count()) # i.e. 0,1,6,7 - n = len(devices) # device count - if n > 1 and batch_size > 0: # check batch_size is divisible by device_count - assert batch_size % n == 0, f'batch-size {batch_size} not multiple of GPU count {n}' - space = ' ' * (len(s) + 1) - for i, d in enumerate(devices): - p = torch.cuda.get_device_properties(i) - s += f"{'' if i == 0 else space}CUDA:{d} ({p.name}, {p.total_memory / 1024 ** 2:.0f}MiB)\n" # bytes to MB - else: - s += 'CPU\n' - - if not newline: - s = s.rstrip() - LOGGER.info(s.encode().decode('ascii', 'ignore') if platform.system() == 'Windows' else s) # emoji-safe - return torch.device('cuda:0' if cuda else 'cpu') - - -def time_sync(): - # pytorch-accurate time - if torch.cuda.is_available(): - torch.cuda.synchronize() - return time.time() - - -def profile(input, ops, n=10, device=None): - # YOLOv5 speed/memory/FLOPs profiler - # - # Usage: - # input = torch.randn(16, 3, 640, 640) - # m1 = lambda x: x * torch.sigmoid(x) - # m2 = nn.SiLU() - # profile(input, [m1, m2], n=100) # profile over 100 iterations - - results = [] - device = device or select_device() - print(f"{'Params':>12s}{'GFLOPs':>12s}{'GPU_mem (GB)':>14s}{'forward (ms)':>14s}{'backward (ms)':>14s}" - f"{'input':>24s}{'output':>24s}") - - for x in input if isinstance(input, list) else [input]: - x = x.to(device) - x.requires_grad = True - for m in ops if isinstance(ops, list) else [ops]: - m = m.to(device) if hasattr(m, 'to') else m # device - m = m.half() if hasattr(m, 'half') and isinstance(x, torch.Tensor) and x.dtype is torch.float16 else m - tf, tb, t = 0, 0, [0, 0, 0] # dt forward, backward - try: - flops = thop.profile(m, inputs=(x,), verbose=False)[0] / 1E9 * 2 # GFLOPs - except: - flops = 0 - - try: - for _ in range(n): - t[0] = time_sync() - y = m(x) - t[1] = time_sync() - try: - _ = (sum(yi.sum() for yi in y) if isinstance(y, list) else y).sum().backward() - t[2] = time_sync() - except Exception as e: # no backward method - # print(e) # for debug - t[2] = float('nan') - tf += (t[1] - t[0]) * 1000 / n # ms per op forward - tb += (t[2] - t[1]) * 1000 / n # ms per op backward - mem = torch.cuda.memory_reserved() / 1E9 if torch.cuda.is_available() else 0 # (GB) - s_in = tuple(x.shape) if isinstance(x, torch.Tensor) else 'list' - s_out = tuple(y.shape) if isinstance(y, torch.Tensor) else 'list' - p = sum(list(x.numel() for x in m.parameters())) if isinstance(m, nn.Module) else 0 # parameters - print(f'{p:12}{flops:12.4g}{mem:>14.3f}{tf:14.4g}{tb:14.4g}{str(s_in):>24s}{str(s_out):>24s}') - results.append([p, flops, mem, tf, tb, s_in, s_out]) - except Exception as e: - print(e) - results.append(None) - torch.cuda.empty_cache() - return results - - -def is_parallel(model): - # Returns True if model is of type DP or DDP - return type(model) in (nn.parallel.DataParallel, nn.parallel.DistributedDataParallel) - - -def de_parallel(model): - # De-parallelize a model: returns single-GPU model if model is of type DP or DDP - return model.module if is_parallel(model) else model - - -def initialize_weights(model): - for m in model.modules(): - t = type(m) - if t is nn.Conv2d: - pass # nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') - elif t is nn.BatchNorm2d: - m.eps = 1e-3 - m.momentum = 0.03 - elif t in [nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU]: - m.inplace = True - - -def find_modules(model, mclass=nn.Conv2d): - # Finds layer indices matching module class 'mclass' - return [i for i, m in enumerate(model.module_list) if isinstance(m, mclass)] - - -def sparsity(model): - # Return global model sparsity - a, b = 0, 0 - for p in model.parameters(): - a += p.numel() - b += (p == 0).sum() - return b / a - - -def prune(model, amount=0.3): - # Prune model to requested global sparsity - import torch.nn.utils.prune as prune - print('Pruning model... ', end='') - for name, m in model.named_modules(): - if isinstance(m, nn.Conv2d): - prune.l1_unstructured(m, name='weight', amount=amount) # prune - prune.remove(m, 'weight') # make permanent - print(' %.3g global sparsity' % sparsity(model)) - - -def fuse_conv_and_bn(conv, bn): - # Fuse convolution and batchnorm layers https://tehnokv.com/posts/fusing-batchnorm-and-conv/ - fusedconv = nn.Conv2d(conv.in_channels, - conv.out_channels, - kernel_size=conv.kernel_size, - stride=conv.stride, - padding=conv.padding, - groups=conv.groups, - bias=True).requires_grad_(False).to(conv.weight.device) - - # prepare filters - w_conv = conv.weight.clone().view(conv.out_channels, -1) - w_bn = torch.diag(bn.weight.div(torch.sqrt(bn.eps + bn.running_var))) - fusedconv.weight.copy_(torch.mm(w_bn, w_conv).view(fusedconv.weight.shape)) - - # prepare spatial bias - b_conv = torch.zeros(conv.weight.size(0), device=conv.weight.device) if conv.bias is None else conv.bias - b_bn = bn.bias - bn.weight.mul(bn.running_mean).div(torch.sqrt(bn.running_var + bn.eps)) - fusedconv.bias.copy_(torch.mm(w_bn, b_conv.reshape(-1, 1)).reshape(-1) + b_bn) - - return fusedconv - - -def model_info(model, verbose=False, img_size=640): - # Model information. img_size may be int or list, i.e. img_size=640 or img_size=[640, 320] - n_p = sum(x.numel() for x in model.parameters()) # number parameters - n_g = sum(x.numel() for x in model.parameters() if x.requires_grad) # number gradients - if verbose: - print(f"{'layer':>5} {'name':>40} {'gradient':>9} {'parameters':>12} {'shape':>20} {'mu':>10} {'sigma':>10}") - for i, (name, p) in enumerate(model.named_parameters()): - name = name.replace('module_list.', '') - print('%5g %40s %9s %12g %20s %10.3g %10.3g' % - (i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std())) - - try: # FLOPs - from thop import profile - stride = max(int(model.stride.max()), 32) if hasattr(model, 'stride') else 32 - img = torch.zeros((1, model.yaml.get('ch', 3), stride, stride), device=next(model.parameters()).device) # input - flops = profile(deepcopy(model), inputs=(img,), verbose=False)[0] / 1E9 * 2 # stride GFLOPs - img_size = img_size if isinstance(img_size, list) else [img_size, img_size] # expand if int/float - fs = ', %.1f GFLOPs' % (flops * img_size[0] / stride * img_size[1] / stride) # 640x640 GFLOPs - except (ImportError, Exception): - fs = '' - - LOGGER.info(f"Model Summary: {len(list(model.modules()))} layers, {n_p} parameters, {n_g} gradients{fs}") - - -def scale_img(img, ratio=1.0, same_shape=False, gs=32): # img(16,3,256,416) - # scales img(bs,3,y,x) by ratio constrained to gs-multiple - if ratio == 1.0: - return img - else: - h, w = img.shape[2:] - s = (int(h * ratio), int(w * ratio)) # new size - img = F.interpolate(img, size=s, mode='bilinear', align_corners=False) # resize - if not same_shape: # pad/crop img - h, w = (math.ceil(x * ratio / gs) * gs for x in (h, w)) - return F.pad(img, [0, w - s[1], 0, h - s[0]], value=0.447) # value = imagenet mean - - -def copy_attr(a, b, include=(), exclude=()): - # Copy attributes from b to a, options to only include [...] and to exclude [...] - for k, v in b.__dict__.items(): - if (len(include) and k not in include) or k.startswith('_') or k in exclude: - continue - else: - setattr(a, k, v) - - -class EarlyStopping: - # YOLOv5 simple early stopper - def __init__(self, patience=30): - self.best_fitness = 0.0 # i.e. mAP - self.best_epoch = 0 - self.patience = patience or float('inf') # epochs to wait after fitness stops improving to stop - self.possible_stop = False # possible stop may occur next epoch - - def __call__(self, epoch, fitness): - if fitness >= self.best_fitness: # >= 0 to allow for early zero-fitness stage of training - self.best_epoch = epoch - self.best_fitness = fitness - delta = epoch - self.best_epoch # epochs without improvement - self.possible_stop = delta >= (self.patience - 1) # possible stop may occur next epoch - stop = delta >= self.patience # stop training if patience exceeded - if stop: - LOGGER.info(f'Stopping training early as no improvement observed in last {self.patience} epochs. ' - f'Best results observed at epoch {self.best_epoch}, best model saved as best.pt.\n' - f'To update EarlyStopping(patience={self.patience}) pass a new patience value, ' - f'i.e. `python train.py --patience 300` or use `--patience 0` to disable EarlyStopping.') - return stop - - -class ModelEMA: - """ Model Exponential Moving Average from https://github.com/rwightman/pytorch-image-models - Keep a moving average of everything in the model state_dict (parameters and buffers). - This is intended to allow functionality like - https://www.tensorflow.org/api_docs/python/tf/train/ExponentialMovingAverage - A smoothed version of the weights is necessary for some training schemes to perform well. - This class is sensitive where it is initialized in the sequence of model init, - GPU assignment and distributed training wrappers. - """ - - def __init__(self, model, decay=0.9999, updates=0): - # Create EMA - self.ema = deepcopy(model.module if is_parallel(model) else model).eval() # FP32 EMA - # if next(model.parameters()).device.type != 'cpu': - # self.ema.half() # FP16 EMA - self.updates = updates # number of EMA updates - self.decay = lambda x: decay * (1 - math.exp(-x / 2000)) # decay exponential ramp (to help early epochs) - for p in self.ema.parameters(): - p.requires_grad_(False) - - def update(self, model): - # Update EMA parameters - with torch.no_grad(): - self.updates += 1 - d = self.decay(self.updates) - - msd = model.module.state_dict() if is_parallel(model) else model.state_dict() # model state_dict - for k, v in self.ema.state_dict().items(): - if v.dtype.is_floating_point: - v *= d - v += (1 - d) * msd[k].detach() - - def update_attr(self, model, include=(), exclude=('process_group', 'reducer')): - # Update EMA attributes - copy_attr(self.ema, model, include, exclude) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolo.py b/cv/pose/alphapose/pytorch/detector/yolov5/models/yolo.py deleted file mode 100755 index 79acc0500..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolo.py +++ /dev/null @@ -1,334 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -YOLO-specific modules - -Usage: - $ python path/to/models/yolo.py --cfg yolov5s.yaml -""" - -import argparse -import sys -import torch -from copy import deepcopy -from pathlib import Path - -FILE = Path(__file__).resolve() -ROOT = FILE.parents[1] # YOLOv5 root directory -if str(ROOT) not in sys.path: - sys.path.append(str(ROOT)) # add ROOT to PATH -# ROOT = ROOT.relative_to(Path.cwd()) # relative - -from .common import * -from .experimental import * -from .utils.autoanchor import check_anchor_order -from .utils.general import LOGGER, check_version, check_yaml, make_divisible, print_args -from .utils.plots import feature_visualization -from .utils.torch_utils import fuse_conv_and_bn, initialize_weights, model_info, scale_img, select_device, time_sync - -try: - import thop # for FLOPs computation -except ImportError: - thop = None - -try: - from .cuda_impl import yolov5_decode as func_cuda_impl -except: - learn_long_tailed_ops_address = "ssh://git@bitbucket.iluvatar.ai:7999/swapp/learn_long_tailed_ops.git" - print(f"Please install yolov5_decode in {learn_long_tailed_ops_address}") - - -class Detect(nn.Module): - stride = None # strides computed during build - onnx_dynamic = False # ONNX export parameter - - def __init__(self, nc=80, anchors=(), ch=(), inplace=True): # detection layer - super().__init__() - self.nc = nc # number of classes - self.no = nc + 5 # number of outputs per anchor - self.nl = len(anchors) # number of detection layers - self.na = len(anchors[0]) // 2 # number of anchors - self.grid = [torch.zeros(1)] * self.nl # init grid - self.anchor_grid = [torch.zeros(1)] * self.nl # init anchor grid - self.register_buffer('anchors', torch.tensor(anchors).float().view(self.nl, -1, 2)) # shape(nl,na,2) - self.m = nn.ModuleList(nn.Conv2d(x, self.no * self.na, 1) for x in ch) # output conv - self.inplace = inplace # use in-place ops (e.g. slice assignment) - - def forward(self, x): - z = [] - - all_anchors = [ - [1.25, 1.625, 2.0, 3.75, 4.125, 2.875], - [1.875, 3.8125, 3.875, 2.8125, 3.6875, 7.43750], - [3.625, 2.8125, 4.875, 6.1875, 11.65625, 10.18750] - ] - - all_strides = [8, 16, 32] - - times = [] - for i in range(self.nl): - - x[i] = self.m[i](x[i]) # conv - bs, _, ny, nx = x[i].shape # x(bs,255,20,20) to x(bs,3,20,20,85) - y = func_cuda_impl(pred_map=x[i], stride=all_strides[i], anchors=all_anchors[i]) - - z.append(y) - return torch.cat(z, 1) - - -class Model(nn.Module): - def __init__(self, cfg='yolov5s.yaml', ch=3, nc=None, anchors=None): # model, input channels, number of classes - super().__init__() - if isinstance(cfg, dict): - self.yaml = cfg # model dict - else: # is *.yaml - import yaml # for torch hub - self.yaml_file = Path(cfg).name - with open(cfg, encoding='ascii', errors='ignore') as f: - self.yaml = yaml.safe_load(f) # model dict - - # Define model - ch = self.yaml['ch'] = self.yaml.get('ch', ch) # input channels - if nc and nc != self.yaml['nc']: - LOGGER.info(f"Overriding model.yaml nc={self.yaml['nc']} with nc={nc}") - self.yaml['nc'] = nc # override yaml value - if anchors: - LOGGER.info(f'Overriding model.yaml anchors with anchors={anchors}') - self.yaml['anchors'] = round(anchors) # override yaml value - self.model, self.save = parse_model(deepcopy(self.yaml), ch=[ch]) # model, savelist - self.names = [str(i) for i in range(self.yaml['nc'])] # default names - self.inplace = self.yaml.get('inplace', True) - - # Build strides, anchors - m = self.model[-1] # Detect() - if isinstance(m, Detect): - s = 256 # 2x min stride - m.inplace = self.inplace - m.stride = torch.tensor([s / x.shape[-2] for x in self.forward(torch.zeros(1, ch, s, s))]) # forward - m.anchors /= m.stride.view(-1, 1, 1) - check_anchor_order(m) - self.stride = m.stride - self._initialize_biases() # only run once - - # Init weights, biases - initialize_weights(self) - self.info() - LOGGER.info('') - - def forward_(self, x, augment=False, profile=False, visualize=False): - if augment: - return self._forward_augment(x) # augmented inference, None - return self._forward_once(x, profile, visualize) # single-scale inference, train - - def forward(self, x): - y = [] # outputs - for m in self.model: - if m.f != -1: # if not from previous layer - x = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f] # from earlier layers - x = m(x) # run - y.append(x if m.i in self.save else None) # save output - - # return x[0] - return x - - def _forward_augment(self, x): - img_size = x.shape[-2:] # height, width - s = [1, 0.83, 0.67] # scales - f = [None, 3, None] # flips (2-ud, 3-lr) - y = [] # outputs - for si, fi in zip(s, f): - xi = scale_img(x.flip(fi) if fi else x, si, gs=int(self.stride.max())) - yi = self._forward_once(xi)[0] # forward - # cv2.imwrite(f'img_{si}.jpg', 255 * xi[0].cpu().numpy().transpose((1, 2, 0))[:, :, ::-1]) # save - yi = self._descale_pred(yi, fi, si, img_size) - y.append(yi) - y = self._clip_augmented(y) # clip augmented tails - return torch.cat(y, 1), None # augmented inference, train - - def _forward_once(self, x, profile=False, visualize=False): - y, dt = [], [] # outputs - for m in self.model: - if m.f != -1: # if not from previous layer - x = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f] # from earlier layers - if profile: - self._profile_one_layer(m, x, dt) - x = m(x) # run - y.append(x if m.i in self.save else None) # save output - if visualize: - feature_visualization(x, m.type, m.i, save_dir=visualize) - return x - - def _descale_pred(self, p, flips, scale, img_size): - # de-scale predictions following augmented inference (inverse operation) - if self.inplace: - p[..., :4] /= scale # de-scale - if flips == 2: - p[..., 1] = img_size[0] - p[..., 1] # de-flip ud - elif flips == 3: - p[..., 0] = img_size[1] - p[..., 0] # de-flip lr - else: - x, y, wh = p[..., 0:1] / scale, p[..., 1:2] / scale, p[..., 2:4] / scale # de-scale - if flips == 2: - y = img_size[0] - y # de-flip ud - elif flips == 3: - x = img_size[1] - x # de-flip lr - p = torch.cat((x, y, wh, p[..., 4:]), -1) - return p - - def _clip_augmented(self, y): - # Clip YOLOv5 augmented inference tails - nl = self.model[-1].nl # number of detection layers (P3-P5) - g = sum(4 ** x for x in range(nl)) # grid points - e = 1 # exclude layer count - i = (y[0].shape[1] // g) * sum(4 ** x for x in range(e)) # indices - y[0] = y[0][:, :-i] # large - i = (y[-1].shape[1] // g) * sum(4 ** (nl - 1 - x) for x in range(e)) # indices - y[-1] = y[-1][:, i:] # small - return y - - def _profile_one_layer(self, m, x, dt): - c = isinstance(m, Detect) # is final layer, copy input as inplace fix - o = thop.profile(m, inputs=(x.copy() if c else x,), verbose=False)[0] / 1E9 * 2 if thop else 0 # FLOPs - t = time_sync() - for _ in range(10): - m(x.copy() if c else x) - dt.append((time_sync() - t) * 100) - if m == self.model[0]: - LOGGER.info(f"{'time (ms)':>10s} {'GFLOPs':>10s} {'params':>10s} {'module'}") - LOGGER.info(f'{dt[-1]:10.2f} {o:10.2f} {m.np:10.0f} {m.type}') - if c: - LOGGER.info(f"{sum(dt):10.2f} {'-':>10s} {'-':>10s} Total") - - def _initialize_biases(self, cf=None): # initialize biases into Detect(), cf is class frequency - # https://arxiv.org/abs/1708.02002 section 3.3 - # cf = torch.bincount(torch.tensor(np.concatenate(dataset.labels, 0)[:, 0]).long(), minlength=nc) + 1. - m = self.model[-1] # Detect() module - for mi, s in zip(m.m, m.stride): # from - b = mi.bias.view(m.na, -1) # conv.bias(255) to (3,85) - b.data[:, 4] += math.log(8 / (640 / s) ** 2) # obj (8 objects per 640 image) - b.data[:, 5:] += math.log(0.6 / (m.nc - 0.999999)) if cf is None else torch.log(cf / cf.sum()) # cls - mi.bias = torch.nn.Parameter(b.view(-1), requires_grad=True) - - def _print_biases(self): - m = self.model[-1] # Detect() module - for mi in m.m: # from - b = mi.bias.detach().view(m.na, -1).T # conv.bias(255) to (3,85) - LOGGER.info( - ('%6g Conv2d.bias:' + '%10.3g' * 6) % (mi.weight.shape[1], *b[:5].mean(1).tolist(), b[5:].mean())) - - # def _print_weights(self): - # for m in self.model.modules(): - # if type(m) is Bottleneck: - # LOGGER.info('%10.3g' % (m.w.detach().sigmoid() * 2)) # shortcut weights - - def fuse(self): # fuse model Conv2d() + BatchNorm2d() layers - LOGGER.info('Fusing layers... ') - for m in self.model.modules(): - if isinstance(m, (Conv, DWConv)) and hasattr(m, 'bn'): - m.conv = fuse_conv_and_bn(m.conv, m.bn) # update conv - delattr(m, 'bn') # remove batchnorm - m.forward = m.forward_fuse # update forward - self.info() - return self - - def info(self, verbose=False, img_size=640): # print model information - model_info(self, verbose, img_size) - - def _apply(self, fn): - # Apply to(), cpu(), cuda(), half() to model tensors that are not parameters or registered buffers - self = super()._apply(fn) - m = self.model[-1] # Detect() - if isinstance(m, Detect): - m.stride = fn(m.stride) - m.grid = list(map(fn, m.grid)) - if isinstance(m.anchor_grid, list): - m.anchor_grid = list(map(fn, m.anchor_grid)) - return self - - -def parse_model(d, ch): # model_dict, input_channels(3) - LOGGER.info(f"\n{'':>3}{'from':>18}{'n':>3}{'params':>10} {'module':<40}{'arguments':<30}") - anchors, nc, gd, gw = d['anchors'], d['nc'], d['depth_multiple'], d['width_multiple'] - na = (len(anchors[0]) // 2) if isinstance(anchors, list) else anchors # number of anchors - no = na * (nc + 5) # number of outputs = anchors * (classes + 5) - - layers, save, c2 = [], [], ch[-1] # layers, savelist, ch out - for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']): # from, number, module, args - m = eval(m) if isinstance(m, str) else m # eval strings - for j, a in enumerate(args): - try: - args[j] = eval(a) if isinstance(a, str) else a # eval strings - except NameError: - pass - - n = n_ = max(round(n * gd), 1) if n > 1 else n # depth gain - if m in [Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, MixConv2d, Focus, CrossConv, - BottleneckCSP, C3, C3TR, C3SPP, C3Ghost]: - c1, c2 = ch[f], args[0] - if c2 != no: # if not output - c2 = make_divisible(c2 * gw, 8) - - args = [c1, c2, *args[1:]] - if m in [BottleneckCSP, C3, C3TR, C3Ghost]: - args.insert(2, n) # number of repeats - n = 1 - elif m is nn.BatchNorm2d: - args = [ch[f]] - elif m is Concat: - c2 = sum(ch[x] for x in f) - elif m is Detect: - args.append([ch[x] for x in f]) - if isinstance(args[1], int): # number of anchors - args[1] = [list(range(args[1] * 2))] * len(f) - elif m is Contract: - c2 = ch[f] * args[0] ** 2 - elif m is Expand: - c2 = ch[f] // args[0] ** 2 - else: - c2 = ch[f] - - m_ = nn.Sequential(*(m(*args) for _ in range(n))) if n > 1 else m(*args) # module - t = str(m)[8:-2].replace('__main__.', '') # module type - np = sum(x.numel() for x in m_.parameters()) # number params - m_.i, m_.f, m_.type, m_.np = i, f, t, np # attach index, 'from' index, type, number params - LOGGER.info(f'{i:>3}{str(f):>18}{n_:>3}{np:10.0f} {t:<40}{str(args):<30}') # print - save.extend(x % i for x in ([f] if isinstance(f, int) else f) if x != -1) # append to savelist - layers.append(m_) - if i == 0: - ch = [] - ch.append(c2) - return nn.Sequential(*layers), sorted(save) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--cfg', type=str, default='yolov5s.yaml', help='model.yaml') - parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') - parser.add_argument('--profile', action='store_true', help='profile model speed') - parser.add_argument('--test', action='store_true', help='test all yolo*.yaml') - opt = parser.parse_args() - opt.cfg = check_yaml(opt.cfg) # check YAML - print_args(FILE.stem, opt) - device = select_device(opt.device) - - # Create model - model = Model(opt.cfg).to(device) - model.train() - - # Profile - if opt.profile: - img = torch.rand(8 if torch.cuda.is_available() else 1, 3, 640, 640).to(device) - y = model(img, profile=True) - - # Test all models - if opt.test: - for cfg in Path(ROOT / 'models').rglob('yolo*.yaml'): - try: - _ = Model(cfg) - except Exception as e: - print(f'Error in {cfg}: {e}') - - # Tensorboard (not working https://github.com/ultralytics/yolov5/issues/2898) - # from torch.utils.tensorboard import SummaryWriter - # tb_writer = SummaryWriter('.') - # LOGGER.info("Run 'tensorboard --logdir=models' to view tensorboard at http://localhost:6006/") - # tb_writer.add_graph(torch.jit.trace(model, img, strict=False), []) # add model graph diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5l.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5l.yaml deleted file mode 100755 index ce8a5de46..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5l.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.0 # model depth multiple -width_multiple: 1.0 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 13 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 17 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 20 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [1024, False]], # 23 (P5/32-large) - - [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5m.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5m.yaml deleted file mode 100755 index ad13ab370..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5m.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 0.67 # model depth multiple -width_multiple: 0.75 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 13 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 17 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 20 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [1024, False]], # 23 (P5/32-large) - - [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5n.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5n.yaml deleted file mode 100755 index 8a28a40d6..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5n.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 0.33 # model depth multiple -width_multiple: 0.25 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 13 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 17 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 20 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [1024, False]], # 23 (P5/32-large) - - [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5s.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5s.yaml deleted file mode 100755 index f35beabb1..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5s.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 0.33 # model depth multiple -width_multiple: 0.50 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 13 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 17 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 20 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [1024, False]], # 23 (P5/32-large) - - [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5x.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5x.yaml deleted file mode 100755 index f617a027d..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/models/yolov5x.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license - -# Parameters -nc: 80 # number of classes -depth_multiple: 1.33 # model depth multiple -width_multiple: 1.25 # layer channel multiple -anchors: - - [10,13, 16,30, 33,23] # P3/8 - - [30,61, 62,45, 59,119] # P4/16 - - [116,90, 156,198, 373,326] # P5/32 - -# YOLOv5 v6.0 backbone -backbone: - # [from, number, module, args] - [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 - [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 - [-1, 3, C3, [128]], - [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 - [-1, 6, C3, [256]], - [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 - [-1, 9, C3, [512]], - [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 - [-1, 3, C3, [1024]], - [-1, 1, SPPF, [1024, 5]], # 9 - ] - -# YOLOv5 v6.0 head -head: - [[-1, 1, Conv, [512, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 6], 1, Concat, [1]], # cat backbone P4 - [-1, 3, C3, [512, False]], # 13 - - [-1, 1, Conv, [256, 1, 1]], - [-1, 1, nn.Upsample, [None, 2, 'nearest']], - [[-1, 4], 1, Concat, [1]], # cat backbone P3 - [-1, 3, C3, [256, False]], # 17 (P3/8-small) - - [-1, 1, Conv, [256, 3, 2]], - [[-1, 14], 1, Concat, [1]], # cat head P4 - [-1, 3, C3, [512, False]], # 20 (P4/16-medium) - - [-1, 1, Conv, [512, 3, 2]], - [[-1, 10], 1, Concat, [1]], # cat head P5 - [-1, 3, C3, [1024, False]], # 23 (P5/32-large) - - [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) - ] diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/__init__.py deleted file mode 100755 index 295aebfbc..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/__init__.py +++ /dev/null @@ -1,37 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -utils/initialization -""" - - -def notebook_init(verbose=True): - # Check system software and hardware - print('Checking setup...') - - import os - import shutil - - from utils.general import check_requirements, emojis, is_colab - from utils.torch_utils import select_device # imports - - check_requirements(('psutil', 'IPython')) - import psutil - from IPython import display # to display images and clear console output - - if is_colab(): - shutil.rmtree('/content/sample_data', ignore_errors=True) # remove colab /sample_data directory - - if verbose: - # System info - # gb = 1 / 1000 ** 3 # bytes to GB - gib = 1 / 1024 ** 3 # bytes to GiB - ram = psutil.virtual_memory().total - total, used, free = shutil.disk_usage("/") - display.clear_output() - s = f'({os.cpu_count()} CPUs, {ram * gib:.1f} GB RAM, {(total - free) * gib:.1f}/{total * gib:.1f} GB disk)' - else: - s = '' - - select_device(newline=False) - print(emojis(f'Setup complete ✅ {s}')) - return display diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/activations.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/activations.py deleted file mode 100755 index a4ff789cf..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/activations.py +++ /dev/null @@ -1,101 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Activation functions -""" - -import torch -import torch.nn as nn -import torch.nn.functional as F - - -# SiLU https://arxiv.org/pdf/1606.08415.pdf ---------------------------------------------------------------------------- -class SiLU(nn.Module): # export-friendly version of nn.SiLU() - @staticmethod - def forward(x): - return x * torch.sigmoid(x) - - -class Hardswish(nn.Module): # export-friendly version of nn.Hardswish() - @staticmethod - def forward(x): - # return x * F.hardsigmoid(x) # for TorchScript and CoreML - return x * F.hardtanh(x + 3, 0.0, 6.0) / 6.0 # for TorchScript, CoreML and ONNX - - -# Mish https://github.com/digantamisra98/Mish -------------------------------------------------------------------------- -class Mish(nn.Module): - @staticmethod - def forward(x): - return x * F.softplus(x).tanh() - - -class MemoryEfficientMish(nn.Module): - class F(torch.autograd.Function): - @staticmethod - def forward(ctx, x): - ctx.save_for_backward(x) - return x.mul(torch.tanh(F.softplus(x))) # x * tanh(ln(1 + exp(x))) - - @staticmethod - def backward(ctx, grad_output): - x = ctx.saved_tensors[0] - sx = torch.sigmoid(x) - fx = F.softplus(x).tanh() - return grad_output * (fx + x * sx * (1 - fx * fx)) - - def forward(self, x): - return self.F.apply(x) - - -# FReLU https://arxiv.org/abs/2007.11824 ------------------------------------------------------------------------------- -class FReLU(nn.Module): - def __init__(self, c1, k=3): # ch_in, kernel - super().__init__() - self.conv = nn.Conv2d(c1, c1, k, 1, 1, groups=c1, bias=False) - self.bn = nn.BatchNorm2d(c1) - - def forward(self, x): - return torch.max(x, self.bn(self.conv(x))) - - -# ACON https://arxiv.org/pdf/2009.04759.pdf ---------------------------------------------------------------------------- -class AconC(nn.Module): - r""" ACON activation (activate or not). - AconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is a learnable parameter - according to "Activate or Not: Learning Customized Activation" . - """ - - def __init__(self, c1): - super().__init__() - self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1)) - self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1)) - self.beta = nn.Parameter(torch.ones(1, c1, 1, 1)) - - def forward(self, x): - dpx = (self.p1 - self.p2) * x - return dpx * torch.sigmoid(self.beta * dpx) + self.p2 * x - - -class MetaAconC(nn.Module): - r""" ACON activation (activate or not). - MetaAconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is generated by a small network - according to "Activate or Not: Learning Customized Activation" . - """ - - def __init__(self, c1, k=1, s=1, r=16): # ch_in, kernel, stride, r - super().__init__() - c2 = max(r, c1 // r) - self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1)) - self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1)) - self.fc1 = nn.Conv2d(c1, c2, k, s, bias=True) - self.fc2 = nn.Conv2d(c2, c1, k, s, bias=True) - # self.bn1 = nn.BatchNorm2d(c2) - # self.bn2 = nn.BatchNorm2d(c1) - - def forward(self, x): - y = x.mean(dim=2, keepdims=True).mean(dim=3, keepdims=True) - # batch-size 1 bug/instabilities https://github.com/ultralytics/yolov5/issues/2891 - # beta = torch.sigmoid(self.bn2(self.fc2(self.bn1(self.fc1(y))))) # bug/unstable - beta = torch.sigmoid(self.fc2(self.fc1(y))) # bug patch BN layers removed - dpx = (self.p1 - self.p2) * x - return dpx * torch.sigmoid(beta * dpx) + self.p2 * x diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/augmentations.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/augmentations.py deleted file mode 100755 index 7b5b7785f..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/augmentations.py +++ /dev/null @@ -1,277 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Image augmentation functions -""" - -import math -import random - -import cv2 -import numpy as np - -from .general import LOGGER, check_version, colorstr, resample_segments, segment2box -from .metrics import bbox_ioa - - -class Albumentations: - # YOLOv5 Albumentations class (optional, only used if package is installed) - def __init__(self): - self.transform = None - try: - import albumentations as A - check_version(A.__version__, '1.0.3', hard=True) # version requirement - - self.transform = A.Compose([ - A.Blur(p=0.01), - A.MedianBlur(p=0.01), - A.ToGray(p=0.01), - A.CLAHE(p=0.01), - A.RandomBrightnessContrast(p=0.0), - A.RandomGamma(p=0.0), - A.ImageCompression(quality_lower=75, p=0.0)], - bbox_params=A.BboxParams(format='yolo', label_fields=['class_labels'])) - - LOGGER.info(colorstr('albumentations: ') + ', '.join(f'{x}' for x in self.transform.transforms if x.p)) - except ImportError: # package not installed, skip - pass - except Exception as e: - LOGGER.info(colorstr('albumentations: ') + f'{e}') - - def __call__(self, im, labels, p=1.0): - if self.transform and random.random() < p: - new = self.transform(image=im, bboxes=labels[:, 1:], class_labels=labels[:, 0]) # transformed - im, labels = new['image'], np.array([[c, *b] for c, b in zip(new['class_labels'], new['bboxes'])]) - return im, labels - - -def augment_hsv(im, hgain=0.5, sgain=0.5, vgain=0.5): - # HSV color-space augmentation - if hgain or sgain or vgain: - r = np.random.uniform(-1, 1, 3) * [hgain, sgain, vgain] + 1 # random gains - hue, sat, val = cv2.split(cv2.cvtColor(im, cv2.COLOR_BGR2HSV)) - dtype = im.dtype # uint8 - - x = np.arange(0, 256, dtype=r.dtype) - lut_hue = ((x * r[0]) % 180).astype(dtype) - lut_sat = np.clip(x * r[1], 0, 255).astype(dtype) - lut_val = np.clip(x * r[2], 0, 255).astype(dtype) - - im_hsv = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val))) - cv2.cvtColor(im_hsv, cv2.COLOR_HSV2BGR, dst=im) # no return needed - - -def hist_equalize(im, clahe=True, bgr=False): - # Equalize histogram on BGR image 'im' with im.shape(n,m,3) and range 0-255 - yuv = cv2.cvtColor(im, cv2.COLOR_BGR2YUV if bgr else cv2.COLOR_RGB2YUV) - if clahe: - c = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) - yuv[:, :, 0] = c.apply(yuv[:, :, 0]) - else: - yuv[:, :, 0] = cv2.equalizeHist(yuv[:, :, 0]) # equalize Y channel histogram - return cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR if bgr else cv2.COLOR_YUV2RGB) # convert YUV image to RGB - - -def replicate(im, labels): - # Replicate labels - h, w = im.shape[:2] - boxes = labels[:, 1:].astype(int) - x1, y1, x2, y2 = boxes.T - s = ((x2 - x1) + (y2 - y1)) / 2 # side length (pixels) - for i in s.argsort()[:round(s.size * 0.5)]: # smallest indices - x1b, y1b, x2b, y2b = boxes[i] - bh, bw = y2b - y1b, x2b - x1b - yc, xc = int(random.uniform(0, h - bh)), int(random.uniform(0, w - bw)) # offset x, y - x1a, y1a, x2a, y2a = [xc, yc, xc + bw, yc + bh] - im[y1a:y2a, x1a:x2a] = im[y1b:y2b, x1b:x2b] # im4[ymin:ymax, xmin:xmax] - labels = np.append(labels, [[labels[i, 0], x1a, y1a, x2a, y2a]], axis=0) - - return im, labels - - -def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32): - # Resize and pad image while meeting stride-multiple constraints - shape = im.shape[:2] # current shape [height, width] - if isinstance(new_shape, int): - new_shape = (new_shape, new_shape) - - # Scale ratio (new / old) - r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) - if not scaleup: # only scale down, do not scale up (for better val mAP) - r = min(r, 1.0) - - # Compute padding - ratio = r, r # width, height ratios - new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) - dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding - if auto: # minimum rectangle - dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding - elif scaleFill: # stretch - dw, dh = 0.0, 0.0 - new_unpad = (new_shape[1], new_shape[0]) - ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios - - dw /= 2 # divide padding into 2 sides - dh /= 2 - - if shape[::-1] != new_unpad: # resize - im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR) - top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) - left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) - im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border - return im, ratio, (dw, dh) - - -def random_perspective(im, targets=(), segments=(), degrees=10, translate=.1, scale=.1, shear=10, perspective=0.0, - border=(0, 0)): - # torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(0.1, 0.1), scale=(0.9, 1.1), shear=(-10, 10)) - # targets = [cls, xyxy] - - height = im.shape[0] + border[0] * 2 # shape(h,w,c) - width = im.shape[1] + border[1] * 2 - - # Center - C = np.eye(3) - C[0, 2] = -im.shape[1] / 2 # x translation (pixels) - C[1, 2] = -im.shape[0] / 2 # y translation (pixels) - - # Perspective - P = np.eye(3) - P[2, 0] = random.uniform(-perspective, perspective) # x perspective (about y) - P[2, 1] = random.uniform(-perspective, perspective) # y perspective (about x) - - # Rotation and Scale - R = np.eye(3) - a = random.uniform(-degrees, degrees) - # a += random.choice([-180, -90, 0, 90]) # add 90deg rotations to small rotations - s = random.uniform(1 - scale, 1 + scale) - # s = 2 ** random.uniform(-scale, scale) - R[:2] = cv2.getRotationMatrix2D(angle=a, center=(0, 0), scale=s) - - # Shear - S = np.eye(3) - S[0, 1] = math.tan(random.uniform(-shear, shear) * math.pi / 180) # x shear (deg) - S[1, 0] = math.tan(random.uniform(-shear, shear) * math.pi / 180) # y shear (deg) - - # Translation - T = np.eye(3) - T[0, 2] = random.uniform(0.5 - translate, 0.5 + translate) * width # x translation (pixels) - T[1, 2] = random.uniform(0.5 - translate, 0.5 + translate) * height # y translation (pixels) - - # Combined rotation matrix - M = T @ S @ R @ P @ C # order of operations (right to left) is IMPORTANT - if (border[0] != 0) or (border[1] != 0) or (M != np.eye(3)).any(): # image changed - if perspective: - im = cv2.warpPerspective(im, M, dsize=(width, height), borderValue=(114, 114, 114)) - else: # affine - im = cv2.warpAffine(im, M[:2], dsize=(width, height), borderValue=(114, 114, 114)) - - # Visualize - # import matplotlib.pyplot as plt - # ax = plt.subplots(1, 2, figsize=(12, 6))[1].ravel() - # ax[0].imshow(im[:, :, ::-1]) # base - # ax[1].imshow(im2[:, :, ::-1]) # warped - - # Transform label coordinates - n = len(targets) - if n: - use_segments = any(x.any() for x in segments) - new = np.zeros((n, 4)) - if use_segments: # warp segments - segments = resample_segments(segments) # upsample - for i, segment in enumerate(segments): - xy = np.ones((len(segment), 3)) - xy[:, :2] = segment - xy = xy @ M.T # transform - xy = xy[:, :2] / xy[:, 2:3] if perspective else xy[:, :2] # perspective rescale or affine - - # clip - new[i] = segment2box(xy, width, height) - - else: # warp boxes - xy = np.ones((n * 4, 3)) - xy[:, :2] = targets[:, [1, 2, 3, 4, 1, 4, 3, 2]].reshape(n * 4, 2) # x1y1, x2y2, x1y2, x2y1 - xy = xy @ M.T # transform - xy = (xy[:, :2] / xy[:, 2:3] if perspective else xy[:, :2]).reshape(n, 8) # perspective rescale or affine - - # create new boxes - x = xy[:, [0, 2, 4, 6]] - y = xy[:, [1, 3, 5, 7]] - new = np.concatenate((x.min(1), y.min(1), x.max(1), y.max(1))).reshape(4, n).T - - # clip - new[:, [0, 2]] = new[:, [0, 2]].clip(0, width) - new[:, [1, 3]] = new[:, [1, 3]].clip(0, height) - - # filter candidates - i = box_candidates(box1=targets[:, 1:5].T * s, box2=new.T, area_thr=0.01 if use_segments else 0.10) - targets = targets[i] - targets[:, 1:5] = new[i] - - return im, targets - - -def copy_paste(im, labels, segments, p=0.5): - # Implement Copy-Paste augmentation https://arxiv.org/abs/2012.07177, labels as nx5 np.array(cls, xyxy) - n = len(segments) - if p and n: - h, w, c = im.shape # height, width, channels - im_new = np.zeros(im.shape, np.uint8) - for j in random.sample(range(n), k=round(p * n)): - l, s = labels[j], segments[j] - box = w - l[3], l[2], w - l[1], l[4] - ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area - if (ioa < 0.30).all(): # allow 30% obscuration of existing labels - labels = np.concatenate((labels, [[l[0], *box]]), 0) - segments.append(np.concatenate((w - s[:, 0:1], s[:, 1:2]), 1)) - cv2.drawContours(im_new, [segments[j].astype(np.int32)], -1, (255, 255, 255), cv2.FILLED) - - result = cv2.bitwise_and(src1=im, src2=im_new) - result = cv2.flip(result, 1) # augment segments (flip left-right) - i = result > 0 # pixels to replace - # i[:, :] = result.max(2).reshape(h, w, 1) # act over ch - im[i] = result[i] # cv2.imwrite('debug.jpg', im) # debug - - return im, labels, segments - - -def cutout(im, labels, p=0.5): - # Applies image cutout augmentation https://arxiv.org/abs/1708.04552 - if random.random() < p: - h, w = im.shape[:2] - scales = [0.5] * 1 + [0.25] * 2 + [0.125] * 4 + [0.0625] * 8 + [0.03125] * 16 # image size fraction - for s in scales: - mask_h = random.randint(1, int(h * s)) # create random masks - mask_w = random.randint(1, int(w * s)) - - # box - xmin = max(0, random.randint(0, w) - mask_w // 2) - ymin = max(0, random.randint(0, h) - mask_h // 2) - xmax = min(w, xmin + mask_w) - ymax = min(h, ymin + mask_h) - - # apply random color mask - im[ymin:ymax, xmin:xmax] = [random.randint(64, 191) for _ in range(3)] - - # return unobscured labels - if len(labels) and s > 0.03: - box = np.array([xmin, ymin, xmax, ymax], dtype=np.float32) - ioa = bbox_ioa(box, labels[:, 1:5]) # intersection over area - labels = labels[ioa < 0.60] # remove >60% obscured labels - - return labels - - -def mixup(im, labels, im2, labels2): - # Applies MixUp augmentation https://arxiv.org/pdf/1710.09412.pdf - r = np.random.beta(32.0, 32.0) # mixup ratio, alpha=beta=32.0 - im = (im * r + im2 * (1 - r)).astype(np.uint8) - labels = np.concatenate((labels, labels2), 0) - return im, labels - - -def box_candidates(box1, box2, wh_thr=2, ar_thr=20, area_thr=0.1, eps=1e-16): # box1(4,n), box2(4,n) - # Compute candidate boxes: box1 before augment, box2 after augment, wh_thr (pixels), aspect_ratio_thr, area_ratio - w1, h1 = box1[2] - box1[0], box1[3] - box1[1] - w2, h2 = box2[2] - box2[0], box2[3] - box2[1] - ar = np.maximum(w2 / (h2 + eps), h2 / (w2 + eps)) # aspect ratio - return (w2 > wh_thr) & (h2 > wh_thr) & (w2 * h2 / (w1 * h1 + eps) > area_thr) & (ar < ar_thr) # candidates diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/autoanchor.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/autoanchor.py deleted file mode 100755 index eef8f6499..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/autoanchor.py +++ /dev/null @@ -1,164 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Auto-anchor utils -""" - -import random - -import numpy as np -import torch -import yaml -from tqdm import tqdm - -from utils.general import LOGGER, colorstr, emojis - -PREFIX = colorstr('AutoAnchor: ') - - -def check_anchor_order(m): - # Check anchor order against stride order for YOLOv5 Detect() module m, and correct if necessary - a = m.anchors.prod(-1).view(-1) # anchor area - da = a[-1] - a[0] # delta a - ds = m.stride[-1] - m.stride[0] # delta s - if da.sign() != ds.sign(): # same order - LOGGER.info(f'{PREFIX}Reversing anchor order') - m.anchors[:] = m.anchors.flip(0) - - -def check_anchors(dataset, model, thr=4.0, imgsz=640): - # Check anchor fit to data, recompute if necessary - m = model.module.model[-1] if hasattr(model, 'module') else model.model[-1] # Detect() - shapes = imgsz * dataset.shapes / dataset.shapes.max(1, keepdims=True) - scale = np.random.uniform(0.9, 1.1, size=(shapes.shape[0], 1)) # augment scale - wh = torch.tensor(np.concatenate([l[:, 3:5] * s for s, l in zip(shapes * scale, dataset.labels)])).float() # wh - - def metric(k): # compute metric - r = wh[:, None] / k[None] - x = torch.min(r, 1 / r).min(2)[0] # ratio metric - best = x.max(1)[0] # best_x - aat = (x > 1 / thr).float().sum(1).mean() # anchors above threshold - bpr = (best > 1 / thr).float().mean() # best possible recall - return bpr, aat - - anchors = m.anchors.clone() * m.stride.to(m.anchors.device).view(-1, 1, 1) # current anchors - bpr, aat = metric(anchors.cpu().view(-1, 2)) - s = f'\n{PREFIX}{aat:.2f} anchors/target, {bpr:.3f} Best Possible Recall (BPR). ' - if bpr > 0.98: # threshold to recompute - LOGGER.info(emojis(f'{s}Current anchors are a good fit to dataset ✅')) - else: - LOGGER.info(emojis(f'{s}Anchors are a poor fit to dataset ⚠️, attempting to improve...')) - na = m.anchors.numel() // 2 # number of anchors - try: - anchors = kmean_anchors(dataset, n=na, img_size=imgsz, thr=thr, gen=1000, verbose=False) - except Exception as e: - LOGGER.info(f'{PREFIX}ERROR: {e}') - new_bpr = metric(anchors)[0] - if new_bpr > bpr: # replace anchors - anchors = torch.tensor(anchors, device=m.anchors.device).type_as(m.anchors) - m.anchors[:] = anchors.clone().view_as(m.anchors) / m.stride.to(m.anchors.device).view(-1, 1, 1) # loss - check_anchor_order(m) - LOGGER.info(f'{PREFIX}New anchors saved to model. Update model *.yaml to use these anchors in the future.') - else: - LOGGER.info(f'{PREFIX}Original anchors better than new anchors. Proceeding with original anchors.') - - -def kmean_anchors(dataset='./data/coco128.yaml', n=9, img_size=640, thr=4.0, gen=1000, verbose=True): - """ Creates kmeans-evolved anchors from training dataset - - Arguments: - dataset: path to data.yaml, or a loaded dataset - n: number of anchors - img_size: image size used for training - thr: anchor-label wh ratio threshold hyperparameter hyp['anchor_t'] used for training, default=4.0 - gen: generations to evolve anchors using genetic algorithm - verbose: print all results - - Return: - k: kmeans evolved anchors - - Usage: - from utils.autoanchor import *; _ = kmean_anchors() - """ - from scipy.cluster.vq import kmeans - - thr = 1 / thr - - def metric(k, wh): # compute metrics - r = wh[:, None] / k[None] - x = torch.min(r, 1 / r).min(2)[0] # ratio metric - # x = wh_iou(wh, torch.tensor(k)) # iou metric - return x, x.max(1)[0] # x, best_x - - def anchor_fitness(k): # mutation fitness - _, best = metric(torch.tensor(k, dtype=torch.float32), wh) - return (best * (best > thr).float()).mean() # fitness - - def print_results(k, verbose=True): - k = k[np.argsort(k.prod(1))] # sort small to large - x, best = metric(k, wh0) - bpr, aat = (best > thr).float().mean(), (x > thr).float().mean() * n # best possible recall, anch > thr - s = f'{PREFIX}thr={thr:.2f}: {bpr:.4f} best possible recall, {aat:.2f} anchors past thr\n' \ - f'{PREFIX}n={n}, img_size={img_size}, metric_all={x.mean():.3f}/{best.mean():.3f}-mean/best, ' \ - f'past_thr={x[x > thr].mean():.3f}-mean: ' - for i, x in enumerate(k): - s += '%i,%i, ' % (round(x[0]), round(x[1])) - if verbose: - LOGGER.info(s[:-2]) - return k - - if isinstance(dataset, str): # *.yaml file - with open(dataset, errors='ignore') as f: - data_dict = yaml.safe_load(f) # model dict - from utils.datasets import LoadImagesAndLabels - dataset = LoadImagesAndLabels(data_dict['train'], augment=True, rect=True) - - # Get label wh - shapes = img_size * dataset.shapes / dataset.shapes.max(1, keepdims=True) - wh0 = np.concatenate([l[:, 3:5] * s for s, l in zip(shapes, dataset.labels)]) # wh - - # Filter - i = (wh0 < 3.0).any(1).sum() - if i: - LOGGER.info(f'{PREFIX}WARNING: Extremely small objects found. {i} of {len(wh0)} labels are < 3 pixels in size.') - wh = wh0[(wh0 >= 2.0).any(1)] # filter > 2 pixels - # wh = wh * (np.random.rand(wh.shape[0], 1) * 0.9 + 0.1) # multiply by random scale 0-1 - - # Kmeans calculation - LOGGER.info(f'{PREFIX}Running kmeans for {n} anchors on {len(wh)} points...') - s = wh.std(0) # sigmas for whitening - k, dist = kmeans(wh / s, n, iter=30) # points, mean distance - assert len(k) == n, f'{PREFIX}ERROR: scipy.cluster.vq.kmeans requested {n} points but returned only {len(k)}' - k *= s - wh = torch.tensor(wh, dtype=torch.float32) # filtered - wh0 = torch.tensor(wh0, dtype=torch.float32) # unfiltered - k = print_results(k, verbose=False) - - # Plot - # k, d = [None] * 20, [None] * 20 - # for i in tqdm(range(1, 21)): - # k[i-1], d[i-1] = kmeans(wh / s, i) # points, mean distance - # fig, ax = plt.subplots(1, 2, figsize=(14, 7), tight_layout=True) - # ax = ax.ravel() - # ax[0].plot(np.arange(1, 21), np.array(d) ** 2, marker='.') - # fig, ax = plt.subplots(1, 2, figsize=(14, 7)) # plot wh - # ax[0].hist(wh[wh[:, 0]<100, 0],400) - # ax[1].hist(wh[wh[:, 1]<100, 1],400) - # fig.savefig('wh.png', dpi=200) - - # Evolve - npr = np.random - f, sh, mp, s = anchor_fitness(k), k.shape, 0.9, 0.1 # fitness, generations, mutation prob, sigma - pbar = tqdm(range(gen), desc=f'{PREFIX}Evolving anchors with Genetic Algorithm:') # progress bar - for _ in pbar: - v = np.ones(sh) - while (v == 1).all(): # mutate until a change occurs (prevent duplicates) - v = ((npr.random(sh) < mp) * random.random() * npr.randn(*sh) * s + 1).clip(0.3, 3.0) - kg = (k.copy() * v).clip(min=2.0) - fg = anchor_fitness(kg) - if fg > f: - f, k = fg, kg.copy() - pbar.desc = f'{PREFIX}Evolving anchors with Genetic Algorithm: fitness = {f:.4f}' - if verbose: - print_results(k, verbose) - - return print_results(k) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/autobatch.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/autobatch.py deleted file mode 100755 index cb94f041e..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/autobatch.py +++ /dev/null @@ -1,57 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Auto-batch utils -""" - -from copy import deepcopy - -import numpy as np -import torch -from torch.cuda import amp - -from utils.general import LOGGER, colorstr -from utils.torch_utils import profile - - -def check_train_batch_size(model, imgsz=640): - # Check YOLOv5 training batch size - with amp.autocast(): - return autobatch(deepcopy(model).train(), imgsz) # compute optimal batch size - - -def autobatch(model, imgsz=640, fraction=0.9, batch_size=16): - # Automatically estimate best batch size to use `fraction` of available CUDA memory - # Usage: - # import torch - # from utils.autobatch import autobatch - # model = torch.hub.load('ultralytics/yolov5', 'yolov5s', autoshape=False) - # print(autobatch(model)) - - prefix = colorstr('AutoBatch: ') - LOGGER.info(f'{prefix}Computing optimal batch size for --imgsz {imgsz}') - device = next(model.parameters()).device # get model device - if device.type == 'cpu': - LOGGER.info(f'{prefix}CUDA not detected, using default CPU batch-size {batch_size}') - return batch_size - - d = str(device).upper() # 'CUDA:0' - properties = torch.cuda.get_device_properties(device) # device properties - t = properties.total_memory / 1024 ** 3 # (GiB) - r = torch.cuda.memory_reserved(device) / 1024 ** 3 # (GiB) - a = torch.cuda.memory_allocated(device) / 1024 ** 3 # (GiB) - f = t - (r + a) # free inside reserved - LOGGER.info(f'{prefix}{d} ({properties.name}) {t:.2f}G total, {r:.2f}G reserved, {a:.2f}G allocated, {f:.2f}G free') - - batch_sizes = [1, 2, 4, 8, 16] - try: - img = [torch.zeros(b, 3, imgsz, imgsz) for b in batch_sizes] - y = profile(img, model, n=3, device=device) - except Exception as e: - LOGGER.warning(f'{prefix}{e}') - - y = [x[2] for x in y if x] # memory [2] - batch_sizes = batch_sizes[:len(y)] - p = np.polyfit(batch_sizes, y, deg=1) # first degree polynomial fit - b = int((f * fraction - p[1]) / p[0]) # y intercept (optimal batch size) - LOGGER.info(f'{prefix}Using batch-size {b} for {d} {t * fraction:.2f}G/{t:.2f}G ({fraction * 100:.0f}%)') - return b diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/mime.sh b/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/mime.sh deleted file mode 100755 index c319a83cf..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/mime.sh +++ /dev/null @@ -1,26 +0,0 @@ -# AWS EC2 instance startup 'MIME' script https://aws.amazon.com/premiumsupport/knowledge-center/execute-user-data-ec2/ -# This script will run on every instance restart, not only on first start -# --- DO NOT COPY ABOVE COMMENTS WHEN PASTING INTO USERDATA --- - -Content-Type: multipart/mixed; boundary="//" -MIME-Version: 1.0 - ---// -Content-Type: text/cloud-config; charset="us-ascii" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Disposition: attachment; filename="cloud-config.txt" - -#cloud-config -cloud_final_modules: -- [scripts-user, always] - ---// -Content-Type: text/x-shellscript; charset="us-ascii" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Disposition: attachment; filename="userdata.txt" - -#!/bin/bash -# --- paste contents of userdata.sh here --- ---// diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/resume.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/resume.py deleted file mode 100755 index b21731c97..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/resume.py +++ /dev/null @@ -1,40 +0,0 @@ -# Resume all interrupted trainings in yolov5/ dir including DDP trainings -# Usage: $ python utils/aws/resume.py - -import os -import sys -from pathlib import Path - -import torch -import yaml - -FILE = Path(__file__).resolve() -ROOT = FILE.parents[2] # YOLOv5 root directory -if str(ROOT) not in sys.path: - sys.path.append(str(ROOT)) # add ROOT to PATH - -port = 0 # --master_port -path = Path('').resolve() -for last in path.rglob('*/**/last.pt'): - ckpt = torch.load(last) - if ckpt['optimizer'] is None: - continue - - # Load opt.yaml - with open(last.parent.parent / 'opt.yaml', errors='ignore') as f: - opt = yaml.safe_load(f) - - # Get device count - d = opt['device'].split(',') # devices - nd = len(d) # number of devices - ddp = nd > 1 or (nd == 0 and torch.cuda.device_count() > 1) # distributed data parallel - - if ddp: # multi-GPU - port += 1 - cmd = f'python -m torch.distributed.run --nproc_per_node {nd} --master_port {port} train.py --resume {last}' - else: # single-GPU - cmd = f'python train.py --resume {last}' - - cmd += ' > /dev/null 2>&1 &' # redirect output to dev/null and run in daemon thread - print(cmd) - os.system(cmd) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/userdata.sh b/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/userdata.sh deleted file mode 100755 index 5fc1332ac..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/aws/userdata.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -# AWS EC2 instance startup script https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html -# This script will run only once on first instance start (for a re-start script see mime.sh) -# /home/ubuntu (ubuntu) or /home/ec2-user (amazon-linux) is working dir -# Use >300 GB SSD - -cd home/ubuntu -if [ ! -d yolov5 ]; then - echo "Running first-time script." # install dependencies, download COCO, pull Docker - git clone https://github.com/ultralytics/yolov5 -b master && sudo chmod -R 777 yolov5 - cd yolov5 - bash data/scripts/get_coco.sh && echo "COCO done." & - sudo docker pull ultralytics/yolov5:latest && echo "Docker done." & - python -m pip install --upgrade pip && pip install -r requirements.txt && python detect.py && echo "Requirements done." & - wait && echo "All tasks done." # finish background tasks -else - echo "Running re-start script." # resume interrupted runs - i=0 - list=$(sudo docker ps -qa) # container list i.e. $'one\ntwo\nthree\nfour' - while IFS= read -r id; do - ((i++)) - echo "restarting container $i: $id" - sudo docker start $id - # sudo docker exec -it $id python train.py --resume # single-GPU - sudo docker exec -d $id python utils/aws/resume.py # multi-scenario - done <<<"$list" -fi diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/callbacks.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/callbacks.py deleted file mode 100755 index c9d936ef0..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/callbacks.py +++ /dev/null @@ -1,77 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Callback utils -""" - - -class Callbacks: - """" - Handles all registered callbacks for YOLOv5 Hooks - """ - - def __init__(self): - # Define the available callbacks - self._callbacks = { - 'on_pretrain_routine_start': [], - 'on_pretrain_routine_end': [], - - 'on_train_start': [], - 'on_train_epoch_start': [], - 'on_train_batch_start': [], - 'optimizer_step': [], - 'on_before_zero_grad': [], - 'on_train_batch_end': [], - 'on_train_epoch_end': [], - - 'on_val_start': [], - 'on_val_batch_start': [], - 'on_val_image_end': [], - 'on_val_batch_end': [], - 'on_val_end': [], - - 'on_fit_epoch_end': [], # fit = train + val - 'on_model_save': [], - 'on_train_end': [], - - 'teardown': [], - } - - def register_action(self, hook, name='', callback=None): - """ - Register a new action to a callback hook - - Args: - hook The callback hook name to register the action to - name The name of the action for later reference - callback The callback to fire - """ - assert hook in self._callbacks, f"hook '{hook}' not found in callbacks {self._callbacks}" - assert callable(callback), f"callback '{callback}' is not callable" - self._callbacks[hook].append({'name': name, 'callback': callback}) - - def get_registered_actions(self, hook=None): - """" - Returns all the registered actions by callback hook - - Args: - hook The name of the hook to check, defaults to all - """ - if hook: - return self._callbacks[hook] - else: - return self._callbacks - - def run(self, hook, *args, **kwargs): - """ - Loop through the registered actions and fire all callbacks - - Args: - hook The name of the hook to check, defaults to all - args Arguments to receive from YOLOv5 - kwargs Keyword Arguments to receive from YOLOv5 - """ - - assert hook in self._callbacks, f"hook '{hook}' not found in callbacks {self._callbacks}" - - for logger in self._callbacks[hook]: - logger['callback'](*args, **kwargs) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/datasets.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/datasets.py deleted file mode 100755 index a388a4ddf..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/datasets.py +++ /dev/null @@ -1,1036 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Dataloaders and dataset utils -""" - -import glob -import hashlib -import json -import os -import random -import shutil -import time -from itertools import repeat -from multiprocessing.pool import Pool, ThreadPool -from pathlib import Path -from threading import Thread -from zipfile import ZipFile - -import cv2 -import numpy as np -import torch -import torch.nn.functional as F -import yaml -from PIL import ExifTags, Image, ImageOps -from torch.utils.data import DataLoader, Dataset, dataloader, distributed -from tqdm import tqdm - -from .augmentations import Albumentations, augment_hsv, copy_paste, letterbox, mixup, random_perspective -from .general import (LOGGER, NUM_THREADS, check_dataset, check_requirements, check_yaml, clean_str, - segments2boxes, xyn2xy, xywh2xyxy, xywhn2xyxy, xyxy2xywhn) -from .torch_utils import torch_distributed_zero_first - -# Parameters -HELP_URL = 'https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data' -IMG_FORMATS = ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'tiff', 'dng', 'webp', 'mpo'] # acceptable image suffixes -VID_FORMATS = ['mov', 'avi', 'mp4', 'mpg', 'mpeg', 'm4v', 'wmv', 'mkv'] # acceptable video suffixes -WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1)) # DPP - -# Get orientation exif tag -for orientation in ExifTags.TAGS.keys(): - if ExifTags.TAGS[orientation] == 'Orientation': - break - - -def get_hash(paths): - # Returns a single hash value of a list of paths (files or dirs) - size = sum(os.path.getsize(p) for p in paths if os.path.exists(p)) # sizes - h = hashlib.md5(str(size).encode()) # hash sizes - h.update(''.join(paths).encode()) # hash paths - return h.hexdigest() # return hash - - -def exif_size(img): - # Returns exif-corrected PIL size - s = img.size # (width, height) - try: - rotation = dict(img._getexif().items())[orientation] - if rotation == 6: # rotation 270 - s = (s[1], s[0]) - elif rotation == 8: # rotation 90 - s = (s[1], s[0]) - except: - pass - - return s - - -def exif_transpose(image): - """ - Transpose a PIL image accordingly if it has an EXIF Orientation tag. - Inplace version of https://github.com/python-pillow/Pillow/blob/master/src/PIL/ImageOps.py exif_transpose() - - :param image: The image to transpose. - :return: An image. - """ - exif = image.getexif() - orientation = exif.get(0x0112, 1) # default 1 - if orientation > 1: - method = {2: Image.FLIP_LEFT_RIGHT, - 3: Image.ROTATE_180, - 4: Image.FLIP_TOP_BOTTOM, - 5: Image.TRANSPOSE, - 6: Image.ROTATE_270, - 7: Image.TRANSVERSE, - 8: Image.ROTATE_90, - }.get(orientation) - if method is not None: - image = image.transpose(method) - del exif[0x0112] - image.info["exif"] = exif.tobytes() - return image - - -def create_dataloader(path, imgsz, batch_size, stride, single_cls=False, hyp=None, augment=False, cache=False, pad=0.0, - rect=False, rank=-1, workers=8, image_weights=False, quad=False, prefix='', shuffle=False): - if rect and shuffle: - LOGGER.warning('WARNING: --rect is incompatible with DataLoader shuffle, setting shuffle=False') - shuffle = False - with torch_distributed_zero_first(rank): # init dataset *.cache only once if DDP - dataset = LoadImagesAndLabels(path, imgsz, batch_size, - augment=augment, # augmentation - hyp=hyp, # hyperparameters - rect=rect, # rectangular batches - cache_images=cache, - single_cls=single_cls, - stride=int(stride), - pad=pad, - image_weights=image_weights, - prefix=prefix) - - batch_size = min(batch_size, len(dataset)) - nw = min([os.cpu_count() // WORLD_SIZE, batch_size if batch_size > 1 else 0, workers]) # number of workers - sampler = None if rank == -1 else distributed.DistributedSampler(dataset, shuffle=shuffle) - loader = DataLoader if image_weights else InfiniteDataLoader # only DataLoader allows for attribute updates - return loader(dataset, - batch_size=batch_size, - shuffle=shuffle and sampler is None, - num_workers=nw, - sampler=sampler, - pin_memory=True, - collate_fn=LoadImagesAndLabels.collate_fn4 if quad else LoadImagesAndLabels.collate_fn), dataset - - -class InfiniteDataLoader(dataloader.DataLoader): - """ Dataloader that reuses workers - - Uses same syntax as vanilla DataLoader - """ - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - object.__setattr__(self, 'batch_sampler', _RepeatSampler(self.batch_sampler)) - self.iterator = super().__iter__() - - def __len__(self): - return len(self.batch_sampler.sampler) - - def __iter__(self): - for i in range(len(self)): - yield next(self.iterator) - - -class _RepeatSampler: - """ Sampler that repeats forever - - Args: - sampler (Sampler) - """ - - def __init__(self, sampler): - self.sampler = sampler - - def __iter__(self): - while True: - yield from iter(self.sampler) - - -class LoadImages: - # YOLOv5 image/video dataloader, i.e. `python detect.py --source image.jpg/vid.mp4` - def __init__(self, path, img_size=640, stride=32, auto=True): - p = str(Path(path).resolve()) # os-agnostic absolute path - if '*' in p: - files = sorted(glob.glob(p, recursive=True)) # glob - elif os.path.isdir(p): - files = sorted(glob.glob(os.path.join(p, '*.*'))) # dir - elif os.path.isfile(p): - files = [p] # files - else: - raise Exception(f'ERROR: {p} does not exist') - - images = [x for x in files if x.split('.')[-1].lower() in IMG_FORMATS] - videos = [x for x in files if x.split('.')[-1].lower() in VID_FORMATS] - ni, nv = len(images), len(videos) - - self.img_size = img_size - self.stride = stride - self.files = images + videos - self.nf = ni + nv # number of files - self.video_flag = [False] * ni + [True] * nv - self.mode = 'image' - self.auto = auto - if any(videos): - self.new_video(videos[0]) # new video - else: - self.cap = None - assert self.nf > 0, f'No images or videos found in {p}. ' \ - f'Supported formats are:\nimages: {IMG_FORMATS}\nvideos: {VID_FORMATS}' - - def __iter__(self): - self.count = 0 - return self - - def __next__(self): - if self.count == self.nf: - raise StopIteration - path = self.files[self.count] - - if self.video_flag[self.count]: - # Read video - self.mode = 'video' - ret_val, img0 = self.cap.read() - while not ret_val: - self.count += 1 - self.cap.release() - if self.count == self.nf: # last video - raise StopIteration - else: - path = self.files[self.count] - self.new_video(path) - ret_val, img0 = self.cap.read() - - self.frame += 1 - s = f'video {self.count + 1}/{self.nf} ({self.frame}/{self.frames}) {path}: ' - - else: - # Read image - self.count += 1 - img0 = cv2.imread(path) # BGR - assert img0 is not None, f'Image Not Found {path}' - s = f'image {self.count}/{self.nf} {path}: ' - - # Padded resize - img = letterbox(img0, self.img_size, stride=self.stride, auto=self.auto)[0] - - # Convert - img = img.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - img = np.ascontiguousarray(img) - - return path, img, img0, self.cap, s - - def new_video(self, path): - self.frame = 0 - self.cap = cv2.VideoCapture(path) - self.frames = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT)) - - def __len__(self): - return self.nf # number of files - - -class LoadWebcam: # for inference - # YOLOv5 local webcam dataloader, i.e. `python detect.py --source 0` - def __init__(self, pipe='0', img_size=640, stride=32): - self.img_size = img_size - self.stride = stride - self.pipe = eval(pipe) if pipe.isnumeric() else pipe - self.cap = cv2.VideoCapture(self.pipe) # video capture object - self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 3) # set buffer size - - def __iter__(self): - self.count = -1 - return self - - def __next__(self): - self.count += 1 - if cv2.waitKey(1) == ord('q'): # q to quit - self.cap.release() - cv2.destroyAllWindows() - raise StopIteration - - # Read frame - ret_val, img0 = self.cap.read() - img0 = cv2.flip(img0, 1) # flip left-right - - # Print - assert ret_val, f'Camera Error {self.pipe}' - img_path = 'webcam.jpg' - s = f'webcam {self.count}: ' - - # Padded resize - img = letterbox(img0, self.img_size, stride=self.stride)[0] - - # Convert - img = img.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - img = np.ascontiguousarray(img) - - return img_path, img, img0, None, s - - def __len__(self): - return 0 - - -class LoadStreams: - # YOLOv5 streamloader, i.e. `python detect.py --source 'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP streams` - def __init__(self, sources='streams.txt', img_size=640, stride=32, auto=True): - self.mode = 'stream' - self.img_size = img_size - self.stride = stride - - if os.path.isfile(sources): - with open(sources) as f: - sources = [x.strip() for x in f.read().strip().splitlines() if len(x.strip())] - else: - sources = [sources] - - n = len(sources) - self.imgs, self.fps, self.frames, self.threads = [None] * n, [0] * n, [0] * n, [None] * n - self.sources = [clean_str(x) for x in sources] # clean source names for later - self.auto = auto - for i, s in enumerate(sources): # index, source - # Start thread to read frames from video stream - st = f'{i + 1}/{n}: {s}... ' - if 'youtube.com/' in s or 'youtu.be/' in s: # if source is YouTube video - check_requirements(('pafy', 'youtube_dl')) - import pafy - s = pafy.new(s).getbest(preftype="mp4").url # YouTube URL - s = eval(s) if s.isnumeric() else s # i.e. s = '0' local webcam - cap = cv2.VideoCapture(s) - assert cap.isOpened(), f'{st}Failed to open {s}' - w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) - h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) - self.fps[i] = max(cap.get(cv2.CAP_PROP_FPS) % 100, 0) or 30.0 # 30 FPS fallback - self.frames[i] = max(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)), 0) or float('inf') # infinite stream fallback - - _, self.imgs[i] = cap.read() # guarantee first frame - self.threads[i] = Thread(target=self.update, args=([i, cap, s]), daemon=True) - LOGGER.info(f"{st} Success ({self.frames[i]} frames {w}x{h} at {self.fps[i]:.2f} FPS)") - self.threads[i].start() - LOGGER.info('') # newline - - # check for common shapes - s = np.stack([letterbox(x, self.img_size, stride=self.stride, auto=self.auto)[0].shape for x in self.imgs]) - self.rect = np.unique(s, axis=0).shape[0] == 1 # rect inference if all shapes equal - if not self.rect: - LOGGER.warning('WARNING: Stream shapes differ. For optimal performance supply similarly-shaped streams.') - - def update(self, i, cap, stream): - # Read stream `i` frames in daemon thread - n, f, read = 0, self.frames[i], 1 # frame number, frame array, inference every 'read' frame - while cap.isOpened() and n < f: - n += 1 - # _, self.imgs[index] = cap.read() - cap.grab() - if n % read == 0: - success, im = cap.retrieve() - if success: - self.imgs[i] = im - else: - LOGGER.warning('WARNING: Video stream unresponsive, please check your IP camera connection.') - self.imgs[i] = np.zeros_like(self.imgs[i]) - cap.open(stream) # re-open stream if signal was lost - time.sleep(1 / self.fps[i]) # wait time - - def __iter__(self): - self.count = -1 - return self - - def __next__(self): - self.count += 1 - if not all(x.is_alive() for x in self.threads) or cv2.waitKey(1) == ord('q'): # q to quit - cv2.destroyAllWindows() - raise StopIteration - - # Letterbox - img0 = self.imgs.copy() - img = [letterbox(x, self.img_size, stride=self.stride, auto=self.rect and self.auto)[0] for x in img0] - - # Stack - img = np.stack(img, 0) - - # Convert - img = img[..., ::-1].transpose((0, 3, 1, 2)) # BGR to RGB, BHWC to BCHW - img = np.ascontiguousarray(img) - - return self.sources, img, img0, None, '' - - def __len__(self): - return len(self.sources) # 1E12 frames = 32 streams at 30 FPS for 30 years - - -def img2label_paths(img_paths): - # Define label paths as a function of image paths - sa, sb = os.sep + 'images' + os.sep, os.sep + 'labels' + os.sep # /images/, /labels/ substrings - return [sb.join(x.rsplit(sa, 1)).rsplit('.', 1)[0] + '.txt' for x in img_paths] - - -class LoadImagesAndLabels(Dataset): - # YOLOv5 train_loader/val_loader, loads images and labels for training and validation - cache_version = 0.6 # dataset labels *.cache version - - def __init__(self, path, img_size=640, batch_size=16, augment=False, hyp=None, rect=False, image_weights=False, - cache_images=False, single_cls=False, stride=32, pad=0.0, prefix=''): - self.img_size = img_size - self.augment = augment - self.hyp = hyp - self.image_weights = image_weights - self.rect = False if image_weights else rect - self.mosaic = self.augment and not self.rect # load 4 images at a time into a mosaic (only during training) - self.mosaic_border = [-img_size // 2, -img_size // 2] - self.stride = stride - self.path = path - self.albumentations = Albumentations() if augment else None - - try: - f = [] # image files - for p in path if isinstance(path, list) else [path]: - p = Path(p) # os-agnostic - if p.is_dir(): # dir - f += glob.glob(str(p / '**' / '*.*'), recursive=True) - # f = list(p.rglob('*.*')) # pathlib - elif p.is_file(): # file - with open(p) as t: - t = t.read().strip().splitlines() - parent = str(p.parent) + os.sep - f += [x.replace('./', parent) if x.startswith('./') else x for x in t] # local to global path - # f += [p.parent / x.lstrip(os.sep) for x in t] # local to global path (pathlib) - else: - raise Exception(f'{prefix}{p} does not exist') - self.img_files = sorted(x.replace('/', os.sep) for x in f if x.split('.')[-1].lower() in IMG_FORMATS) - # self.img_files = sorted([x for x in f if x.suffix[1:].lower() in IMG_FORMATS]) # pathlib - assert self.img_files, f'{prefix}No images found' - except Exception as e: - raise Exception(f'{prefix}Error loading data from {path}: {e}\nSee {HELP_URL}') - - # Check cache - self.label_files = img2label_paths(self.img_files) # labels - cache_path = (p if p.is_file() else Path(self.label_files[0]).parent).with_suffix('.cache') - try: - cache, exists = np.load(cache_path, allow_pickle=True).item(), True # load dict - assert cache['version'] == self.cache_version # same version - assert cache['hash'] == get_hash(self.label_files + self.img_files) # same hash - except: - cache, exists = self.cache_labels(cache_path, prefix), False # cache - - # Display cache - nf, nm, ne, nc, n = cache.pop('results') # found, missing, empty, corrupted, total - if exists: - d = f"Scanning '{cache_path}' images and labels... {nf} found, {nm} missing, {ne} empty, {nc} corrupted" - tqdm(None, desc=prefix + d, total=n, initial=n) # display cache results - if cache['msgs']: - LOGGER.info('\n'.join(cache['msgs'])) # display warnings - assert nf > 0 or not augment, f'{prefix}No labels in {cache_path}. Can not train without labels. See {HELP_URL}' - - # Read cache - [cache.pop(k) for k in ('hash', 'version', 'msgs')] # remove items - labels, shapes, self.segments = zip(*cache.values()) - self.labels = list(labels) - self.shapes = np.array(shapes, dtype=np.float64) - self.img_files = list(cache.keys()) # update - self.label_files = img2label_paths(cache.keys()) # update - n = len(shapes) # number of images - bi = np.floor(np.arange(n) / batch_size).astype(np.int) # batch index - nb = bi[-1] + 1 # number of batches - self.batch = bi # batch index of image - self.n = n - self.indices = range(n) - - # Update labels - include_class = [] # filter labels to include only these classes (optional) - include_class_array = np.array(include_class).reshape(1, -1) - for i, (label, segment) in enumerate(zip(self.labels, self.segments)): - if include_class: - j = (label[:, 0:1] == include_class_array).any(1) - self.labels[i] = label[j] - if segment: - self.segments[i] = segment[j] - if single_cls: # single-class training, merge all classes into 0 - self.labels[i][:, 0] = 0 - if segment: - self.segments[i][:, 0] = 0 - - # Rectangular Training - if self.rect: - # Sort by aspect ratio - s = self.shapes # wh - ar = s[:, 1] / s[:, 0] # aspect ratio - irect = ar.argsort() - self.img_files = [self.img_files[i] for i in irect] - self.label_files = [self.label_files[i] for i in irect] - self.labels = [self.labels[i] for i in irect] - self.shapes = s[irect] # wh - ar = ar[irect] - - # Set training image shapes - shapes = [[1, 1]] * nb - for i in range(nb): - ari = ar[bi == i] - mini, maxi = ari.min(), ari.max() - if maxi < 1: - shapes[i] = [maxi, 1] - elif mini > 1: - shapes[i] = [1, 1 / mini] - - self.batch_shapes = np.ceil(np.array(shapes) * img_size / stride + pad).astype(np.int) * stride - - # Cache images into memory for faster training (WARNING: large datasets may exceed system RAM) - self.imgs, self.img_npy = [None] * n, [None] * n - if cache_images: - if cache_images == 'disk': - self.im_cache_dir = Path(Path(self.img_files[0]).parent.as_posix() + '_npy') - self.img_npy = [self.im_cache_dir / Path(f).with_suffix('.npy').name for f in self.img_files] - self.im_cache_dir.mkdir(parents=True, exist_ok=True) - gb = 0 # Gigabytes of cached images - self.img_hw0, self.img_hw = [None] * n, [None] * n - results = ThreadPool(NUM_THREADS).imap(lambda x: load_image(*x), zip(repeat(self), range(n))) - pbar = tqdm(enumerate(results), total=n) - for i, x in pbar: - if cache_images == 'disk': - if not self.img_npy[i].exists(): - np.save(self.img_npy[i].as_posix(), x[0]) - gb += self.img_npy[i].stat().st_size - else: - self.imgs[i], self.img_hw0[i], self.img_hw[i] = x # im, hw_orig, hw_resized = load_image(self, i) - gb += self.imgs[i].nbytes - pbar.desc = f'{prefix}Caching images ({gb / 1E9:.1f}GB {cache_images})' - pbar.close() - - def cache_labels(self, path=Path('./labels.cache'), prefix=''): - # Cache dataset labels, check images and read shapes - x = {} # dict - nm, nf, ne, nc, msgs = 0, 0, 0, 0, [] # number missing, found, empty, corrupt, messages - desc = f"{prefix}Scanning '{path.parent / path.stem}' images and labels..." - with Pool(NUM_THREADS) as pool: - pbar = tqdm(pool.imap(verify_image_label, zip(self.img_files, self.label_files, repeat(prefix))), - desc=desc, total=len(self.img_files)) - for im_file, l, shape, segments, nm_f, nf_f, ne_f, nc_f, msg in pbar: - nm += nm_f - nf += nf_f - ne += ne_f - nc += nc_f - if im_file: - x[im_file] = [l, shape, segments] - if msg: - msgs.append(msg) - pbar.desc = f"{desc}{nf} found, {nm} missing, {ne} empty, {nc} corrupted" - - pbar.close() - if msgs: - LOGGER.info('\n'.join(msgs)) - if nf == 0: - LOGGER.warning(f'{prefix}WARNING: No labels found in {path}. See {HELP_URL}') - x['hash'] = get_hash(self.label_files + self.img_files) - x['results'] = nf, nm, ne, nc, len(self.img_files) - x['msgs'] = msgs # warnings - x['version'] = self.cache_version # cache version - try: - np.save(path, x) # save cache for next time - path.with_suffix('.cache.npy').rename(path) # remove .npy suffix - LOGGER.info(f'{prefix}New cache created: {path}') - except Exception as e: - LOGGER.warning(f'{prefix}WARNING: Cache directory {path.parent} is not writeable: {e}') # not writeable - return x - - def __len__(self): - return len(self.img_files) - - # def __iter__(self): - # self.count = -1 - # print('ran dataset iter') - # #self.shuffled_vector = np.random.permutation(self.nF) if self.augment else np.arange(self.nF) - # return self - - def __getitem__(self, index): - index = self.indices[index] # linear, shuffled, or image_weights - - hyp = self.hyp - mosaic = self.mosaic and random.random() < hyp['mosaic'] - if mosaic: - # Load mosaic - img, labels = load_mosaic(self, index) - shapes = None - - # MixUp augmentation - if random.random() < hyp['mixup']: - img, labels = mixup(img, labels, *load_mosaic(self, random.randint(0, self.n - 1))) - - else: - # Load image - img, (h0, w0), (h, w) = load_image(self, index) - - # Letterbox - shape = self.batch_shapes[self.batch[index]] if self.rect else self.img_size # final letterboxed shape - img, ratio, pad = letterbox(img, shape, auto=False, scaleup=self.augment) - shapes = (h0, w0), ((h / h0, w / w0), pad) # for COCO mAP rescaling - - labels = self.labels[index].copy() - if labels.size: # normalized xywh to pixel xyxy format - labels[:, 1:] = xywhn2xyxy(labels[:, 1:], ratio[0] * w, ratio[1] * h, padw=pad[0], padh=pad[1]) - - if self.augment: - img, labels = random_perspective(img, labels, - degrees=hyp['degrees'], - translate=hyp['translate'], - scale=hyp['scale'], - shear=hyp['shear'], - perspective=hyp['perspective']) - - nl = len(labels) # number of labels - if nl: - labels[:, 1:5] = xyxy2xywhn(labels[:, 1:5], w=img.shape[1], h=img.shape[0], clip=True, eps=1E-3) - - if self.augment: - # Albumentations - img, labels = self.albumentations(img, labels) - nl = len(labels) # update after albumentations - - # HSV color-space - augment_hsv(img, hgain=hyp['hsv_h'], sgain=hyp['hsv_s'], vgain=hyp['hsv_v']) - - # Flip up-down - if random.random() < hyp['flipud']: - img = np.flipud(img) - if nl: - labels[:, 2] = 1 - labels[:, 2] - - # Flip left-right - if random.random() < hyp['fliplr']: - img = np.fliplr(img) - if nl: - labels[:, 1] = 1 - labels[:, 1] - - # Cutouts - # labels = cutout(img, labels, p=0.5) - # nl = len(labels) # update after cutout - - labels_out = torch.zeros((nl, 6)) - if nl: - labels_out[:, 1:] = torch.from_numpy(labels) - - # Convert - img = img.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB - img = np.ascontiguousarray(img) - - return torch.from_numpy(img), labels_out, self.img_files[index], shapes - - @staticmethod - def collate_fn(batch): - img, label, path, shapes = zip(*batch) # transposed - for i, l in enumerate(label): - l[:, 0] = i # add target image index for build_targets() - return torch.stack(img, 0), torch.cat(label, 0), path, shapes - - @staticmethod - def collate_fn4(batch): - img, label, path, shapes = zip(*batch) # transposed - n = len(shapes) // 4 - img4, label4, path4, shapes4 = [], [], path[:n], shapes[:n] - - ho = torch.tensor([[0.0, 0, 0, 1, 0, 0]]) - wo = torch.tensor([[0.0, 0, 1, 0, 0, 0]]) - s = torch.tensor([[1, 1, 0.5, 0.5, 0.5, 0.5]]) # scale - for i in range(n): # zidane torch.zeros(16,3,720,1280) # BCHW - i *= 4 - if random.random() < 0.5: - im = F.interpolate(img[i].unsqueeze(0).float(), scale_factor=2.0, mode='bilinear', align_corners=False)[ - 0].type(img[i].type()) - l = label[i] - else: - im = torch.cat((torch.cat((img[i], img[i + 1]), 1), torch.cat((img[i + 2], img[i + 3]), 1)), 2) - l = torch.cat((label[i], label[i + 1] + ho, label[i + 2] + wo, label[i + 3] + ho + wo), 0) * s - img4.append(im) - label4.append(l) - - for i, l in enumerate(label4): - l[:, 0] = i # add target image index for build_targets() - - return torch.stack(img4, 0), torch.cat(label4, 0), path4, shapes4 - - -# Ancillary functions -------------------------------------------------------------------------------------------------- -def load_image(self, i): - # loads 1 image from dataset index 'i', returns im, original hw, resized hw - im = self.imgs[i] - if im is None: # not cached in ram - npy = self.img_npy[i] - if npy and npy.exists(): # load npy - im = np.load(npy) - else: # read image - path = self.img_files[i] - im = cv2.imread(path) # BGR - assert im is not None, f'Image Not Found {path}' - h0, w0 = im.shape[:2] # orig hw - r = self.img_size / max(h0, w0) # ratio - if r != 1: # if sizes are not equal - im = cv2.resize(im, (int(w0 * r), int(h0 * r)), - interpolation=cv2.INTER_AREA if r < 1 and not self.augment else cv2.INTER_LINEAR) - return im, (h0, w0), im.shape[:2] # im, hw_original, hw_resized - else: - return self.imgs[i], self.img_hw0[i], self.img_hw[i] # im, hw_original, hw_resized - - -def load_mosaic(self, index): - # YOLOv5 4-mosaic loader. Loads 1 image + 3 random images into a 4-image mosaic - labels4, segments4 = [], [] - s = self.img_size - yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in self.mosaic_border) # mosaic center x, y - indices = [index] + random.choices(self.indices, k=3) # 3 additional image indices - random.shuffle(indices) - for i, index in enumerate(indices): - # Load image - img, _, (h, w) = load_image(self, index) - - # place img in img4 - if i == 0: # top left - img4 = np.full((s * 2, s * 2, img.shape[2]), 114, dtype=np.uint8) # base image with 4 tiles - x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc # xmin, ymin, xmax, ymax (large image) - x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h # xmin, ymin, xmax, ymax (small image) - elif i == 1: # top right - x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc - x1b, y1b, x2b, y2b = 0, h - (y2a - y1a), min(w, x2a - x1a), h - elif i == 2: # bottom left - x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h) - x1b, y1b, x2b, y2b = w - (x2a - x1a), 0, w, min(y2a - y1a, h) - elif i == 3: # bottom right - x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h) - x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h) - - img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b] # img4[ymin:ymax, xmin:xmax] - padw = x1a - x1b - padh = y1a - y1b - - # Labels - labels, segments = self.labels[index].copy(), self.segments[index].copy() - if labels.size: - labels[:, 1:] = xywhn2xyxy(labels[:, 1:], w, h, padw, padh) # normalized xywh to pixel xyxy format - segments = [xyn2xy(x, w, h, padw, padh) for x in segments] - labels4.append(labels) - segments4.extend(segments) - - # Concat/clip labels - labels4 = np.concatenate(labels4, 0) - for x in (labels4[:, 1:], *segments4): - np.clip(x, 0, 2 * s, out=x) # clip when using random_perspective() - # img4, labels4 = replicate(img4, labels4) # replicate - - # Augment - img4, labels4, segments4 = copy_paste(img4, labels4, segments4, p=self.hyp['copy_paste']) - img4, labels4 = random_perspective(img4, labels4, segments4, - degrees=self.hyp['degrees'], - translate=self.hyp['translate'], - scale=self.hyp['scale'], - shear=self.hyp['shear'], - perspective=self.hyp['perspective'], - border=self.mosaic_border) # border to remove - - return img4, labels4 - - -def load_mosaic9(self, index): - # YOLOv5 9-mosaic loader. Loads 1 image + 8 random images into a 9-image mosaic - labels9, segments9 = [], [] - s = self.img_size - indices = [index] + random.choices(self.indices, k=8) # 8 additional image indices - random.shuffle(indices) - for i, index in enumerate(indices): - # Load image - img, _, (h, w) = load_image(self, index) - - # place img in img9 - if i == 0: # center - img9 = np.full((s * 3, s * 3, img.shape[2]), 114, dtype=np.uint8) # base image with 4 tiles - h0, w0 = h, w - c = s, s, s + w, s + h # xmin, ymin, xmax, ymax (base) coordinates - elif i == 1: # top - c = s, s - h, s + w, s - elif i == 2: # top right - c = s + wp, s - h, s + wp + w, s - elif i == 3: # right - c = s + w0, s, s + w0 + w, s + h - elif i == 4: # bottom right - c = s + w0, s + hp, s + w0 + w, s + hp + h - elif i == 5: # bottom - c = s + w0 - w, s + h0, s + w0, s + h0 + h - elif i == 6: # bottom left - c = s + w0 - wp - w, s + h0, s + w0 - wp, s + h0 + h - elif i == 7: # left - c = s - w, s + h0 - h, s, s + h0 - elif i == 8: # top left - c = s - w, s + h0 - hp - h, s, s + h0 - hp - - padx, pady = c[:2] - x1, y1, x2, y2 = (max(x, 0) for x in c) # allocate coords - - # Labels - labels, segments = self.labels[index].copy(), self.segments[index].copy() - if labels.size: - labels[:, 1:] = xywhn2xyxy(labels[:, 1:], w, h, padx, pady) # normalized xywh to pixel xyxy format - segments = [xyn2xy(x, w, h, padx, pady) for x in segments] - labels9.append(labels) - segments9.extend(segments) - - # Image - img9[y1:y2, x1:x2] = img[y1 - pady:, x1 - padx:] # img9[ymin:ymax, xmin:xmax] - hp, wp = h, w # height, width previous - - # Offset - yc, xc = (int(random.uniform(0, s)) for _ in self.mosaic_border) # mosaic center x, y - img9 = img9[yc:yc + 2 * s, xc:xc + 2 * s] - - # Concat/clip labels - labels9 = np.concatenate(labels9, 0) - labels9[:, [1, 3]] -= xc - labels9[:, [2, 4]] -= yc - c = np.array([xc, yc]) # centers - segments9 = [x - c for x in segments9] - - for x in (labels9[:, 1:], *segments9): - np.clip(x, 0, 2 * s, out=x) # clip when using random_perspective() - # img9, labels9 = replicate(img9, labels9) # replicate - - # Augment - img9, labels9 = random_perspective(img9, labels9, segments9, - degrees=self.hyp['degrees'], - translate=self.hyp['translate'], - scale=self.hyp['scale'], - shear=self.hyp['shear'], - perspective=self.hyp['perspective'], - border=self.mosaic_border) # border to remove - - return img9, labels9 - - -def create_folder(path='./new'): - # Create folder - if os.path.exists(path): - shutil.rmtree(path) # delete output folder - os.makedirs(path) # make new output folder - - -def flatten_recursive(path='../datasets/coco128'): - # Flatten a recursive directory by bringing all files to top level - new_path = Path(path + '_flat') - create_folder(new_path) - for file in tqdm(glob.glob(str(Path(path)) + '/**/*.*', recursive=True)): - shutil.copyfile(file, new_path / Path(file).name) - - -def extract_boxes(path='../datasets/coco128'): # from utils.datasets import *; extract_boxes() - # Convert detection dataset into classification dataset, with one directory per class - path = Path(path) # images dir - shutil.rmtree(path / 'classifier') if (path / 'classifier').is_dir() else None # remove existing - files = list(path.rglob('*.*')) - n = len(files) # number of files - for im_file in tqdm(files, total=n): - if im_file.suffix[1:] in IMG_FORMATS: - # image - im = cv2.imread(str(im_file))[..., ::-1] # BGR to RGB - h, w = im.shape[:2] - - # labels - lb_file = Path(img2label_paths([str(im_file)])[0]) - if Path(lb_file).exists(): - with open(lb_file) as f: - lb = np.array([x.split() for x in f.read().strip().splitlines()], dtype=np.float32) # labels - - for j, x in enumerate(lb): - c = int(x[0]) # class - f = (path / 'classifier') / f'{c}' / f'{path.stem}_{im_file.stem}_{j}.jpg' # new filename - if not f.parent.is_dir(): - f.parent.mkdir(parents=True) - - b = x[1:] * [w, h, w, h] # box - # b[2:] = b[2:].max() # rectangle to square - b[2:] = b[2:] * 1.2 + 3 # pad - b = xywh2xyxy(b.reshape(-1, 4)).ravel().astype(np.int) - - b[[0, 2]] = np.clip(b[[0, 2]], 0, w) # clip boxes outside of image - b[[1, 3]] = np.clip(b[[1, 3]], 0, h) - assert cv2.imwrite(str(f), im[b[1]:b[3], b[0]:b[2]]), f'box failure in {f}' - - -def autosplit(path='../datasets/coco128/images', weights=(0.9, 0.1, 0.0), annotated_only=False): - """ Autosplit a dataset into train/val/test splits and save path/autosplit_*.txt files - Usage: from utils.datasets import *; autosplit() - Arguments - path: Path to images directory - weights: Train, val, test weights (list, tuple) - annotated_only: Only use images with an annotated txt file - """ - path = Path(path) # images dir - files = sorted(x for x in path.rglob('*.*') if x.suffix[1:].lower() in IMG_FORMATS) # image files only - n = len(files) # number of files - random.seed(0) # for reproducibility - indices = random.choices([0, 1, 2], weights=weights, k=n) # assign each image to a split - - txt = ['autosplit_train.txt', 'autosplit_val.txt', 'autosplit_test.txt'] # 3 txt files - [(path.parent / x).unlink(missing_ok=True) for x in txt] # remove existing - - print(f'Autosplitting images from {path}' + ', using *.txt labeled images only' * annotated_only) - for i, img in tqdm(zip(indices, files), total=n): - if not annotated_only or Path(img2label_paths([str(img)])[0]).exists(): # check label - with open(path.parent / txt[i], 'a') as f: - f.write('./' + img.relative_to(path.parent).as_posix() + '\n') # add image to txt file - - -def verify_image_label(args): - # Verify one image-label pair - im_file, lb_file, prefix = args - nm, nf, ne, nc, msg, segments = 0, 0, 0, 0, '', [] # number (missing, found, empty, corrupt), message, segments - try: - # verify images - im = Image.open(im_file) - im.verify() # PIL verify - shape = exif_size(im) # image size - assert (shape[0] > 9) & (shape[1] > 9), f'image size {shape} <10 pixels' - assert im.format.lower() in IMG_FORMATS, f'invalid image format {im.format}' - if im.format.lower() in ('jpg', 'jpeg'): - with open(im_file, 'rb') as f: - f.seek(-2, 2) - if f.read() != b'\xff\xd9': # corrupt JPEG - ImageOps.exif_transpose(Image.open(im_file)).save(im_file, 'JPEG', subsampling=0, quality=100) - msg = f'{prefix}WARNING: {im_file}: corrupt JPEG restored and saved' - - # verify labels - if os.path.isfile(lb_file): - nf = 1 # label found - with open(lb_file) as f: - l = [x.split() for x in f.read().strip().splitlines() if len(x)] - if any([len(x) > 8 for x in l]): # is segment - classes = np.array([x[0] for x in l], dtype=np.float32) - segments = [np.array(x[1:], dtype=np.float32).reshape(-1, 2) for x in l] # (cls, xy1...) - l = np.concatenate((classes.reshape(-1, 1), segments2boxes(segments)), 1) # (cls, xywh) - l = np.array(l, dtype=np.float32) - nl = len(l) - if nl: - assert l.shape[1] == 5, f'labels require 5 columns, {l.shape[1]} columns detected' - assert (l >= 0).all(), f'negative label values {l[l < 0]}' - assert (l[:, 1:] <= 1).all(), f'non-normalized or out of bounds coordinates {l[:, 1:][l[:, 1:] > 1]}' - _, i = np.unique(l, axis=0, return_index=True) - if len(i) < nl: # duplicate row check - l = l[i] # remove duplicates - if segments: - segments = segments[i] - msg = f'{prefix}WARNING: {im_file}: {nl - len(i)} duplicate labels removed' - else: - ne = 1 # label empty - l = np.zeros((0, 5), dtype=np.float32) - else: - nm = 1 # label missing - l = np.zeros((0, 5), dtype=np.float32) - return im_file, l, shape, segments, nm, nf, ne, nc, msg - except Exception as e: - nc = 1 - msg = f'{prefix}WARNING: {im_file}: ignoring corrupt image/label: {e}' - return [None, None, None, None, nm, nf, ne, nc, msg] - - -def dataset_stats(path='coco128.yaml', autodownload=False, verbose=False, profile=False, hub=False): - """ Return dataset statistics dictionary with images and instances counts per split per class - To run in parent directory: export PYTHONPATH="$PWD/yolov5" - Usage1: from utils.datasets import *; dataset_stats('coco128.yaml', autodownload=True) - Usage2: from utils.datasets import *; dataset_stats('../datasets/coco128_with_yaml.zip') - Arguments - path: Path to data.yaml or data.zip (with data.yaml inside data.zip) - autodownload: Attempt to download dataset if not found locally - verbose: Print stats dictionary - """ - - def round_labels(labels): - # Update labels to integer class and 6 decimal place floats - return [[int(c), *(round(x, 4) for x in points)] for c, *points in labels] - - def unzip(path): - # Unzip data.zip TODO: CONSTRAINT: path/to/abc.zip MUST unzip to 'path/to/abc/' - if str(path).endswith('.zip'): # path is data.zip - assert Path(path).is_file(), f'Error unzipping {path}, file not found' - ZipFile(path).extractall(path=path.parent) # unzip - dir = path.with_suffix('') # dataset directory == zip name - return True, str(dir), next(dir.rglob('*.yaml')) # zipped, data_dir, yaml_path - else: # path is data.yaml - return False, None, path - - def hub_ops(f, max_dim=1920): - # HUB ops for 1 image 'f': resize and save at reduced quality in /dataset-hub for web/app viewing - f_new = im_dir / Path(f).name # dataset-hub image filename - try: # use PIL - im = Image.open(f) - r = max_dim / max(im.height, im.width) # ratio - if r < 1.0: # image too large - im = im.resize((int(im.width * r), int(im.height * r))) - im.save(f_new, 'JPEG', quality=75, optimize=True) # save - except Exception as e: # use OpenCV - print(f'WARNING: HUB ops PIL failure {f}: {e}') - im = cv2.imread(f) - im_height, im_width = im.shape[:2] - r = max_dim / max(im_height, im_width) # ratio - if r < 1.0: # image too large - im = cv2.resize(im, (int(im_width * r), int(im_height * r)), interpolation=cv2.INTER_AREA) - cv2.imwrite(str(f_new), im) - - zipped, data_dir, yaml_path = unzip(Path(path)) - with open(check_yaml(yaml_path), errors='ignore') as f: - data = yaml.safe_load(f) # data dict - if zipped: - data['path'] = data_dir # TODO: should this be dir.resolve()? - check_dataset(data, autodownload) # download dataset if missing - hub_dir = Path(data['path'] + ('-hub' if hub else '')) - stats = {'nc': data['nc'], 'names': data['names']} # statistics dictionary - for split in 'train', 'val', 'test': - if data.get(split) is None: - stats[split] = None # i.e. no test set - continue - x = [] - dataset = LoadImagesAndLabels(data[split]) # load dataset - for label in tqdm(dataset.labels, total=dataset.n, desc='Statistics'): - x.append(np.bincount(label[:, 0].astype(int), minlength=data['nc'])) - x = np.array(x) # shape(128x80) - stats[split] = {'instance_stats': {'total': int(x.sum()), 'per_class': x.sum(0).tolist()}, - 'image_stats': {'total': dataset.n, 'unlabelled': int(np.all(x == 0, 1).sum()), - 'per_class': (x > 0).sum(0).tolist()}, - 'labels': [{str(Path(k).name): round_labels(v.tolist())} for k, v in - zip(dataset.img_files, dataset.labels)]} - - if hub: - im_dir = hub_dir / 'images' - im_dir.mkdir(parents=True, exist_ok=True) - for _ in tqdm(ThreadPool(NUM_THREADS).imap(hub_ops, dataset.img_files), total=dataset.n, desc='HUB Ops'): - pass - - # Profile - stats_path = hub_dir / 'stats.json' - if profile: - for _ in range(1): - file = stats_path.with_suffix('.npy') - t1 = time.time() - np.save(file, stats) - t2 = time.time() - x = np.load(file, allow_pickle=True) - print(f'stats.npy times: {time.time() - t2:.3f}s read, {t2 - t1:.3f}s write') - - file = stats_path.with_suffix('.json') - t1 = time.time() - with open(file, 'w') as f: - json.dump(stats, f) # save stats *.json - t2 = time.time() - with open(file) as f: - x = json.load(f) # load hyps dict - print(f'stats.json times: {time.time() - t2:.3f}s read, {t2 - t1:.3f}s write') - - # Save, print and return - if hub: - print(f'Saving {stats_path.resolve()}...') - with open(stats_path, 'w') as f: - json.dump(stats, f) # save stats.json - if verbose: - print(json.dumps(stats, indent=2, sort_keys=False)) - return stats diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/downloads.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/downloads.py deleted file mode 100755 index 998a7a582..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/downloads.py +++ /dev/null @@ -1,150 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Download utils -""" - -import os -import platform -import subprocess -import time -import urllib -from pathlib import Path -from zipfile import ZipFile - -import requests -import torch - - -def gsutil_getsize(url=''): - # gs://bucket/file size https://cloud.google.com/storage/docs/gsutil/commands/du - s = subprocess.check_output(f'gsutil du {url}', shell=True).decode('utf-8') - return eval(s.split(' ')[0]) if len(s) else 0 # bytes - - -def safe_download(file, url, url2=None, min_bytes=1E0, error_msg=''): - # Attempts to download file from url or url2, checks and removes incomplete downloads < min_bytes - file = Path(file) - assert_msg = f"Downloaded file '{file}' does not exist or size is < min_bytes={min_bytes}" - try: # url1 - print(f'Downloading {url} to {file}...') - torch.hub.download_url_to_file(url, str(file)) - assert file.exists() and file.stat().st_size > min_bytes, assert_msg # check - except Exception as e: # url2 - file.unlink(missing_ok=True) # remove partial downloads - print(f'ERROR: {e}\nRe-attempting {url2 or url} to {file}...') - os.system(f"curl -L '{url2 or url}' -o '{file}' --retry 3 -C -") # curl download, retry and resume on fail - finally: - if not file.exists() or file.stat().st_size < min_bytes: # check - file.unlink(missing_ok=True) # remove partial downloads - print(f"ERROR: {assert_msg}\n{error_msg}") - print('') - - -def attempt_download(file, repo='ultralytics/yolov5'): # from utils.downloads import *; attempt_download() - # Attempt file download if does not exist - file = Path(str(file).strip().replace("'", '')) - - if not file.exists(): - # URL specified - name = Path(urllib.parse.unquote(str(file))).name # decode '%2F' to '/' etc. - if str(file).startswith(('http:/', 'https:/')): # download - url = str(file).replace(':/', '://') # Pathlib turns :// -> :/ - name = name.split('?')[0] # parse authentication https://url.com/file.txt?auth... - safe_download(file=name, url=url, min_bytes=1E5) - return name - - # GitHub assets - file.parent.mkdir(parents=True, exist_ok=True) # make parent dir (if required) - try: - response = requests.get(f'https://api.github.com/repos/{repo}/releases/latest').json() # github api - assets = [x['name'] for x in response['assets']] # release assets, i.e. ['yolov5s.pt', 'yolov5m.pt', ...] - tag = response['tag_name'] # i.e. 'v1.0' - except: # fallback plan - assets = ['yolov5n.pt', 'yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt', - 'yolov5n6.pt', 'yolov5s6.pt', 'yolov5m6.pt', 'yolov5l6.pt', 'yolov5x6.pt'] - try: - tag = subprocess.check_output('git tag', shell=True, stderr=subprocess.STDOUT).decode().split()[-1] - except: - tag = 'v6.0' # current release - - if name in assets: - safe_download(file, - url=f'https://github.com/{repo}/releases/download/{tag}/{name}', - # url2=f'https://storage.googleapis.com/{repo}/ckpt/{name}', # backup url (optional) - min_bytes=1E5, - error_msg=f'{file} missing, try downloading from https://github.com/{repo}/releases/') - - return str(file) - - -def gdrive_download(id='16TiPfZj7htmTyhntwcZyEEAejOUxuT6m', file='tmp.zip'): - # Downloads a file from Google Drive. from yolov5.utils.downloads import *; gdrive_download() - t = time.time() - file = Path(file) - cookie = Path('cookie') # gdrive cookie - print(f'Downloading https://drive.google.com/uc?export=download&id={id} as {file}... ', end='') - file.unlink(missing_ok=True) # remove existing file - cookie.unlink(missing_ok=True) # remove existing cookie - - # Attempt file download - out = "NUL" if platform.system() == "Windows" else "/dev/null" - os.system(f'curl -c ./cookie -s -L "drive.google.com/uc?export=download&id={id}" > {out}') - if os.path.exists('cookie'): # large file - s = f'curl -Lb ./cookie "drive.google.com/uc?export=download&confirm={get_token()}&id={id}" -o {file}' - else: # small file - s = f'curl -s -L -o {file} "drive.google.com/uc?export=download&id={id}"' - r = os.system(s) # execute, capture return - cookie.unlink(missing_ok=True) # remove existing cookie - - # Error check - if r != 0: - file.unlink(missing_ok=True) # remove partial - print('Download error ') # raise Exception('Download error') - return r - - # Unzip if archive - if file.suffix == '.zip': - print('unzipping... ', end='') - ZipFile(file).extractall(path=file.parent) # unzip - file.unlink() # remove zip - - print(f'Done ({time.time() - t:.1f}s)') - return r - - -def get_token(cookie="./cookie"): - with open(cookie) as f: - for line in f: - if "download" in line: - return line.split()[-1] - return "" - -# Google utils: https://cloud.google.com/storage/docs/reference/libraries ---------------------------------------------- -# -# -# def upload_blob(bucket_name, source_file_name, destination_blob_name): -# # Uploads a file to a bucket -# # https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-python -# -# storage_client = storage.Client() -# bucket = storage_client.get_bucket(bucket_name) -# blob = bucket.blob(destination_blob_name) -# -# blob.upload_from_filename(source_file_name) -# -# print('File {} uploaded to {}.'.format( -# source_file_name, -# destination_blob_name)) -# -# -# def download_blob(bucket_name, source_blob_name, destination_file_name): -# # Uploads a blob from a bucket -# storage_client = storage.Client() -# bucket = storage_client.get_bucket(bucket_name) -# blob = bucket.blob(source_blob_name) -# -# blob.download_to_filename(destination_file_name) -# -# print('Blob {} downloaded to {}.'.format( -# source_blob_name, -# destination_file_name)) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/README.md b/cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/README.md deleted file mode 100755 index a726acbd9..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Flask REST API - -[REST](https://en.wikipedia.org/wiki/Representational_state_transfer) [API](https://en.wikipedia.org/wiki/API)s are -commonly used to expose Machine Learning (ML) models to other services. This folder contains an example REST API -created using Flask to expose the YOLOv5s model from [PyTorch Hub](https://pytorch.org/hub/ultralytics_yolov5/). - -## Requirements - -[Flask](https://palletsprojects.com/p/flask/) is required. Install with: - -```shell -$ pip install Flask -``` - -## Run - -After Flask installation run: - -```shell -$ python3 restapi.py --port 5000 -``` - -Then use [curl](https://curl.se/) to perform a request: - -```shell -$ curl -X POST -F image=@zidane.jpg 'http://localhost:5000/v1/object-detection/yolov5s' -``` - -The model inference results are returned as a JSON response: - -```json -[ - { - "class": 0, - "confidence": 0.8900438547, - "height": 0.9318675399, - "name": "person", - "width": 0.3264600933, - "xcenter": 0.7438579798, - "ycenter": 0.5207948685 - }, - { - "class": 0, - "confidence": 0.8440024257, - "height": 0.7155083418, - "name": "person", - "width": 0.6546785235, - "xcenter": 0.427829951, - "ycenter": 0.6334488392 - }, - { - "class": 27, - "confidence": 0.3771208823, - "height": 0.3902671337, - "name": "tie", - "width": 0.0696444362, - "xcenter": 0.3675483763, - "ycenter": 0.7991207838 - }, - { - "class": 27, - "confidence": 0.3527112305, - "height": 0.1540903747, - "name": "tie", - "width": 0.0336618312, - "xcenter": 0.7814827561, - "ycenter": 0.5065554976 - } -] -``` - -An example python script to perform inference using [requests](https://docs.python-requests.org/en/master/) is given -in `example_request.py` diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/example_request.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/example_request.py deleted file mode 100755 index ff21f30f9..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/example_request.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Perform test request""" -import pprint - -import requests - -DETECTION_URL = "http://localhost:5000/v1/object-detection/yolov5s" -TEST_IMAGE = "zidane.jpg" - -image_data = open(TEST_IMAGE, "rb").read() - -response = requests.post(DETECTION_URL, files={"image": image_data}).json() - -pprint.pprint(response) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/restapi.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/restapi.py deleted file mode 100755 index b93ad16a0..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/flask_rest_api/restapi.py +++ /dev/null @@ -1,37 +0,0 @@ -""" -Run a rest API exposing the yolov5s object detection model -""" -import argparse -import io - -import torch -from flask import Flask, request -from PIL import Image - -app = Flask(__name__) - -DETECTION_URL = "/v1/object-detection/yolov5s" - - -@app.route(DETECTION_URL, methods=["POST"]) -def predict(): - if not request.method == "POST": - return - - if request.files.get("image"): - image_file = request.files["image"] - image_bytes = image_file.read() - - img = Image.open(io.BytesIO(image_bytes)) - - results = model(img, size=640) # reduce size=320 for faster inference - return results.pandas().xyxy[0].to_json(orient="records") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Flask API exposing YOLOv5 model") - parser.add_argument("--port", default=5000, type=int, help="port number") - args = parser.parse_args() - - model = torch.hub.load("ultralytics/yolov5", "yolov5s", force_reload=True) # force_reload to recache - app.run(host="0.0.0.0", port=args.port) # debug=True causes Restarting with stat diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/general.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/general.py deleted file mode 100755 index 5c99dcc2d..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/general.py +++ /dev/null @@ -1,844 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -General utils -""" - -import contextlib -import glob -import logging -import math -import os -import platform -import random -import re -import shutil -import signal -import time -import urllib -from itertools import repeat -from multiprocessing.pool import ThreadPool -from pathlib import Path -from subprocess import check_output -from zipfile import ZipFile - -import cv2 -import numpy as np -import pandas as pd -import pkg_resources as pkg -import torch -import torchvision -import yaml - -from .downloads import gsutil_getsize -from .metrics import box_iou, fitness - -# Settings -FILE = Path(__file__).resolve() -ROOT = FILE.parents[1] # YOLOv5 root directory -NUM_THREADS = min(8, max(1, os.cpu_count() - 1)) # number of YOLOv5 multiprocessing threads - -torch.set_printoptions(linewidth=320, precision=5, profile='long') -np.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format}) # format short g, %precision=5 -pd.options.display.max_columns = 10 -cv2.setNumThreads(0) # prevent OpenCV from multithreading (incompatible with PyTorch DataLoader) -os.environ['NUMEXPR_MAX_THREADS'] = str(NUM_THREADS) # NumExpr max threads - - -def set_logging(name=None, verbose=True): - # Sets level and returns logger - rank = int(os.getenv('RANK', -1)) # rank in world for Multi-GPU trainings - logging.basicConfig(format="%(message)s", level=logging.INFO if (verbose and rank in (-1, 0)) else logging.WARNING) - return logging.getLogger(name) - - -LOGGER = set_logging(__name__) # define globally (used in train.py, val.py, detect.py, etc.) - - -class Profile(contextlib.ContextDecorator): - # Usage: @Profile() decorator or 'with Profile():' context manager - def __enter__(self): - self.start = time.time() - - def __exit__(self, type, value, traceback): - print(f'Profile results: {time.time() - self.start:.5f}s') - - -class Timeout(contextlib.ContextDecorator): - # Usage: @Timeout(seconds) decorator or 'with Timeout(seconds):' context manager - def __init__(self, seconds, *, timeout_msg='', suppress_timeout_errors=True): - self.seconds = int(seconds) - self.timeout_message = timeout_msg - self.suppress = bool(suppress_timeout_errors) - - def _timeout_handler(self, signum, frame): - raise TimeoutError(self.timeout_message) - - def __enter__(self): - signal.signal(signal.SIGALRM, self._timeout_handler) # Set handler for SIGALRM - signal.alarm(self.seconds) # start countdown for SIGALRM to be raised - - def __exit__(self, exc_type, exc_val, exc_tb): - signal.alarm(0) # Cancel SIGALRM if it's scheduled - if self.suppress and exc_type is TimeoutError: # Suppress TimeoutError - return True - - -class WorkingDirectory(contextlib.ContextDecorator): - # Usage: @WorkingDirectory(dir) decorator or 'with WorkingDirectory(dir):' context manager - def __init__(self, new_dir): - self.dir = new_dir # new dir - self.cwd = Path.cwd().resolve() # current dir - - def __enter__(self): - os.chdir(self.dir) - - def __exit__(self, exc_type, exc_val, exc_tb): - os.chdir(self.cwd) - - -def try_except(func): - # try-except function. Usage: @try_except decorator - def handler(*args, **kwargs): - try: - func(*args, **kwargs) - except Exception as e: - print(e) - - return handler - - -def methods(instance): - # Get class/instance methods - return [f for f in dir(instance) if callable(getattr(instance, f)) and not f.startswith("__")] - - -def print_args(name, opt): - # Print argparser arguments - LOGGER.info(colorstr(f'{name}: ') + ', '.join(f'{k}={v}' for k, v in vars(opt).items())) - - -def init_seeds(seed=0): - # Initialize random number generator (RNG) seeds https://pytorch.org/docs/stable/notes/randomness.html - # cudnn seed 0 settings are slower and more reproducible, else faster and less reproducible - import torch.backends.cudnn as cudnn - random.seed(seed) - np.random.seed(seed) - torch.manual_seed(seed) - cudnn.benchmark, cudnn.deterministic = (False, True) if seed == 0 else (True, False) - - -def intersect_dicts(da, db, exclude=()): - # Dictionary intersection of matching keys and shapes, omitting 'exclude' keys, using da values - return {k: v for k, v in da.items() if k in db and not any(x in k for x in exclude) and v.shape == db[k].shape} - - -def get_latest_run(search_dir='.'): - # Return path to most recent 'last.pt' in /runs (i.e. to --resume from) - last_list = glob.glob(f'{search_dir}/**/last*.pt', recursive=True) - return max(last_list, key=os.path.getctime) if last_list else '' - - -def user_config_dir(dir='Ultralytics', env_var='YOLOV5_CONFIG_DIR'): - # Return path of user configuration directory. Prefer environment variable if exists. Make dir if required. - env = os.getenv(env_var) - if env: - path = Path(env) # use environment variable - else: - cfg = {'Windows': 'AppData/Roaming', 'Linux': '.config', 'Darwin': 'Library/Application Support'} # 3 OS dirs - path = Path.home() / cfg.get(platform.system(), '') # OS-specific config dir - path = (path if is_writeable(path) else Path('/tmp')) / dir # GCP and AWS lambda fix, only /tmp is writeable - path.mkdir(exist_ok=True) # make if required - return path - - -def is_writeable(dir, test=False): - # Return True if directory has write permissions, test opening a file with write permissions if test=True - if test: # method 1 - file = Path(dir) / 'tmp.txt' - try: - with open(file, 'w'): # open file with write permissions - pass - file.unlink() # remove file - return True - except OSError: - return False - else: # method 2 - return os.access(dir, os.R_OK) # possible issues on Windows - - -def is_docker(): - # Is environment a Docker container? - return Path('/workspace').exists() # or Path('/.dockerenv').exists() - - -def is_colab(): - # Is environment a Google Colab instance? - try: - import google.colab - return True - except ImportError: - return False - - -def is_pip(): - # Is file in a pip package? - return 'site-packages' in Path(__file__).resolve().parts - - -def is_ascii(s=''): - # Is string composed of all ASCII (no UTF) characters? (note str().isascii() introduced in python 3.7) - s = str(s) # convert list, tuple, None, etc. to str - return len(s.encode().decode('ascii', 'ignore')) == len(s) - - -def is_chinese(s='人工智能'): - # Is string composed of any Chinese characters? - return re.search('[\u4e00-\u9fff]', s) - - -def emojis(str=''): - # Return platform-dependent emoji-safe version of string - return str.encode().decode('ascii', 'ignore') if platform.system() == 'Windows' else str - - -def file_size(path): - # Return file/dir size (MB) - path = Path(path) - if path.is_file(): - return path.stat().st_size / 1E6 - elif path.is_dir(): - return sum(f.stat().st_size for f in path.glob('**/*') if f.is_file()) / 1E6 - else: - return 0.0 - - -def check_online(): - # Check internet connectivity - import socket - try: - socket.create_connection(("1.1.1.1", 443), 5) # check host accessibility - return True - except OSError: - return False - - -@try_except -@WorkingDirectory(ROOT) -def check_git_status(): - # Recommend 'git pull' if code is out of date - msg = ', for updates see https://github.com/ultralytics/yolov5' - print(colorstr('github: '), end='') - assert Path('.git').exists(), 'skipping check (not a git repository)' + msg - assert not is_docker(), 'skipping check (Docker image)' + msg - assert check_online(), 'skipping check (offline)' + msg - - cmd = 'git fetch && git config --get remote.origin.url' - url = check_output(cmd, shell=True, timeout=5).decode().strip().rstrip('.git') # git fetch - branch = check_output('git rev-parse --abbrev-ref HEAD', shell=True).decode().strip() # checked out - n = int(check_output(f'git rev-list {branch}..origin/master --count', shell=True)) # commits behind - if n > 0: - s = f"⚠️ YOLOv5 is out of date by {n} commit{'s' * (n > 1)}. Use `git pull` or `git clone {url}` to update." - else: - s = f'up to date with {url} ✅' - print(emojis(s)) # emoji-safe - - -def check_python(minimum='3.6.2'): - # Check current python version vs. required python version - check_version(platform.python_version(), minimum, name='Python ', hard=True) - - -def check_version(current='0.0.0', minimum='0.0.0', name='version ', pinned=False, hard=False): - # Check version vs. required version - current, minimum = (pkg.parse_version(x) for x in (current, minimum)) - result = (current == minimum) if pinned else (current >= minimum) # bool - if hard: # assert min requirements met - assert result, f'{name}{minimum} required by YOLOv5, but {name}{current} is currently installed' - else: - return result - - -@try_except -def check_requirements(requirements=ROOT / 'requirements.txt', exclude=(), install=True): - # Check installed dependencies meet requirements (pass *.txt file or list of packages) - prefix = colorstr('red', 'bold', 'requirements:') - check_python() # check python version - if isinstance(requirements, (str, Path)): # requirements.txt file - file = Path(requirements) - assert file.exists(), f"{prefix} {file.resolve()} not found, check failed." - with file.open() as f: - requirements = [f'{x.name}{x.specifier}' for x in pkg.parse_requirements(f) if x.name not in exclude] - else: # list or tuple of packages - requirements = [x for x in requirements if x not in exclude] - - n = 0 # number of packages updates - for r in requirements: - try: - pkg.require(r) - except Exception as e: # DistributionNotFound or VersionConflict if requirements not met - s = f"{prefix} {r} not found and is required by YOLOv5" - if install: - print(f"{s}, attempting auto-update...") - try: - assert check_online(), f"'pip install {r}' skipped (offline)" - print(check_output(f"pip install '{r}'", shell=True).decode()) - n += 1 - except Exception as e: - print(f'{prefix} {e}') - else: - print(f'{s}. Please install and rerun your command.') - - if n: # if packages updated - source = file.resolve() if 'file' in locals() else requirements - s = f"{prefix} {n} package{'s' * (n > 1)} updated per {source}\n" \ - f"{prefix} ⚠️ {colorstr('bold', 'Restart runtime or rerun command for updates to take effect')}\n" - print(emojis(s)) - - -def check_img_size(imgsz, s=32, floor=0): - # Verify image size is a multiple of stride s in each dimension - if isinstance(imgsz, int): # integer i.e. img_size=640 - new_size = max(make_divisible(imgsz, int(s)), floor) - else: # list i.e. img_size=[640, 480] - new_size = [max(make_divisible(x, int(s)), floor) for x in imgsz] - if new_size != imgsz: - print(f'WARNING: --img-size {imgsz} must be multiple of max stride {s}, updating to {new_size}') - return new_size - - -def check_imshow(): - # Check if environment supports image displays - try: - assert not is_docker(), 'cv2.imshow() is disabled in Docker environments' - assert not is_colab(), 'cv2.imshow() is disabled in Google Colab environments' - cv2.imshow('test', np.zeros((1, 1, 3))) - cv2.waitKey(1) - cv2.destroyAllWindows() - cv2.waitKey(1) - return True - except Exception as e: - print(f'WARNING: Environment does not support cv2.imshow() or PIL Image.show() image displays\n{e}') - return False - - -def check_suffix(file='yolov5s.pt', suffix=('.pt',), msg=''): - # Check file(s) for acceptable suffix - if file and suffix: - if isinstance(suffix, str): - suffix = [suffix] - for f in file if isinstance(file, (list, tuple)) else [file]: - s = Path(f).suffix.lower() # file suffix - if len(s): - assert s in suffix, f"{msg}{f} acceptable suffix is {suffix}" - - -def check_yaml(file, suffix=('.yaml', '.yml')): - # Search/download YAML file (if necessary) and return path, checking suffix - return check_file(file, suffix) - - -def check_file(file, suffix=''): - # Search/download file (if necessary) and return path - check_suffix(file, suffix) # optional - file = str(file) # convert to str() - if Path(file).is_file() or file == '': # exists - return file - elif file.startswith(('http:/', 'https:/')): # download - url = str(Path(file)).replace(':/', '://') # Pathlib turns :// -> :/ - file = Path(urllib.parse.unquote(file).split('?')[0]).name # '%2F' to '/', split https://url.com/file.txt?auth - if Path(file).is_file(): - print(f'Found {url} locally at {file}') # file already exists - else: - print(f'Downloading {url} to {file}...') - torch.hub.download_url_to_file(url, file) - assert Path(file).exists() and Path(file).stat().st_size > 0, f'File download failed: {url}' # check - return file - else: # search - files = [] - for d in 'data', 'models', 'utils': # search directories - files.extend(glob.glob(str(ROOT / d / '**' / file), recursive=True)) # find file - assert len(files), f'File not found: {file}' # assert file was found - assert len(files) == 1, f"Multiple files match '{file}', specify exact path: {files}" # assert unique - return files[0] # return file - - -def check_dataset(data, autodownload=True): - # Download and/or unzip dataset if not found locally - # Usage: https://github.com/ultralytics/yolov5/releases/download/v1.0/coco128_with_yaml.zip - - # Download (optional) - extract_dir = '' - if isinstance(data, (str, Path)) and str(data).endswith('.zip'): # i.e. gs://bucket/dir/coco128.zip - download(data, dir='../datasets', unzip=True, delete=False, curl=False, threads=1) - data = next((Path('../datasets') / Path(data).stem).rglob('*.yaml')) - extract_dir, autodownload = data.parent, False - - # Read yaml (optional) - if isinstance(data, (str, Path)): - with open(data, errors='ignore') as f: - data = yaml.safe_load(f) # dictionary - - # Parse yaml - path = extract_dir or Path(data.get('path') or '') # optional 'path' default to '.' - for k in 'train', 'val', 'test': - if data.get(k): # prepend path - data[k] = str(path / data[k]) if isinstance(data[k], str) else [str(path / x) for x in data[k]] - - assert 'nc' in data, "Dataset 'nc' key missing." - if 'names' not in data: - data['names'] = [f'class{i}' for i in range(data['nc'])] # assign class names if missing - train, val, test, s = (data.get(x) for x in ('train', 'val', 'test', 'download')) - if val: - val = [Path(x).resolve() for x in (val if isinstance(val, list) else [val])] # val path - if not all(x.exists() for x in val): - print('\nWARNING: Dataset not found, nonexistent paths: %s' % [str(x) for x in val if not x.exists()]) - if s and autodownload: # download script - root = path.parent if 'path' in data else '..' # unzip directory i.e. '../' - if s.startswith('http') and s.endswith('.zip'): # URL - f = Path(s).name # filename - print(f'Downloading {s} to {f}...') - torch.hub.download_url_to_file(s, f) - Path(root).mkdir(parents=True, exist_ok=True) # create root - ZipFile(f).extractall(path=root) # unzip - Path(f).unlink() # remove zip - r = None # success - elif s.startswith('bash '): # bash script - print(f'Running {s} ...') - r = os.system(s) - else: # python script - r = exec(s, {'yaml': data}) # return None - print(f"Dataset autodownload {f'success, saved to {root}' if r in (0, None) else 'failure'}\n") - else: - raise Exception('Dataset not found.') - - return data # dictionary - - -def url2file(url): - # Convert URL to filename, i.e. https://url.com/file.txt?auth -> file.txt - url = str(Path(url)).replace(':/', '://') # Pathlib turns :// -> :/ - file = Path(urllib.parse.unquote(url)).name.split('?')[0] # '%2F' to '/', split https://url.com/file.txt?auth - return file - - -def download(url, dir='.', unzip=True, delete=True, curl=False, threads=1): - # Multi-threaded file download and unzip function, used in data.yaml for autodownload - def download_one(url, dir): - # Download 1 file - f = dir / Path(url).name # filename - if Path(url).is_file(): # exists in current path - Path(url).rename(f) # move to dir - elif not f.exists(): - print(f'Downloading {url} to {f}...') - if curl: - os.system(f"curl -L '{url}' -o '{f}' --retry 9 -C -") # curl download, retry and resume on fail - else: - torch.hub.download_url_to_file(url, f, progress=True) # torch download - if unzip and f.suffix in ('.zip', '.gz'): - print(f'Unzipping {f}...') - if f.suffix == '.zip': - ZipFile(f).extractall(path=dir) # unzip - elif f.suffix == '.gz': - os.system(f'tar xfz {f} --directory {f.parent}') # unzip - if delete: - f.unlink() # remove zip - - dir = Path(dir) - dir.mkdir(parents=True, exist_ok=True) # make directory - if threads > 1: - pool = ThreadPool(threads) - pool.imap(lambda x: download_one(*x), zip(url, repeat(dir))) # multi-threaded - pool.close() - pool.join() - else: - for u in [url] if isinstance(url, (str, Path)) else url: - download_one(u, dir) - - -def make_divisible(x, divisor): - # Returns nearest x divisible by divisor - if isinstance(divisor, torch.Tensor): - divisor = int(divisor.max()) # to int - return math.ceil(x / divisor) * divisor - - -def clean_str(s): - # Cleans a string by replacing special characters with underscore _ - return re.sub(pattern="[|@#!¡·$€%&()=?¿^*;:,¨´><+]", repl="_", string=s) - - -def one_cycle(y1=0.0, y2=1.0, steps=100): - # lambda function for sinusoidal ramp from y1 to y2 https://arxiv.org/pdf/1812.01187.pdf - return lambda x: ((1 - math.cos(x * math.pi / steps)) / 2) * (y2 - y1) + y1 - - -def colorstr(*input): - # Colors a string https://en.wikipedia.org/wiki/ANSI_escape_code, i.e. colorstr('blue', 'hello world') - *args, string = input if len(input) > 1 else ('blue', 'bold', input[0]) # color arguments, string - colors = {'black': '\033[30m', # basic colors - 'red': '\033[31m', - 'green': '\033[32m', - 'yellow': '\033[33m', - 'blue': '\033[34m', - 'magenta': '\033[35m', - 'cyan': '\033[36m', - 'white': '\033[37m', - 'bright_black': '\033[90m', # bright colors - 'bright_red': '\033[91m', - 'bright_green': '\033[92m', - 'bright_yellow': '\033[93m', - 'bright_blue': '\033[94m', - 'bright_magenta': '\033[95m', - 'bright_cyan': '\033[96m', - 'bright_white': '\033[97m', - 'end': '\033[0m', # misc - 'bold': '\033[1m', - 'underline': '\033[4m'} - return ''.join(colors[x] for x in args) + f'{string}' + colors['end'] - - -def labels_to_class_weights(labels, nc=80): - # Get class weights (inverse frequency) from training labels - if labels[0] is None: # no labels loaded - return torch.Tensor() - - labels = np.concatenate(labels, 0) # labels.shape = (866643, 5) for COCO - classes = labels[:, 0].astype(np.int) # labels = [class xywh] - weights = np.bincount(classes, minlength=nc) # occurrences per class - - # Prepend gridpoint count (for uCE training) - # gpi = ((320 / 32 * np.array([1, 2, 4])) ** 2 * 3).sum() # gridpoints per image - # weights = np.hstack([gpi * len(labels) - weights.sum() * 9, weights * 9]) ** 0.5 # prepend gridpoints to start - - weights[weights == 0] = 1 # replace empty bins with 1 - weights = 1 / weights # number of targets per class - weights /= weights.sum() # normalize - return torch.from_numpy(weights) - - -def labels_to_image_weights(labels, nc=80, class_weights=np.ones(80)): - # Produces image weights based on class_weights and image contents - class_counts = np.array([np.bincount(x[:, 0].astype(np.int), minlength=nc) for x in labels]) - image_weights = (class_weights.reshape(1, nc) * class_counts).sum(1) - # index = random.choices(range(n), weights=image_weights, k=1) # weight image sample - return image_weights - - -def coco80_to_coco91_class(): # converts 80-index (val2014) to 91-index (paper) - # https://tech.amikelive.com/node-718/what-object-categories-labels-are-in-coco-dataset/ - # a = np.loadtxt('data/coco.names', dtype='str', delimiter='\n') - # b = np.loadtxt('data/coco_paper.names', dtype='str', delimiter='\n') - # x1 = [list(a[i] == b).index(True) + 1 for i in range(80)] # darknet to coco - # x2 = [list(b[i] == a).index(True) if any(b[i] == a) else None for i in range(91)] # coco to darknet - x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90] - return x - - -def xyxy2xywh(x): - # Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] where xy1=top-left, xy2=bottom-right - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = (x[:, 0] + x[:, 2]) / 2 # x center - y[:, 1] = (x[:, 1] + x[:, 3]) / 2 # y center - y[:, 2] = x[:, 2] - x[:, 0] # width - y[:, 3] = x[:, 3] - x[:, 1] # height - return y - - -def xywh2xyxy(x): - # Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = x[:, 0] - x[:, 2] / 2 # top left x - y[:, 1] = x[:, 1] - x[:, 3] / 2 # top left y - y[:, 2] = x[:, 0] + x[:, 2] / 2 # bottom right x - y[:, 3] = x[:, 1] + x[:, 3] / 2 # bottom right y - return y - - -def xywhn2xyxy(x, w=640, h=640, padw=0, padh=0): - # Convert nx4 boxes from [x, y, w, h] normalized to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = w * (x[:, 0] - x[:, 2] / 2) + padw # top left x - y[:, 1] = h * (x[:, 1] - x[:, 3] / 2) + padh # top left y - y[:, 2] = w * (x[:, 0] + x[:, 2] / 2) + padw # bottom right x - y[:, 3] = h * (x[:, 1] + x[:, 3] / 2) + padh # bottom right y - return y - - -def xyxy2xywhn(x, w=640, h=640, clip=False, eps=0.0): - # Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] normalized where xy1=top-left, xy2=bottom-right - if clip: - clip_coords(x, (h - eps, w - eps)) # warning: inplace clip - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = ((x[:, 0] + x[:, 2]) / 2) / w # x center - y[:, 1] = ((x[:, 1] + x[:, 3]) / 2) / h # y center - y[:, 2] = (x[:, 2] - x[:, 0]) / w # width - y[:, 3] = (x[:, 3] - x[:, 1]) / h # height - return y - - -def xyn2xy(x, w=640, h=640, padw=0, padh=0): - # Convert normalized segments into pixel segments, shape (n,2) - y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) - y[:, 0] = w * x[:, 0] + padw # top left x - y[:, 1] = h * x[:, 1] + padh # top left y - return y - - -def segment2box(segment, width=640, height=640): - # Convert 1 segment label to 1 box label, applying inside-image constraint, i.e. (xy1, xy2, ...) to (xyxy) - x, y = segment.T # segment xy - inside = (x >= 0) & (y >= 0) & (x <= width) & (y <= height) - x, y, = x[inside], y[inside] - return np.array([x.min(), y.min(), x.max(), y.max()]) if any(x) else np.zeros((1, 4)) # xyxy - - -def segments2boxes(segments): - # Convert segment labels to box labels, i.e. (cls, xy1, xy2, ...) to (cls, xywh) - boxes = [] - for s in segments: - x, y = s.T # segment xy - boxes.append([x.min(), y.min(), x.max(), y.max()]) # cls, xyxy - return xyxy2xywh(np.array(boxes)) # cls, xywh - - -def resample_segments(segments, n=1000): - # Up-sample an (n,2) segment - for i, s in enumerate(segments): - x = np.linspace(0, len(s) - 1, n) - xp = np.arange(len(s)) - segments[i] = np.concatenate([np.interp(x, xp, s[:, i]) for i in range(2)]).reshape(2, -1).T # segment xy - return segments - - -def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None): - # Rescale coords (xyxy) from img1_shape to img0_shape - if ratio_pad is None: # calculate from img0_shape - gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1]) # gain = old / new - pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2 # wh padding - else: - gain = ratio_pad[0][0] - pad = ratio_pad[1] - - coords[:, [0, 2]] -= pad[0] # x padding - coords[:, [1, 3]] -= pad[1] # y padding - coords[:, :4] /= gain - clip_coords(coords, img0_shape) - return coords - - -def clip_coords(boxes, shape): - # Clip bounding xyxy bounding boxes to image shape (height, width) - if isinstance(boxes, torch.Tensor): # faster individually - boxes[:, 0].clamp_(0, shape[1]) # x1 - boxes[:, 1].clamp_(0, shape[0]) # y1 - boxes[:, 2].clamp_(0, shape[1]) # x2 - boxes[:, 3].clamp_(0, shape[0]) # y2 - else: # np.array (faster grouped) - boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1]) # x1, x2 - boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2 - - -def non_max_suppression(prediction, conf_thres=0.25, iou_thres=0.45, classes=None, agnostic=False, multi_label=False, - labels=(), max_det=300): - """Runs Non-Maximum Suppression (NMS) on inference results - - Returns: - list of detections, on (n,6) tensor per image [xyxy, conf, cls] - """ - nc = prediction.shape[2] - 5 # number of classes - xc = prediction[..., 4] > conf_thres # candidates - - # Checks - assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0' - assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0' - - # Settings - min_wh, max_wh = 2, 4096 # (pixels) minimum and maximum box width and height - max_nms = 30000 # maximum number of boxes into torchvision.ops.nms() - time_limit = 10.0 # seconds to quit after - redundant = True # require redundant detections - multi_label &= nc > 1 # multiple labels per box (adds 0.5ms/img) - merge = False # use merge-NMS - - t = time.time() - output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0] - for xi, x in enumerate(prediction): # image index, image inference - # Apply constraints - # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0 # width-height - x = x[xc[xi]] # confidence - - # Cat apriori labels if autolabelling - if labels and len(labels[xi]): - l = labels[xi] - v = torch.zeros((len(l), nc + 5), device=x.device) - v[:, :4] = l[:, 1:5] # box - v[:, 4] = 1.0 # conf - v[range(len(l)), l[:, 0].long() + 5] = 1.0 # cls - x = torch.cat((x, v), 0) - - # If none remain process next image - if not x.shape[0]: - continue - - # Compute conf - x[:, 5:] *= x[:, 4:5] # conf = obj_conf * cls_conf - - # Box (center x, center y, width, height) to (x1, y1, x2, y2) - box = xywh2xyxy(x[:, :4]) - - # Detections matrix nx6 (xyxy, conf, cls) - if multi_label: - i, j = (x[:, 5:] > conf_thres).nonzero(as_tuple=False).T - x = torch.cat((box[i], x[i, j + 5, None], j[:, None].float()), 1) - else: # best class only - conf, j = x[:, 5:].max(1, keepdim=True) - x = torch.cat((box, conf, j.float()), 1)[conf.view(-1) > conf_thres] - - # Filter by class - if classes is not None: - x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)] - - # Apply finite constraint - # if not torch.isfinite(x).all(): - # x = x[torch.isfinite(x).all(1)] - - # Check shape - n = x.shape[0] # number of boxes - if not n: # no boxes - continue - elif n > max_nms: # excess boxes - x = x[x[:, 4].argsort(descending=True)[:max_nms]] # sort by confidence - - # Batched NMS - c = x[:, 5:6] * (0 if agnostic else max_wh) # classes - boxes, scores = x[:, :4] + c, x[:, 4] # boxes (offset by class), scores - i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS - if i.shape[0] > max_det: # limit detections - i = i[:max_det] - - if merge and (1 < n < 3E3): # Merge NMS (boxes merged using weighted mean) - # update boxes as boxes(i,4) = weights(i,n) * boxes(n,4) - iou = box_iou(boxes[i], boxes) > iou_thres # iou matrix - weights = iou * scores[None] # box weights - x[i, :4] = torch.mm(weights, x[:, :4]).float() / weights.sum(1, keepdim=True) # merged boxes - if redundant: - i = i[iou.sum(1) > 1] # require redundancy - - output[xi] = x[i] - if (time.time() - t) > time_limit: - print(f'WARNING: NMS time limit {time_limit}s exceeded') - break # time limit exceeded - - return output - - -def strip_optimizer(f='best.pt', s=''): # from utils.general import *; strip_optimizer() - # Strip optimizer from 'f' to finalize training, optionally save as 's' - x = torch.load(f, map_location=torch.device('cpu')) - if x.get('ema'): - x['model'] = x['ema'] # replace model with ema - for k in 'optimizer', 'best_fitness', 'wandb_id', 'ema', 'updates': # keys - x[k] = None - x['epoch'] = -1 - x['model'].half() # to FP16 - for p in x['model'].parameters(): - p.requires_grad = False - torch.save(x, s or f) - mb = os.path.getsize(s or f) / 1E6 # filesize - print(f"Optimizer stripped from {f},{(' saved as %s,' % s) if s else ''} {mb:.1f}MB") - - -def print_mutation(results, hyp, save_dir, bucket): - evolve_csv, results_csv, evolve_yaml = save_dir / 'evolve.csv', save_dir / 'results.csv', save_dir / 'hyp_evolve.yaml' - keys = ('metrics/precision', 'metrics/recall', 'metrics/mAP_0.5', 'metrics/mAP_0.5:0.95', - 'val/box_loss', 'val/obj_loss', 'val/cls_loss') + tuple(hyp.keys()) # [results + hyps] - keys = tuple(x.strip() for x in keys) - vals = results + tuple(hyp.values()) - n = len(keys) - - # Download (optional) - if bucket: - url = f'gs://{bucket}/evolve.csv' - if gsutil_getsize(url) > (os.path.getsize(evolve_csv) if os.path.exists(evolve_csv) else 0): - os.system(f'gsutil cp {url} {save_dir}') # download evolve.csv if larger than local - - # Log to evolve.csv - s = '' if evolve_csv.exists() else (('%20s,' * n % keys).rstrip(',') + '\n') # add header - with open(evolve_csv, 'a') as f: - f.write(s + ('%20.5g,' * n % vals).rstrip(',') + '\n') - - # Print to screen - print(colorstr('evolve: ') + ', '.join(f'{x.strip():>20s}' for x in keys)) - print(colorstr('evolve: ') + ', '.join(f'{x:20.5g}' for x in vals), end='\n\n\n') - - # Save yaml - with open(evolve_yaml, 'w') as f: - data = pd.read_csv(evolve_csv) - data = data.rename(columns=lambda x: x.strip()) # strip keys - i = np.argmax(fitness(data.values[:, :7])) # - f.write('# YOLOv5 Hyperparameter Evolution Results\n' + - f'# Best generation: {i}\n' + - f'# Last generation: {len(data) - 1}\n' + - '# ' + ', '.join(f'{x.strip():>20s}' for x in keys[:7]) + '\n' + - '# ' + ', '.join(f'{x:>20.5g}' for x in data.values[i, :7]) + '\n\n') - yaml.safe_dump(hyp, f, sort_keys=False) - - if bucket: - os.system(f'gsutil cp {evolve_csv} {evolve_yaml} gs://{bucket}') # upload - - -def apply_classifier(x, model, img, im0): - # Apply a second stage classifier to YOLO outputs - # Example model = torchvision.models.__dict__['efficientnet_b0'](pretrained=True).to(device).eval() - im0 = [im0] if isinstance(im0, np.ndarray) else im0 - for i, d in enumerate(x): # per image - if d is not None and len(d): - d = d.clone() - - # Reshape and pad cutouts - b = xyxy2xywh(d[:, :4]) # boxes - b[:, 2:] = b[:, 2:].max(1)[0].unsqueeze(1) # rectangle to square - b[:, 2:] = b[:, 2:] * 1.3 + 30 # pad - d[:, :4] = xywh2xyxy(b).long() - - # Rescale boxes from img_size to im0 size - scale_coords(img.shape[2:], d[:, :4], im0[i].shape) - - # Classes - pred_cls1 = d[:, 5].long() - ims = [] - for j, a in enumerate(d): # per item - cutout = im0[i][int(a[1]):int(a[3]), int(a[0]):int(a[2])] - im = cv2.resize(cutout, (224, 224)) # BGR - # cv2.imwrite('example%i.jpg' % j, cutout) - - im = im[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, to 3x416x416 - im = np.ascontiguousarray(im, dtype=np.float32) # uint8 to float32 - im /= 255 # 0 - 255 to 0.0 - 1.0 - ims.append(im) - - pred_cls2 = model(torch.Tensor(ims).to(d.device)).argmax(1) # classifier prediction - x[i] = x[i][pred_cls1 == pred_cls2] # retain matching class detections - - return x - - -def increment_path(path, exist_ok=False, sep='', mkdir=False): - # Increment file or directory path, i.e. runs/exp --> runs/exp{sep}2, runs/exp{sep}3, ... etc. - path = Path(path) # os-agnostic - if path.exists() and not exist_ok: - path, suffix = (path.with_suffix(''), path.suffix) if path.is_file() else (path, '') - dirs = glob.glob(f"{path}{sep}*") # similar paths - matches = [re.search(rf"%s{sep}(\d+)" % path.stem, d) for d in dirs] - i = [int(m.groups()[0]) for m in matches if m] # indices - n = max(i) + 1 if i else 2 # increment number - path = Path(f"{path}{sep}{n}{suffix}") # increment path - if mkdir: - path.mkdir(parents=True, exist_ok=True) # make directory - return path - - -# Variables -NCOLS = 0 if is_docker() else shutil.get_terminal_size().columns # terminal window size for tqdm diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/Dockerfile b/cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/Dockerfile deleted file mode 100755 index 0155618f4..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -FROM gcr.io/google-appengine/python - -# Create a virtualenv for dependencies. This isolates these packages from -# system-level packages. -# Use -p python3 or -p python3.7 to select python version. Default is version 2. -RUN virtualenv /env -p python3 - -# Setting these environment variables are the same as running -# source /env/bin/activate. -ENV VIRTUAL_ENV /env -ENV PATH /env/bin:$PATH - -RUN apt-get update && apt-get install -y python-opencv - -# Copy the application's requirements.txt and run pip to install all -# dependencies into the virtualenv. -ADD requirements.txt /app/requirements.txt -RUN pip install -r /app/requirements.txt - -# Add the application source code. -ADD . /app - -# Run a WSGI server to serve the application. gunicorn must be declared as -# a dependency in requirements.txt. -CMD gunicorn -b :$PORT main:app diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/additional_requirements.txt b/cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/additional_requirements.txt deleted file mode 100755 index 42d7ffc0e..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/additional_requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -# add these requirements in your app on top of the existing ones -pip==21.1 -Flask==1.0.2 -gunicorn==19.9.0 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/app.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/app.yaml deleted file mode 100755 index 5056b7c11..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/google_app_engine/app.yaml +++ /dev/null @@ -1,14 +0,0 @@ -runtime: custom -env: flex - -service: yolov5app - -liveness_check: - initial_delay_sec: 600 - -manual_scaling: - instances: 1 -resources: - cpu: 1 - memory_gb: 4 - disk_size_gb: 20 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/__init__.py deleted file mode 100755 index 2a68d9785..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/__init__.py +++ /dev/null @@ -1,159 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Logging utils -""" - -import os -import warnings -from threading import Thread - -import pkg_resources as pkg -import torch -from torch.utils.tensorboard import SummaryWriter - -from utils.general import colorstr, emojis -from utils.loggers.wandb.wandb_utils import WandbLogger -from utils.plots import plot_images, plot_results -from utils.torch_utils import de_parallel - -LOGGERS = ('csv', 'tb', 'wandb') # text-file, TensorBoard, Weights & Biases -RANK = int(os.getenv('RANK', -1)) - -try: - import wandb - - assert hasattr(wandb, '__version__') # verify package import not local dir - if pkg.parse_version(wandb.__version__) >= pkg.parse_version('0.12.2') and RANK in [0, -1]: - try: - wandb_login_success = wandb.login(timeout=30) - except wandb.errors.UsageError: # known non-TTY terminal issue - wandb_login_success = False - if not wandb_login_success: - wandb = None -except (ImportError, AssertionError): - wandb = None - - -class Loggers(): - # YOLOv5 Loggers class - def __init__(self, save_dir=None, weights=None, opt=None, hyp=None, logger=None, include=LOGGERS): - self.save_dir = save_dir - self.weights = weights - self.opt = opt - self.hyp = hyp - self.logger = logger # for printing results to console - self.include = include - self.keys = ['train/box_loss', 'train/obj_loss', 'train/cls_loss', # train loss - 'metrics/precision', 'metrics/recall', 'metrics/mAP_0.5', 'metrics/mAP_0.5:0.95', # metrics - 'val/box_loss', 'val/obj_loss', 'val/cls_loss', # val loss - 'x/lr0', 'x/lr1', 'x/lr2'] # params - for k in LOGGERS: - setattr(self, k, None) # init empty logger dictionary - self.csv = True # always log to csv - - # Message - if not wandb: - prefix = colorstr('Weights & Biases: ') - s = f"{prefix}run 'pip install wandb' to automatically track and visualize YOLOv5 🚀 runs (RECOMMENDED)" - print(emojis(s)) - - # TensorBoard - s = self.save_dir - if 'tb' in self.include and not self.opt.evolve: - prefix = colorstr('TensorBoard: ') - self.logger.info(f"{prefix}Start with 'tensorboard --logdir {s.parent}', view at http://localhost:6006/") - self.tb = SummaryWriter(str(s)) - - # W&B - if wandb and 'wandb' in self.include: - wandb_artifact_resume = isinstance(self.opt.resume, str) and self.opt.resume.startswith('wandb-artifact://') - run_id = torch.load(self.weights).get('wandb_id') if self.opt.resume and not wandb_artifact_resume else None - self.opt.hyp = self.hyp # add hyperparameters - self.wandb = WandbLogger(self.opt, run_id) - else: - self.wandb = None - - def on_pretrain_routine_end(self): - # Callback runs on pre-train routine end - paths = self.save_dir.glob('*labels*.jpg') # training labels - if self.wandb: - self.wandb.log({"Labels": [wandb.Image(str(x), caption=x.name) for x in paths]}) - - def on_train_batch_end(self, ni, model, imgs, targets, paths, plots, sync_bn): - # Callback runs on train batch end - if plots: - if ni == 0: - if not sync_bn: # tb.add_graph() --sync known issue https://github.com/ultralytics/yolov5/issues/3754 - with warnings.catch_warnings(): - warnings.simplefilter('ignore') # suppress jit trace warning - self.tb.add_graph(torch.jit.trace(de_parallel(model), imgs[0:1], strict=False), []) - if ni < 3: - f = self.save_dir / f'train_batch{ni}.jpg' # filename - Thread(target=plot_images, args=(imgs, targets, paths, f), daemon=True).start() - if self.wandb and ni == 10: - files = sorted(self.save_dir.glob('train*.jpg')) - self.wandb.log({'Mosaics': [wandb.Image(str(f), caption=f.name) for f in files if f.exists()]}) - - def on_train_epoch_end(self, epoch): - # Callback runs on train epoch end - if self.wandb: - self.wandb.current_epoch = epoch + 1 - - def on_val_image_end(self, pred, predn, path, names, im): - # Callback runs on val image end - if self.wandb: - self.wandb.val_one_image(pred, predn, path, names, im) - - def on_val_end(self): - # Callback runs on val end - if self.wandb: - files = sorted(self.save_dir.glob('val*.jpg')) - self.wandb.log({"Validation": [wandb.Image(str(f), caption=f.name) for f in files]}) - - def on_fit_epoch_end(self, vals, epoch, best_fitness, fi): - # Callback runs at the end of each fit (train+val) epoch - x = {k: v for k, v in zip(self.keys, vals)} # dict - if self.csv: - file = self.save_dir / 'results.csv' - n = len(x) + 1 # number of cols - s = '' if file.exists() else (('%20s,' * n % tuple(['epoch'] + self.keys)).rstrip(',') + '\n') # add header - with open(file, 'a') as f: - f.write(s + ('%20.5g,' * n % tuple([epoch] + vals)).rstrip(',') + '\n') - - if self.tb: - for k, v in x.items(): - self.tb.add_scalar(k, v, epoch) - - if self.wandb: - self.wandb.log(x) - self.wandb.end_epoch(best_result=best_fitness == fi) - - def on_model_save(self, last, epoch, final_epoch, best_fitness, fi): - # Callback runs on model save event - if self.wandb: - if ((epoch + 1) % self.opt.save_period == 0 and not final_epoch) and self.opt.save_period != -1: - self.wandb.log_model(last.parent, self.opt, epoch, fi, best_model=best_fitness == fi) - - def on_train_end(self, last, best, plots, epoch, results): - # Callback runs on training end - if plots: - plot_results(file=self.save_dir / 'results.csv') # save results.png - files = ['results.png', 'confusion_matrix.png', *(f'{x}_curve.png' for x in ('F1', 'PR', 'P', 'R'))] - files = [(self.save_dir / f) for f in files if (self.save_dir / f).exists()] # filter - - if self.tb: - import cv2 - for f in files: - self.tb.add_image(f.stem, cv2.imread(str(f))[..., ::-1], epoch, dataformats='HWC') - - if self.wandb: - self.wandb.log({"Results": [wandb.Image(str(f), caption=f.name) for f in files]}) - # Calling wandb.log. TODO: Refactor this into WandbLogger.log_model - if not self.opt.evolve: - wandb.log_artifact(str(best if best.exists() else last), type='model', - name='run_' + self.wandb.wandb_run.id + '_model', - aliases=['latest', 'best', 'stripped']) - self.wandb.finish_run() - else: - self.wandb.finish_run() - self.wandb = WandbLogger(self.opt) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/README.md b/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/README.md deleted file mode 100755 index 63d999859..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/README.md +++ /dev/null @@ -1,152 +0,0 @@ -📚 This guide explains how to use **Weights & Biases** (W&B) with YOLOv5 🚀. UPDATED 29 September 2021. -* [About Weights & Biases](#about-weights-&-biases) -* [First-Time Setup](#first-time-setup) -* [Viewing runs](#viewing-runs) -* [Disabling wandb](#disabling-wandb) -* [Advanced Usage: Dataset Versioning and Evaluation](#advanced-usage) -* [Reports: Share your work with the world!](#reports) - -## About Weights & Biases -Think of [W&B](https://wandb.ai/site?utm_campaign=repo_yolo_wandbtutorial) like GitHub for machine learning models. With a few lines of code, save everything you need to debug, compare and reproduce your models — architecture, hyperparameters, git commits, model weights, GPU usage, and even datasets and predictions. - -Used by top researchers including teams at OpenAI, Lyft, Github, and MILA, W&B is part of the new standard of best practices for machine learning. How W&B can help you optimize your machine learning workflows: - - * [Debug](https://wandb.ai/wandb/getting-started/reports/Visualize-Debug-Machine-Learning-Models--VmlldzoyNzY5MDk#Free-2) model performance in real time - * [GPU usage](https://wandb.ai/wandb/getting-started/reports/Visualize-Debug-Machine-Learning-Models--VmlldzoyNzY5MDk#System-4) visualized automatically - * [Custom charts](https://wandb.ai/wandb/customizable-charts/reports/Powerful-Custom-Charts-To-Debug-Model-Peformance--VmlldzoyNzY4ODI) for powerful, extensible visualization - * [Share insights](https://wandb.ai/wandb/getting-started/reports/Visualize-Debug-Machine-Learning-Models--VmlldzoyNzY5MDk#Share-8) interactively with collaborators - * [Optimize hyperparameters](https://docs.wandb.com/sweeps) efficiently - * [Track](https://docs.wandb.com/artifacts) datasets, pipelines, and production models - -## First-Time Setup -
- Toggle Details -When you first train, W&B will prompt you to create a new account and will generate an **API key** for you. If you are an existing user you can retrieve your key from https://wandb.ai/authorize. This key is used to tell W&B where to log your data. You only need to supply your key once, and then it is remembered on the same device. - -W&B will create a cloud **project** (default is 'YOLOv5') for your training runs, and each new training run will be provided a unique run **name** within that project as project/name. You can also manually set your project and run name as: - - ```shell - $ python train.py --project ... --name ... - ``` - -YOLOv5 notebook example: Open In Colab Open In Kaggle -Screen Shot 2021-09-29 at 10 23 13 PM - - -
- -## Viewing Runs -
- Toggle Details -Run information streams from your environment to the W&B cloud console as you train. This allows you to monitor and even cancel runs in realtime . All important information is logged: - - * Training & Validation losses - * Metrics: Precision, Recall, mAP@0.5, mAP@0.5:0.95 - * Learning Rate over time - * A bounding box debugging panel, showing the training progress over time - * GPU: Type, **GPU Utilization**, power, temperature, **CUDA memory usage** - * System: Disk I/0, CPU utilization, RAM memory usage - * Your trained model as W&B Artifact - * Environment: OS and Python types, Git repository and state, **training command** - -

Weights & Biases dashboard

-
- - ## Disabling wandb -* training after running `wandb disabled` inside that directory creates no wandb run -![Screenshot (84)](https://user-images.githubusercontent.com/15766192/143441777-c780bdd7-7cb4-4404-9559-b4316030a985.png) - -* To enable wandb again, run `wandb online` -![Screenshot (85)](https://user-images.githubusercontent.com/15766192/143441866-7191b2cb-22f0-4e0f-ae64-2dc47dc13078.png) - -## Advanced Usage -You can leverage W&B artifacts and Tables integration to easily visualize and manage your datasets, models and training evaluations. Here are some quick examples to get you started. -
-

1: Train and Log Evaluation simultaneousy

- This is an extension of the previous section, but it'll also training after uploading the dataset. This also evaluation Table - Evaluation table compares your predictions and ground truths across the validation set for each epoch. It uses the references to the already uploaded datasets, - so no images will be uploaded from your system more than once. -
- Usage - Code $ python train.py --upload_data val - -![Screenshot from 2021-11-21 17-40-06](https://user-images.githubusercontent.com/15766192/142761183-c1696d8c-3f38-45ab-991a-bb0dfd98ae7d.png) -
- -

2. Visualize and Version Datasets

- Log, visualize, dynamically query, and understand your data with W&B Tables. You can use the following command to log your dataset as a W&B Table. This will generate a {dataset}_wandb.yaml file which can be used to train from dataset artifact. -
- Usage - Code $ python utils/logger/wandb/log_dataset.py --project ... --name ... --data .. - - ![Screenshot (64)](https://user-images.githubusercontent.com/15766192/128486078-d8433890-98a3-4d12-8986-b6c0e3fc64b9.png) -
- -

3: Train using dataset artifact

- When you upload a dataset as described in the first section, you get a new config file with an added `_wandb` to its name. This file contains the information that - can be used to train a model directly from the dataset artifact. This also logs evaluation -
- Usage - Code $ python train.py --data {data}_wandb.yaml - -![Screenshot (72)](https://user-images.githubusercontent.com/15766192/128979739-4cf63aeb-a76f-483f-8861-1c0100b938a5.png) -
- -

4: Save model checkpoints as artifacts

- To enable saving and versioning checkpoints of your experiment, pass `--save_period n` with the base cammand, where `n` represents checkpoint interval. - You can also log both the dataset and model checkpoints simultaneously. If not passed, only the final model will be logged - -
- Usage - Code $ python train.py --save_period 1 - -![Screenshot (68)](https://user-images.githubusercontent.com/15766192/128726138-ec6c1f60-639d-437d-b4ee-3acd9de47ef3.png) -
- -
- -

5: Resume runs from checkpoint artifacts.

-Any run can be resumed using artifacts if the --resume argument starts with wandb-artifact:// prefix followed by the run path, i.e, wandb-artifact://username/project/runid . This doesn't require the model checkpoint to be present on the local system. - -
- Usage - Code $ python train.py --resume wandb-artifact://{run_path} - -![Screenshot (70)](https://user-images.githubusercontent.com/15766192/128728988-4e84b355-6c87-41ae-a591-14aecf45343e.png) -
- -

6: Resume runs from dataset artifact & checkpoint artifacts.

- Local dataset or model checkpoints are not required. This can be used to resume runs directly on a different device - The syntax is same as the previous section, but you'll need to lof both the dataset and model checkpoints as artifacts, i.e, set bot --upload_dataset or - train from _wandb.yaml file and set --save_period - -
- Usage - Code $ python train.py --resume wandb-artifact://{run_path} - -![Screenshot (70)](https://user-images.githubusercontent.com/15766192/128728988-4e84b355-6c87-41ae-a591-14aecf45343e.png) -
- - - -

Reports

-W&B Reports can be created from your saved runs for sharing online. Once a report is created you will receive a link you can use to publically share your results. Here is an example report created from the COCO128 tutorial trainings of all four YOLOv5 models ([link](https://wandb.ai/glenn-jocher/yolov5_tutorial/reports/YOLOv5-COCO128-Tutorial-Results--VmlldzozMDI5OTY)). - -Weights & Biases Reports - - -## Environments - -YOLOv5 may be run in any of the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): - -- **Google Colab and Kaggle** notebooks with free GPU: Open In Colab Open In Kaggle -- **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](https://github.com/ultralytics/yolov5/wiki/GCP-Quickstart) -- **Amazon** Deep Learning AMI. See [AWS Quickstart Guide](https://github.com/ultralytics/yolov5/wiki/AWS-Quickstart) -- **Docker Image**. See [Docker Quickstart Guide](https://github.com/ultralytics/yolov5/wiki/Docker-Quickstart) Docker Pulls - - -## Status - -![CI CPU testing](https://github.com/ultralytics/yolov5/workflows/CI%20CPU%20testing/badge.svg) - -If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 training ([train.py](https://github.com/ultralytics/yolov5/blob/master/train.py)), validation ([val.py](https://github.com/ultralytics/yolov5/blob/master/val.py)), inference ([detect.py](https://github.com/ultralytics/yolov5/blob/master/detect.py)) and export ([export.py](https://github.com/ultralytics/yolov5/blob/master/export.py)) on MacOS, Windows, and Ubuntu every 24 hours and on every commit. diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/__init__.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/log_dataset.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/log_dataset.py deleted file mode 100755 index 06e81fb69..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/log_dataset.py +++ /dev/null @@ -1,27 +0,0 @@ -import argparse - -from wandb_utils import WandbLogger - -from utils.general import LOGGER - -WANDB_ARTIFACT_PREFIX = 'wandb-artifact://' - - -def create_dataset_artifact(opt): - logger = WandbLogger(opt, None, job_type='Dataset Creation') # TODO: return value unused - if not logger.wandb: - LOGGER.info("install wandb using `pip install wandb` to log the dataset") - - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--data', type=str, default='data/coco128.yaml', help='data.yaml path') - parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset') - parser.add_argument('--project', type=str, default='YOLOv5', help='name of W&B Project') - parser.add_argument('--entity', default=None, help='W&B entity') - parser.add_argument('--name', type=str, default='log dataset', help='name of W&B run') - - opt = parser.parse_args() - opt.resume = False # Explicitly disallow resume check for dataset upload job - - create_dataset_artifact(opt) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/sweep.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/sweep.py deleted file mode 100755 index 206059bc3..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/sweep.py +++ /dev/null @@ -1,41 +0,0 @@ -import sys -from pathlib import Path - -import wandb - -FILE = Path(__file__).resolve() -ROOT = FILE.parents[3] # YOLOv5 root directory -if str(ROOT) not in sys.path: - sys.path.append(str(ROOT)) # add ROOT to PATH - -from train import parse_opt, train -from utils.callbacks import Callbacks -from utils.general import increment_path -from utils.torch_utils import select_device - - -def sweep(): - wandb.init() - # Get hyp dict from sweep agent - hyp_dict = vars(wandb.config).get("_items") - - # Workaround: get necessary opt args - opt = parse_opt(known=True) - opt.batch_size = hyp_dict.get("batch_size") - opt.save_dir = str(increment_path(Path(opt.project) / opt.name, exist_ok=opt.exist_ok or opt.evolve)) - opt.epochs = hyp_dict.get("epochs") - opt.nosave = True - opt.data = hyp_dict.get("data") - opt.weights = str(opt.weights) - opt.cfg = str(opt.cfg) - opt.data = str(opt.data) - opt.hyp = str(opt.hyp) - opt.project = str(opt.project) - device = select_device(opt.device, batch_size=opt.batch_size) - - # train - train(hyp_dict, opt, device, callbacks=Callbacks()) - - -if __name__ == "__main__": - sweep() diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/sweep.yaml b/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/sweep.yaml deleted file mode 100755 index c7790d75f..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/sweep.yaml +++ /dev/null @@ -1,143 +0,0 @@ -# Hyperparameters for training -# To set range- -# Provide min and max values as: -# parameter: -# -# min: scalar -# max: scalar -# OR -# -# Set a specific list of search space- -# parameter: -# values: [scalar1, scalar2, scalar3...] -# -# You can use grid, bayesian and hyperopt search strategy -# For more info on configuring sweeps visit - https://docs.wandb.ai/guides/sweeps/configuration - -program: utils/loggers/wandb/sweep.py -method: random -metric: - name: metrics/mAP_0.5 - goal: maximize - -parameters: - # hyperparameters: set either min, max range or values list - data: - value: "data/coco128.yaml" - batch_size: - values: [64] - epochs: - values: [10] - - lr0: - distribution: uniform - min: 1e-5 - max: 1e-1 - lrf: - distribution: uniform - min: 0.01 - max: 1.0 - momentum: - distribution: uniform - min: 0.6 - max: 0.98 - weight_decay: - distribution: uniform - min: 0.0 - max: 0.001 - warmup_epochs: - distribution: uniform - min: 0.0 - max: 5.0 - warmup_momentum: - distribution: uniform - min: 0.0 - max: 0.95 - warmup_bias_lr: - distribution: uniform - min: 0.0 - max: 0.2 - box: - distribution: uniform - min: 0.02 - max: 0.2 - cls: - distribution: uniform - min: 0.2 - max: 4.0 - cls_pw: - distribution: uniform - min: 0.5 - max: 2.0 - obj: - distribution: uniform - min: 0.2 - max: 4.0 - obj_pw: - distribution: uniform - min: 0.5 - max: 2.0 - iou_t: - distribution: uniform - min: 0.1 - max: 0.7 - anchor_t: - distribution: uniform - min: 2.0 - max: 8.0 - fl_gamma: - distribution: uniform - min: 0.0 - max: 0.1 - hsv_h: - distribution: uniform - min: 0.0 - max: 0.1 - hsv_s: - distribution: uniform - min: 0.0 - max: 0.9 - hsv_v: - distribution: uniform - min: 0.0 - max: 0.9 - degrees: - distribution: uniform - min: 0.0 - max: 45.0 - translate: - distribution: uniform - min: 0.0 - max: 0.9 - scale: - distribution: uniform - min: 0.0 - max: 0.9 - shear: - distribution: uniform - min: 0.0 - max: 10.0 - perspective: - distribution: uniform - min: 0.0 - max: 0.001 - flipud: - distribution: uniform - min: 0.0 - max: 1.0 - fliplr: - distribution: uniform - min: 0.0 - max: 1.0 - mosaic: - distribution: uniform - min: 0.0 - max: 1.0 - mixup: - distribution: uniform - min: 0.0 - max: 1.0 - copy_paste: - distribution: uniform - min: 0.0 - max: 1.0 diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/wandb_utils.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/wandb_utils.py deleted file mode 100755 index 221d3c88c..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loggers/wandb/wandb_utils.py +++ /dev/null @@ -1,560 +0,0 @@ -"""Utilities and tools for tracking runs with Weights & Biases.""" - -import logging -import os -import sys -from contextlib import contextmanager -from pathlib import Path -from typing import Dict - -import yaml -from tqdm import tqdm - -FILE = Path(__file__).resolve() -ROOT = FILE.parents[3] # YOLOv5 root directory -if str(ROOT) not in sys.path: - sys.path.append(str(ROOT)) # add ROOT to PATH - -from utils.datasets import LoadImagesAndLabels, img2label_paths -from utils.general import LOGGER, check_dataset, check_file - -try: - import wandb - - assert hasattr(wandb, '__version__') # verify package import not local dir -except (ImportError, AssertionError): - wandb = None - -RANK = int(os.getenv('RANK', -1)) -WANDB_ARTIFACT_PREFIX = 'wandb-artifact://' - - -def remove_prefix(from_string, prefix=WANDB_ARTIFACT_PREFIX): - return from_string[len(prefix):] - - -def check_wandb_config_file(data_config_file): - wandb_config = '_wandb.'.join(data_config_file.rsplit('.', 1)) # updated data.yaml path - if Path(wandb_config).is_file(): - return wandb_config - return data_config_file - - -def check_wandb_dataset(data_file): - is_trainset_wandb_artifact = False - is_valset_wandb_artifact = False - if check_file(data_file) and data_file.endswith('.yaml'): - with open(data_file, errors='ignore') as f: - data_dict = yaml.safe_load(f) - is_trainset_wandb_artifact = (isinstance(data_dict['train'], str) and - data_dict['train'].startswith(WANDB_ARTIFACT_PREFIX)) - is_valset_wandb_artifact = (isinstance(data_dict['val'], str) and - data_dict['val'].startswith(WANDB_ARTIFACT_PREFIX)) - if is_trainset_wandb_artifact or is_valset_wandb_artifact: - return data_dict - else: - return check_dataset(data_file) - - -def get_run_info(run_path): - run_path = Path(remove_prefix(run_path, WANDB_ARTIFACT_PREFIX)) - run_id = run_path.stem - project = run_path.parent.stem - entity = run_path.parent.parent.stem - model_artifact_name = 'run_' + run_id + '_model' - return entity, project, run_id, model_artifact_name - - -def check_wandb_resume(opt): - process_wandb_config_ddp_mode(opt) if RANK not in [-1, 0] else None - if isinstance(opt.resume, str): - if opt.resume.startswith(WANDB_ARTIFACT_PREFIX): - if RANK not in [-1, 0]: # For resuming DDP runs - entity, project, run_id, model_artifact_name = get_run_info(opt.resume) - api = wandb.Api() - artifact = api.artifact(entity + '/' + project + '/' + model_artifact_name + ':latest') - modeldir = artifact.download() - opt.weights = str(Path(modeldir) / "last.pt") - return True - return None - - -def process_wandb_config_ddp_mode(opt): - with open(check_file(opt.data), errors='ignore') as f: - data_dict = yaml.safe_load(f) # data dict - train_dir, val_dir = None, None - if isinstance(data_dict['train'], str) and data_dict['train'].startswith(WANDB_ARTIFACT_PREFIX): - api = wandb.Api() - train_artifact = api.artifact(remove_prefix(data_dict['train']) + ':' + opt.artifact_alias) - train_dir = train_artifact.download() - train_path = Path(train_dir) / 'data/images/' - data_dict['train'] = str(train_path) - - if isinstance(data_dict['val'], str) and data_dict['val'].startswith(WANDB_ARTIFACT_PREFIX): - api = wandb.Api() - val_artifact = api.artifact(remove_prefix(data_dict['val']) + ':' + opt.artifact_alias) - val_dir = val_artifact.download() - val_path = Path(val_dir) / 'data/images/' - data_dict['val'] = str(val_path) - if train_dir or val_dir: - ddp_data_path = str(Path(val_dir) / 'wandb_local_data.yaml') - with open(ddp_data_path, 'w') as f: - yaml.safe_dump(data_dict, f) - opt.data = ddp_data_path - - -class WandbLogger(): - """Log training runs, datasets, models, and predictions to Weights & Biases. - - This logger sends information to W&B at wandb.ai. By default, this information - includes hyperparameters, system configuration and metrics, model metrics, - and basic data metrics and analyses. - - By providing additional command line arguments to train.py, datasets, - models and predictions can also be logged. - - For more on how this logger is used, see the Weights & Biases documentation: - https://docs.wandb.com/guides/integrations/yolov5 - """ - - def __init__(self, opt, run_id=None, job_type='Training'): - """ - - Initialize WandbLogger instance - - Upload dataset if opt.upload_dataset is True - - Setup trainig processes if job_type is 'Training' - - arguments: - opt (namespace) -- Commandline arguments for this run - run_id (str) -- Run ID of W&B run to be resumed - job_type (str) -- To set the job_type for this run - - """ - # Pre-training routine -- - self.job_type = job_type - self.wandb, self.wandb_run = wandb, None if not wandb else wandb.run - self.val_artifact, self.train_artifact = None, None - self.train_artifact_path, self.val_artifact_path = None, None - self.result_artifact = None - self.val_table, self.result_table = None, None - self.bbox_media_panel_images = [] - self.val_table_path_map = None - self.max_imgs_to_log = 16 - self.wandb_artifact_data_dict = None - self.data_dict = None - # It's more elegant to stick to 1 wandb.init call, - # but useful config data is overwritten in the WandbLogger's wandb.init call - if isinstance(opt.resume, str): # checks resume from artifact - if opt.resume.startswith(WANDB_ARTIFACT_PREFIX): - entity, project, run_id, model_artifact_name = get_run_info(opt.resume) - model_artifact_name = WANDB_ARTIFACT_PREFIX + model_artifact_name - assert wandb, 'install wandb to resume wandb runs' - # Resume wandb-artifact:// runs here| workaround for not overwriting wandb.config - self.wandb_run = wandb.init(id=run_id, - project=project, - entity=entity, - resume='allow', - allow_val_change=True) - opt.resume = model_artifact_name - elif self.wandb: - self.wandb_run = wandb.init(config=opt, - resume="allow", - project='YOLOv5' if opt.project == 'runs/train' else Path(opt.project).stem, - entity=opt.entity, - name=opt.name if opt.name != 'exp' else None, - job_type=job_type, - id=run_id, - allow_val_change=True) if not wandb.run else wandb.run - if self.wandb_run: - if self.job_type == 'Training': - if opt.upload_dataset: - if not opt.resume: - self.wandb_artifact_data_dict = self.check_and_upload_dataset(opt) - - if opt.resume: - # resume from artifact - if isinstance(opt.resume, str) and opt.resume.startswith(WANDB_ARTIFACT_PREFIX): - self.data_dict = dict(self.wandb_run.config.data_dict) - else: # local resume - self.data_dict = check_wandb_dataset(opt.data) - else: - self.data_dict = check_wandb_dataset(opt.data) - self.wandb_artifact_data_dict = self.wandb_artifact_data_dict or self.data_dict - - # write data_dict to config. useful for resuming from artifacts. Do this only when not resuming. - self.wandb_run.config.update({'data_dict': self.wandb_artifact_data_dict}, - allow_val_change=True) - self.setup_training(opt) - - if self.job_type == 'Dataset Creation': - self.wandb_run.config.update({"upload_dataset": True}) - self.data_dict = self.check_and_upload_dataset(opt) - - def check_and_upload_dataset(self, opt): - """ - Check if the dataset format is compatible and upload it as W&B artifact - - arguments: - opt (namespace)-- Commandline arguments for current run - - returns: - Updated dataset info dictionary where local dataset paths are replaced by WAND_ARFACT_PREFIX links. - """ - assert wandb, 'Install wandb to upload dataset' - config_path = self.log_dataset_artifact(opt.data, - opt.single_cls, - 'YOLOv5' if opt.project == 'runs/train' else Path(opt.project).stem) - with open(config_path, errors='ignore') as f: - wandb_data_dict = yaml.safe_load(f) - return wandb_data_dict - - def setup_training(self, opt): - """ - Setup the necessary processes for training YOLO models: - - Attempt to download model checkpoint and dataset artifacts if opt.resume stats with WANDB_ARTIFACT_PREFIX - - Update data_dict, to contain info of previous run if resumed and the paths of dataset artifact if downloaded - - Setup log_dict, initialize bbox_interval - - arguments: - opt (namespace) -- commandline arguments for this run - - """ - self.log_dict, self.current_epoch = {}, 0 - self.bbox_interval = opt.bbox_interval - if isinstance(opt.resume, str): - modeldir, _ = self.download_model_artifact(opt) - if modeldir: - self.weights = Path(modeldir) / "last.pt" - config = self.wandb_run.config - opt.weights, opt.save_period, opt.batch_size, opt.bbox_interval, opt.epochs, opt.hyp = str( - self.weights), config.save_period, config.batch_size, config.bbox_interval, config.epochs, \ - config.hyp - data_dict = self.data_dict - if self.val_artifact is None: # If --upload_dataset is set, use the existing artifact, don't download - self.train_artifact_path, self.train_artifact = self.download_dataset_artifact(data_dict.get('train'), - opt.artifact_alias) - self.val_artifact_path, self.val_artifact = self.download_dataset_artifact(data_dict.get('val'), - opt.artifact_alias) - - if self.train_artifact_path is not None: - train_path = Path(self.train_artifact_path) / 'data/images/' - data_dict['train'] = str(train_path) - if self.val_artifact_path is not None: - val_path = Path(self.val_artifact_path) / 'data/images/' - data_dict['val'] = str(val_path) - - if self.val_artifact is not None: - self.result_artifact = wandb.Artifact("run_" + wandb.run.id + "_progress", "evaluation") - columns = ["epoch", "id", "ground truth", "prediction"] - columns.extend(self.data_dict['names']) - self.result_table = wandb.Table(columns) - self.val_table = self.val_artifact.get("val") - if self.val_table_path_map is None: - self.map_val_table_path() - if opt.bbox_interval == -1: - self.bbox_interval = opt.bbox_interval = (opt.epochs // 10) if opt.epochs > 10 else 1 - train_from_artifact = self.train_artifact_path is not None and self.val_artifact_path is not None - # Update the the data_dict to point to local artifacts dir - if train_from_artifact: - self.data_dict = data_dict - - def download_dataset_artifact(self, path, alias): - """ - download the model checkpoint artifact if the path starts with WANDB_ARTIFACT_PREFIX - - arguments: - path -- path of the dataset to be used for training - alias (str)-- alias of the artifact to be download/used for training - - returns: - (str, wandb.Artifact) -- path of the downladed dataset and it's corresponding artifact object if dataset - is found otherwise returns (None, None) - """ - if isinstance(path, str) and path.startswith(WANDB_ARTIFACT_PREFIX): - artifact_path = Path(remove_prefix(path, WANDB_ARTIFACT_PREFIX) + ":" + alias) - dataset_artifact = wandb.use_artifact(artifact_path.as_posix().replace("\\", "/")) - assert dataset_artifact is not None, "'Error: W&B dataset artifact doesn\'t exist'" - datadir = dataset_artifact.download() - return datadir, dataset_artifact - return None, None - - def download_model_artifact(self, opt): - """ - download the model checkpoint artifact if the resume path starts with WANDB_ARTIFACT_PREFIX - - arguments: - opt (namespace) -- Commandline arguments for this run - """ - if opt.resume.startswith(WANDB_ARTIFACT_PREFIX): - model_artifact = wandb.use_artifact(remove_prefix(opt.resume, WANDB_ARTIFACT_PREFIX) + ":latest") - assert model_artifact is not None, 'Error: W&B model artifact doesn\'t exist' - modeldir = model_artifact.download() - epochs_trained = model_artifact.metadata.get('epochs_trained') - total_epochs = model_artifact.metadata.get('total_epochs') - is_finished = total_epochs is None - assert not is_finished, 'training is finished, can only resume incomplete runs.' - return modeldir, model_artifact - return None, None - - def log_model(self, path, opt, epoch, fitness_score, best_model=False): - """ - Log the model checkpoint as W&B artifact - - arguments: - path (Path) -- Path of directory containing the checkpoints - opt (namespace) -- Command line arguments for this run - epoch (int) -- Current epoch number - fitness_score (float) -- fitness score for current epoch - best_model (boolean) -- Boolean representing if the current checkpoint is the best yet. - """ - model_artifact = wandb.Artifact('run_' + wandb.run.id + '_model', type='model', metadata={ - 'original_url': str(path), - 'epochs_trained': epoch + 1, - 'save period': opt.save_period, - 'project': opt.project, - 'total_epochs': opt.epochs, - 'fitness_score': fitness_score - }) - model_artifact.add_file(str(path / 'last.pt'), name='last.pt') - wandb.log_artifact(model_artifact, - aliases=['latest', 'last', 'epoch ' + str(self.current_epoch), 'best' if best_model else '']) - LOGGER.info(f"Saving model artifact on epoch {epoch + 1}") - - def log_dataset_artifact(self, data_file, single_cls, project, overwrite_config=False): - """ - Log the dataset as W&B artifact and return the new data file with W&B links - - arguments: - data_file (str) -- the .yaml file with information about the dataset like - path, classes etc. - single_class (boolean) -- train multi-class data as single-class - project (str) -- project name. Used to construct the artifact path - overwrite_config (boolean) -- overwrites the data.yaml file if set to true otherwise creates a new - file with _wandb postfix. Eg -> data_wandb.yaml - - returns: - the new .yaml file with artifact links. it can be used to start training directly from artifacts - """ - upload_dataset = self.wandb_run.config.upload_dataset - log_val_only = isinstance(upload_dataset, str) and upload_dataset == 'val' - self.data_dict = check_dataset(data_file) # parse and check - data = dict(self.data_dict) - nc, names = (1, ['item']) if single_cls else (int(data['nc']), data['names']) - names = {k: v for k, v in enumerate(names)} # to index dictionary - - # log train set - if not log_val_only: - self.train_artifact = self.create_dataset_table(LoadImagesAndLabels( - data['train'], rect=True, batch_size=1), names, name='train') if data.get('train') else None - if data.get('train'): - data['train'] = WANDB_ARTIFACT_PREFIX + str(Path(project) / 'train') - - self.val_artifact = self.create_dataset_table(LoadImagesAndLabels( - data['val'], rect=True, batch_size=1), names, name='val') if data.get('val') else None - if data.get('val'): - data['val'] = WANDB_ARTIFACT_PREFIX + str(Path(project) / 'val') - - path = Path(data_file) - # create a _wandb.yaml file with artifacts links if both train and test set are logged - if not log_val_only: - path = (path.stem if overwrite_config else path.stem + '_wandb') + '.yaml' # updated data.yaml path - path = Path('data') / path - data.pop('download', None) - data.pop('path', None) - with open(path, 'w') as f: - yaml.safe_dump(data, f) - LOGGER.info(f"Created dataset config file {path}") - - if self.job_type == 'Training': # builds correct artifact pipeline graph - if not log_val_only: - self.wandb_run.log_artifact( - self.train_artifact) # calling use_artifact downloads the dataset. NOT NEEDED! - self.wandb_run.use_artifact(self.val_artifact) - self.val_artifact.wait() - self.val_table = self.val_artifact.get('val') - self.map_val_table_path() - else: - self.wandb_run.log_artifact(self.train_artifact) - self.wandb_run.log_artifact(self.val_artifact) - return path - - def map_val_table_path(self): - """ - Map the validation dataset Table like name of file -> it's id in the W&B Table. - Useful for - referencing artifacts for evaluation. - """ - self.val_table_path_map = {} - LOGGER.info("Mapping dataset") - for i, data in enumerate(tqdm(self.val_table.data)): - self.val_table_path_map[data[3]] = data[0] - - def create_dataset_table(self, dataset: LoadImagesAndLabels, class_to_id: Dict[int, str], name: str = 'dataset'): - """ - Create and return W&B artifact containing W&B Table of the dataset. - - arguments: - dataset -- instance of LoadImagesAndLabels class used to iterate over the data to build Table - class_to_id -- hash map that maps class ids to labels - name -- name of the artifact - - returns: - dataset artifact to be logged or used - """ - # TODO: Explore multiprocessing to slpit this loop parallely| This is essential for speeding up the the logging - artifact = wandb.Artifact(name=name, type="dataset") - img_files = tqdm([dataset.path]) if isinstance(dataset.path, str) and Path(dataset.path).is_dir() else None - img_files = tqdm(dataset.img_files) if not img_files else img_files - for img_file in img_files: - if Path(img_file).is_dir(): - artifact.add_dir(img_file, name='data/images') - labels_path = 'labels'.join(dataset.path.rsplit('images', 1)) - artifact.add_dir(labels_path, name='data/labels') - else: - artifact.add_file(img_file, name='data/images/' + Path(img_file).name) - label_file = Path(img2label_paths([img_file])[0]) - artifact.add_file(str(label_file), - name='data/labels/' + label_file.name) if label_file.exists() else None - table = wandb.Table(columns=["id", "train_image", "Classes", "name"]) - class_set = wandb.Classes([{'id': id, 'name': name} for id, name in class_to_id.items()]) - for si, (img, labels, paths, shapes) in enumerate(tqdm(dataset)): - box_data, img_classes = [], {} - for cls, *xywh in labels[:, 1:].tolist(): - cls = int(cls) - box_data.append({"position": {"middle": [xywh[0], xywh[1]], "width": xywh[2], "height": xywh[3]}, - "class_id": cls, - "box_caption": "%s" % (class_to_id[cls])}) - img_classes[cls] = class_to_id[cls] - boxes = {"ground_truth": {"box_data": box_data, "class_labels": class_to_id}} # inference-space - table.add_data(si, wandb.Image(paths, classes=class_set, boxes=boxes), list(img_classes.values()), - Path(paths).name) - artifact.add(table, name) - return artifact - - def log_training_progress(self, predn, path, names): - """ - Build evaluation Table. Uses reference from validation dataset table. - - arguments: - predn (list): list of predictions in the native space in the format - [xmin, ymin, xmax, ymax, confidence, class] - path (str): local path of the current evaluation image - names (dict(int, str)): hash map that maps class ids to labels - """ - class_set = wandb.Classes([{'id': id, 'name': name} for id, name in names.items()]) - box_data = [] - avg_conf_per_class = [0] * len(self.data_dict['names']) - pred_class_count = {} - for *xyxy, conf, cls in predn.tolist(): - if conf >= 0.25: - cls = int(cls) - box_data.append( - {"position": {"minX": xyxy[0], "minY": xyxy[1], "maxX": xyxy[2], "maxY": xyxy[3]}, - "class_id": cls, - "box_caption": f"{names[cls]} {conf:.3f}", - "scores": {"class_score": conf}, - "domain": "pixel"}) - avg_conf_per_class[cls] += conf - - if cls in pred_class_count: - pred_class_count[cls] += 1 - else: - pred_class_count[cls] = 1 - - for pred_class in pred_class_count.keys(): - avg_conf_per_class[pred_class] = avg_conf_per_class[pred_class] / pred_class_count[pred_class] - - boxes = {"predictions": {"box_data": box_data, "class_labels": names}} # inference-space - id = self.val_table_path_map[Path(path).name] - self.result_table.add_data(self.current_epoch, - id, - self.val_table.data[id][1], - wandb.Image(self.val_table.data[id][1], boxes=boxes, classes=class_set), - *avg_conf_per_class - ) - - def val_one_image(self, pred, predn, path, names, im): - """ - Log validation data for one image. updates the result Table if validation dataset is uploaded and log bbox media panel - - arguments: - pred (list): list of scaled predictions in the format - [xmin, ymin, xmax, ymax, confidence, class] - predn (list): list of predictions in the native space - [xmin, ymin, xmax, ymax, confidence, class] - path (str): local path of the current evaluation image - """ - if self.val_table and self.result_table: # Log Table if Val dataset is uploaded as artifact - self.log_training_progress(predn, path, names) - - if len(self.bbox_media_panel_images) < self.max_imgs_to_log and self.current_epoch > 0: - if self.current_epoch % self.bbox_interval == 0: - box_data = [{"position": {"minX": xyxy[0], "minY": xyxy[1], "maxX": xyxy[2], "maxY": xyxy[3]}, - "class_id": int(cls), - "box_caption": f"{names[cls]} {conf:.3f}", - "scores": {"class_score": conf}, - "domain": "pixel"} for *xyxy, conf, cls in pred.tolist()] - boxes = {"predictions": {"box_data": box_data, "class_labels": names}} # inference-space - self.bbox_media_panel_images.append(wandb.Image(im, boxes=boxes, caption=path.name)) - - def log(self, log_dict): - """ - save the metrics to the logging dictionary - - arguments: - log_dict (Dict) -- metrics/media to be logged in current step - """ - if self.wandb_run: - for key, value in log_dict.items(): - self.log_dict[key] = value - - def end_epoch(self, best_result=False): - """ - commit the log_dict, model artifacts and Tables to W&B and flush the log_dict. - - arguments: - best_result (boolean): Boolean representing if the result of this evaluation is best or not - """ - if self.wandb_run: - with all_logging_disabled(): - if self.bbox_media_panel_images: - self.log_dict["BoundingBoxDebugger"] = self.bbox_media_panel_images - try: - wandb.log(self.log_dict) - except BaseException as e: - LOGGER.info( - f"An error occurred in wandb logger. The training will proceed without interruption. More info\n{e}") - self.wandb_run.finish() - self.wandb_run = None - - self.log_dict = {} - self.bbox_media_panel_images = [] - if self.result_artifact: - self.result_artifact.add(self.result_table, 'result') - wandb.log_artifact(self.result_artifact, aliases=['latest', 'last', 'epoch ' + str(self.current_epoch), - ('best' if best_result else '')]) - - wandb.log({"evaluation": self.result_table}) - columns = ["epoch", "id", "ground truth", "prediction"] - columns.extend(self.data_dict['names']) - self.result_table = wandb.Table(columns) - self.result_artifact = wandb.Artifact("run_" + wandb.run.id + "_progress", "evaluation") - - def finish_run(self): - """ - Log metrics if any and finish the current W&B run - """ - if self.wandb_run: - if self.log_dict: - with all_logging_disabled(): - wandb.log(self.log_dict) - wandb.run.finish() - - -@contextmanager -def all_logging_disabled(highest_level=logging.CRITICAL): - """ source - https://gist.github.com/simon-weber/7853144 - A context manager that will prevent any logging messages triggered during the body from being processed. - :param highest_level: the maximum logging level in use. - This would only need to be changed if a custom level greater than CRITICAL is defined. - """ - previous_level = logging.root.manager.disable - logging.disable(highest_level) - try: - yield - finally: - logging.disable(previous_level) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loss.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/loss.py deleted file mode 100755 index 194c8e503..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/loss.py +++ /dev/null @@ -1,222 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Loss functions -""" - -import torch -import torch.nn as nn - -from utils.metrics import bbox_iou -from utils.torch_utils import is_parallel - - -def smooth_BCE(eps=0.1): # https://github.com/ultralytics/yolov3/issues/238#issuecomment-598028441 - # return positive, negative label smoothing BCE targets - return 1.0 - 0.5 * eps, 0.5 * eps - - -class BCEBlurWithLogitsLoss(nn.Module): - # BCEwithLogitLoss() with reduced missing label effects. - def __init__(self, alpha=0.05): - super().__init__() - self.loss_fcn = nn.BCEWithLogitsLoss(reduction='none') # must be nn.BCEWithLogitsLoss() - self.alpha = alpha - - def forward(self, pred, true): - loss = self.loss_fcn(pred, true) - pred = torch.sigmoid(pred) # prob from logits - dx = pred - true # reduce only missing label effects - # dx = (pred - true).abs() # reduce missing label and false label effects - alpha_factor = 1 - torch.exp((dx - 1) / (self.alpha + 1e-4)) - loss *= alpha_factor - return loss.mean() - - -class FocalLoss(nn.Module): - # Wraps focal loss around existing loss_fcn(), i.e. criteria = FocalLoss(nn.BCEWithLogitsLoss(), gamma=1.5) - def __init__(self, loss_fcn, gamma=1.5, alpha=0.25): - super().__init__() - self.loss_fcn = loss_fcn # must be nn.BCEWithLogitsLoss() - self.gamma = gamma - self.alpha = alpha - self.reduction = loss_fcn.reduction - self.loss_fcn.reduction = 'none' # required to apply FL to each element - - def forward(self, pred, true): - loss = self.loss_fcn(pred, true) - # p_t = torch.exp(-loss) - # loss *= self.alpha * (1.000001 - p_t) ** self.gamma # non-zero power for gradient stability - - # TF implementation https://github.com/tensorflow/addons/blob/v0.7.1/tensorflow_addons/losses/focal_loss.py - pred_prob = torch.sigmoid(pred) # prob from logits - p_t = true * pred_prob + (1 - true) * (1 - pred_prob) - alpha_factor = true * self.alpha + (1 - true) * (1 - self.alpha) - modulating_factor = (1.0 - p_t) ** self.gamma - loss *= alpha_factor * modulating_factor - - if self.reduction == 'mean': - return loss.mean() - elif self.reduction == 'sum': - return loss.sum() - else: # 'none' - return loss - - -class QFocalLoss(nn.Module): - # Wraps Quality focal loss around existing loss_fcn(), i.e. criteria = FocalLoss(nn.BCEWithLogitsLoss(), gamma=1.5) - def __init__(self, loss_fcn, gamma=1.5, alpha=0.25): - super().__init__() - self.loss_fcn = loss_fcn # must be nn.BCEWithLogitsLoss() - self.gamma = gamma - self.alpha = alpha - self.reduction = loss_fcn.reduction - self.loss_fcn.reduction = 'none' # required to apply FL to each element - - def forward(self, pred, true): - loss = self.loss_fcn(pred, true) - - pred_prob = torch.sigmoid(pred) # prob from logits - alpha_factor = true * self.alpha + (1 - true) * (1 - self.alpha) - modulating_factor = torch.abs(true - pred_prob) ** self.gamma - loss *= alpha_factor * modulating_factor - - if self.reduction == 'mean': - return loss.mean() - elif self.reduction == 'sum': - return loss.sum() - else: # 'none' - return loss - - -class ComputeLoss: - # Compute losses - def __init__(self, model, autobalance=False): - self.sort_obj_iou = False - device = next(model.parameters()).device # get model device - h = model.hyp # hyperparameters - - # Define criteria - BCEcls = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([h['cls_pw']], device=device)) - BCEobj = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([h['obj_pw']], device=device)) - - # Class label smoothing https://arxiv.org/pdf/1902.04103.pdf eqn 3 - self.cp, self.cn = smooth_BCE(eps=h.get('label_smoothing', 0.0)) # positive, negative BCE targets - - # Focal loss - g = h['fl_gamma'] # focal loss gamma - if g > 0: - BCEcls, BCEobj = FocalLoss(BCEcls, g), FocalLoss(BCEobj, g) - - det = model.module.model[-1] if is_parallel(model) else model.model[-1] # Detect() module - self.balance = {3: [4.0, 1.0, 0.4]}.get(det.nl, [4.0, 1.0, 0.25, 0.06, 0.02]) # P3-P7 - self.ssi = list(det.stride).index(16) if autobalance else 0 # stride 16 index - self.BCEcls, self.BCEobj, self.gr, self.hyp, self.autobalance = BCEcls, BCEobj, 1.0, h, autobalance - for k in 'na', 'nc', 'nl', 'anchors': - setattr(self, k, getattr(det, k)) - - def __call__(self, p, targets): # predictions, targets, model - device = targets.device - lcls, lbox, lobj = torch.zeros(1, device=device), torch.zeros(1, device=device), torch.zeros(1, device=device) - tcls, tbox, indices, anchors = self.build_targets(p, targets) # targets - - # Losses - for i, pi in enumerate(p): # layer index, layer predictions - b, a, gj, gi = indices[i] # image, anchor, gridy, gridx - tobj = torch.zeros_like(pi[..., 0], device=device) # target obj - - n = b.shape[0] # number of targets - if n: - ps = pi[b, a, gj, gi] # prediction subset corresponding to targets - - # Regression - pxy = ps[:, :2].sigmoid() * 2 - 0.5 - pwh = (ps[:, 2:4].sigmoid() * 2) ** 2 * anchors[i] - pbox = torch.cat((pxy, pwh), 1) # predicted box - iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True) # iou(prediction, target) - lbox += (1.0 - iou).mean() # iou loss - - # Objectness - score_iou = iou.detach().clamp(0).type(tobj.dtype) - if self.sort_obj_iou: - sort_id = torch.argsort(score_iou) - b, a, gj, gi, score_iou = b[sort_id], a[sort_id], gj[sort_id], gi[sort_id], score_iou[sort_id] - tobj[b, a, gj, gi] = (1.0 - self.gr) + self.gr * score_iou # iou ratio - - # Classification - if self.nc > 1: # cls loss (only if multiple classes) - t = torch.full_like(ps[:, 5:], self.cn, device=device) # targets - t[range(n), tcls[i]] = self.cp - lcls += self.BCEcls(ps[:, 5:], t) # BCE - - # Append targets to text file - # with open('targets.txt', 'a') as file: - # [file.write('%11.5g ' * 4 % tuple(x) + '\n') for x in torch.cat((txy[i], twh[i]), 1)] - - obji = self.BCEobj(pi[..., 4], tobj) - lobj += obji * self.balance[i] # obj loss - if self.autobalance: - self.balance[i] = self.balance[i] * 0.9999 + 0.0001 / obji.detach().item() - - if self.autobalance: - self.balance = [x / self.balance[self.ssi] for x in self.balance] - lbox *= self.hyp['box'] - lobj *= self.hyp['obj'] - lcls *= self.hyp['cls'] - bs = tobj.shape[0] # batch size - - return (lbox + lobj + lcls) * bs, torch.cat((lbox, lobj, lcls)).detach() - - def build_targets(self, p, targets): - # Build targets for compute_loss(), input targets(image,class,x,y,w,h) - na, nt = self.na, targets.shape[0] # number of anchors, targets - tcls, tbox, indices, anch = [], [], [], [] - gain = torch.ones(7, device=targets.device) # normalized to gridspace gain - ai = torch.arange(na, device=targets.device).float().view(na, 1).repeat(1, nt) # same as .repeat_interleave(nt) - targets = torch.cat((targets.repeat(na, 1, 1), ai[:, :, None]), 2) # append anchor indices - - g = 0.5 # bias - off = torch.tensor([[0, 0], - [1, 0], [0, 1], [-1, 0], [0, -1], # j,k,l,m - # [1, 1], [1, -1], [-1, 1], [-1, -1], # jk,jm,lk,lm - ], device=targets.device).float() * g # offsets - - for i in range(self.nl): - anchors = self.anchors[i] - gain[2:6] = torch.tensor(p[i].shape)[[3, 2, 3, 2]] # xyxy gain - - # Match targets to anchors - t = targets * gain - if nt: - # Matches - r = t[:, :, 4:6] / anchors[:, None] # wh ratio - j = torch.max(r, 1 / r).max(2)[0] < self.hyp['anchor_t'] # compare - # j = wh_iou(anchors, t[:, 4:6]) > model.hyp['iou_t'] # iou(3,n)=wh_iou(anchors(3,2), gwh(n,2)) - t = t[j] # filter - - # Offsets - gxy = t[:, 2:4] # grid xy - gxi = gain[[2, 3]] - gxy # inverse - j, k = ((gxy % 1 < g) & (gxy > 1)).T - l, m = ((gxi % 1 < g) & (gxi > 1)).T - j = torch.stack((torch.ones_like(j), j, k, l, m)) - t = t.repeat((5, 1, 1))[j] - offsets = (torch.zeros_like(gxy)[None] + off[:, None])[j] - else: - t = targets[0] - offsets = 0 - - # Define - b, c = t[:, :2].long().T # image, class - gxy = t[:, 2:4] # grid xy - gwh = t[:, 4:6] # grid wh - gij = (gxy - offsets).long() - gi, gj = gij.T # grid xy indices - - # Append - a = t[:, 6].long() # anchor indices - indices.append((b, a, gj.clamp_(0, gain[3] - 1), gi.clamp_(0, gain[2] - 1))) # image, anchor, grid indices - tbox.append(torch.cat((gxy - gij, gwh), 1)) # box - anch.append(anchors[a]) # anchors - tcls.append(c) # class - - return tcls, tbox, indices, anch diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/metrics.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/metrics.py deleted file mode 100755 index 3f1dc559c..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/metrics.py +++ /dev/null @@ -1,344 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Model validation metrics -""" - -import math -import warnings -from pathlib import Path - -import matplotlib.pyplot as plt -import numpy as np -import torch - - -def fitness(x): - # Model fitness as a weighted combination of metrics - w = [0.0, 0.0, 0.1, 0.9] # weights for [P, R, mAP@0.5, mAP@0.5:0.95] - return (x[:, :4] * w).sum(1) - - -def ap_per_class(tp, conf, pred_cls, target_cls, plot=False, save_dir='.', names=(), eps=1e-16): - """ Compute the average precision, given the recall and precision curves. - Source: https://github.com/rafaelpadilla/Object-Detection-Metrics. - # Arguments - tp: True positives (nparray, nx1 or nx10). - conf: Objectness value from 0-1 (nparray). - pred_cls: Predicted object classes (nparray). - target_cls: True object classes (nparray). - plot: Plot precision-recall curve at mAP@0.5 - save_dir: Plot save directory - # Returns - The average precision as computed in py-faster-rcnn. - """ - - # Sort by objectness - i = np.argsort(-conf) - tp, conf, pred_cls = tp[i], conf[i], pred_cls[i] - - # Find unique classes - unique_classes, nt = np.unique(target_cls, return_counts=True) - nc = unique_classes.shape[0] # number of classes, number of detections - - # Create Precision-Recall curve and compute AP for each class - px, py = np.linspace(0, 1, 1000), [] # for plotting - ap, p, r = np.zeros((nc, tp.shape[1])), np.zeros((nc, 1000)), np.zeros((nc, 1000)) - for ci, c in enumerate(unique_classes): - i = pred_cls == c - n_l = nt[ci] # number of labels - n_p = i.sum() # number of predictions - - if n_p == 0 or n_l == 0: - continue - else: - # Accumulate FPs and TPs - fpc = (1 - tp[i]).cumsum(0) - tpc = tp[i].cumsum(0) - - # Recall - recall = tpc / (n_l + eps) # recall curve - r[ci] = np.interp(-px, -conf[i], recall[:, 0], left=0) # negative x, xp because xp decreases - - # Precision - precision = tpc / (tpc + fpc) # precision curve - p[ci] = np.interp(-px, -conf[i], precision[:, 0], left=1) # p at pr_score - - # AP from recall-precision curve - for j in range(tp.shape[1]): - ap[ci, j], mpre, mrec = compute_ap(recall[:, j], precision[:, j]) - if plot and j == 0: - py.append(np.interp(px, mrec, mpre)) # precision at mAP@0.5 - - # Compute F1 (harmonic mean of precision and recall) - f1 = 2 * p * r / (p + r + eps) - names = [v for k, v in names.items() if k in unique_classes] # list: only classes that have data - names = {i: v for i, v in enumerate(names)} # to dict - if plot: - plot_pr_curve(px, py, ap, Path(save_dir) / 'PR_curve.png', names) - plot_mc_curve(px, f1, Path(save_dir) / 'F1_curve.png', names, ylabel='F1') - plot_mc_curve(px, p, Path(save_dir) / 'P_curve.png', names, ylabel='Precision') - plot_mc_curve(px, r, Path(save_dir) / 'R_curve.png', names, ylabel='Recall') - - i = f1.mean(0).argmax() # max F1 index - p, r, f1 = p[:, i], r[:, i], f1[:, i] - tp = (r * nt).round() # true positives - fp = (tp / (p + eps) - tp).round() # false positives - return tp, fp, p, r, f1, ap, unique_classes.astype('int32') - - -def compute_ap(recall, precision): - """ Compute the average precision, given the recall and precision curves - # Arguments - recall: The recall curve (list) - precision: The precision curve (list) - # Returns - Average precision, precision curve, recall curve - """ - - # Append sentinel values to beginning and end - mrec = np.concatenate(([0.0], recall, [1.0])) - mpre = np.concatenate(([1.0], precision, [0.0])) - - # Compute the precision envelope - mpre = np.flip(np.maximum.accumulate(np.flip(mpre))) - - # Integrate area under curve - method = 'interp' # methods: 'continuous', 'interp' - if method == 'interp': - x = np.linspace(0, 1, 101) # 101-point interp (COCO) - ap = np.trapz(np.interp(x, mrec, mpre), x) # integrate - else: # 'continuous' - i = np.where(mrec[1:] != mrec[:-1])[0] # points where x axis (recall) changes - ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) # area under curve - - return ap, mpre, mrec - - -class ConfusionMatrix: - # Updated version of https://github.com/kaanakan/object_detection_confusion_matrix - def __init__(self, nc, conf=0.25, iou_thres=0.45): - self.matrix = np.zeros((nc + 1, nc + 1)) - self.nc = nc # number of classes - self.conf = conf - self.iou_thres = iou_thres - - def process_batch(self, detections, labels): - """ - Return intersection-over-union (Jaccard index) of boxes. - Both sets of boxes are expected to be in (x1, y1, x2, y2) format. - Arguments: - detections (Array[N, 6]), x1, y1, x2, y2, conf, class - labels (Array[M, 5]), class, x1, y1, x2, y2 - Returns: - None, updates confusion matrix accordingly - """ - detections = detections[detections[:, 4] > self.conf] - gt_classes = labels[:, 0].int() - detection_classes = detections[:, 5].int() - iou = box_iou(labels[:, 1:], detections[:, :4]) - - x = torch.where(iou > self.iou_thres) - if x[0].shape[0]: - matches = torch.cat((torch.stack(x, 1), iou[x[0], x[1]][:, None]), 1).cpu().numpy() - if x[0].shape[0] > 1: - matches = matches[matches[:, 2].argsort()[::-1]] - matches = matches[np.unique(matches[:, 1], return_index=True)[1]] - matches = matches[matches[:, 2].argsort()[::-1]] - matches = matches[np.unique(matches[:, 0], return_index=True)[1]] - else: - matches = np.zeros((0, 3)) - - n = matches.shape[0] > 0 - m0, m1, _ = matches.transpose().astype(np.int16) - for i, gc in enumerate(gt_classes): - j = m0 == i - if n and sum(j) == 1: - self.matrix[detection_classes[m1[j]], gc] += 1 # correct - else: - self.matrix[self.nc, gc] += 1 # background FP - - if n: - for i, dc in enumerate(detection_classes): - if not any(m1 == i): - self.matrix[dc, self.nc] += 1 # background FN - - def matrix(self): - return self.matrix - - def tp_fp(self): - tp = self.matrix.diagonal() # true positives - fp = self.matrix.sum(1) - tp # false positives - # fn = self.matrix.sum(0) - tp # false negatives (missed detections) - return tp[:-1], fp[:-1] # remove background class - - def plot(self, normalize=True, save_dir='', names=()): - try: - import seaborn as sn - - array = self.matrix / ((self.matrix.sum(0).reshape(1, -1) + 1E-6) if normalize else 1) # normalize columns - array[array < 0.005] = np.nan # don't annotate (would appear as 0.00) - - fig = plt.figure(figsize=(12, 9), tight_layout=True) - sn.set(font_scale=1.0 if self.nc < 50 else 0.8) # for label size - labels = (0 < len(names) < 99) and len(names) == self.nc # apply names to ticklabels - with warnings.catch_warnings(): - warnings.simplefilter('ignore') # suppress empty matrix RuntimeWarning: All-NaN slice encountered - sn.heatmap(array, annot=self.nc < 30, annot_kws={"size": 8}, cmap='Blues', fmt='.2f', square=True, - xticklabels=names + ['background FP'] if labels else "auto", - yticklabels=names + ['background FN'] if labels else "auto").set_facecolor((1, 1, 1)) - fig.axes[0].set_xlabel('True') - fig.axes[0].set_ylabel('Predicted') - fig.savefig(Path(save_dir) / 'confusion_matrix.png', dpi=250) - plt.close() - except Exception as e: - print(f'WARNING: ConfusionMatrix plot failure: {e}') - - def print(self): - for i in range(self.nc + 1): - print(' '.join(map(str, self.matrix[i]))) - - -def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, eps=1e-7): - # Returns the IoU of box1 to box2. box1 is 4, box2 is nx4 - box2 = box2.T - - # Get the coordinates of bounding boxes - if x1y1x2y2: # x1, y1, x2, y2 = box1 - b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3] - b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3] - else: # transform from xywh to xyxy - b1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2 - b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2 - b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2 - b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2 - - # Intersection area - inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \ - (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0) - - # Union Area - w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps - w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps - union = w1 * h1 + w2 * h2 - inter + eps - - iou = inter / union - if GIoU or DIoU or CIoU: - cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1) # convex (smallest enclosing box) width - ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1) # convex height - if CIoU or DIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1 - c2 = cw ** 2 + ch ** 2 + eps # convex diagonal squared - rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + - (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # center distance squared - if DIoU: - return iou - rho2 / c2 # DIoU - elif CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47 - v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2) - with torch.no_grad(): - alpha = v / (v - iou + (1 + eps)) - return iou - (rho2 / c2 + v * alpha) # CIoU - else: # GIoU https://arxiv.org/pdf/1902.09630.pdf - c_area = cw * ch + eps # convex area - return iou - (c_area - union) / c_area # GIoU - else: - return iou # IoU - - -def box_iou(box1, box2): - # https://github.com/pytorch/vision/blob/master/torchvision/ops/boxes.py - """ - Return intersection-over-union (Jaccard index) of boxes. - Both sets of boxes are expected to be in (x1, y1, x2, y2) format. - Arguments: - box1 (Tensor[N, 4]) - box2 (Tensor[M, 4]) - Returns: - iou (Tensor[N, M]): the NxM matrix containing the pairwise - IoU values for every element in boxes1 and boxes2 - """ - - def box_area(box): - # box = 4xn - return (box[2] - box[0]) * (box[3] - box[1]) - - area1 = box_area(box1.T) - area2 = box_area(box2.T) - - # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2) - inter = (torch.min(box1[:, None, 2:], box2[:, 2:]) - torch.max(box1[:, None, :2], box2[:, :2])).clamp(0).prod(2) - return inter / (area1[:, None] + area2 - inter) # iou = inter / (area1 + area2 - inter) - - -def bbox_ioa(box1, box2, eps=1E-7): - """ Returns the intersection over box2 area given box1, box2. Boxes are x1y1x2y2 - box1: np.array of shape(4) - box2: np.array of shape(nx4) - returns: np.array of shape(n) - """ - - box2 = box2.transpose() - - # Get the coordinates of bounding boxes - b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3] - b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3] - - # Intersection area - inter_area = (np.minimum(b1_x2, b2_x2) - np.maximum(b1_x1, b2_x1)).clip(0) * \ - (np.minimum(b1_y2, b2_y2) - np.maximum(b1_y1, b2_y1)).clip(0) - - # box2 area - box2_area = (b2_x2 - b2_x1) * (b2_y2 - b2_y1) + eps - - # Intersection over box2 area - return inter_area / box2_area - - -def wh_iou(wh1, wh2): - # Returns the nxm IoU matrix. wh1 is nx2, wh2 is mx2 - wh1 = wh1[:, None] # [N,1,2] - wh2 = wh2[None] # [1,M,2] - inter = torch.min(wh1, wh2).prod(2) # [N,M] - return inter / (wh1.prod(2) + wh2.prod(2) - inter) # iou = inter / (area1 + area2 - inter) - - -# Plots ---------------------------------------------------------------------------------------------------------------- - -def plot_pr_curve(px, py, ap, save_dir='pr_curve.png', names=()): - # Precision-recall curve - fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True) - py = np.stack(py, axis=1) - - if 0 < len(names) < 21: # display per-class legend if < 21 classes - for i, y in enumerate(py.T): - ax.plot(px, y, linewidth=1, label=f'{names[i]} {ap[i, 0]:.3f}') # plot(recall, precision) - else: - ax.plot(px, py, linewidth=1, color='grey') # plot(recall, precision) - - ax.plot(px, py.mean(1), linewidth=3, color='blue', label='all classes %.3f mAP@0.5' % ap[:, 0].mean()) - ax.set_xlabel('Recall') - ax.set_ylabel('Precision') - ax.set_xlim(0, 1) - ax.set_ylim(0, 1) - plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left") - fig.savefig(Path(save_dir), dpi=250) - plt.close() - - -def plot_mc_curve(px, py, save_dir='mc_curve.png', names=(), xlabel='Confidence', ylabel='Metric'): - # Metric-confidence curve - fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True) - - if 0 < len(names) < 21: # display per-class legend if < 21 classes - for i, y in enumerate(py): - ax.plot(px, y, linewidth=1, label=f'{names[i]}') # plot(confidence, metric) - else: - ax.plot(px, py.T, linewidth=1, color='grey') # plot(confidence, metric) - - y = py.mean(0) - ax.plot(px, y, linewidth=3, color='blue', label=f'all classes {y.max():.2f} at {px[y.argmax()]:.3f}') - ax.set_xlabel(xlabel) - ax.set_ylabel(ylabel) - ax.set_xlim(0, 1) - ax.set_ylim(0, 1) - plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left") - fig.savefig(Path(save_dir), dpi=250) - plt.close() diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/plots.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/plots.py deleted file mode 100755 index 6df0efd4a..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/plots.py +++ /dev/null @@ -1,470 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -Plotting utils -""" - -import math -import os -from copy import copy -from pathlib import Path - -import cv2 -import matplotlib -import matplotlib.pyplot as plt -import numpy as np -import pandas as pd -import seaborn as sn -import torch -from PIL import Image, ImageDraw, ImageFont - -from .general import (LOGGER, Timeout, check_requirements, clip_coords, increment_path, is_ascii, is_chinese, - try_except, user_config_dir, xywh2xyxy, xyxy2xywh) -from .metrics import fitness - -# Settings -CONFIG_DIR = user_config_dir() # Ultralytics settings dir -RANK = int(os.getenv('RANK', -1)) -matplotlib.rc('font', **{'size': 11}) -matplotlib.use('Agg') # for writing to files only - - -class Colors: - # Ultralytics color palette https://ultralytics.com/ - def __init__(self): - # hex = matplotlib.colors.TABLEAU_COLORS.values() - hex = ('FF3838', 'FF9D97', 'FF701F', 'FFB21D', 'CFD231', '48F90A', '92CC17', '3DDB86', '1A9334', '00D4BB', - '2C99A8', '00C2FF', '344593', '6473FF', '0018EC', '8438FF', '520085', 'CB38FF', 'FF95C8', 'FF37C7') - self.palette = [self.hex2rgb('#' + c) for c in hex] - self.n = len(self.palette) - - def __call__(self, i, bgr=False): - c = self.palette[int(i) % self.n] - return (c[2], c[1], c[0]) if bgr else c - - @staticmethod - def hex2rgb(h): # rgb order (PIL) - return tuple(int(h[1 + i:1 + i + 2], 16) for i in (0, 2, 4)) - - -colors = Colors() # create instance for 'from utils.plots import colors' - - -def check_font(font='Arial.ttf', size=10): - # Return a PIL TrueType Font, downloading to CONFIG_DIR if necessary - font = Path(font) - font = font if font.exists() else (CONFIG_DIR / font.name) - try: - return ImageFont.truetype(str(font) if font.exists() else font.name, size) - except Exception as e: # download if missing - url = "https://ultralytics.com/assets/" + font.name - print(f'Downloading {url} to {font}...') - torch.hub.download_url_to_file(url, str(font), progress=False) - try: - return ImageFont.truetype(str(font), size) - except TypeError: - check_requirements('Pillow>=8.4.0') # known issue https://github.com/ultralytics/yolov5/issues/5374 - - -class Annotator: - if RANK in (-1, 0): - check_font() # download TTF if necessary - - # YOLOv5 Annotator for train/val mosaics and jpgs and detect/hub inference annotations - def __init__(self, im, line_width=None, font_size=None, font='Arial.ttf', pil=False, example='abc'): - assert im.data.contiguous, 'Image not contiguous. Apply np.ascontiguousarray(im) to Annotator() input images.' - self.pil = pil or not is_ascii(example) or is_chinese(example) - if self.pil: # use PIL - self.im = im if isinstance(im, Image.Image) else Image.fromarray(im) - self.draw = ImageDraw.Draw(self.im) - self.font = check_font(font='Arial.Unicode.ttf' if is_chinese(example) else font, - size=font_size or max(round(sum(self.im.size) / 2 * 0.035), 12)) - else: # use cv2 - self.im = im - self.lw = line_width or max(round(sum(im.shape) / 2 * 0.003), 2) # line width - - def box_label(self, box, label='', color=(128, 128, 128), txt_color=(255, 255, 255)): - # Add one xyxy box to image with label - if self.pil or not is_ascii(label): - self.draw.rectangle(box, width=self.lw, outline=color) # box - if label: - w, h = self.font.getsize(label) # text width, height - outside = box[1] - h >= 0 # label fits outside box - self.draw.rectangle([box[0], - box[1] - h if outside else box[1], - box[0] + w + 1, - box[1] + 1 if outside else box[1] + h + 1], fill=color) - # self.draw.text((box[0], box[1]), label, fill=txt_color, font=self.font, anchor='ls') # for PIL>8.0 - self.draw.text((box[0], box[1] - h if outside else box[1]), label, fill=txt_color, font=self.font) - else: # cv2 - p1, p2 = (int(box[0]), int(box[1])), (int(box[2]), int(box[3])) - cv2.rectangle(self.im, p1, p2, color, thickness=self.lw, lineType=cv2.LINE_AA) - if label: - tf = max(self.lw - 1, 1) # font thickness - w, h = cv2.getTextSize(label, 0, fontScale=self.lw / 3, thickness=tf)[0] # text width, height - outside = p1[1] - h - 3 >= 0 # label fits outside box - p2 = p1[0] + w, p1[1] - h - 3 if outside else p1[1] + h + 3 - cv2.rectangle(self.im, p1, p2, color, -1, cv2.LINE_AA) # filled - cv2.putText(self.im, label, (p1[0], p1[1] - 2 if outside else p1[1] + h + 2), 0, self.lw / 3, txt_color, - thickness=tf, lineType=cv2.LINE_AA) - - def rectangle(self, xy, fill=None, outline=None, width=1): - # Add rectangle to image (PIL-only) - self.draw.rectangle(xy, fill, outline, width) - - def text(self, xy, text, txt_color=(255, 255, 255)): - # Add text to image (PIL-only) - w, h = self.font.getsize(text) # text width, height - self.draw.text((xy[0], xy[1] - h + 1), text, fill=txt_color, font=self.font) - - def result(self): - # Return annotated image as array - return np.asarray(self.im) - - -def feature_visualization(x, module_type, stage, n=32, save_dir=Path('runs/detect/exp')): - """ - x: Features to be visualized - module_type: Module type - stage: Module stage within model - n: Maximum number of feature maps to plot - save_dir: Directory to save results - """ - if 'Detect' not in module_type: - batch, channels, height, width = x.shape # batch, channels, height, width - if height > 1 and width > 1: - f = save_dir / f"stage{stage}_{module_type.split('.')[-1]}_features.png" # filename - - blocks = torch.chunk(x[0].cpu(), channels, dim=0) # select batch index 0, block by channels - n = min(n, channels) # number of plots - fig, ax = plt.subplots(math.ceil(n / 8), 8, tight_layout=True) # 8 rows x n/8 cols - ax = ax.ravel() - plt.subplots_adjust(wspace=0.05, hspace=0.05) - for i in range(n): - ax[i].imshow(blocks[i].squeeze()) # cmap='gray' - ax[i].axis('off') - - print(f'Saving {f}... ({n}/{channels})') - plt.savefig(f, dpi=300, bbox_inches='tight') - plt.close() - np.save(str(f.with_suffix('.npy')), x[0].cpu().numpy()) # npy save - - -def hist2d(x, y, n=100): - # 2d histogram used in labels.png and evolve.png - xedges, yedges = np.linspace(x.min(), x.max(), n), np.linspace(y.min(), y.max(), n) - hist, xedges, yedges = np.histogram2d(x, y, (xedges, yedges)) - xidx = np.clip(np.digitize(x, xedges) - 1, 0, hist.shape[0] - 1) - yidx = np.clip(np.digitize(y, yedges) - 1, 0, hist.shape[1] - 1) - return np.log(hist[xidx, yidx]) - - -def butter_lowpass_filtfilt(data, cutoff=1500, fs=50000, order=5): - from scipy.signal import butter, filtfilt - - # https://stackoverflow.com/questions/28536191/how-to-filter-smooth-with-scipy-numpy - def butter_lowpass(cutoff, fs, order): - nyq = 0.5 * fs - normal_cutoff = cutoff / nyq - return butter(order, normal_cutoff, btype='low', analog=False) - - b, a = butter_lowpass(cutoff, fs, order=order) - return filtfilt(b, a, data) # forward-backward filter - - -def output_to_target(output): - # Convert model output to target format [batch_id, class_id, x, y, w, h, conf] - targets = [] - for i, o in enumerate(output): - for *box, conf, cls in o.cpu().numpy(): - targets.append([i, cls, *list(*xyxy2xywh(np.array(box)[None])), conf]) - return np.array(targets) - - -def plot_images(images, targets, paths=None, fname='images.jpg', names=None, max_size=1920, max_subplots=16): - # Plot image grid with labels - if isinstance(images, torch.Tensor): - images = images.cpu().float().numpy() - if isinstance(targets, torch.Tensor): - targets = targets.cpu().numpy() - if np.max(images[0]) <= 1: - images *= 255 # de-normalise (optional) - bs, _, h, w = images.shape # batch size, _, height, width - bs = min(bs, max_subplots) # limit plot images - ns = np.ceil(bs ** 0.5) # number of subplots (square) - - # Build Image - mosaic = np.full((int(ns * h), int(ns * w), 3), 255, dtype=np.uint8) # init - for i, im in enumerate(images): - if i == max_subplots: # if last batch has fewer images than we expect - break - x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin - im = im.transpose(1, 2, 0) - mosaic[y:y + h, x:x + w, :] = im - - # Resize (optional) - scale = max_size / ns / max(h, w) - if scale < 1: - h = math.ceil(scale * h) - w = math.ceil(scale * w) - mosaic = cv2.resize(mosaic, tuple(int(x * ns) for x in (w, h))) - - # Annotate - fs = int((h + w) * ns * 0.01) # font size - annotator = Annotator(mosaic, line_width=round(fs / 10), font_size=fs, pil=True) - for i in range(i + 1): - x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin - annotator.rectangle([x, y, x + w, y + h], None, (255, 255, 255), width=2) # borders - if paths: - annotator.text((x + 5, y + 5 + h), text=Path(paths[i]).name[:40], txt_color=(220, 220, 220)) # filenames - if len(targets) > 0: - ti = targets[targets[:, 0] == i] # image targets - boxes = xywh2xyxy(ti[:, 2:6]).T - classes = ti[:, 1].astype('int') - labels = ti.shape[1] == 6 # labels if no conf column - conf = None if labels else ti[:, 6] # check for confidence presence (label vs pred) - - if boxes.shape[1]: - if boxes.max() <= 1.01: # if normalized with tolerance 0.01 - boxes[[0, 2]] *= w # scale to pixels - boxes[[1, 3]] *= h - elif scale < 1: # absolute coords need scale if image scales - boxes *= scale - boxes[[0, 2]] += x - boxes[[1, 3]] += y - for j, box in enumerate(boxes.T.tolist()): - cls = classes[j] - color = colors(cls) - cls = names[cls] if names else cls - if labels or conf[j] > 0.25: # 0.25 conf thresh - label = f'{cls}' if labels else f'{cls} {conf[j]:.1f}' - annotator.box_label(box, label, color=color) - annotator.im.save(fname) # save - - -def plot_lr_scheduler(optimizer, scheduler, epochs=300, save_dir=''): - # Plot LR simulating training for full epochs - optimizer, scheduler = copy(optimizer), copy(scheduler) # do not modify originals - y = [] - for _ in range(epochs): - scheduler.step() - y.append(optimizer.param_groups[0]['lr']) - plt.plot(y, '.-', label='LR') - plt.xlabel('epoch') - plt.ylabel('LR') - plt.grid() - plt.xlim(0, epochs) - plt.ylim(0) - plt.savefig(Path(save_dir) / 'LR.png', dpi=200) - plt.close() - - -def plot_val_txt(): # from utils.plots import *; plot_val() - # Plot val.txt histograms - x = np.loadtxt('val.txt', dtype=np.float32) - box = xyxy2xywh(x[:, :4]) - cx, cy = box[:, 0], box[:, 1] - - fig, ax = plt.subplots(1, 1, figsize=(6, 6), tight_layout=True) - ax.hist2d(cx, cy, bins=600, cmax=10, cmin=0) - ax.set_aspect('equal') - plt.savefig('hist2d.png', dpi=300) - - fig, ax = plt.subplots(1, 2, figsize=(12, 6), tight_layout=True) - ax[0].hist(cx, bins=600) - ax[1].hist(cy, bins=600) - plt.savefig('hist1d.png', dpi=200) - - -def plot_targets_txt(): # from utils.plots import *; plot_targets_txt() - # Plot targets.txt histograms - x = np.loadtxt('targets.txt', dtype=np.float32).T - s = ['x targets', 'y targets', 'width targets', 'height targets'] - fig, ax = plt.subplots(2, 2, figsize=(8, 8), tight_layout=True) - ax = ax.ravel() - for i in range(4): - ax[i].hist(x[i], bins=100, label=f'{x[i].mean():.3g} +/- {x[i].std():.3g}') - ax[i].legend() - ax[i].set_title(s[i]) - plt.savefig('targets.jpg', dpi=200) - - -def plot_val_study(file='', dir='', x=None): # from utils.plots import *; plot_val_study() - # Plot file=study.txt generated by val.py (or plot all study*.txt in dir) - save_dir = Path(file).parent if file else Path(dir) - plot2 = False # plot additional results - if plot2: - ax = plt.subplots(2, 4, figsize=(10, 6), tight_layout=True)[1].ravel() - - fig2, ax2 = plt.subplots(1, 1, figsize=(8, 4), tight_layout=True) - # for f in [save_dir / f'study_coco_{x}.txt' for x in ['yolov5n6', 'yolov5s6', 'yolov5m6', 'yolov5l6', 'yolov5x6']]: - for f in sorted(save_dir.glob('study*.txt')): - y = np.loadtxt(f, dtype=np.float32, usecols=[0, 1, 2, 3, 7, 8, 9], ndmin=2).T - x = np.arange(y.shape[1]) if x is None else np.array(x) - if plot2: - s = ['P', 'R', 'mAP@.5', 'mAP@.5:.95', 't_preprocess (ms/img)', 't_inference (ms/img)', 't_NMS (ms/img)'] - for i in range(7): - ax[i].plot(x, y[i], '.-', linewidth=2, markersize=8) - ax[i].set_title(s[i]) - - j = y[3].argmax() + 1 - ax2.plot(y[5, 1:j], y[3, 1:j] * 1E2, '.-', linewidth=2, markersize=8, - label=f.stem.replace('study_coco_', '').replace('yolo', 'YOLO')) - - ax2.plot(1E3 / np.array([209, 140, 97, 58, 35, 18]), [34.6, 40.5, 43.0, 47.5, 49.7, 51.5], - 'k.-', linewidth=2, markersize=8, alpha=.25, label='EfficientDet') - - ax2.grid(alpha=0.2) - ax2.set_yticks(np.arange(20, 60, 5)) - ax2.set_xlim(0, 57) - ax2.set_ylim(25, 55) - ax2.set_xlabel('GPU Speed (ms/img)') - ax2.set_ylabel('COCO AP val') - ax2.legend(loc='lower right') - f = save_dir / 'study.png' - print(f'Saving {f}...') - plt.savefig(f, dpi=300) - - -@try_except # known issue https://github.com/ultralytics/yolov5/issues/5395 -@Timeout(30) # known issue https://github.com/ultralytics/yolov5/issues/5611 -def plot_labels(labels, names=(), save_dir=Path('')): - # plot dataset labels - LOGGER.info(f"Plotting labels to {save_dir / 'labels.jpg'}... ") - c, b = labels[:, 0], labels[:, 1:].transpose() # classes, boxes - nc = int(c.max() + 1) # number of classes - x = pd.DataFrame(b.transpose(), columns=['x', 'y', 'width', 'height']) - - # seaborn correlogram - sn.pairplot(x, corner=True, diag_kind='auto', kind='hist', diag_kws=dict(bins=50), plot_kws=dict(pmax=0.9)) - plt.savefig(save_dir / 'labels_correlogram.jpg', dpi=200) - plt.close() - - # matplotlib labels - matplotlib.use('svg') # faster - ax = plt.subplots(2, 2, figsize=(8, 8), tight_layout=True)[1].ravel() - y = ax[0].hist(c, bins=np.linspace(0, nc, nc + 1) - 0.5, rwidth=0.8) - # [y[2].patches[i].set_color([x / 255 for x in colors(i)]) for i in range(nc)] # update colors bug #3195 - ax[0].set_ylabel('instances') - if 0 < len(names) < 30: - ax[0].set_xticks(range(len(names))) - ax[0].set_xticklabels(names, rotation=90, fontsize=10) - else: - ax[0].set_xlabel('classes') - sn.histplot(x, x='x', y='y', ax=ax[2], bins=50, pmax=0.9) - sn.histplot(x, x='width', y='height', ax=ax[3], bins=50, pmax=0.9) - - # rectangles - labels[:, 1:3] = 0.5 # center - labels[:, 1:] = xywh2xyxy(labels[:, 1:]) * 2000 - img = Image.fromarray(np.ones((2000, 2000, 3), dtype=np.uint8) * 255) - for cls, *box in labels[:1000]: - ImageDraw.Draw(img).rectangle(box, width=1, outline=colors(cls)) # plot - ax[1].imshow(img) - ax[1].axis('off') - - for a in [0, 1, 2, 3]: - for s in ['top', 'right', 'left', 'bottom']: - ax[a].spines[s].set_visible(False) - - plt.savefig(save_dir / 'labels.jpg', dpi=200) - matplotlib.use('Agg') - plt.close() - - -def plot_evolve(evolve_csv='path/to/evolve.csv'): # from utils.plots import *; plot_evolve() - # Plot evolve.csv hyp evolution results - evolve_csv = Path(evolve_csv) - data = pd.read_csv(evolve_csv) - keys = [x.strip() for x in data.columns] - x = data.values - f = fitness(x) - j = np.argmax(f) # max fitness index - plt.figure(figsize=(10, 12), tight_layout=True) - matplotlib.rc('font', **{'size': 8}) - for i, k in enumerate(keys[7:]): - v = x[:, 7 + i] - mu = v[j] # best single result - plt.subplot(6, 5, i + 1) - plt.scatter(v, f, c=hist2d(v, f, 20), cmap='viridis', alpha=.8, edgecolors='none') - plt.plot(mu, f.max(), 'k+', markersize=15) - plt.title(f'{k} = {mu:.3g}', fontdict={'size': 9}) # limit to 40 characters - if i % 5 != 0: - plt.yticks([]) - print(f'{k:>15}: {mu:.3g}') - f = evolve_csv.with_suffix('.png') # filename - plt.savefig(f, dpi=200) - plt.close() - print(f'Saved {f}') - - -def plot_results(file='path/to/results.csv', dir=''): - # Plot training results.csv. Usage: from utils.plots import *; plot_results('path/to/results.csv') - save_dir = Path(file).parent if file else Path(dir) - fig, ax = plt.subplots(2, 5, figsize=(12, 6), tight_layout=True) - ax = ax.ravel() - files = list(save_dir.glob('results*.csv')) - assert len(files), f'No results.csv files found in {save_dir.resolve()}, nothing to plot.' - for fi, f in enumerate(files): - try: - data = pd.read_csv(f) - s = [x.strip() for x in data.columns] - x = data.values[:, 0] - for i, j in enumerate([1, 2, 3, 4, 5, 8, 9, 10, 6, 7]): - y = data.values[:, j] - # y[y == 0] = np.nan # don't show zero values - ax[i].plot(x, y, marker='.', label=f.stem, linewidth=2, markersize=8) - ax[i].set_title(s[j], fontsize=12) - # if j in [8, 9, 10]: # share train and val loss y axes - # ax[i].get_shared_y_axes().join(ax[i], ax[i - 5]) - except Exception as e: - print(f'Warning: Plotting error for {f}: {e}') - ax[1].legend() - fig.savefig(save_dir / 'results.png', dpi=200) - plt.close() - - -def profile_idetection(start=0, stop=0, labels=(), save_dir=''): - # Plot iDetection '*.txt' per-image logs. from utils.plots import *; profile_idetection() - ax = plt.subplots(2, 4, figsize=(12, 6), tight_layout=True)[1].ravel() - s = ['Images', 'Free Storage (GB)', 'RAM Usage (GB)', 'Battery', 'dt_raw (ms)', 'dt_smooth (ms)', 'real-world FPS'] - files = list(Path(save_dir).glob('frames*.txt')) - for fi, f in enumerate(files): - try: - results = np.loadtxt(f, ndmin=2).T[:, 90:-30] # clip first and last rows - n = results.shape[1] # number of rows - x = np.arange(start, min(stop, n) if stop else n) - results = results[:, x] - t = (results[0] - results[0].min()) # set t0=0s - results[0] = x - for i, a in enumerate(ax): - if i < len(results): - label = labels[fi] if len(labels) else f.stem.replace('frames_', '') - a.plot(t, results[i], marker='.', label=label, linewidth=1, markersize=5) - a.set_title(s[i]) - a.set_xlabel('time (s)') - # if fi == len(files) - 1: - # a.set_ylim(bottom=0) - for side in ['top', 'right']: - a.spines[side].set_visible(False) - else: - a.remove() - except Exception as e: - print(f'Warning: Plotting error for {f}; {e}') - ax[1].legend() - plt.savefig(Path(save_dir) / 'idetection_profile.png', dpi=200) - - -def save_one_box(xyxy, im, file='image.jpg', gain=1.02, pad=10, square=False, BGR=False, save=True): - # Save image crop as {file} with crop size multiple {gain} and {pad} pixels. Save and/or return crop - xyxy = torch.tensor(xyxy).view(-1, 4) - b = xyxy2xywh(xyxy) # boxes - if square: - b[:, 2:] = b[:, 2:].max(1)[0].unsqueeze(1) # attempt rectangle to square - b[:, 2:] = b[:, 2:] * gain + pad # box wh * gain + pad - xyxy = xywh2xyxy(b).long() - clip_coords(xyxy, im.shape) - crop = im[int(xyxy[0, 1]):int(xyxy[0, 3]), int(xyxy[0, 0]):int(xyxy[0, 2]), ::(1 if BGR else -1)] - if save: - file.parent.mkdir(parents=True, exist_ok=True) # make directory - cv2.imwrite(str(increment_path(file).with_suffix('.jpg')), crop) - return crop diff --git a/cv/pose/alphapose/pytorch/detector/yolov5/utils/torch_utils.py b/cv/pose/alphapose/pytorch/detector/yolov5/utils/torch_utils.py deleted file mode 100755 index e61830e3c..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5/utils/torch_utils.py +++ /dev/null @@ -1,318 +0,0 @@ -# YOLOv5 🚀 by Ultralytics, GPL-3.0 license -""" -PyTorch utils -""" - -import datetime -import math -import os -import platform -import subprocess -import time -from contextlib import contextmanager -from copy import deepcopy -from pathlib import Path - -import torch -import torch.distributed as dist -import torch.nn as nn -import torch.nn.functional as F - -from .general import LOGGER - -try: - import thop # for FLOPs computation -except ImportError: - thop = None - - -@contextmanager -def torch_distributed_zero_first(local_rank: int): - """ - Decorator to make all processes in distributed training wait for each local_master to do something. - """ - if local_rank not in [-1, 0]: - dist.barrier(device_ids=[local_rank]) - yield - if local_rank == 0: - dist.barrier(device_ids=[0]) - - -def date_modified(path=__file__): - # return human-readable file modification date, i.e. '2021-3-26' - t = datetime.datetime.fromtimestamp(Path(path).stat().st_mtime) - return f'{t.year}-{t.month}-{t.day}' - - -def git_describe(path=Path(__file__).parent): # path must be a directory - # return human-readable git description, i.e. v5.0-5-g3e25f1e https://git-scm.com/docs/git-describe - s = f'git -C {path} describe --tags --long --always' - try: - return subprocess.check_output(s, shell=True, stderr=subprocess.STDOUT).decode()[:-1] - except subprocess.CalledProcessError as e: - return '' # not a git repository - - -def select_device(device='', batch_size=0, newline=True): - # device = 'cpu' or '0' or '0,1,2,3' - s = f'YOLOv5 🚀 {git_describe() or date_modified()} torch {torch.__version__} ' # string - device = str(device).strip().lower().replace('cuda:', '') # to string, 'cuda:0' to '0' - cpu = device == 'cpu' - if cpu: - os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # force torch.cuda.is_available() = False - elif device: # non-cpu device requested - os.environ['CUDA_VISIBLE_DEVICES'] = device # set environment variable - assert torch.cuda.is_available(), f'CUDA unavailable, invalid device {device} requested' # check availability - - cuda = not cpu and torch.cuda.is_available() - if cuda: - devices = device.split(',') if device else '0' # range(torch.cuda.device_count()) # i.e. 0,1,6,7 - n = len(devices) # device count - if n > 1 and batch_size > 0: # check batch_size is divisible by device_count - assert batch_size % n == 0, f'batch-size {batch_size} not multiple of GPU count {n}' - space = ' ' * (len(s) + 1) - for i, d in enumerate(devices): - p = torch.cuda.get_device_properties(i) - s += f"{'' if i == 0 else space}CUDA:{d} ({p.name}, {p.total_memory / 1024 ** 2:.0f}MiB)\n" # bytes to MB - else: - s += 'CPU\n' - - if not newline: - s = s.rstrip() - LOGGER.info(s.encode().decode('ascii', 'ignore') if platform.system() == 'Windows' else s) # emoji-safe - return torch.device('cuda:0' if cuda else 'cpu') - - -def time_sync(): - # pytorch-accurate time - if torch.cuda.is_available(): - torch.cuda.synchronize() - return time.time() - - -def profile(input, ops, n=10, device=None): - # YOLOv5 speed/memory/FLOPs profiler - # - # Usage: - # input = torch.randn(16, 3, 640, 640) - # m1 = lambda x: x * torch.sigmoid(x) - # m2 = nn.SiLU() - # profile(input, [m1, m2], n=100) # profile over 100 iterations - - results = [] - device = device or select_device() - print(f"{'Params':>12s}{'GFLOPs':>12s}{'GPU_mem (GB)':>14s}{'forward (ms)':>14s}{'backward (ms)':>14s}" - f"{'input':>24s}{'output':>24s}") - - for x in input if isinstance(input, list) else [input]: - x = x.to(device) - x.requires_grad = True - for m in ops if isinstance(ops, list) else [ops]: - m = m.to(device) if hasattr(m, 'to') else m # device - m = m.half() if hasattr(m, 'half') and isinstance(x, torch.Tensor) and x.dtype is torch.float16 else m - tf, tb, t = 0, 0, [0, 0, 0] # dt forward, backward - try: - flops = thop.profile(m, inputs=(x,), verbose=False)[0] / 1E9 * 2 # GFLOPs - except: - flops = 0 - - try: - for _ in range(n): - t[0] = time_sync() - y = m(x) - t[1] = time_sync() - try: - _ = (sum(yi.sum() for yi in y) if isinstance(y, list) else y).sum().backward() - t[2] = time_sync() - except Exception as e: # no backward method - # print(e) # for debug - t[2] = float('nan') - tf += (t[1] - t[0]) * 1000 / n # ms per op forward - tb += (t[2] - t[1]) * 1000 / n # ms per op backward - mem = torch.cuda.memory_reserved() / 1E9 if torch.cuda.is_available() else 0 # (GB) - s_in = tuple(x.shape) if isinstance(x, torch.Tensor) else 'list' - s_out = tuple(y.shape) if isinstance(y, torch.Tensor) else 'list' - p = sum(list(x.numel() for x in m.parameters())) if isinstance(m, nn.Module) else 0 # parameters - print(f'{p:12}{flops:12.4g}{mem:>14.3f}{tf:14.4g}{tb:14.4g}{str(s_in):>24s}{str(s_out):>24s}') - results.append([p, flops, mem, tf, tb, s_in, s_out]) - except Exception as e: - print(e) - results.append(None) - torch.cuda.empty_cache() - return results - - -def is_parallel(model): - # Returns True if model is of type DP or DDP - return type(model) in (nn.parallel.DataParallel, nn.parallel.DistributedDataParallel) - - -def de_parallel(model): - # De-parallelize a model: returns single-GPU model if model is of type DP or DDP - return model.module if is_parallel(model) else model - - -def initialize_weights(model): - for m in model.modules(): - t = type(m) - if t is nn.Conv2d: - pass # nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') - elif t is nn.BatchNorm2d: - m.eps = 1e-3 - m.momentum = 0.03 - elif t in [nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU]: - m.inplace = True - - -def find_modules(model, mclass=nn.Conv2d): - # Finds layer indices matching module class 'mclass' - return [i for i, m in enumerate(model.module_list) if isinstance(m, mclass)] - - -def sparsity(model): - # Return global model sparsity - a, b = 0, 0 - for p in model.parameters(): - a += p.numel() - b += (p == 0).sum() - return b / a - - -def prune(model, amount=0.3): - # Prune model to requested global sparsity - import torch.nn.utils.prune as prune - print('Pruning model... ', end='') - for name, m in model.named_modules(): - if isinstance(m, nn.Conv2d): - prune.l1_unstructured(m, name='weight', amount=amount) # prune - prune.remove(m, 'weight') # make permanent - print(' %.3g global sparsity' % sparsity(model)) - - -def fuse_conv_and_bn(conv, bn): - # Fuse convolution and batchnorm layers https://tehnokv.com/posts/fusing-batchnorm-and-conv/ - fusedconv = nn.Conv2d(conv.in_channels, - conv.out_channels, - kernel_size=conv.kernel_size, - stride=conv.stride, - padding=conv.padding, - groups=conv.groups, - bias=True).requires_grad_(False).to(conv.weight.device) - - # prepare filters - w_conv = conv.weight.clone().view(conv.out_channels, -1) - w_bn = torch.diag(bn.weight.div(torch.sqrt(bn.eps + bn.running_var))) - fusedconv.weight.copy_(torch.mm(w_bn, w_conv).view(fusedconv.weight.shape)) - - # prepare spatial bias - b_conv = torch.zeros(conv.weight.size(0), device=conv.weight.device) if conv.bias is None else conv.bias - b_bn = bn.bias - bn.weight.mul(bn.running_mean).div(torch.sqrt(bn.running_var + bn.eps)) - fusedconv.bias.copy_(torch.mm(w_bn, b_conv.reshape(-1, 1)).reshape(-1) + b_bn) - - return fusedconv - - -def model_info(model, verbose=False, img_size=640): - # Model information. img_size may be int or list, i.e. img_size=640 or img_size=[640, 320] - n_p = sum(x.numel() for x in model.parameters()) # number parameters - n_g = sum(x.numel() for x in model.parameters() if x.requires_grad) # number gradients - if verbose: - print(f"{'layer':>5} {'name':>40} {'gradient':>9} {'parameters':>12} {'shape':>20} {'mu':>10} {'sigma':>10}") - for i, (name, p) in enumerate(model.named_parameters()): - name = name.replace('module_list.', '') - print('%5g %40s %9s %12g %20s %10.3g %10.3g' % - (i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std())) - - try: # FLOPs - from thop import profile - stride = max(int(model.stride.max()), 32) if hasattr(model, 'stride') else 32 - img = torch.zeros((1, model.yaml.get('ch', 3), stride, stride), device=next(model.parameters()).device) # input - flops = profile(deepcopy(model), inputs=(img,), verbose=False)[0] / 1E9 * 2 # stride GFLOPs - img_size = img_size if isinstance(img_size, list) else [img_size, img_size] # expand if int/float - fs = ', %.1f GFLOPs' % (flops * img_size[0] / stride * img_size[1] / stride) # 640x640 GFLOPs - except (ImportError, Exception): - fs = '' - - LOGGER.info(f"Model Summary: {len(list(model.modules()))} layers, {n_p} parameters, {n_g} gradients{fs}") - - -def scale_img(img, ratio=1.0, same_shape=False, gs=32): # img(16,3,256,416) - # scales img(bs,3,y,x) by ratio constrained to gs-multiple - if ratio == 1.0: - return img - else: - h, w = img.shape[2:] - s = (int(h * ratio), int(w * ratio)) # new size - img = F.interpolate(img, size=s, mode='bilinear', align_corners=False) # resize - if not same_shape: # pad/crop img - h, w = (math.ceil(x * ratio / gs) * gs for x in (h, w)) - return F.pad(img, [0, w - s[1], 0, h - s[0]], value=0.447) # value = imagenet mean - - -def copy_attr(a, b, include=(), exclude=()): - # Copy attributes from b to a, options to only include [...] and to exclude [...] - for k, v in b.__dict__.items(): - if (len(include) and k not in include) or k.startswith('_') or k in exclude: - continue - else: - setattr(a, k, v) - - -class EarlyStopping: - # YOLOv5 simple early stopper - def __init__(self, patience=30): - self.best_fitness = 0.0 # i.e. mAP - self.best_epoch = 0 - self.patience = patience or float('inf') # epochs to wait after fitness stops improving to stop - self.possible_stop = False # possible stop may occur next epoch - - def __call__(self, epoch, fitness): - if fitness >= self.best_fitness: # >= 0 to allow for early zero-fitness stage of training - self.best_epoch = epoch - self.best_fitness = fitness - delta = epoch - self.best_epoch # epochs without improvement - self.possible_stop = delta >= (self.patience - 1) # possible stop may occur next epoch - stop = delta >= self.patience # stop training if patience exceeded - if stop: - LOGGER.info(f'Stopping training early as no improvement observed in last {self.patience} epochs. ' - f'Best results observed at epoch {self.best_epoch}, best model saved as best.pt.\n' - f'To update EarlyStopping(patience={self.patience}) pass a new patience value, ' - f'i.e. `python train.py --patience 300` or use `--patience 0` to disable EarlyStopping.') - return stop - - -class ModelEMA: - """ Model Exponential Moving Average from https://github.com/rwightman/pytorch-image-models - Keep a moving average of everything in the model state_dict (parameters and buffers). - This is intended to allow functionality like - https://www.tensorflow.org/api_docs/python/tf/train/ExponentialMovingAverage - A smoothed version of the weights is necessary for some training schemes to perform well. - This class is sensitive where it is initialized in the sequence of model init, - GPU assignment and distributed training wrappers. - """ - - def __init__(self, model, decay=0.9999, updates=0): - # Create EMA - self.ema = deepcopy(model.module if is_parallel(model) else model).eval() # FP32 EMA - # if next(model.parameters()).device.type != 'cpu': - # self.ema.half() # FP16 EMA - self.updates = updates # number of EMA updates - self.decay = lambda x: decay * (1 - math.exp(-x / 2000)) # decay exponential ramp (to help early epochs) - for p in self.ema.parameters(): - p.requires_grad_(False) - - def update(self, model): - # Update EMA parameters - with torch.no_grad(): - self.updates += 1 - d = self.decay(self.updates) - - msd = model.module.state_dict() if is_parallel(model) else model.state_dict() # model state_dict - for k, v in self.ema.state_dict().items(): - if v.dtype.is_floating_point: - v *= d - v += (1 - d) * msd[k].detach() - - def update_attr(self, model, include=(), exclude=('process_group', 'reducer')): - # Update EMA attributes - copy_attr(self.ema, model, include, exclude) diff --git a/cv/pose/alphapose/pytorch/detector/yolov5_api.py b/cv/pose/alphapose/pytorch/detector/yolov5_api.py deleted file mode 100755 index febe9d73b..000000000 --- a/cv/pose/alphapose/pytorch/detector/yolov5_api.py +++ /dev/null @@ -1,326 +0,0 @@ -# ----------------------------------------------------- -# Copyright (c) Shanghai Jiao Tong University. All rights reserved. -# Written by Chao Xu (xuchao.19962007@sjtu.edu.cn) -# ----------------------------------------------------- -# Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -"""API of yolo detector""" -import os -import sys -sys.path.insert(0, os.path.dirname(__file__)) -from abc import ABC, abstractmethod -import platform - -import torch -import numpy as np - -from yolo.preprocess import prep_image, prep_frame -from yolo.darknet import Darknet -from yolo.util import unique -from yolo.bbox import bbox_iou - -from detector.apis import BaseDetector - -#only windows visual studio 2013 ~2017 support compile c/cuda extensions -#If you force to compile extension on Windows and ensure appropriate visual studio -#is intalled, you can try to use these ext_modules. -# if platform.system() != 'Windows': -# from detector.nms import nms_wrapper - -from detector.nms import nms -from yolov5.utils.general import non_max_suppression - -class YOLODetector(BaseDetector): - def __init__(self, cfg, opt=None): - super(YOLODetector, self).__init__() - - self.detector_cfg = cfg - self.detector_opt = opt - self.model_cfg = cfg.get('CONFIG', 'detector/yolo/cfg/yolov3-spp.cfg') - self.model_weights = cfg.get('WEIGHTS', 'detector/yolo/data/yolov3-spp.weights') - # self.inp_dim = cfg.get('INP_DIM', 608) - # self.inp_dim = cfg.get('INP_DIM', 640) - self.inp_dim = 640 - self.nms_thres = cfg.get('NMS_THRES', 0.6) - self.confidence = 0.3 if (False if not hasattr(opt, 'tracking') else opt.tracking) else cfg.get('CONFIDENCE', 0.05) - self.num_classes = cfg.get('NUM_CLASSES', 80) - self.model = None - - def load_model(self): - args = self.detector_opt - - print('Loading YOLOV5 model..') - """ - self.model = Darknet(self.model_cfg) - self.model.load_weights(self.model_weights) - self.model.net_info['height'] = self.inp_dim - """ - - from yolov5.models.common import DetectMultiBackend - device = torch.device('cuda') - self.model = DetectMultiBackend(weights='./yolov5/yolov5s.pt', device=device, dnn=False) - - if args: - if len(args.gpus) > 1: - self.model = torch.nn.DataParallel(self.model, device_ids=args.gpus).to(args.device) - else: - self.model.to(args.device) - else: - self.model.cuda() - self.model.eval() - - def image_preprocess(self, img_source): - """ - Pre-process the img before fed to the object detection network - Input: image name(str) or raw image data(ndarray or torch.Tensor,channel GBR) - Output: pre-processed image data(torch.FloatTensor,(1,3,h,w)) - """ - if isinstance(img_source, str): - img, orig_img, im_dim_list = prep_image(img_source, self.inp_dim) - elif isinstance(img_source, torch.Tensor) or isinstance(img_source, np.ndarray): - img, orig_img, im_dim_list = prep_frame(img_source, self.inp_dim) - else: - raise IOError('Unknown image source type: {}'.format(type(img_source))) - - return img - - def images_detection(self, imgs, orig_dim_list): - """ - Feed the img data into object detection network and - collect bbox w.r.t original image size - Input: imgs(torch.FloatTensor,(b,3,h,w)): pre-processed mini-batch image input - orig_dim_list(torch.FloatTensor, (b,(w,h,w,h))): original mini-batch image size - Output: dets(torch.cuda.FloatTensor,(n,(batch_idx,x1,y1,x2,y2,c,s,idx of cls))): human detection results - """ - args = self.detector_opt - _CUDA = True - if args: - if args.gpus[0] < 0: - _CUDA = False - if not self.model: - self.load_model() - with torch.no_grad(): - imgs = imgs.to(args.device) if args else imgs.cuda() - # prediction = self.model(imgs, args=args) - prediction = self.model(imgs, augment=False, visualize=False) - #do nms to the detection results, only human category is left - # dets = self.dynamic_write_results(prediction, self.confidence, - # self.num_classes, nms=True, - # nms_conf=self.nms_thres) - - - # prediction = non_max_suppression(prediction, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det) - prediction = non_max_suppression(prediction, 0.25, 0.45, None, False, max_det=10) - prediction_cat = [] - for tmp in prediction: - num_objs, _ = tmp.shape - if num_objs < 10: - pad = torch.zeros((10-num_objs, 6)).to(tmp.device) - tmp = torch.cat([tmp, pad], dim=0) - prediction_cat.append(tmp) - prediction = torch.stack(prediction_cat) - - dets = self.dynamic_write_results(prediction, self.confidence, - self.num_classes, nms=False, - nms_conf=self.nms_thres) - - if isinstance(dets, int) or dets.shape[0] == 0: - return 0 - dets = dets.cpu() - - orig_dim_list = torch.index_select(orig_dim_list, 0, dets[:, 0].long()) - scaling_factor = torch.min(self.inp_dim / orig_dim_list, 1)[0].view(-1, 1) - dets[:, [1, 3]] -= (self.inp_dim - scaling_factor * orig_dim_list[:, 0].view(-1, 1)) / 2 - dets[:, [2, 4]] -= (self.inp_dim - scaling_factor * orig_dim_list[:, 1].view(-1, 1)) / 2 - dets[:, 1:5] /= scaling_factor - for i in range(dets.shape[0]): - dets[i, [1, 3]] = torch.clamp(dets[i, [1, 3]], 0.0, orig_dim_list[i, 0]) - dets[i, [2, 4]] = torch.clamp(dets[i, [2, 4]], 0.0, orig_dim_list[i, 1]) - - return dets - - def dynamic_write_results(self, prediction, confidence, num_classes, nms=True, nms_conf=0.4): - prediction_bak = prediction.clone() - dets = self.write_results(prediction.clone(), confidence, num_classes, nms, nms_conf) - if isinstance(dets, int): - return dets - - if dets.shape[0] > 100: - nms_conf -= 0.05 - dets = self.write_results(prediction_bak.clone(), confidence, num_classes, nms, nms_conf) - - return dets - - def write_results(self, prediction, confidence, num_classes, nms=True, nms_conf=0.4): - args = self.detector_opt - #prediction: (batchsize, num of objects, (xc,yc,w,h,box confidence, 80 class scores)) - conf_mask = (prediction[:, :, 4] > confidence).float().unsqueeze(2) - prediction = prediction * conf_mask - - try: - ind_nz = torch.nonzero(prediction[:,:,4]).transpose(0,1).contiguous() - except: - return 0 - - #the 3rd channel of prediction: (xc,yc,w,h)->(x1,y1,x2,y2) - box_a = prediction.new(prediction.shape) - box_a[:,:,0] = (prediction[:,:,0] - prediction[:,:,2]/2) - box_a[:,:,1] = (prediction[:,:,1] - prediction[:,:,3]/2) - box_a[:,:,2] = (prediction[:,:,0] + prediction[:,:,2]/2) - box_a[:,:,3] = (prediction[:,:,1] + prediction[:,:,3]/2) - prediction[:,:,:4] = box_a[:,:,:4] - - batch_size = prediction.size(0) - - output = prediction.new(1, prediction.size(2) + 1) - write = False - num = 0 - for ind in range(batch_size): - #select the image from the batch - image_pred = prediction[ind] - - #Get the class having maximum score, and the index of that class - #Get rid of num_classes softmax scores - #Add the class index and the class score of class having maximum score - max_conf, max_conf_score = torch.max(image_pred[:,5:5+ num_classes], 1) - max_conf = max_conf.float().unsqueeze(1) - max_conf_score = max_conf_score.float().unsqueeze(1) - seq = (image_pred[:,:5], max_conf, max_conf_score) - #image_pred:(n,(x1,y1,x2,y2,c,s,idx of cls)) - image_pred = torch.cat(seq, 1) - - #Get rid of the zero entries - non_zero_ind = (torch.nonzero(image_pred[:,4])) - - image_pred_ = image_pred[non_zero_ind.squeeze(),:].view(-1,7) - - #Get the various classes detected in the image - try: - img_classes = unique(image_pred_[:,-1]) - except: - continue - - #WE will do NMS classwise - #print(img_classes) - for cls in img_classes: - if cls != 0: - continue - #get the detections with one particular class - cls_mask = image_pred_*(image_pred_[:,-1] == cls).float().unsqueeze(1) - class_mask_ind = torch.nonzero(cls_mask[:,-2]).squeeze() - - image_pred_class = image_pred_[class_mask_ind].view(-1,7) - - #sort the detections such that the entry with the maximum objectness - #confidence is at the top - conf_sort_index = torch.sort(image_pred_class[:,4], descending = True )[1] - image_pred_class = image_pred_class[conf_sort_index] - idx = image_pred_class.size(0) - - #if nms has to be done - if nms: - if platform.system() != 'Windows': - #We use faster rcnn implementation of nms (soft nms is optional) - nms_op = getattr(nms_wrapper, 'nms') - #nms_op input:(n,(x1,y1,x2,y2,c)) - #nms_op output: input[inds,:], inds - _, inds = nms_op(image_pred_class[:,:5], nms_conf) - - image_pred_class = image_pred_class[inds] - else: - # Perform non-maximum suppression - max_detections = [] - while image_pred_class.size(0): - # Get detection with highest confidence and save as max detection - max_detections.append(image_pred_class[0].unsqueeze(0)) - # Stop if we're at the last detection - if len(image_pred_class) == 1: - break - # Get the IOUs for all boxes with lower confidence - ious = bbox_iou(max_detections[-1], image_pred_class[1:], args) - # Remove detections with IoU >= NMS threshold - image_pred_class = image_pred_class[1:][ious < nms_conf] - - image_pred_class = torch.cat(max_detections).data - - #Concatenate the batch_id of the image to the detection - #this helps us identify which image does the detection correspond to - #We use a linear straucture to hold ALL the detections from the batch - #the batch_dim is flattened - #batch is identified by extra batch column - - batch_ind = image_pred_class.new(image_pred_class.size(0), 1).fill_(ind) - seq = batch_ind, image_pred_class - if not write: - output = torch.cat(seq,1) - write = True - else: - out = torch.cat(seq,1) - output = torch.cat((output,out)) - num += 1 - - if not num: - return 0 - #output:(n,(batch_ind,x1,y1,x2,y2,c,s,idx of cls)) - return output - - def detect_one_img(self, img_name): - """ - Detect bboxs in one image - Input: 'str', full path of image - Output: '[{"category_id":1,"score":float,"bbox":[x,y,w,h],"image_id":str},...]', - The output results are similar with coco results type, except that image_id uses full path str - instead of coco %012d id for generalization. - """ - args = self.detector_opt - _CUDA = True - if args: - if args.gpus[0] < 0: - _CUDA = False - if not self.model: - self.load_model() - if isinstance(self.model, torch.nn.DataParallel): - self.model = self.model.module - dets_results = [] - #pre-process(scale, normalize, ...) the image - img, orig_img, img_dim_list = prep_image(img_name, self.inp_dim) - with torch.no_grad(): - img_dim_list = torch.FloatTensor([img_dim_list]).repeat(1, 2) - img = img.to(args.device) if args else img.cuda() - #prediction = self.model(img, args=args) - prediction = self.model(img) - #do nms to the detection results, only human category is left - # dets = self.dynamic_write_results(prediction, self.confidence, - # self.num_classes, nms=True, - # nms_conf=self.nms_thres) - - dets = self.dynamic_write_results(prediction, self.confidence, - self.num_classes, nms=False, - nms_conf=self.nms_thres) - - if isinstance(dets, int) or dets.shape[0] == 0: - return None - dets = dets.cpu() - - img_dim_list = torch.index_select(img_dim_list, 0, dets[:, 0].long()) - scaling_factor = torch.min(self.inp_dim / img_dim_list, 1)[0].view(-1, 1) - dets[:, [1, 3]] -= (self.inp_dim - scaling_factor * img_dim_list[:, 0].view(-1, 1)) / 2 - dets[:, [2, 4]] -= (self.inp_dim - scaling_factor * img_dim_list[:, 1].view(-1, 1)) / 2 - dets[:, 1:5] /= scaling_factor - for i in range(dets.shape[0]): - dets[i, [1, 3]] = torch.clamp(dets[i, [1, 3]], 0.0, img_dim_list[i, 0]) - dets[i, [2, 4]] = torch.clamp(dets[i, [2, 4]], 0.0, img_dim_list[i, 1]) - - #write results - det_dict = {} - x = float(dets[i, 1]) - y = float(dets[i, 2]) - w = float(dets[i, 3] - dets[i, 1]) - h = float(dets[i, 4] - dets[i, 2]) - det_dict["category_id"] = 1 - det_dict["score"] = float(dets[i, 5]) - det_dict["bbox"] = [x, y, w, h] - det_dict["image_id"] = int(os.path.basename(img_name).split('.')[0]) - dets_results.append(det_dict) - - return dets_results diff --git a/cv/pose/alphapose/pytorch/scripts/main_pipeline_time.py b/cv/pose/alphapose/pytorch/scripts/main_pipeline_time.py deleted file mode 100755 index cf0846999..000000000 --- a/cv/pose/alphapose/pytorch/scripts/main_pipeline_time.py +++ /dev/null @@ -1,327 +0,0 @@ -""" -Test the time of pipeline or modules(yolov5s and alphapose) for a single person of a single way! - -""" - -import os -import sys -import cv2 -import time -import argparse -import torchvision -import numpy as np -import multiprocessing -from torch.multiprocessing import Process - -import torch -import torch.nn as nn - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) - -from detector.yolo_cfg import cfg -from detector.yolov5.utils.general import non_max_suppression - -from alphapose.models import builder -from alphapose.utils.config import update_config -from alphapose.utils.transforms import heatmap_to_coord_simple -from alphapose.utils.pPose_nms import pose_nms - -from process_utils import scale_coords, test_transform, plot_pose_res - - -"""----------------------------- Test Time options -----------------------------""" -parser = argparse.ArgumentParser(description='Test the time of pipeline or modules(yolov5s and alphapose) for a single person of a single way') -parser.add_argument('--cfg', - type=str, - default="./configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml", - help='experiment configure file name') -parser.add_argument('--checkpoint', - type=str, - default="./pretrained_models/fast_res50_256x192.pth", - help='checkpoint file name') -parser.add_argument('--inp_path', - type=str, - default="./examples/demo/0.png", - help='the path of input image') -parser.add_argument('--flag', - type=str, - default='pipeline', - choices=['pipeline', 'modules'], - help='whether test the pipeline or part') -parser.add_argument('--inp_size', - type=tuple, - default=(640, 384), - help='the input size of model') -args = parser.parse_args() -cfg = update_config(args.cfg) -args.device = torch.device("cuda:0") -torch.backends.cudnn.benchmark = True -print("Input Size: ", args.inp_size) - - -def cal_avg_time(times_ix): - assert isinstance(times_ix, list), "The inpust must be a list" - times = times_ix[:] - max_index = times.index(max(times)) - del times[max_index] - - min_index = times.index(min(times)) - del times[min_index] - - time_avg = sum(times) / len(times) - return time_avg - - -def letterbox_image(img, inp_dim=(640, 384)): - '''resize image with unchanged aspect ratio using padding''' - img_w, img_h = img.shape[1], img.shape[0] - w, h = inp_dim - new_w = int(img_w * min(w / img_w, h / img_h)) - new_h = int(img_h * min(w / img_w, h / img_h)) - resized_image = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_CUBIC) - - canvas = np.full((inp_dim[1], inp_dim[0], 3), 128) - - canvas[(h - new_h) // 2:(h - new_h) // 2 + new_h, (w - new_w) // 2:(w - new_w) // 2 + new_w, :] = resized_image - - return canvas - - -def load_det_data(orig_im, inp_path=''): - - dim = orig_im.shape[1], orig_im.shape[0] - # PadResize - img = (letterbox_image(orig_im, args.inp_size)) - # BGR--->RGB, (384, 640, 3)--->(3, 384, 640) - img = img[:, :, ::-1].transpose((2, 0, 1)).copy() - # np.array--->torch.tensor, (0, 255)--->(0, 1), (3, 384, 640)--->(1, 3, 384, 640) - img = torch.from_numpy(img).float().div(255.).unsqueeze(0) - im_name = os.path.basename(inp_path) - return (img, orig_im, im_name, dim) - - -def load_det_model(opt, cfg): - weights = "../yolov5/yolov5s.pt" - from detector.yolov5.models.experimental import attempt_download, attempt_load # scoped to avoid circular import - det_model = attempt_load(weights, map_location=None) - det_model.to(args.device) - det_model.eval() - return det_model - - -def det_forward(inps, det_model): - img, orig_img, im_name, im_dim = inps - img = img.to(args.device) - with torch.no_grad(): - prediction = det_model(img) - det_model_out = (prediction, orig_img, im_dim, im_name) - return det_model_out - - -def nms(prediction, conf_thres=0.25, iou_thres=0.45, max_det=100): - xc = prediction[..., 4] > conf_thres # candidates - output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0] - for xi, x in enumerate(prediction): # image index, image inference - x = x[xc[xi]] # confidence - - boxes, scores = x[:, :4], x[:, 4] - i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS - if i.shape[0] > max_det: # limit detections - i = i[:max_det] - - output[xi] = x[i] - return output - - -def det_post(det_model_out): - prediction, orig_img, im_shape, im_name = det_model_out - - # prediction = non_max_suppression(prediction, 0.25, 0.45, None, False, max_det=100) - prediction = nms(prediction) - prediction = prediction[0] # torch.tensor(num_objs x 6) - prediction[:, :4] = scale_coords(args.inp_size, prediction[:, :4], im_shape).round() - - dets = prediction.cpu() - boxes = dets[:, :4] - - scores = dets[:, 4:5] - labels = dets[:, 5:6] - flag = labels[:, 0] == 1. # select the person - - ids = torch.zeros(scores.shape) - - inps_idx = torch.zeros(boxes.size(0), 3, 256, 192) - cropped_boxes = torch.zeros(boxes.size(0), 4) - det_res = (orig_img, im_name, boxes[flag], scores[flag], ids[flag], inps_idx[flag], cropped_boxes[flag]) - - return det_res - - -# Stage2: pose estimation(alphapose) -def load_pose_data(det_res): - with torch.no_grad(): - orig_img, im_name, boxes, scores, ids, inps, cropped_boxes = det_res - for j, box in enumerate(boxes): - inps[j], cropped_box = test_transform(orig_img, box) - cropped_boxes[j] = torch.FloatTensor(cropped_box) - - pose_inps = (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) - return pose_inps - - -def load_pose_model(): - pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - print('Loading pose model from %s...' % (args.checkpoint,)) - pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) - pose_model.to(args.device) - pose_model.eval() - return pose_model - - -def pose_forward(pose_inps, pose_model): - with torch.no_grad(): - (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) = pose_inps - inps = inps.to(args.device) - hm = pose_model(inps) - pose_model_out = (boxes, scores, ids, hm, cropped_boxes, orig_img, im_name) - return pose_model_out - - -def pose_post(pose_model_out): - boxes, scores, ids, hm_data, cropped_boxes, orig_img, im_name = pose_model_out - hm_data = hm_data.cpu() - orig_img = np.array(orig_img, dtype=np.uint8)[:, :, ::-1] - - eval_joints = [*range(0,17)] - hm_size = (64, 48) - min_box_area = 0 - - pose_coords = [] - pose_scores = [] - for i in range(hm_data.shape[0]): - bbox = cropped_boxes[i].tolist() - pose_coord, pose_score = heatmap_to_coord_simple(hm_data[i][eval_joints], bbox, hm_shape=hm_size, norm_type=None) - pose_coords.append(torch.from_numpy(pose_coord).unsqueeze(0)) - pose_scores.append(torch.from_numpy(pose_score).unsqueeze(0)) - - preds_img = torch.cat(pose_coords) - preds_scores = torch.cat(pose_scores) - boxes, scores, ids, preds_img, preds_scores, pick_ids = \ - pose_nms(boxes, scores, ids, preds_img, preds_scores, min_box_area) - - _result = [] - for k in range(len(scores)): - _result.append( - { - 'keypoints':preds_img[k], - 'kp_score':preds_scores[k], - 'proposal_score': torch.mean(preds_scores[k]) + scores[k] + 1.25 * max(preds_scores[k]), - 'idx':ids[k], - 'box':[boxes[k][0], boxes[k][1], boxes[k][2]-boxes[k][0],boxes[k][3]-boxes[k][1]] - } - ) - - result = { - 'imgname': im_name, - 'result': _result - } - return result - - -def all_pipeline_time(inp_path, det_model, pose_model): - times_ix = [] - - img = cv2.imread(inp_path) - - for i in range(256): - torch.cuda.synchronize() - s = time.time() - - inps = load_det_data(img) - det_model_out = det_forward(inps, det_model) - det_res = det_post(det_model_out) - pose_inps = load_pose_data(det_res) - pose_model_out = pose_forward(pose_inps, pose_model) - pose_res = pose_post(pose_model_out) - - torch.cuda.synchronize() - e = time.time() - times_ix.append(e - s) - print('iter: %d, %.6f' % (i, (e - s))) - - time_avg = cal_avg_time(times_ix) - print('pipeline time: ', time_avg) - - -def all_modules_time(inp_path, det_model, pose_model): - - times_s1 = [] - times_s2 = [] - times_s3 = [] - times_s4 = [] - times_s5 = [] - times_s6 = [] - times_total = [] - - img = cv2.imread(inp_path) - - for i in range(256): - - torch.cuda.synchronize() - t0 = time.time() - - inps = load_det_data(img) - torch.cuda.synchronize() - t1 = time.time() - times_s1.append(t1 - t0) - - det_model_out = det_forward(inps, det_model) - torch.cuda.synchronize() - t2 = time.time() - times_s2.append(t2 - t1) - - det_res = det_post(det_model_out) - torch.cuda.synchronize() - t3 = time.time() - times_s3.append(t3 - t2) - - pose_inps = load_pose_data(det_res) - torch.cuda.synchronize() - t4 = time.time() - times_s4.append(t4 - t3) - - pose_model_out = pose_forward(pose_inps, pose_model) - torch.cuda.synchronize() - t5 = time.time() - times_s5.append(t5 - t4) - - pose_res = pose_post(pose_model_out) - torch.cuda.synchronize() - t6 = time.time() - times_s6.append(t6 - t5) - - times_total.append(t6 - t0) - print('iter: %d, %.6f' % (i, (t6 - t0))) - - time_avg_s1 = cal_avg_time(times_s1) - time_avg_s2 = cal_avg_time(times_s2) - time_avg_s3 = cal_avg_time(times_s3) - time_avg_s4 = cal_avg_time(times_s4) - time_avg_s5 = cal_avg_time(times_s5) - time_avg_s6 = cal_avg_time(times_s6) - time_avg_total = cal_avg_time(times_total) - - # print('pipeline time: ', time_avg) - print(f"load_det_data: {time_avg_s1}; \n det_forward: {time_avg_s2}; \n det_post: {time_avg_s3};") - print(f"load_pose_data: {time_avg_s4}; \n pose_forward: {time_avg_s5}; \n pose_post: {time_avg_s6}") - - -if __name__ == "__main__": - det_model = load_det_model(args, cfg) - pose_model = load_pose_model() - - if args.flag == 'pipeline': - all_pipeline_time(args.inp_path, det_model, pose_model) - else: - all_modules_time(args.inp_path, det_model, pose_model) diff --git a/cv/pose/alphapose/pytorch/scripts/multi_persons_multi_ways_batch.py b/cv/pose/alphapose/pytorch/scripts/multi_persons_multi_ways_batch.py deleted file mode 100755 index 98b7c4f24..000000000 --- a/cv/pose/alphapose/pytorch/scripts/multi_persons_multi_ways_batch.py +++ /dev/null @@ -1,427 +0,0 @@ -""" -Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways! -In main process of bs = multi ways forward. - -""" - -import os -import re -import sys -import cv2 -import time -import argparse -import torchvision -from torchvision import transforms -import numpy as np - -import torch -import torch.nn as nn -import torch.utils.data as Data - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) - -from detector.yolo_cfg import cfg -from detector.yolov5.utils.general import non_max_suppression - -from alphapose.models import builder -from alphapose.utils.config import update_config -from alphapose.utils.transforms import heatmap_to_coord_simple -from alphapose.utils.pPose_nms import pose_nms - -from process_utils import scale_coords, test_transform, plot_pose_res - - -"""----------------------------- Test Time options -----------------------------""" -parser = argparse.ArgumentParser(description='Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways') -parser.add_argument('--cfg', - type=str, - default="./configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml", - help='experiment configure file name') -parser.add_argument('--checkpoint', - type=str, - default="./pretrained_models/fast_res50_256x192.pth", - help='checkpoint file name') -parser.add_argument('--imgsdir', - type=str, - default="./examples/batch_imgs_multi_persons/singleway", - help='the directory of input image') -parser.add_argument('--flag', - type=str, - default='pipeline', - choices=['pipeline', 'modules'], - help='test the all pipeline or all sub module') -parser.add_argument('--inp_size', - type=tuple, - default=(640, 384), - help='the input size of model') -parser.add_argument('--pose_res', - action='store_true', - help='test the pose results') -parser.add_argument('--FP16', - action='store_true', - help='whether use FP16') -args = parser.parse_args() -cfg = update_config(args.cfg) -args.device = torch.device("cuda:0") -torch.backends.cudnn.benchmark = True -print("Input Size: ", args.inp_size) -if args.FP16: - print("Forward(yolov5s_alphapose) by FP16") - - -def cal_avg_time(times_ix): - assert isinstance(times_ix, list), "The inpust must be a list" - times = times_ix[:] - max_index = times.index(max(times)) - del times[max_index] - - min_index = times.index(min(times)) - del times[min_index] - - time_avg = sum(times) / len(times) - return time_avg - - -def letterbox_image(img, inp_dim=(640, 384)): - # BGR--->RGB, (384, 640, 3)--->(3, 384, 640) - img = torch.transpose(img, 1, 2) - img = torch.transpose(img, 0, 1) - dst = torch.empty_like(img[0]) - dst.copy_(img[0], non_blocking=True) - img[0].copy_(img[2], non_blocking=True) - img[2].copy_(dst, non_blocking=True) - '''resize image with unchanged aspect ratio using padding''' - transform = transforms.Compose([transforms.Resize(size=(360, 640)), - transforms.Pad(padding=(0, 12), fill=128)]) - return transform(img) - - -def load_det_model(opt, cfg): - weights = "../yolov5/yolov5s.pt" - from detector.yolov5.models.experimental import attempt_download, attempt_load # scoped to avoid circular import - det_model = attempt_load(weights, map_location=None) - if args.FP16: - det_model.half() - det_model.to(args.device) - det_model.eval() - return det_model - - -def batched_nms(prediction, conf_thres=0.25, iou_thres=0.45, max_det=100): - output = [] - bs, boxes_num, _ = prediction.shape - idxs = torch.from_numpy(np.arange(bs)).unsqueeze(-1).expand(bs, boxes_num) - - xc = prediction[..., 4] > conf_thres # candidates - - x = prediction[xc] # confidence - idxs = idxs[xc] - - boxes, scores = x[:, :4], x[:, 4] - i = torchvision.ops.batched_nms(boxes, scores, idxs, iou_thres) # NMS - - res = x[i] - idxs_batch = idxs[i] - for j in range(bs): - output.append(res[idxs_batch == j]) - return output - - -def batched_det_post_to_pose_data(prediction, orig_img, im_dim, im_name): - pose_inps = [] - pose_infor = [] - pose_index = [] - - for i, (pred, y, z) in enumerate(zip(prediction, orig_img, im_name)): - pred[:, :4] = scale_coords(args.inp_size, pred[:, :4], (1280, 720)).round() - det = pred.cpu() - - boxes = det[:, :4] - scores = det[:, 4:5] - labels = det[:, 5:6] - flag = labels[:, 0] == 1. # select the person - - ids = torch.zeros(scores.shape) - - inps_idx = torch.zeros(boxes.size(0), 3, 256, 192) - cropped_boxes = torch.zeros(boxes.size(0), 4) - # det_res = (y, z, boxes[flag], scores[flag], ids[flag], inps_idx[flag], cropped_boxes[flag]) - inps = inps_idx[flag] - for j, box in enumerate(boxes[flag]): - inps[j], cropped_box = test_transform(y, box) - cropped_boxes[j] = torch.FloatTensor(cropped_box) - pose_infor.append((y, z, boxes[flag], scores[flag], ids[flag], cropped_boxes[flag])) - pose_inps.append(inps) - pose_index.extend([i for j in range(len(boxes[flag]))]) - - pose_inps = torch.cat(pose_inps, dim=0) - pose_index = torch.tensor(pose_index) - return pose_inps, pose_infor, pose_index - - -def detection(data, det_model): - img, orig_img, im_name, im_dim = data - with torch.no_grad(): - prediction = det_model(img) - - prediction = batched_nms(prediction) - pose_inps, pose_infor, pose_index = batched_det_post_to_pose_data(prediction, orig_img, im_dim, im_name) - - return pose_inps, pose_infor, pose_index - - -# Stage2: pose estimation(alphapose) -def load_pose_model(): - pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - print('Loading pose model from %s...' % (args.checkpoint,)) - pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) - if args.FP16: - pose_model.half() - pose_model.to(args.device) - pose_model.eval() - return pose_model - - -def pose_post(hm_data, pose_infor): - orig_img, im_name, boxes, scores, ids, cropped_boxes = pose_infor - hm_data = hm_data.cpu() - - orig_img = np.array(orig_img, dtype=np.uint8)[:, :, ::-1] - - eval_joints = [*range(0,17)] - hm_size = (64, 48) - min_box_area = 0 - - pose_coords = [] - pose_scores = [] - - for i in range(hm_data.shape[0]): - bbox = cropped_boxes[i].tolist() - pose_coord, pose_score = heatmap_to_coord_simple(hm_data[i][eval_joints], bbox, hm_shape=hm_size, norm_type=None) - pose_coords.append(torch.from_numpy(pose_coord).unsqueeze(0)) - pose_scores.append(torch.from_numpy(pose_score).unsqueeze(0)) - - preds_img = torch.cat(pose_coords) - preds_scores = torch.cat(pose_scores) - - boxes, scores, ids, preds_img, preds_scores, pick_ids = \ - pose_nms(boxes, scores, ids, preds_img, preds_scores, min_box_area) - - _result = [] - for k in range(len(scores)): - _result.append( - { - 'keypoints':preds_img[k], - 'kp_score':preds_scores[k], - 'proposal_score': torch.mean(preds_scores[k]) + scores[k] + 1.25 * max(preds_scores[k]), - 'idx':ids[k], - 'box':[boxes[k][0], boxes[k][1], boxes[k][2]-boxes[k][0],boxes[k][3]-boxes[k][1]] - } - ) - - result = { - 'imgname': im_name, - 'result': _result - } - return result - - -def pose(pose_inps, pose_infor, pose_model, pose_index): - pose_out = [] - with torch.no_grad(): - pose_inps = pose_inps.to(args.device) - if args.FP16: - pose_inps = pose_inps.half() - hm = pose_model(pose_inps) - - if args.FP16: - hm = hm.float() - - for i, infor in enumerate(pose_infor): - hm_data = hm[pose_index == i] - if hm_data.dim == 3: - hm_data = hm_data.unsqeeze(0) - res = pose_post(hm_data, infor) - pose_out.append(res) - return pose_out - - -def preprocess(orig_im): - # PadResize - img = (letterbox_image(orig_im, args.inp_size)) - #(0, 255)--->(0, 1), (3, 384, 640)--->(1, 3, 384, 640) - img = img.div(255.).unsqueeze(0) - return img - - -stream_length = 4 -streams = [torch.cuda.Stream() for i in range(stream_length)] - - -def all_pipeline_time(det_model, pose_model): - times = [] - for i in range(256): - s = time.time() - - rootdir = args.imgsdir - imgnames = [x for x in os.listdir(rootdir) if x.endswith('png') or x.endswith('jpg')] - imgpaths = [os.path.join(rootdir, imgname) for imgname in imgnames] - orig_im_batch = [cv2.imread(imgpath) for imgpath in imgpaths] - - s = time.time() - dims_batch = [(orig_im.shape[1], orig_im.shape[0]) for orig_im in orig_im_batch] - img_batch = [] - for idx, orig_im in enumerate(orig_im_batch): - with torch.cuda.stream(streams[idx % stream_length]): - if args.FP16: - img_batch.append(preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True).to(torch.half))) - else: - img_batch.append(preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True).to(torch.float))) - - torch.cuda.synchronize() - - img = torch.cat(img_batch, dim=0) - data = (img, orig_im_batch, imgnames, dims_batch) - - pose_inps, pose_infor, pose_index = detection(data, det_model) - pose_out = pose(pose_inps, pose_infor, pose_model, pose_index) - e = time.time() - time_once = e - s - times.append(time_once) - print('iter: %d, time: %.6f' % (i, time_once)) - - avg_times = cal_avg_time(times) - print('avg_times: %.6f' % (avg_times)) - - -def all_module_time(det_model, pose_model): - times_ix = [] - prof_load_det_data = [] - prof_det_forward = [] - prof_det_post = [] - prof_load_pose_data = [] - prof_pose_forward = [] - prof_pose_post = [] - - for i in range(256): - rootdir = args.imgsdir - imgnames = [x for x in os.listdir(rootdir) if x.endswith('png') or x.endswith('jpg')] - imgpaths = [os.path.join(rootdir, imgname) for imgname in imgnames] - - orig_im_batch = [cv2.imread(imgpath) for imgpath in imgpaths] - - t0 = time.time() - dims_batch = [(orig_im.shape[1], orig_im.shape[0]) for orig_im in orig_im_batch] - img_batch = [] - for idx,orig_im in enumerate(orig_im_batch): - with torch.cuda.stream(streams[idx%stream_length]): - if args.FP16: - img_batch.append(preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True).to(torch.half))) - else: - img_batch.append(preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True).to(torch.float))) - - torch.cuda.synchronize() - - img = torch.cat(img_batch, dim=0) - data = (img, orig_im_batch, imgnames, dims_batch) - torch.cuda.synchronize() - t1 = time.time() - prof_load_det_data.append(t1 - t0) - - img, orig_img, im_name, im_dim = data - with torch.no_grad(): - prediction = det_model(img) - torch.cuda.synchronize() - t2 = time.time() - prof_det_forward.append(t2 - t1) - - det_out = [] - prediction = batched_nms(prediction) - pose_inps, pose_infor, pose_index = batched_det_post_to_pose_data(prediction, orig_img, im_dim, im_name) - t3 = time.time() - prof_det_post.append(t3 - t2) - - torch.cuda.synchronize() - t4 = time.time() - prof_load_pose_data.append(t4 - t3) - - pose_out = [] - with torch.no_grad(): - pose_inps = pose_inps.to(args.device) - if args.FP16: - pose_inps = pose_inps.half() - hm = pose_model(pose_inps) - torch.cuda.synchronize() - t5 = time.time() - prof_pose_forward.append(t5 - t4) - - if args.FP16: - hm = hm.float() - - for i, infor in enumerate(pose_infor): - hm_data = hm[pose_index == i] - if hm_data.dim == 3: - hm_data = hm_data.unsqeeze(0) - res = pose_post(hm_data, infor) - pose_out.append(res) - - torch.cuda.synchronize() - t6 = time.time() - prof_pose_post.append(t6 - t5) - times_ix.append((t6 - t0)) - - time_avg = cal_avg_time(times_ix) - t1_avg = cal_avg_time(prof_load_det_data) - t2_avg = cal_avg_time(prof_det_forward) - t3_avg = cal_avg_time(prof_det_post) - t4_avg = cal_avg_time(prof_load_pose_data) - t5_avg = cal_avg_time(prof_pose_forward) - t6_avg = cal_avg_time(prof_pose_post) - - print(""" - ************************************************* - pipeline_time_avg: {:.6f} s, - prof_load_det_data_avg: {:.6f} s, - prof_det_forward_avg: {:.6f} s, - prof_det_post_avg: {:.6f} s, - prof_load_pose_data_avg: {:.6f} s, - prof_pose_forward_avg: {:.6f} s, - prof_pose_post_avg: {:.6f} s, - """.format(time_avg, t1_avg, t2_avg, t3_avg, t4_avg, t5_avg, t6_avg)) - - -def test_pose(det_model, pose_model): - rootdir = './examples/batch_imgs_multi_persons/singleway' - imgnames = [x for x in os.listdir(rootdir) if x.endswith('png') or x.endswith('jpg')] - imgpaths = [os.path.join(rootdir, imgname) for imgname in imgnames] - - orig_im_batch = [cv2.imread(imgpath) for imgpath in imgpaths] - - dims_batch = [(orig_im.shape[1], orig_im.shape[0]) for orig_im in orig_im_batch] - img_batch = [preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True)) for orig_im in orig_im_batch] - - img = torch.cat(img_batch, dim=0) - if args.FP16: - img = img.half() - data = (img, orig_im_batch, imgnames, dims_batch) - - pose_inps, pose_infor, pose_index = detection(data, det_model) - pose_out = pose(pose_inps, pose_infor, pose_model, pose_index) - - plot_pose_res(imgpaths[0], pose_out[0], './res.jpg') - - -if __name__ == "__main__": - det_model = load_det_model(args, cfg) - pose_model = load_pose_model() - - if args.pose_res: - test_pose(det_model, pose_model) - else: - if args.flag == 'pipeline': - call_func = all_pipeline_time # test the time of all pipeline - else: - call_func = all_module_time # test the time of six module time - - results = call_func(det_model, pose_model) diff --git a/cv/pose/alphapose/pytorch/scripts/multi_ways_batch.py b/cv/pose/alphapose/pytorch/scripts/multi_ways_batch.py deleted file mode 100755 index 23cde4f14..000000000 --- a/cv/pose/alphapose/pytorch/scripts/multi_ways_batch.py +++ /dev/null @@ -1,432 +0,0 @@ -""" -Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways! -In main process of bs = multi ways forward. - -""" - -import os -import re -import sys -import cv2 -import time -import argparse -import torchvision -from torchvision import transforms -import numpy as np - -import torch -import torch.nn as nn -import torch.utils.data as Data - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) - -from detector.yolo_cfg import cfg -from detector.yolov5.utils.general import non_max_suppression - -from alphapose.models import builder -from alphapose.utils.config import update_config -from alphapose.utils.transforms import heatmap_to_coord_simple -from alphapose.utils.pPose_nms import pose_nms - -from process_utils import scale_coords, test_transform, plot_pose_res - - -"""----------------------------- Test Time options -----------------------------""" -parser = argparse.ArgumentParser(description='Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways') -parser.add_argument('--cfg', - type=str, - default="./configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml", - help='experiment configure file name') -parser.add_argument('--checkpoint', - type=str, - default="./pretrained_models/fast_res50_256x192.pth", - help='checkpoint file name') -parser.add_argument('--imgsdir', - type=str, - default="./examples/batch_imgs/singleway", - help='the directory of input image') -parser.add_argument('--flag', - type=str, - default='pipeline', - choices=['pipeline', 'modules'], - help='test the all pipeline or all sub module') -parser.add_argument('--inp_size', - type=tuple, - default=(640, 384), - help='the input size of model') -parser.add_argument('--pose_res', - action='store_true', - help='test the pose results') -parser.add_argument('--FP16', - action='store_true', - help='whether use FP16') -args = parser.parse_args() -cfg = update_config(args.cfg) -args.device = torch.device("cuda:0") -torch.backends.cudnn.benchmark = True -print("Input Size: ", args.inp_size) -if args.FP16: - print("Forward(yolov5s_alphapose) by FP16") - - -def cal_avg_time(times_ix): - assert isinstance(times_ix, list), "The inpust must be a list" - times = times_ix[:] - max_index = times.index(max(times)) - del times[max_index] - - min_index = times.index(min(times)) - del times[min_index] - - time_avg = sum(times) / len(times) - return time_avg - - -def letterbox_image(img, inp_dim=(640, 384)): - # BGR--->RGB, (384, 640, 3)--->(3, 384, 640) - img = torch.transpose(img, 1, 2) - img = torch.transpose(img, 0, 1) - dst = torch.empty_like(img[0]) - dst.copy_(img[0], non_blocking=True) - img[0].copy_(img[2], non_blocking=True) - img[2].copy_(dst, non_blocking=True) - '''resize image with unchanged aspect ratio using padding''' - transform = transforms.Compose([transforms.Resize(size=(360, 640)), - transforms.Pad(padding=(0, 12), fill=128)]) - return transform(img) - - -def load_det_model(opt, cfg): - weights = "../yolov5/yolov5s.pt" - from detector.yolov5.models.experimental import attempt_download, attempt_load # scoped to avoid circular import - det_model = attempt_load(weights, map_location=None) - if args.FP16: - det_model.half() - det_model.to(args.device) - det_model.eval() - return det_model - - -def nms(prediction, conf_thres=0.25, iou_thres=0.45, max_det=100): - xc = prediction[..., 4] > conf_thres # candidates - output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0] - for xi, x in enumerate(prediction): # image index, image inference - x = x[xc[xi]] # confidence - - boxes, scores = x[:, :4], x[:, 4] - i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS - if i.shape[0] > max_det: # limit detections - i = i[:max_det] - - output[xi] = x[i] - return output - - -def batched_nms(prediction, conf_thres=0.25, iou_thres=0.45, max_det=100): - bs, boxes_num, _ = prediction.shape - idxs = torch.from_numpy(np.arange(bs)).unsqueeze(-1).expand(bs, boxes_num) - - xc = prediction[..., 4] > conf_thres # candidates - - x = prediction[xc] # confidence - idxs = idxs[xc] - - boxes, scores = x[:, :4], x[:, 4] - i = torchvision.ops.batched_nms(boxes, scores, idxs, iou_thres) # NMS - - output = x[i] - idxs_batch = idxs[i] - - return output, idxs_batch - - -def batched_det_post_to_pose_data(prediction, idxs_batch, orig_img, im_dim, im_name): - pose_inps = [] - pose_infor = [] - - prediction[:, :4] = scale_coords(args.inp_size, prediction[:, :4], (1280, 720)).round() - dets = prediction.cpu() - - for i, (y, z) in enumerate(zip(orig_img, im_name)): - det = dets[idxs_batch == i] - boxes = det[:, :4] - - scores = det[:, 4:5] - labels = det[:, 5:6] - flag = labels[:, 0] == 1. # select the person - - ids = torch.zeros(scores.shape) - - inps_idx = torch.zeros(boxes.size(0), 3, 256, 192) - cropped_boxes = torch.zeros(boxes.size(0), 4) - # det_res = (y, z, boxes[flag], scores[flag], ids[flag], inps_idx[flag], cropped_boxes[flag]) - inps = inps_idx[flag] - # select the numer of box(=1) - for j, box in enumerate(boxes[flag]): - inps[j], cropped_box = test_transform(y, box) - cropped_boxes[j] = torch.FloatTensor(cropped_box) - break - # pose_infor.append((y, z, boxes[flag], scores[flag], ids[flag], cropped_boxes[flag])) - pose_infor.append((y, z, boxes[flag][0:1], scores[flag][0:1], ids[flag][0:1], cropped_boxes[flag][0:1])) - pose_inps.append(inps) - - pose_inps = torch.cat(pose_inps, dim=0) - - return pose_inps, pose_infor - - -def detection(data, det_model): - img, orig_img, im_name, im_dim = data - with torch.no_grad(): - prediction = det_model(img) - prediction, idxs_batch = batched_nms(prediction) - pose_inps, pose_infor = batched_det_post_to_pose_data(prediction, idxs_batch, orig_img, im_dim, im_name) - - return pose_inps, pose_infor - - -# Stage2: pose estimation(alphapose) -def load_pose_model(): - pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - print('Loading pose model from %s...' % (args.checkpoint,)) - pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) - if args.FP16: - pose_model.half() - pose_model.to(args.device) - pose_model.eval() - return pose_model - - -def pose_post(hm_data, pose_infor): - orig_img, im_name, boxes, scores, ids, cropped_boxes = pose_infor - hm_data = hm_data.cpu() - - orig_img = np.array(orig_img, dtype=np.uint8)[:, :, ::-1] - - eval_joints = [*range(0,17)] - hm_size = (64, 48) - min_box_area = 0 - - pose_coords = [] - pose_scores = [] - - for i in range(hm_data.shape[0]): - bbox = cropped_boxes[i].tolist() - pose_coord, pose_score = heatmap_to_coord_simple(hm_data[i][eval_joints], bbox, hm_shape=hm_size, norm_type=None) - pose_coords.append(torch.from_numpy(pose_coord).unsqueeze(0)) - pose_scores.append(torch.from_numpy(pose_score).unsqueeze(0)) - - preds_img = torch.cat(pose_coords) - preds_scores = torch.cat(pose_scores) - - boxes, scores, ids, preds_img, preds_scores, pick_ids = \ - pose_nms(boxes, scores, ids, preds_img, preds_scores, min_box_area) - - _result = [] - for k in range(len(scores)): - _result.append( - { - 'keypoints':preds_img[k], - 'kp_score':preds_scores[k], - 'proposal_score': torch.mean(preds_scores[k]) + scores[k] + 1.25 * max(preds_scores[k]), - 'idx':ids[k], - 'box':[boxes[k][0], boxes[k][1], boxes[k][2]-boxes[k][0],boxes[k][3]-boxes[k][1]] - } - ) - - result = { - 'imgname': im_name, - 'result': _result - } - return result - - -def pose(pose_inps, pose_infor, pose_model): - pose_out = [] - with torch.no_grad(): - pose_inps = pose_inps.to(args.device) - if args.FP16: - pose_inps = pose_inps.half() - hm = pose_model(pose_inps) - - if args.FP16: - hm = hm.float() - for hm_data, infor in zip(hm, pose_infor): - res = pose_post(hm_data.unsqueeze(0), infor) - pose_out.append(res) - return pose_out - - -def preprocess(orig_im): - # PadResize - img = (letterbox_image(orig_im, args.inp_size)) - #(0, 255)--->(0, 1), (3, 384, 640)--->(1, 3, 384, 640) - img = img.div(255.).unsqueeze(0) - return img - - -stream_length = 4 -streams = [torch.cuda.Stream() for i in range(stream_length)] - - -def all_pipeline_time(det_model, pose_model): - times = [] - for i in range(256): - s = time.time() - - rootdir = args.imgsdir - imgnames = [x for x in os.listdir(rootdir) if x.endswith('png') or x.endswith('jpg')] - imgpaths = [os.path.join(rootdir, imgname) for imgname in imgnames] - orig_im_batch = [cv2.imread(imgpath) for imgpath in imgpaths] - - s = time.time() - dims_batch = [(orig_im.shape[1], orig_im.shape[0]) for orig_im in orig_im_batch] - img_batch = [] - for idx, orig_im in enumerate(orig_im_batch): - with torch.cuda.stream(streams[idx % stream_length]): - if args.FP16: - img_batch.append(preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True).to(torch.half))) - else: - img_batch.append(preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True).to(torch.float))) - - torch.cuda.synchronize() - img = torch.cat(img_batch, dim=0) - data = (img, orig_im_batch, imgnames, dims_batch) - - pose_inps, pose_infor = detection(data, det_model) - pose_out = pose(pose_inps, pose_infor, pose_model) - e = time.time() - time_once = e - s - times.append(time_once) - print('iter: %d, time: %.6f' % (i, time_once)) - - avg_times = cal_avg_time(times) - print('avg_times: %.6f' % (avg_times)) - - -def all_module_time(det_model, pose_model): - times_ix = [] - prof_load_det_data = [] - prof_det_forward = [] - prof_det_post = [] - prof_load_pose_data = [] - prof_pose_forward = [] - prof_pose_post = [] - - for i in range(256): - rootdir = args.imgsdir - imgnames = [x for x in os.listdir(rootdir) if x.endswith('png') or x.endswith('jpg')] - imgpaths = [os.path.join(rootdir, imgname) for imgname in imgnames] - - orig_im_batch = [cv2.imread(imgpath) for imgpath in imgpaths] - - t0 = time.time() - dims_batch = [(orig_im.shape[1], orig_im.shape[0]) for orig_im in orig_im_batch] - img_batch = [] - for idx,orig_im in enumerate(orig_im_batch): - with torch.cuda.stream(streams[idx%stream_length]): - if args.FP16: - img_batch.append(preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True).to(torch.half))) - else: - img_batch.append(preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True).to(torch.float))) - - torch.cuda.synchronize() - - img = torch.cat(img_batch, dim=0) - data = (img, orig_im_batch, imgnames, dims_batch) - torch.cuda.synchronize() - t1 = time.time() - prof_load_det_data.append(t1 - t0) - - img, orig_img, im_name, im_dim = data - with torch.no_grad(): - prediction = det_model(img) - torch.cuda.synchronize() - t2 = time.time() - prof_det_forward.append(t2 - t1) - - det_out = [] - prediction, idxs_batch = batched_nms(prediction) - pose_inps, pose_infor = batched_det_post_to_pose_data(prediction, idxs_batch, orig_img, im_dim, im_name) - t3 = time.time() - prof_det_post.append(t3 - t2) - - torch.cuda.synchronize() - t4 = time.time() - prof_load_pose_data.append(t4 - t3) - - pose_out = [] - with torch.no_grad(): - pose_inps = pose_inps.to(args.device) - if args.FP16: - pose_inps = pose_inps.half() - hm = pose_model(pose_inps) - torch.cuda.synchronize() - t5 = time.time() - prof_pose_forward.append(t5 - t4) - - if args.FP16: - hm = hm.float() - for hm_data, infor in zip(hm, pose_infor): - res = pose_post(hm_data.unsqueeze(0), infor) - pose_out.append(res) - torch.cuda.synchronize() - t6 = time.time() - prof_pose_post.append(t6 - t5) - times_ix.append((t6 - t0)) - - time_avg = cal_avg_time(times_ix) - t1_avg = cal_avg_time(prof_load_det_data) - t2_avg = cal_avg_time(prof_det_forward) - t3_avg = cal_avg_time(prof_det_post) - t4_avg = cal_avg_time(prof_load_pose_data) - t5_avg = cal_avg_time(prof_pose_forward) - t6_avg = cal_avg_time(prof_pose_post) - - print(""" - ************************************************* - pipeline_time_avg: {:.6f} s, - prof_load_det_data_avg: {:.6f} s, - prof_det_forward_avg: {:.6f} s, - prof_det_post_avg: {:.6f} s, - prof_load_pose_data_avg: {:.6f} s, - prof_pose_forward_avg: {:.6f} s, - prof_pose_post_avg: {:.6f} s, - """.format(time_avg, t1_avg, t2_avg, t3_avg, t4_avg, t5_avg, t6_avg)) - - -def test_pose(det_model, pose_model): - rootdir = './examples/batch_imgs/singleway' - imgnames = [x for x in os.listdir(rootdir) if x.endswith('png') or x.endswith('jpg')] - imgpaths = [os.path.join(rootdir, imgname) for imgname in imgnames] - - orig_im_batch = [cv2.imread(imgpath) for imgpath in imgpaths] - - dims_batch = [(orig_im.shape[1], orig_im.shape[0]) for orig_im in orig_im_batch] - img_batch = [preprocess(torch.from_numpy(orig_im).pin_memory().to(args.device, non_blocking=True)) for orig_im in orig_im_batch] - - img = torch.cat(img_batch, dim=0) - if args.FP16: - img = img.half() - data = (img, orig_im_batch, imgnames, dims_batch) - - pose_inps, pose_infor = detection(data, det_model) - pose_out = pose(pose_inps, pose_infor, pose_model) - - plot_pose_res(imgpaths[0], pose_out[0], './res.jpg') - - -if __name__ == "__main__": - det_model = load_det_model(args, cfg) - pose_model = load_pose_model() - - if args.pose_res: - test_pose(det_model, pose_model) - else: - if args.flag == 'pipeline': - call_func = all_pipeline_time # test the time of all pipeline - else: - call_func = all_module_time # test the time of six module time - - results = call_func(det_model, pose_model) diff --git a/cv/pose/alphapose/pytorch/scripts/multi_ways_forward.py b/cv/pose/alphapose/pytorch/scripts/multi_ways_forward.py deleted file mode 100755 index cfe757ec8..000000000 --- a/cv/pose/alphapose/pytorch/scripts/multi_ways_forward.py +++ /dev/null @@ -1,463 +0,0 @@ -""" -Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways! -Contain multi process of bs = 1 forward. - -""" - -import os -import sys -import cv2 -import time -import argparse -import torchvision -import numpy as np -import multiprocessing -from torch.multiprocessing import Process -from threading import Thread -import re - -import torch -import torch.nn as nn - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) - -from detector.yolo_cfg import cfg -from detector.yolov5.utils.general import non_max_suppression - -from alphapose.models import builder -from alphapose.utils.config import update_config -from alphapose.utils.transforms import heatmap_to_coord_simple -from alphapose.utils.pPose_nms import pose_nms - -from process_utils import scale_coords, test_transform - - -"""----------------------------- Test Time options -----------------------------""" -parser = argparse.ArgumentParser(description='Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways') -parser.add_argument('--cfg', - type=str, - default="./configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml", - help='experiment configure file name') -parser.add_argument('--checkpoint', - type=str, - default="./pretrained_models/fast_res50_256x192.pth", - help='checkpoint file name') -parser.add_argument('--inp_path', - type=str, - default="./examples/test_stream_videos.txt", - help='the path of input image') -parser.add_argument('--flag', - type=str, - default='pipeline', - choices=['pipeline', 'modules'], - help='test the all pipeline or all sub module') -parser.add_argument('--inp_size', - type=tuple, - default=(640, 384), - help='the input size of model') - -args = parser.parse_args() -cfg = update_config(args.cfg) -args.device = torch.device("cuda:0") -torch.backends.cudnn.benchmark = True -print("Input Size: ", args.inp_size) - - -# load stream -def clean_str(s): - # Cleans a string by replacing special characters with underscore _ - return re.sub(pattern="[|@#!¡·$€%&()=?¿^*;:,¨´><+]", repl="_", string=s) - - -class LoadStreams: - # YOLOv5 streamloader, i.e. `python detect.py --source 'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP streams` - def __init__(self, sources='streams.txt', img_size=640, stride=32, auto=True): - self.mode = 'stream' - self.img_size = img_size - self.stride = stride - - if os.path.isfile(sources): - with open(sources) as f: - sources = [x.strip() for x in f.read().strip().splitlines() if len(x.strip())] - else: - sources = [sources] - - n = len(sources) - self.imgs, self.fps, self.frames, self.threads = [None] * n, [0] * n, [0] * n, [None] * n - self.sources = [clean_str(x) for x in sources] # clean source names for later - self.auto = auto - for i, s in enumerate(sources): # index, source - # Start thread to read frames from video stream - st = f'{i + 1}/{n}: {s}... ' - s = eval(s) if s.isnumeric() else s # i.e. s = '0' local webcam - cap = cv2.VideoCapture(s) - assert cap.isOpened(), f'{st}Failed to open {s}' - w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) - h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) - - self.fps[i] = 25#max(cap.get(cv2.CAP_PROP_FPS) % 100, 0) or 30.0 # 30 FPS fallback - self.frames[i] = max(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)), 0) or float('inf') # infinite stream fallback - - _, self.imgs[i] = cap.read() # guarantee first frame - self.threads[i] = Thread(target=self.update, args=([i, cap, s]), daemon=True) - print(f"{st} Success ({self.frames[i]} frames {w}x{h} at {self.fps[i]:.2f} FPS)") - self.threads[i].start() - print('') # newline - - # check for common shapes - #print([letterbox(x, self.img_size, stride=self.stride, auto=self.auto)[0].shape for x in self.imgs]) - #s = np.stack([letterbox(x, self.img_size, stride=self.stride, auto=self.auto)[0].shape for x in self.imgs]) - #self.rect = np.unique(s, axis=0).shape[0] == 1 # rect inference if all shapes equal - #if not self.rect: - # print('WARNING: Stream shapes differ. For optimal performance supply similarly-shaped streams.') - - def update(self, i, cap, stream): - # Read stream `i` frames in daemon thread - n, f, read = 0, self.frames[i], 1 # frame number, frame array, inference every 'read' frame - while cap.isOpened() and n < f: - n += 1 - # _, self.imgs[index] = cap.read() - cap.grab() - if n % read == 0: - success, im = cap.retrieve() - if success: - self.imgs[i] = im - else: - print('WARNING: Video stream unresponsive, please check your IP camera connection.') - self.imgs[i] *= 0 - cap.open(stream) # re-open stream if signal was lost - time.sleep(1 / self.fps[i]) # wait time - - def __iter__(self): - self.count = -1 - return self - - def __next__(self): - self.count += 1 - if not all(x.is_alive() for x in self.threads) or cv2.waitKey(1) == ord('q'): # q to quit - cv2.destroyAllWindows() - raise StopIteration - - _frame_cnt = self.count - img0 = self.imgs.copy() - - return _frame_cnt, img0 - - def __len__(self): - return len(self.sources) # 1E12 frames = 32 streams at 30 FPS for 30 years - - -def cal_avg_time(times_ix): - assert isinstance(times_ix, list), "The inpust must be a list" - times = times_ix[:] - max_index = times.index(max(times)) - del times[max_index] - - min_index = times.index(min(times)) - del times[min_index] - - time_avg = sum(times) / len(times) - return time_avg - - -def letterbox_image(img, inp_dim=(640, 384)): - '''resize image with unchanged aspect ratio using padding''' - img_w, img_h = img.shape[1], img.shape[0] - w, h = inp_dim - new_w = int(img_w * min(w / img_w, h / img_h)) - new_h = int(img_h * min(w / img_w, h / img_h)) - resized_image = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_CUBIC) - - canvas = np.full((inp_dim[1], inp_dim[0], 3), 128) - - canvas[(h - new_h) // 2:(h - new_h) // 2 + new_h, (w - new_w) // 2:(w - new_w) // 2 + new_w, :] = resized_image - - return canvas - - -def load_det_data(orig_im, inp_path=''): - dim = orig_im.shape[1], orig_im.shape[0] - # PadResize - img = (letterbox_image(orig_im, args.inp_size)) - # BGR--->RGB, (384, 640, 3)--->(3, 384, 640) - img = img[:, :, ::-1].transpose((2, 0, 1)).copy() - # np.array--->torch.tensor, (0, 255)--->(0, 1), (3, 384, 640)--->(1, 3, 384, 640) - img = torch.from_numpy(img).float().div(255.).unsqueeze(0) - im_name = os.path.basename(inp_path) - return (img, orig_im, im_name, dim) - - -def load_det_model(opt, cfg): - weights = "../yolov5/yolov5s.pt" - from detector.yolov5.models.experimental import attempt_download, attempt_load # scoped to avoid circular import - det_model = attempt_load(weights, map_location=None) - det_model.to(args.device) - det_model.eval() - return det_model - - -def det_forward(inps, det_model): - img, orig_img, im_name, im_dim = inps - img = img.to(args.device) - with torch.no_grad(): - prediction = det_model(img) - det_model_out = (prediction, orig_img, im_dim, im_name) - return det_model_out - - -def nms(prediction, conf_thres=0.25, iou_thres=0.45, max_det=100): - xc = prediction[..., 4] > conf_thres # candidates - output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0] - for xi, x in enumerate(prediction): # image index, image inference - x = x[xc[xi]] # confidence - - boxes, scores = x[:, :4], x[:, 4] - i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS - if i.shape[0] > max_det: # limit detections - i = i[:max_det] - - output[xi] = x[i] - return output - - -def det_post(det_model_out): - prediction, orig_img, im_shape, im_name = det_model_out - - # prediction = non_max_suppression(prediction, 0.25, 0.45, None, False, max_det=100) - prediction = nms(prediction) - prediction = prediction[0] # torch.tensor(num_objs x 6) - prediction[:, :4] = scale_coords(args.inp_size, prediction[:, :4], im_shape).round() - - dets = prediction.cpu() - boxes = dets[:, :4] - - scores = dets[:, 4:5] - labels = dets[:, 5:6] - flag = labels[:, 0] == 1. # select the person - - ids = torch.zeros(scores.shape) - - inps_idx = torch.zeros(boxes.size(0), 3, 256, 192) - cropped_boxes = torch.zeros(boxes.size(0), 4) - det_res = (orig_img, im_name, boxes[flag], scores[flag], ids[flag], inps_idx[flag], cropped_boxes[flag]) - - return det_res - - -# Stage2: pose estimation(alphapose) -def load_pose_data(det_res): - with torch.no_grad(): - orig_img, im_name, boxes, scores, ids, inps, cropped_boxes = det_res - for j, box in enumerate(boxes): - inps[j], cropped_box = test_transform(orig_img, box) - cropped_boxes[j] = torch.FloatTensor(cropped_box) - - pose_inps = (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) - return pose_inps - - -def load_pose_model(): - pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - print('Loading pose model from %s...' % (args.checkpoint,)) - pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) - pose_model.to(args.device) - pose_model.eval() - return pose_model - - -def pose_forward(pose_inps, pose_model): - with torch.no_grad(): - (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) = pose_inps - inps = inps.to(args.device) - hm = pose_model(inps) - pose_model_out = (boxes, scores, ids, hm, cropped_boxes, orig_img, im_name) - return pose_model_out - - -def pose_post(pose_model_out): - boxes, scores, ids, hm_data, cropped_boxes, orig_img, im_name = pose_model_out - hm_data = hm_data.cpu() - - orig_img = np.array(orig_img, dtype=np.uint8)[:, :, ::-1] - - eval_joints = [*range(0,17)] - hm_size = (64, 48) - min_box_area = 0 - - pose_coords = [] - pose_scores = [] - for i in range(hm_data.shape[0]): - bbox = cropped_boxes[i].tolist() - pose_coord, pose_score = heatmap_to_coord_simple(hm_data[i][eval_joints], bbox, hm_shape=hm_size, norm_type=None) - pose_coords.append(torch.from_numpy(pose_coord).unsqueeze(0)) - pose_scores.append(torch.from_numpy(pose_score).unsqueeze(0)) - - preds_img = torch.cat(pose_coords) - preds_scores = torch.cat(pose_scores) - boxes, scores, ids, preds_img, preds_scores, pick_ids = \ - pose_nms(boxes, scores, ids, preds_img, preds_scores, min_box_area) - - _result = [] - for k in range(len(scores)): - _result.append( - { - 'keypoints':preds_img[k], - 'kp_score':preds_scores[k], - 'proposal_score': torch.mean(preds_scores[k]) + scores[k] + 1.25 * max(preds_scores[k]), - 'idx':ids[k], - 'box':[boxes[k][0], boxes[k][1], boxes[k][2]-boxes[k][0],boxes[k][3]-boxes[k][1]] - } - ) - - result = { - 'imgname': im_name, - 'result': _result - } - return result - - -def all_pipeline_time(inp_path, det_model, pose_model, q): - dataset = LoadStreams(inp_path) - - times_ix = [] - for frame_cnt, img in dataset: - if img[0] is None or frame_cnt == 256: - break - torch.cuda.synchronize() - s = time.time() - - inps = load_det_data(img[0]) - det_model_out = det_forward(inps, det_model) - det_res = det_post(det_model_out) - pose_inps = load_pose_data(det_res) - if pose_inps[0].shape[0] == 0: - continue - pose_model_out = pose_forward(pose_inps, pose_model) - pose_res = pose_post(pose_model_out) - torch.cuda.synchronize() - e = time.time() - times_ix.append((e - s)) - - if frame_cnt % 10 == 0: - print('iter: %d, %.6f ms' % (frame_cnt, (e - s) * 1E3)) - - time_avg = cal_avg_time(times_ix) - - q.put(time_avg) - - -def all_module_time(inp_path, det_model, pose_model, q): - dataset = LoadStreams(inp_path) - - times_ix = [] - prof_load_det_data = [] - prof_det_forward = [] - prof_det_post = [] - prof_load_pose_data = [] - prof_pose_forward = [] - prof_pose_post = [] - for frame_cnt, img in dataset: - if img[0] is None or frame_cnt == 256: - break - torch.cuda.synchronize() - t0 = time.time() - - inps = load_det_data(img[0]) - torch.cuda.synchronize() - t1 = time.time() - prof_load_det_data.append(t1 - t0) - - det_model_out = det_forward(inps, det_model) - torch.cuda.synchronize() - t2 = time.time() - prof_det_forward.append(t2 - t1) - - det_res = det_post(det_model_out) - torch.cuda.synchronize() - t3 = time.time() - prof_det_post.append(t3 - t2) - - pose_inps = load_pose_data(det_res) - torch.cuda.synchronize() - t4 = time.time() - prof_load_pose_data.append(t4 - t3) - - if pose_inps[0].shape[0] == 0: - continue - - pose_model_out = pose_forward(pose_inps, pose_model) - torch.cuda.synchronize() - t5 = time.time() - prof_pose_forward.append(t5 - t4) - - pose_res = pose_post(pose_model_out) - torch.cuda.synchronize() - t6 = time.time() - prof_pose_post.append(t6 - t5) - - times_ix.append((t6 - t0)) - - if frame_cnt % 10 == 0: - print('iter: %d, %.6f ms' % (frame_cnt, (t6 - t0) * 1E3)) - - time_avg = cal_avg_time(times_ix) - prof_load_det_data_avg = cal_avg_time(prof_load_det_data) - prof_det_forward_avg = cal_avg_time(prof_det_forward) - prof_det_post_avg = cal_avg_time(prof_det_post) - prof_load_pose_data_avg = cal_avg_time(prof_load_pose_data) - prof_pose_forward_avg = cal_avg_time(prof_pose_forward) - prof_pose_post_avg = cal_avg_time(prof_pose_post) - - q.put([time_avg, prof_load_det_data_avg, prof_det_forward_avg, prof_det_post_avg, prof_load_pose_data_avg, prof_pose_forward_avg, prof_pose_post_avg]) - - -if __name__ == "__main__": - - torch.multiprocessing.set_start_method('spawn', force=True) - with open(args.inp_path, 'r') as f: - inp_path_list = f.read().splitlines() - - n = len(inp_path_list) - assert n > 0 - print('num process:', n) - all_pipelines = [] - all_pipelines_q = torch.multiprocessing.Queue() - - if args.flag == 'pipeline': - call_func = all_pipeline_time # test the time of all pipeline - else: - call_func = all_module_time # test the time of six module time - - # the number of process according the videos txt file - for i in range(n): - det_model = load_det_model(args, cfg) - pose_model = load_pose_model() - p = Process(target=call_func, args=(inp_path_list[i], det_model, pose_model, all_pipelines_q)) - all_pipelines.append(p) - - for p in all_pipelines: - p.start() - - - if args.flag == 'pipeline': - results = [all_pipelines_q.get() for p in all_pipelines] - print('pipeline_num: {}, pipeline_time: {}, pipeline_time_avg: {:.6f}'.format(n, results, sum(results) / len(results))) - else: - results = np.array([all_pipelines_q.get() for p in all_pipelines]) - avg_results = tuple(np.sum(results, axis=0) / n) - - print(""" - ************************************************* - pipeline_num: {}, - pipeline_time: {}, - pipeline_time_avg: {:.6f} ms, - prof_load_det_data_avg: {:.6f} ms, - prof_det_forward_avg: {:.6f} ms, - prof_det_post_avg: {:.6f} ms, - prof_load_pose_data_avg: {:.6f} ms, - prof_pose_forward_avg: {:.6f} ms, - prof_pose_post_avg: {:.6f} ms, - sum_prof: {:.6f} ms - """ - .format(n, results, *avg_results, sum(avg_results)-avg_results[0])) diff --git a/cv/pose/alphapose/pytorch/scripts/multi_ways_loop.py b/cv/pose/alphapose/pytorch/scripts/multi_ways_loop.py deleted file mode 100755 index f4b50b3fd..000000000 --- a/cv/pose/alphapose/pytorch/scripts/multi_ways_loop.py +++ /dev/null @@ -1,346 +0,0 @@ -""" -Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways! -single process: process data by loop -single process: model forward(batch_size = the number of loop for process data) -""" - -import os -import re -import sys -import cv2 -import time -import argparse -import torchvision -import numpy as np -import multiprocessing -# from multiprocessing import Process -from threading import Thread -from torch.multiprocessing import Process - -import torch -import torch.nn as nn - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) - -from detector.yolo_cfg import cfg -from detector.yolov5.utils.general import non_max_suppression - -from alphapose.models import builder -from alphapose.utils.config import update_config -from alphapose.utils.transforms import heatmap_to_coord_simple -from alphapose.utils.pPose_nms import pose_nms - -from process_utils import scale_coords, test_transform - - -"""----------------------------- Test Time options -----------------------------""" -parser = argparse.ArgumentParser(description='Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways') -parser.add_argument('--cfg', - type=str, - default="./configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml", - help='experiment configure file name') -parser.add_argument('--checkpoint', - type=str, - default="./pretrained_models/fast_res50_256x192.pth", - help='checkpoint file name') -parser.add_argument('--inp_path', - type=str, - default="./examples/test_stream_jpg.txt", - help='the path of input image') -parser.add_argument('--flag', - type=str, - default='pipeline', - help='test all pipeline or all parts') -parser.add_argument('--inp_size', - type=tuple, - default=(640, 384), - help='the input size of model') -args = parser.parse_args() -cfg = update_config(args.cfg) -args.device = torch.device("cuda:0") -torch.backends.cudnn.benchmark = True -print("Input Size: ", args.inp_size) - - -# ================================Step1 Load Video Stream================================ -def clean_str(s): - # Cleans a string by replacing special characters with underscore _ - return re.sub(pattern="[|@#!¡·$€%&()=?¿^*;:,¨´><+]", repl="_", string=s) - - -class LoadStreams: - # YOLOv5 streamloader, i.e. `python detect.py --source 'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP streams` - def __init__(self, sources='streams.txt', img_size=640, stride=32, auto=True): - self.mode = 'stream' - self.img_size = img_size - self.stride = stride - - if os.path.isfile(sources): - with open(sources) as f: - sources = [x.strip() for x in f.read().strip().splitlines() if len(x.strip())] - else: - sources = [sources] - - n = len(sources) - self.imgs, self.fps, self.frames, self.threads = [None] * n, [0] * n, [0] * n, [None] * n - self.sources = [clean_str(x) for x in sources] # clean source names for later - self.auto = auto - for i, s in enumerate(sources): # index, source - # Start thread to read frames from video stream - st = f'{i + 1}/{n}: {s}... ' - s = eval(s) if s.isnumeric() else s # i.e. s = '0' local webcam - cap = cv2.VideoCapture(s) - assert cap.isOpened(), f'{st}Failed to open {s}' - w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) - h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) - - self.fps[i] = 25#max(cap.get(cv2.CAP_PROP_FPS) % 100, 0) or 30.0 # 30 FPS fallback - self.frames[i] = max(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)), 0) or float('inf') # infinite stream fallback - - _, self.imgs[i] = cap.read() # guarantee first frame - self.threads[i] = Thread(target=self.update, args=([i, cap, s]), daemon=True) - print(f"{st} Success ({self.frames[i]} frames {w}x{h} at {self.fps[i]:.2f} FPS)") - self.threads[i].start() - print('') # newline - - # check for common shapes - #print([letterbox(x, self.img_size, stride=self.stride, auto=self.auto)[0].shape for x in self.imgs]) - #s = np.stack([letterbox(x, self.img_size, stride=self.stride, auto=self.auto)[0].shape for x in self.imgs]) - #self.rect = np.unique(s, axis=0).shape[0] == 1 # rect inference if all shapes equal - #if not self.rect: - # print('WARNING: Stream shapes differ. For optimal performance supply similarly-shaped streams.') - - def update(self, i, cap, stream): - # Read stream `i` frames in daemon thread - n, f, read = 0, self.frames[i], 1 # frame number, frame array, inference every 'read' frame - while cap.isOpened() and n < f: - n += 1 - # _, self.imgs[index] = cap.read() - cap.grab() - if n % read == 0: - success, im = cap.retrieve() - if success: - self.imgs[i] = im - else: - print('WARNING: Video stream unresponsive, please check your IP camera connection.') - self.imgs[i] *= 0 - cap.open(stream) # re-open stream if signal was lost - time.sleep(1 / self.fps[i]) # wait time - - def __iter__(self): - self.count = -1 - return self - - def __next__(self): - self.count += 1 - if not all(x.is_alive() for x in self.threads) or cv2.waitKey(1) == ord('q'): # q to quit - cv2.destroyAllWindows() - raise StopIteration - - _frame_cnt = self.count - img0 = self.imgs.copy() - - return _frame_cnt, img0 - - def __len__(self): - return len(self.sources) # 1E12 frames = 32 streams at 30 FPS for 30 years - - -def cal_avg_time(times_ix): - assert isinstance(times_ix, list), "The inpust must be a list" - times = times_ix[:] - max_index = times.index(max(times)) - del times[max_index] - - min_index = times.index(min(times)) - del times[min_index] - - time_avg = sum(times) / len(times) - return time_avg - - -def letterbox_image(img, inp_dim=(640, 384)): - '''resize image with unchanged aspect ratio using padding''' - img_w, img_h = img.shape[1], img.shape[0] - w, h = inp_dim - new_w = int(img_w * min(w / img_w, h / img_h)) - new_h = int(img_h * min(w / img_w, h / img_h)) - resized_image = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_CUBIC) - - canvas = np.full((inp_dim[1], inp_dim[0], 3), 128) - - canvas[(h - new_h) // 2:(h - new_h) // 2 + new_h, (w - new_w) // 2:(w - new_w) // 2 + new_w, :] = resized_image - - return canvas - - -# ================================Step2 Yolov5s Forward=========================== -def load_det_data(orig_im, inp_path): - dim = orig_im.shape[1], orig_im.shape[0] - # PadResize - img = (letterbox_image(orig_im, args.inp_size)) - # BGR--->RGB, (384, 640, 3)--->(3, 384, 640) - img = img[:, :, ::-1].transpose((2, 0, 1)).copy() - # np.array--->torch.tensor, (0, 255)--->(0, 1), (3, 384, 640)--->(1, 3, 384, 640) - img = torch.from_numpy(img).float().div(255.).unsqueeze(0) - im_name = os.path.basename(inp_path) - return (img, orig_im, dim, im_name) - - -def load_det_model(opt, cfg): - weights = "../yolov5/yolov5s.pt" - from detector.yolov5.models.experimental import attempt_download, attempt_load # scoped to avoid circular import - det_model = attempt_load(weights, map_location=None) - det_model.to(args.device) - det_model.eval() - return det_model - - -def nms(prediction, conf_thres=0.25, iou_thres=0.45, max_det=100): - xc = prediction[..., 4] > conf_thres # candidates - output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0] - for xi, x in enumerate(prediction): # image index, image inference - x = x[xc[xi]] # confidence - - boxes, scores = x[:, :4], x[:, 4] - i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS - if i.shape[0] > max_det: # limit detections - i = i[:max_det] - - output[xi] = x[i] - return output - - -def det_post(det_model_out): - prediction, orig_img, im_shape, im_name = det_model_out - # prediction = non_max_suppression(prediction, 0.5, 0.5, None, False, max_det=100) # list - prediction = nms(prediction) - prediction = prediction[0] # torch.tensor(num_objs x 6) - prediction[:, :4] = scale_coords(args.inp_size, prediction[:, :4], im_shape).round() - - dets = prediction.cpu() - boxes = dets[:, :4] - - scores = dets[:, 4:5] - labels = dets[:, 5:6] - flag = labels[:, 0] == 1. # select the person - - ids = torch.zeros(scores.shape) - - inps_idx = torch.zeros(boxes.size(0), 3, 256, 192) - cropped_boxes = torch.zeros(boxes.size(0), 4) - det_res = (orig_img, im_name, boxes[flag], scores[flag], ids[flag], inps_idx[flag], cropped_boxes[flag]) - return det_res - - -# ================================Step3 Alphapose Forward=========================== -def load_pose_data(det_res): - with torch.no_grad(): - orig_img, im_name, boxes, scores, ids, inps, cropped_boxes = det_res - for j, box in enumerate(boxes): - inps[j], cropped_box = test_transform(orig_img, box) - cropped_boxes[j] = torch.FloatTensor(cropped_box) - - pose_inps = (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) - return pose_inps - - -def load_pose_model(): - pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - print('Loading pose model from %s...' % (args.checkpoint,)) - pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) - pose_model.to(args.device) - pose_model.eval() - return pose_model - - -def pose_post(pose_model_out): - hm, orig_img, im_name, boxes, scores, ids, cropped_boxes = pose_model_out - hm_data = hm.cpu() - orig_img = np.array(orig_img, dtype=np.uint8)[:, :, ::-1] - - eval_joints = [*range(0,17)] - hm_size = (64, 48) - min_box_area = 0 - - pose_coords = [] - pose_scores = [] - for i in range(hm_data.shape[0]): - bbox = cropped_boxes[i].tolist() - pose_coord, pose_score = heatmap_to_coord_simple(hm_data[i][eval_joints], bbox, hm_shape=hm_size, norm_type=None) - pose_coords.append(torch.from_numpy(pose_coord).unsqueeze(0)) - pose_scores.append(torch.from_numpy(pose_score).unsqueeze(0)) - - preds_img = torch.cat(pose_coords) - preds_scores = torch.cat(pose_scores) - boxes, scores, ids, preds_img, preds_scores, pick_ids = \ - pose_nms(boxes, scores, ids, preds_img, preds_scores, min_box_area) - - _result = [] - for k in range(len(scores)): - _result.append( - { - 'keypoints':preds_img[k], - 'kp_score':preds_scores[k], - 'proposal_score': torch.mean(preds_scores[k]) + scores[k] + 1.25 * max(preds_scores[k]), - 'idx':ids[k], - 'box':[boxes[k][0], boxes[k][1], boxes[k][2]-boxes[k][0],boxes[k][3]-boxes[k][1]] - } - ) - - result = { - 'imgname': im_name, - 'result': _result - } - return result - - -def run(): - torch.multiprocessing.set_start_method('spawn', force=True) - - det_model = load_det_model(args, cfg) - pose_model = load_pose_model() - - with open(args.inp_path, 'r') as f: - inp_path_list = f.read().splitlines() - - n = len(inp_path_list) - assert n > 0 - - # stage1 loop load data(detection) - det_inps0 = [] - for i in range(n): - img = cv2.imread(inp_path_list[i]) - det_inps_idx = load_det_data(img, '') - det_inps0.append(det_inps_idx) - - det_inps = [x[0] for x in det_inps0] - det_inps = torch.cat(det_inps, dim=0) - - # stage2 yolov5s forward - with torch.no_grad(): - det_inps = det_inps.to(args.device) - det_out = det_model(det_inps) - - # stage3 loop post process(detection) - det_res = [] - for i in range(n): - det_res_idx = det_post((det_out[i:i+1],) + det_inps0[i][1:]) - det_res.append(det_res_idx) - - # stage4 loop load data(pose) - pose_inps0 = [load_pose_data(det_res[i]) for i in range(n)] - pose_inps = [x[0] for x in pose_inps0] - pose_inps = torch.cat(pose_inps, dim=0) - - # stage5 alphapose forward - with torch.no_grad(): - pose_inps = pose_inps.to(args.device) - pose_model_out = pose_model(pose_inps) - - pose_res = [pose_post((pose_model_out[i:i+1], ) + pose_inps0[i][1:]) for i in range(n)] - - -if __name__ == '__main__': - run() diff --git a/cv/pose/alphapose/pytorch/scripts/multi_ways_process.py b/cv/pose/alphapose/pytorch/scripts/multi_ways_process.py deleted file mode 100755 index 882def8e3..000000000 --- a/cv/pose/alphapose/pytorch/scripts/multi_ways_process.py +++ /dev/null @@ -1,394 +0,0 @@ -""" -Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways! -multi process: process data -single process: model forward(batch_size = the number of process data) -""" - -import os -import re -import sys -import cv2 -import time -import argparse -import torchvision -import numpy as np -import multiprocessing -from threading import Thread -from torch.multiprocessing import Process - -import torch -import torch.nn as nn - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) - -from detector.yolo_cfg import cfg -from detector.yolov5.utils.general import non_max_suppression - -from alphapose.models import builder -from alphapose.utils.config import update_config -from alphapose.utils.transforms import heatmap_to_coord_simple -from alphapose.utils.pPose_nms import pose_nms - -from process_utils import scale_coords, test_transform - - -"""----------------------------- Test Time options -----------------------------""" -parser = argparse.ArgumentParser(description='Test the time of pipeline or modules(yolov5s and alphapose) for a single person of multi ways') -parser.add_argument('--cfg', - type=str, - default="./configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml", - help='experiment configure file name') -parser.add_argument('--checkpoint', - type=str, - default="./pretrained_models/fast_res50_256x192.pth", - help='checkpoint file name') -parser.add_argument('--inp_path', - type=str, - default="./examples/test_stream_jpg.txt", - help='the path of input image') -parser.add_argument('--flag', - type=str, - default='pipeline', - help='test all pipeline or all parts') -parser.add_argument('--inp_size', - type=tuple, - default=(640, 384), - help='the input size of model') - -args = parser.parse_args() -cfg = update_config(args.cfg) -args.device = torch.device("cuda:0") -torch.backends.cudnn.benchmark = True -print("Input Size: ", args.inp_size) - - -# ================================Step1 Load Video Stream================================ -def clean_str(s): - # Cleans a string by replacing special characters with underscore _ - return re.sub(pattern="[|@#!¡·$€%&()=?¿^*;:,¨´><+]", repl="_", string=s) - - -class LoadStreams: - # YOLOv5 streamloader, i.e. `python detect.py --source 'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP streams` - def __init__(self, sources='streams.txt', img_size=640, stride=32, auto=True): - self.mode = 'stream' - self.img_size = img_size - self.stride = stride - - if os.path.isfile(sources): - with open(sources) as f: - sources = [x.strip() for x in f.read().strip().splitlines() if len(x.strip())] - else: - sources = [sources] - - n = len(sources) - self.imgs, self.fps, self.frames, self.threads = [None] * n, [0] * n, [0] * n, [None] * n - self.sources = [clean_str(x) for x in sources] # clean source names for later - self.auto = auto - for i, s in enumerate(sources): # index, source - # Start thread to read frames from video stream - st = f'{i + 1}/{n}: {s}... ' - s = eval(s) if s.isnumeric() else s # i.e. s = '0' local webcam - cap = cv2.VideoCapture(s) - assert cap.isOpened(), f'{st}Failed to open {s}' - w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) - h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) - - self.fps[i] = 25#max(cap.get(cv2.CAP_PROP_FPS) % 100, 0) or 30.0 # 30 FPS fallback - self.frames[i] = max(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)), 0) or float('inf') # infinite stream fallback - - _, self.imgs[i] = cap.read() # guarantee first frame - self.threads[i] = Thread(target=self.update, args=([i, cap, s]), daemon=True) - print(f"{st} Success ({self.frames[i]} frames {w}x{h} at {self.fps[i]:.2f} FPS)") - self.threads[i].start() - print('') # newline - - # check for common shapes - #print([letterbox(x, self.img_size, stride=self.stride, auto=self.auto)[0].shape for x in self.imgs]) - #s = np.stack([letterbox(x, self.img_size, stride=self.stride, auto=self.auto)[0].shape for x in self.imgs]) - #self.rect = np.unique(s, axis=0).shape[0] == 1 # rect inference if all shapes equal - #if not self.rect: - # print('WARNING: Stream shapes differ. For optimal performance supply similarly-shaped streams.') - - def update(self, i, cap, stream): - # Read stream `i` frames in daemon thread - n, f, read = 0, self.frames[i], 1 # frame number, frame array, inference every 'read' frame - while cap.isOpened() and n < f: - n += 1 - # _, self.imgs[index] = cap.read() - cap.grab() - if n % read == 0: - success, im = cap.retrieve() - if success: - self.imgs[i] = im - else: - print('WARNING: Video stream unresponsive, please check your IP camera connection.') - self.imgs[i] *= 0 - cap.open(stream) # re-open stream if signal was lost - time.sleep(1 / self.fps[i]) # wait time - - def __iter__(self): - self.count = -1 - return self - - def __next__(self): - self.count += 1 - if not all(x.is_alive() for x in self.threads) or cv2.waitKey(1) == ord('q'): # q to quit - cv2.destroyAllWindows() - raise StopIteration - - _frame_cnt = self.count - img0 = self.imgs.copy() - - return _frame_cnt, img0 - - def __len__(self): - return len(self.sources) # 1E12 frames = 32 streams at 30 FPS for 30 years - - -def cal_avg_time(times_ix): - assert isinstance(times_ix, list), "The inpust must be a list" - times = times_ix[:] - max_index = times.index(max(times)) - del times[max_index] - - min_index = times.index(min(times)) - del times[min_index] - - time_avg = sum(times) / len(times) - return time_avg - - -def letterbox_image(img, inp_dim=(640, 384)): - '''resize image with unchanged aspect ratio using padding''' - img_w, img_h = img.shape[1], img.shape[0] - w, h = inp_dim - new_w = int(img_w * min(w / img_w, h / img_h)) - new_h = int(img_h * min(w / img_w, h / img_h)) - resized_image = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_CUBIC) - - canvas = np.full((inp_dim[1], inp_dim[0], 3), 128) - - canvas[(h - new_h) // 2:(h - new_h) // 2 + new_h, (w - new_w) // 2:(w - new_w) // 2 + new_w, :] = resized_image - - return canvas - - -# ================================Step2 Yolov5s Forward=========================== -def load_det_data(orig_im, inp_path, q): - dim = orig_im.shape[1], orig_im.shape[0] - # PadResize - img = (letterbox_image(orig_im, args.inp_size)) - # BGR--->RGB, (384, 640, 3)--->(3, 384, 640) - img = img[:, :, ::-1].transpose((2, 0, 1)).copy() - # np.array--->torch.tensor, (0, 255)--->(0, 1), (3, 384, 640)--->(1, 3, 384, 640) - img = torch.from_numpy(img).float().div(255.).unsqueeze(0) - im_name = os.path.basename(inp_path) - q.put((img, orig_im, dim, im_name)) - - -def load_det_data_(inp_path_, inp_path, q): - - dataset = LoadStreams(inp_path_) - for j, img in dataset: - orig_im = img[0] - break - - dim = orig_im.shape[1], orig_im.shape[0] - # PadResize - img = (letterbox_image(orig_im, args.inp_size)) - # BGR--->RGB, (384, 640, 3)--->(3, 384, 640) - img = img[:, :, ::-1].transpose((2, 0, 1)).copy() - # np.array--->torch.tensor, (0, 255)--->(0, 1), (3, 384, 640)--->(1, 3, 384, 640) - img = torch.from_numpy(img).float().div(255.).unsqueeze(0) - im_name = os.path.basename(inp_path) - q.put((img, orig_im, im_name, dim)) - - -def load_det_model(opt, cfg): - weights = "../yolov5/yolov5s.pt" - from detector.yolov5.models.experimental import attempt_download, attempt_load # scoped to avoid circular import - det_model = attempt_load(weights, map_location=None) - det_model.to(args.device) - det_model.eval() - return det_model - - -def nms(prediction, conf_thres=0.25, iou_thres=0.45, max_det=100): - xc = prediction[..., 4] > conf_thres # candidates - output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0] - for xi, x in enumerate(prediction): # image index, image inference - x = x[xc[xi]] # confidence - - boxes, scores = x[:, :4], x[:, 4] - i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS - if i.shape[0] > max_det: # limit detections - i = i[:max_det] - - output[xi] = x[i] - return output - - -def det_post(det_model_out, q): - prediction, orig_img, im_shape, im_name = det_model_out - # prediction = non_max_suppression(prediction, 0.5, 0.5, None, False, max_det=100) # list - prediction = nms(prediction) - prediction = prediction[0] # torch.tensor(num_objs x 6) - prediction[:, :4] = scale_coords(args.inp_size, prediction[:, :4], im_shape).round() - - dets = prediction.cpu() - boxes = dets[:, :4] - - scores = dets[:, 4:5] - labels = dets[:, 5:6] - flag = labels[:, 0] == 1. # select the person - - ids = torch.zeros(scores.shape) - - inps_idx = torch.zeros(boxes.size(0), 3, 256, 192) - cropped_boxes = torch.zeros(boxes.size(0), 4) - det_res = (orig_img, im_name, boxes[flag], scores[flag], ids[flag], inps_idx[flag], cropped_boxes[flag]) - q.put(det_res) - - -# ================================Step3 Alphapose Forward=========================== -def load_pose_data(det_res, q): - with torch.no_grad(): - orig_img, im_name, boxes, scores, ids, inps, cropped_boxes = det_res - for j, box in enumerate(boxes): - inps[j], cropped_box = test_transform(orig_img, box) - cropped_boxes[j] = torch.FloatTensor(cropped_box) - - pose_inps = (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) - q.put(pose_inps) - - -def load_pose_model(): - pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - print('Loading pose model from %s...' % (args.checkpoint,)) - pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) - pose_model.to(args.device) - pose_model.eval() - return pose_model - - -def pose_post(pose_model_out, q): - hm, orig_img, im_name, boxes, scores, ids, cropped_boxes = pose_model_out - hm_data = hm.cpu() - orig_img = np.array(orig_img, dtype=np.uint8)[:, :, ::-1] - - eval_joints = [*range(0,17)] - hm_size = (64, 48) - min_box_area = 0 - - pose_coords = [] - pose_scores = [] - for i in range(hm_data.shape[0]): - bbox = cropped_boxes[i].tolist() - pose_coord, pose_score = heatmap_to_coord_simple(hm_data[i][eval_joints], bbox, hm_shape=hm_size, norm_type=None) - pose_coords.append(torch.from_numpy(pose_coord).unsqueeze(0)) - pose_scores.append(torch.from_numpy(pose_score).unsqueeze(0)) - - preds_img = torch.cat(pose_coords) - preds_scores = torch.cat(pose_scores) - boxes, scores, ids, preds_img, preds_scores, pick_ids = \ - pose_nms(boxes, scores, ids, preds_img, preds_scores, min_box_area) - - _result = [] - for k in range(len(scores)): - _result.append( - { - 'keypoints':preds_img[k], - 'kp_score':preds_scores[k], - 'proposal_score': torch.mean(preds_scores[k]) + scores[k] + 1.25 * max(preds_scores[k]), - 'idx':ids[k], - 'box':[boxes[k][0], boxes[k][1], boxes[k][2]-boxes[k][0],boxes[k][3]-boxes[k][1]] - } - ) - - result = { - 'imgname': im_name, - 'result': _result - } - q.put(result) - - -def run(): - torch.multiprocessing.set_start_method('spawn', force=True) - - det_model = load_det_model(args, cfg) - pose_model = load_pose_model() - - with open(args.inp_path, 'r') as f: - inp_path_list = f.read().splitlines() - - n = len(inp_path_list) - assert n > 0 - - # stage1 multiprocess load data(detection) - stage1 = [] - stage1_q = torch.multiprocessing.Queue() - for i in range(n): - img = cv2.imread(inp_path_list[i]) - p1 = Process(target=load_det_data, args=(img, '', stage1_q)) - stage1.append(p1) - - for p in stage1: - p.start() - - det_inps0 = [stage1_q.get() for p in stage1] - - det_inps = torch.cat(det_inps, dim=0) - - # stage2 yolov5s forward - with torch.no_grad(): - det_inps = det_inps.to(args.device) - det_out = det_model(det_inps) - - # stage3 multiprocess post process(detection) - stage3 = [] - stage3_q = torch.multiprocessing.Queue() - for i in range(n): - p3 = Process(target=det_post, args=((det_out[i:i+1],) + det_inps0[i][1:], stage3_q)) - stage3.append(p3) - - for p3 in stage3: - p3.start() - det_res = [stage3_q.get() for p3 in stage3] - - # stage4 multiprocess load data(pose) - stage4 = [] - stage4_q = torch.multiprocessing.Queue() - - for i in range(n): - p4 = Process(target=load_pose_data, args=(det_res[i], stage4_q)) - stage4.append(p4) - - for p4 in stage4: - p4.start() - pose_inps0 = [stage4_q.get() for p4 in stage4] - - pose_inps = [x[0] for x in pose_inps0] - pose_inps = torch.cat(pose_inps, dim=0) - - # stage5 alphapose forward - with torch.no_grad(): - pose_inps = pose_inps.to(args.device) - pose_model_out = pose_model(pose_inps) - - # stage6 multiprocess post process(alphapose) - stage6 = [] - stage6_q = torch.multiprocessing.Queue() - - for i in range(n): - p6 = Process(target=pose_post, args=((pose_model_out[i:i+1], ) + pose_inps0[i][1:] , stage6_q)) - stage6.append(p6) - - for p6 in stage6: - p6.start() - pose_res = [stage6_q.get() for p6 in stage6] - - -if __name__ == '__main__': - run() diff --git a/cv/pose/alphapose/pytorch/scripts/process_utils.py b/cv/pose/alphapose/pytorch/scripts/process_utils.py deleted file mode 100755 index d165c7d5e..000000000 --- a/cv/pose/alphapose/pytorch/scripts/process_utils.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 - -import os -import cv2 -import numpy as np -import torch - - -def letterbox_image(img, inp_dim): - '''resize image with unchanged aspect ratio using padding''' - img_w, img_h = img.shape[1], img.shape[0] - w, h = inp_dim - new_w = int(img_w * min(w / img_w, h / img_h)) - new_h = int(img_h * min(w / img_w, h / img_h)) - resized_image = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_CUBIC) - - canvas = np.full((inp_dim[1], inp_dim[0], 3), 128) - - canvas[(h - new_h) // 2:(h - new_h) // 2 + new_h, (w - new_w) // 2:(w - new_w) // 2 + new_w, :] = resized_image - - return canvas - - -def prep_image(img, inp_dim): - """ - Prepare image for inputting to the neural network. - - Returns a Variable - """ - - orig_im = cv2.imread(img) - dim = orig_im.shape[1], orig_im.shape[0] - img = (letterbox_image(orig_im, (inp_dim, inp_dim))) - img_ = img[:, :, ::-1].transpose((2, 0, 1)).copy() - img_ = torch.from_numpy(img_).float().div(255.0).unsqueeze(0) - return img_, orig_im, dim - - -def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None): - # Rescale coords (xyxy) from img1_shape to img0_shape - gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1]) # gain = old / new - # pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2 # wh padding - pad = (img1_shape[0] - img0_shape[0] * gain) / 2, (img1_shape[1] - img0_shape[1] * gain) / 2# wh padding - - coords[:, [0, 2]] -= pad[0] # x padding - coords[:, [1, 3]] -= pad[1] # y padding - coords[:, :4] /= gain - return coords - -def scale_coords_(img1_shape, coords, img0_shape, ratio_pad=None): - # Rescale coords (xyxy) from img1_shape to img0_shape - if ratio_pad is None: # calculate from img0_shape - gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1]) # gain = old / new - # pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2 # wh padding - pad = (img1_shape[0] - img0_shape[0] * gain) / 2, (img1_shape[1] - img0_shape[1] * gain) / 2# wh padding - else: - gain = ratio_pad[0][0] - pad = ratio_pad[1] - - coords[:, [0, 2]] -= pad[0] # x padding - coords[:, [1, 3]] -= pad[1] # y padding - coords[:, :4] /= gain - clip_coords(coords, img0_shape) - return coords - - -def clip_coords(boxes, shape): - # Clip bounding xyxy bounding boxes to image shape (height, width) - if isinstance(boxes, torch.Tensor): # faster individually - boxes[:, 0].clamp_(0, shape[1]) # x1 - boxes[:, 1].clamp_(0, shape[0]) # y1 - boxes[:, 2].clamp_(0, shape[1]) # x2 - boxes[:, 3].clamp_(0, shape[0]) # y2 - else: # np.array (faster grouped) - boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1]) # x1, x2 - boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2 - - -def test_transform(src, bbox): - from alphapose.utils.bbox import _box_to_center_scale, _center_scale_to_box - from alphapose.utils.transforms import get_affine_transform, im_to_torch - - aspect_ratio = float(192 / 256) - input_size = (192, 256) - xmin, ymin, xmax, ymax = bbox - center, scale = _box_to_center_scale( - xmin, ymin, xmax - xmin, ymax - ymin, aspect_ratio) - scale = scale * 1.0 - - inp_w, inp_h = input_size - - trans = get_affine_transform(center, scale, 0, [inp_w, inp_h]) - img = cv2.warpAffine(src, trans, (int(inp_w), int(inp_h)), flags=cv2.INTER_LINEAR) - bbox = _center_scale_to_box(center, scale) - - img = im_to_torch(img) - img[0].add_(-0.406) - img[1].add_(-0.457) - img[2].add_(-0.480) - - return img, bbox - - -def plot_pose_res(inp_path, pose_res, res_path): - """ - Plot the pose and box in the image - Arguments: - inp_path: (type: str) - pose_res: (type: dict) - res_path: (type: str) - """ - im_name = pose_res['imgname'] - result = pose_res['result'] - - img = cv2.imread(inp_path) - for temp in result: - keypoints = temp['keypoints'].numpy().tolist() - for keypoint in keypoints: - keypoint = [int(x) for x in keypoint] - x, y = keypoint - cv2.circle(img, (x, y), 2, (0, 255, 0), 2) - - box = temp['box'] - box = [int(x) for x in box] - x, y, w, h = box - cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) - - cv2.imwrite(res_path, img) - print(f"Save pose result image in {res_path}") diff --git a/cv/pose/alphapose/pytorch/scripts/test_demo.py b/cv/pose/alphapose/pytorch/scripts/test_demo.py deleted file mode 100755 index dba355a6a..000000000 --- a/cv/pose/alphapose/pytorch/scripts/test_demo.py +++ /dev/null @@ -1,277 +0,0 @@ -""" -Build pipeline of yolov5s and alphapose, inference one image. - -""" - -import os -import sys -import cv2 -import time -import argparse -import torchvision -import numpy as np - -import torch -import torch.nn as nn - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) - -from detector.yolo_cfg import cfg -from detector.yolov5.utils.general import non_max_suppression - -from alphapose.models import builder -from alphapose.utils.config import update_config -from alphapose.utils.transforms import heatmap_to_coord_simple -from alphapose.utils.pPose_nms import pose_nms - -from process_utils import scale_coords, test_transform, plot_pose_res - - - -"""----------------------------- Inference options -----------------------------""" -parser = argparse.ArgumentParser(description='Inference of yolov5s and alphapose') -parser.add_argument('--cfg', - type=str, - default="./configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml", - help='experiment configure file name') -parser.add_argument('--checkpoint', - type=str, - default="./pretrained_models/fast_res50_256x192.pth", - help='checkpoint file name') -parser.add_argument('--inp_path', - type=str, - default="./examples/demo/0.png", - help='the path of input image') -parser.add_argument('--res_path', - type=str, - default="./examples/res/0.jpg", - help='the path of save pose results') -parser.add_argument('--vis_pose', - type=bool, - default=True, - help='whether save the pose result') -parser.add_argument('--inp_size', - type=tuple, - default=(640, 384), - help='the input size of model') - -args = parser.parse_args() -cfg = update_config(args.cfg) -args.device = torch.device("cuda:0") -torch.backends.cudnn.benchmark = True -print("Input Size: ", args.inp_size) - - -def letterbox_image(img, inp_dim=(640, 384)): - '''resize image with unchanged aspect ratio using padding''' - img_w, img_h = img.shape[1], img.shape[0] - w, h = inp_dim - new_w = int(img_w * min(w / img_w, h / img_h)) - new_h = int(img_h * min(w / img_w, h / img_h)) - resized_image = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_CUBIC) - - canvas = np.full((inp_dim[1], inp_dim[0], 3), 128) - - canvas[(h - new_h) // 2:(h - new_h) // 2 + new_h, (w - new_w) // 2:(w - new_w) // 2 + new_w, :] = resized_image - - return canvas - - -# Stage1: detection(yolov5s) -def load_det_data(orig_im, inp_path=''): - - dim = orig_im.shape[1], orig_im.shape[0] - # PadResize - img = (letterbox_image(orig_im, args.inp_size)) - # BGR--->RGB, (640, 640, 3)--->(3, 640, 640) - img = img[:, :, ::-1].transpose((2, 0, 1)).copy() - # np.array--->torch.tensor, (0, 255)--->(0, 1), (3, 640, 640)--->(1, 3, 640, 640) - img = torch.from_numpy(img).float().div(255.).unsqueeze(0) - im_name = os.path.basename(inp_path) - return (img, orig_im, im_name, dim) - - -def load_det_model(opt, cfg): - weights = "../yolov5/yolov5s.pt" - from detector.yolov5.models.experimental import attempt_download, attempt_load # scoped to avoid circular import - det_model = attempt_load(weights, map_location=None) - det_model.to(args.device) - det_model.eval() - return det_model - - -def det_forward(det_inps, det_model): - img, orig_img, im_name, im_dim = det_inps - img = img.to(args.device) - with torch.no_grad(): - prediction = det_model(img) - det_model_out = (prediction, orig_img, im_dim, im_name) - return det_model_out - - -# def nms(prediction, conf_thres=0.25, iou_thres=0.45, max_det=100): -# xc = prediction[..., -2] > conf_thres # candidates -# output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0] - -# for xi, x in enumerate(prediction): # image index, image inference -# x = x[xc[xi]] # confidence - -# boxes, scores = x[:, :4], x[:, -2] - -# i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS -# if i.shape[0] > max_det: # limit detections -# i = i[:max_det] - -# output[xi] = x[i] -# return output - -def nms(prediction, conf_thres=0.25, iou_thres=0.45, max_det=100): - # xc = prediction[..., -2] > conf_thres # candidates - output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0] - - for xi, x in enumerate(prediction): # image index, image inference - # x = x[xc[xi]] # confidence - - boxes, scores = x[:, :4], x[:, -2] - - i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS - if i.shape[0] > max_det: # limit detections - i = i[:max_det] - - output[xi] = x[i] - return output - -""" -def det_post(det_model_out): - prediction, orig_img, im_shape, im_name = det_model_out - - prediction = nms(prediction) - prediction = prediction[0] # torch.tensor(num_objs x 6) - prediction[:, :4] = scale_coords(args.inp_size, prediction[:, :4], im_shape).round() - - dets = prediction.cpu() - boxes = dets[:, :4] - - scores = dets[:, 4:5] - labels = dets[:, 5:6] - flag = labels[:, 0] == 1. # select the person - - ids = torch.zeros(scores.shape) - - inps_idx = torch.zeros(boxes.size(0), 3, 256, 192) - cropped_boxes = torch.zeros(boxes.size(0), 4) - det_res = (orig_img, im_name, boxes[flag], scores[flag], ids[flag], inps_idx[flag], cropped_boxes[flag]) - return det_res -""" - -def det_post(det_model_out): - prediction, orig_img, im_shape, im_name = det_model_out - # prediction = non_max_suppression(prediction, 0.25, 0.45, None, False, max_det=100) - # prediction = nms(prediction) - prediction = prediction[0] # torch.tensor(num_objs x 6) - prediction[:, :4] = scale_coords(args.inp_size, prediction[:, :4], im_shape).round() - - dets = prediction.cpu() - boxes = dets[:, :4] - - scores = dets[:, 4:5] - # labels = dets[:, 5:6] - # flag = labels[:, 0] == 1. # select the person - - ids = torch.zeros(scores.shape) - - inps_idx = torch.zeros(boxes.size(0), 3, 256, 192) - cropped_boxes = torch.zeros(boxes.size(0), 4) - # det_res = (orig_img, im_name, boxes[flag], scores[flag], ids[flag], inps_idx[flag], cropped_boxes[flag]) - det_res = (orig_img, im_name, boxes, scores, ids, inps_idx, cropped_boxes) - - return det_res - - -# Stage2: pose estimation(alphapose) -def load_pose_data(det_res): - with torch.no_grad(): - orig_img, im_name, boxes, scores, ids, inps, cropped_boxes = det_res - for j, box in enumerate(boxes): - inps[j], cropped_box = test_transform(orig_img, box) - cropped_boxes[j] = torch.FloatTensor(cropped_box) - - pose_inps = (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) - return pose_inps - - -def load_pose_model(): - pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - print('Loading pose model from %s...' % (args.checkpoint,)) - pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) - pose_model.to(args.device) - pose_model.eval() - return pose_model - - -def pose_forward(pose_inps, pose_model): - with torch.no_grad(): - (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) = pose_inps - inps = inps.to(args.device) - hm = pose_model(inps) - pose_model_out = (boxes, scores, ids, hm, cropped_boxes, orig_img, im_name) - return pose_model_out - - -def pose_post(pose_model_out): - boxes, scores, ids, hm_data, cropped_boxes, orig_img, im_name = pose_model_out - hm_data = hm_data.cpu() - orig_img = np.array(orig_img, dtype=np.uint8)[:, :, ::-1] - - eval_joints = [*range(0,17)] - hm_size = (64, 48) - min_box_area = 0 - - pose_coords = [] - pose_scores = [] - for i in range(hm_data.shape[0]): - bbox = cropped_boxes[i].tolist() - pose_coord, pose_score = heatmap_to_coord_simple(hm_data[i][eval_joints], bbox, hm_shape=hm_size, norm_type=None) - pose_coords.append(torch.from_numpy(pose_coord).unsqueeze(0)) - pose_scores.append(torch.from_numpy(pose_score).unsqueeze(0)) - - preds_img = torch.cat(pose_coords) - preds_scores = torch.cat(pose_scores) - boxes, scores, ids, preds_img, preds_scores, pick_ids = \ - pose_nms(boxes, scores, ids, preds_img, preds_scores, min_box_area) - - _result = [] - for k in range(len(scores)): - _result.append( - { - 'keypoints':preds_img[k], - 'kp_score':preds_scores[k], - 'proposal_score': torch.mean(preds_scores[k]) + scores[k] + 1.25 * max(preds_scores[k]), - 'idx':ids[k], - 'box':[boxes[k][0], boxes[k][1], boxes[k][2]-boxes[k][0],boxes[k][3]-boxes[k][1]] - } - ) - - pose_res = { - 'imgname': im_name, - 'result': _result - } - return pose_res - - -if __name__ == "__main__": - det_model = load_det_model(args, cfg) - pose_model = load_pose_model() - - img = cv2.imread(args.inp_path) - det_inps = load_det_data(img) - print('input size:', det_inps[0].shape) - det_model_out = det_forward(det_inps, det_model) - det_res = det_post(det_model_out) - - pose_inps = load_pose_data(det_res) - pose_model_out = pose_forward(pose_inps, pose_model) - pose_res = pose_post(pose_model_out) - if args.vis_pose: - plot_pose_res(args.inp_path, pose_res, args.res_path) # validate the pose result diff --git a/cv/pose/alphapose/pytorch/scripts/trainval/train.py b/cv/pose/alphapose/pytorch/scripts/train.py old mode 100755 new mode 100644 similarity index 100% rename from cv/pose/alphapose/pytorch/scripts/trainval/train.py rename to cv/pose/alphapose/pytorch/scripts/train.py diff --git a/cv/pose/alphapose/pytorch/scripts/trainval/train.sh b/cv/pose/alphapose/pytorch/scripts/train.sh old mode 100755 new mode 100644 similarity index 95% rename from cv/pose/alphapose/pytorch/scripts/trainval/train.sh rename to cv/pose/alphapose/pytorch/scripts/train.sh index 86fee4d69..4980498bc --- a/cv/pose/alphapose/pytorch/scripts/trainval/train.sh +++ b/cv/pose/alphapose/pytorch/scripts/train.sh @@ -18,6 +18,6 @@ set -x CONFIG=$1 EXPID=${2:-"alphapose"} -python3 ./scripts/trainval/train.py \ +python3 ./scripts/train.py \ --exp-id ${EXPID} \ --cfg ${CONFIG} diff --git a/cv/pose/alphapose/pytorch/scripts/trainval/demo_api.py b/cv/pose/alphapose/pytorch/scripts/trainval/demo_api.py deleted file mode 100755 index 5bd8af101..000000000 --- a/cv/pose/alphapose/pytorch/scripts/trainval/demo_api.py +++ /dev/null @@ -1,365 +0,0 @@ -# ----------------------------------------------------- -# Copyright (c) Shanghai Jiao Tong University. All rights reserved. -# Written by Haoyi Zhu,Hao-Shu Fang -# ----------------------------------------------------- - -"""Script for single-image demo.""" -import argparse -import torch -import os -import platform -import sys -import math -import time - -import cv2 -import numpy as np - -from alphapose.utils.transforms import get_func_heatmap_to_coord -from alphapose.utils.pPose_nms import pose_nms -from alphapose.utils.presets import SimpleTransform -from alphapose.utils.transforms import flip, flip_heatmap -from alphapose.models import builder -from alphapose.utils.config import update_config -from detector.apis import get_detector -from alphapose.utils.vis import getTime - -"""----------------------------- Demo options -----------------------------""" -parser = argparse.ArgumentParser(description='AlphaPose Single-Image Demo') -parser.add_argument('--cfg', type=str, required=True, - help='experiment configure file name') -parser.add_argument('--checkpoint', type=str, required=True, - help='checkpoint file name') -parser.add_argument('--detector', dest='detector', - help='detector name', default="yolo") -parser.add_argument('--image', dest='inputimg', - help='image-name', default="") -parser.add_argument('--save_img', default=False, action='store_true', - help='save result as image') -parser.add_argument('--vis', default=False, action='store_true', - help='visualize image') -parser.add_argument('--showbox', default=False, action='store_true', - help='visualize human bbox') -parser.add_argument('--profile', default=False, action='store_true', - help='add speed profiling at screen output') -parser.add_argument('--format', type=str, - help='save in the format of cmu or coco or openpose, option: coco/cmu/open') -parser.add_argument('--min_box_area', type=int, default=0, - help='min box area to filter out') -parser.add_argument('--eval', dest='eval', default=False, action='store_true', - help='save the result json as coco format, using image index(int) instead of image name(str)') -parser.add_argument('--gpus', type=str, dest='gpus', default="0", - help='choose which cuda device to use by index and input comma to use multi gpus, e.g. 0,1,2,3. (input -1 for cpu only)') -parser.add_argument('--flip', default=False, action='store_true', - help='enable flip testing') -parser.add_argument('--debug', default=False, action='store_true', - help='print detail information') -parser.add_argument('--vis_fast', dest='vis_fast', - help='use fast rendering', action='store_true', default=False) -"""----------------------------- Tracking options -----------------------------""" -parser.add_argument('--pose_flow', dest='pose_flow', - help='track humans in video with PoseFlow', action='store_true', default=False) -parser.add_argument('--pose_track', dest='pose_track', - help='track humans in video with reid', action='store_true', default=False) - -args = parser.parse_args() -cfg = update_config(args.cfg) - -args.gpus = [int(args.gpus[0])] if torch.cuda.device_count() >= 1 else [-1] -args.device = torch.device("cuda:" + str(args.gpus[0]) if args.gpus[0] >= 0 else "cpu") -args.tracking = args.pose_track or args.pose_flow or args.detector=='tracker' - -class DetectionLoader(): - def __init__(self, detector, cfg, opt): - self.cfg = cfg - self.opt = opt - self.device = opt.device - self.detector = detector - - self._input_size = cfg.DATA_PRESET.IMAGE_SIZE - self._output_size = cfg.DATA_PRESET.HEATMAP_SIZE - - self._sigma = cfg.DATA_PRESET.SIGMA - - pose_dataset = builder.retrieve_dataset(self.cfg.DATASET.TRAIN) - if cfg.DATA_PRESET.TYPE == 'simple': - self.transformation = SimpleTransform( - pose_dataset, scale_factor=0, - input_size=self._input_size, - output_size=self._output_size, - rot=0, sigma=self._sigma, - train=False, add_dpg=False, gpu_device=self.device) - - self.image = (None, None, None, None) - self.det = (None, None, None, None, None, None, None) - self.pose = (None, None, None, None, None, None, None) - - def process(self, im_name, image): - # start to pre process images for object detection - self.image_preprocess(im_name, image) - # start to detect human in images - self.image_detection() - # start to post process cropped human image for pose estimation - self.image_postprocess() - return self - - def image_preprocess(self, im_name, image): - # expected image shape like (1,3,h,w) or (3,h,w) - img = self.detector.image_preprocess(image) - if isinstance(img, np.ndarray): - img = torch.from_numpy(img) - # add one dimension at the front for batch if image shape (3,h,w) - if img.dim() == 3: - img = img.unsqueeze(0) - orig_img = image # scipy.misc.imread(im_name_k, mode='RGB') is depreciated - im_dim = orig_img.shape[1], orig_img.shape[0] - - im_name = os.path.basename(im_name) - - with torch.no_grad(): - im_dim = torch.FloatTensor(im_dim).repeat(1, 2) - - self.image = (img, orig_img, im_name, im_dim) - - def image_detection(self): - imgs, orig_imgs, im_names, im_dim_list = self.image - if imgs is None: - self.det = (None, None, None, None, None, None, None) - return - - with torch.no_grad(): - dets = self.detector.images_detection(imgs, im_dim_list) - if isinstance(dets, int) or dets.shape[0] == 0: - self.det = (orig_imgs, im_names, None, None, None, None, None) - return - if isinstance(dets, np.ndarray): - dets = torch.from_numpy(dets) - dets = dets.cpu() - boxes = dets[:, 1:5] - scores = dets[:, 5:6] - ids = torch.zeros(scores.shape) - - boxes = boxes[dets[:, 0] == 0] - if isinstance(boxes, int) or boxes.shape[0] == 0: - self.det = (orig_imgs, im_names, None, None, None, None, None) - return - inps = torch.zeros(boxes.size(0), 3, *self._input_size) - cropped_boxes = torch.zeros(boxes.size(0), 4) - - self.det = (orig_imgs, im_names, boxes, scores[dets[:, 0] == 0], ids[dets[:, 0] == 0], inps, cropped_boxes) - - def image_postprocess(self): - with torch.no_grad(): - (orig_img, im_name, boxes, scores, ids, inps, cropped_boxes) = self.det - if orig_img is None: - self.pose = (None, None, None, None, None, None, None) - return - if boxes is None or boxes.nelement() == 0: - self.pose = (None, orig_img, im_name, boxes, scores, ids, None) - return - - for i, box in enumerate(boxes): - inps[i], cropped_box = self.transformation.test_transform(orig_img, box) - cropped_boxes[i] = torch.FloatTensor(cropped_box) - - self.pose = (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) - - def read(self): - return self.pose - - -class DataWriter(): - def __init__(self, cfg, opt): - self.cfg = cfg - self.opt = opt - - self.eval_joints = list(range(cfg.DATA_PRESET.NUM_JOINTS)) - self.heatmap_to_coord = get_func_heatmap_to_coord(cfg) - self.item = (None, None, None, None, None, None, None) - - def start(self): - # start to read pose estimation results - return self.update() - - def update(self): - norm_type = self.cfg.LOSS.get('NORM_TYPE', None) - hm_size = self.cfg.DATA_PRESET.HEATMAP_SIZE - - # get item - (boxes, scores, ids, hm_data, cropped_boxes, orig_img, im_name) = self.item - if orig_img is None: - return None - # image channel RGB->BGR - orig_img = np.array(orig_img, dtype=np.uint8)[:, :, ::-1] - self.orig_img = orig_img - if boxes is None or len(boxes) == 0: - return None - else: - # location prediction (n, kp, 2) | score prediction (n, kp, 1) - assert hm_data.dim() == 4 - if hm_data.size()[1] == 136: - self.eval_joints = [*range(0,136)] - elif hm_data.size()[1] == 26: - self.eval_joints = [*range(0,26)] - pose_coords = [] - pose_scores = [] - - for i in range(hm_data.shape[0]): - bbox = cropped_boxes[i].tolist() - pose_coord, pose_score = self.heatmap_to_coord(hm_data[i][self.eval_joints], bbox, hm_shape=hm_size, norm_type=norm_type) - pose_coords.append(torch.from_numpy(pose_coord).unsqueeze(0)) - pose_scores.append(torch.from_numpy(pose_score).unsqueeze(0)) - preds_img = torch.cat(pose_coords) - preds_scores = torch.cat(pose_scores) - - boxes, scores, ids, preds_img, preds_scores, pick_ids = \ - pose_nms(boxes, scores, ids, preds_img, preds_scores, self.opt.min_box_area) - - _result = [] - for k in range(len(scores)): - _result.append( - { - 'keypoints':preds_img[k], - 'kp_score':preds_scores[k], - 'proposal_score': torch.mean(preds_scores[k]) + scores[k] + 1.25 * max(preds_scores[k]), - 'idx':ids[k], - 'bbox':[boxes[k][0], boxes[k][1], boxes[k][2]-boxes[k][0],boxes[k][3]-boxes[k][1]] - } - ) - - result = { - 'imgname': im_name, - 'result': _result - } - - if hm_data.size()[1] == 49: - from alphapose.utils.vis import vis_frame_dense as vis_frame - elif self.opt.vis_fast: - from alphapose.utils.vis import vis_frame_fast as vis_frame - else: - from alphapose.utils.vis import vis_frame - self.vis_frame = vis_frame - - return result - - def save(self, boxes, scores, ids, hm_data, cropped_boxes, orig_img, im_name): - self.item = (boxes, scores, ids, hm_data, cropped_boxes, orig_img, im_name) - -class SingleImageAlphaPose(): - def __init__(self, args, cfg): - self.args = args - self.cfg = cfg - - # Load pose model - self.pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - - print(f'Loading pose model from {args.checkpoint}...') - self.pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) - self.pose_dataset = builder.retrieve_dataset(cfg.DATASET.TRAIN) - - self.pose_model.to(args.device) - self.pose_model.eval() - - self.det_loader = DetectionLoader(get_detector(self.args), self.cfg, self.args) - - def process(self, im_name, image): - # Init data writer - self.writer = DataWriter(self.cfg, self.args) - - runtime_profile = { - 'dt': [], - 'pt': [], - 'pn': [] - } - pose = None - try: - start_time = getTime() - with torch.no_grad(): - (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) = self.det_loader.process(im_name, image).read() - if orig_img is None: - raise Exception("no image is given") - if boxes is None or boxes.nelement() == 0: - if self.args.profile: - ckpt_time, det_time = getTime(start_time) - runtime_profile['dt'].append(det_time) - self.writer.save(None, None, None, None, None, orig_img, im_name) - if self.args.profile: - ckpt_time, pose_time = getTime(ckpt_time) - runtime_profile['pt'].append(pose_time) - pose = self.writer.start() - if self.args.profile: - ckpt_time, post_time = getTime(ckpt_time) - runtime_profile['pn'].append(post_time) - else: - if self.args.profile: - ckpt_time, det_time = getTime(start_time) - runtime_profile['dt'].append(det_time) - # Pose Estimation - inps = inps.to(self.args.device) - if self.args.flip: - inps = torch.cat((inps, flip(inps))) - hm = self.pose_model(inps) - if self.args.flip: - hm_flip = flip_heatmap(hm[int(len(hm) / 2):], self.pose_dataset.joint_pairs, shift=True) - hm = (hm[0:int(len(hm) / 2)] + hm_flip) / 2 - if self.args.profile: - ckpt_time, pose_time = getTime(ckpt_time) - runtime_profile['pt'].append(pose_time) - hm = hm.cpu() - self.writer.save(boxes, scores, ids, hm, cropped_boxes, orig_img, im_name) - pose = self.writer.start() - if self.args.profile: - ckpt_time, post_time = getTime(ckpt_time) - runtime_profile['pn'].append(post_time) - - if self.args.profile: - print( - 'det time: {dt:.4f} | pose time: {pt:.4f} | post processing: {pn:.4f}'.format( - dt=np.mean(runtime_profile['dt']), pt=np.mean(runtime_profile['pt']), pn=np.mean(runtime_profile['pn'])) - ) - print('===========================> Finish Model Running.') - except Exception as e: - print(repr(e)) - print('An error as above occurs when processing the images, please check it') - pass - except KeyboardInterrupt: - print('===========================> Finish Model Running.') - - return pose - - def getImg(self): - return self.writer.orig_img - - def vis(self, image, pose): - if pose is not None: - image = self.writer.vis_frame(image, pose, self.writer.opt) - return image - - def writeJson(self, final_result, outputpath, form='coco', for_eval=False): - from alphapose.utils.pPose_nms import write_json - write_json(final_result, outputpath, form=form, for_eval=for_eval) - print("Results have been written to json.") - -def example(): - outputpath = "examples/res/" - if not os.path.exists(outputpath + '/vis'): - os.mkdir(outputpath + '/vis') - - demo = SingleImageAlphaPose(args, cfg) - im_name = args.inputimg # the path to the target image - image = cv2.cvtColor(cv2.imread(im_name), cv2.COLOR_BGR2RGB) - pose = demo.process(im_name, image) - img = demo.getImg() # or you can just use: img = cv2.imread(image) - img = demo.vis(img, pose) # visulize the pose result - cv2.imwrite(os.path.join(outputpath, 'vis', os.path.basename(im_name)), img) - - # if you want to vis the img: - # cv2.imshow("AlphaPose Demo", img) - # cv2.waitKey(30) - - # write the result to json: - result = [pose] - demo.writeJson(result, outputpath, form=args.format, for_eval=args.eval) - -if __name__ == "__main__": - example() diff --git a/cv/pose/alphapose/pytorch/scripts/trainval/demo_inference.py b/cv/pose/alphapose/pytorch/scripts/trainval/demo_inference.py deleted file mode 100755 index e46df135a..000000000 --- a/cv/pose/alphapose/pytorch/scripts/trainval/demo_inference.py +++ /dev/null @@ -1,300 +0,0 @@ -"""Script for single-gpu/multi-gpu demo.""" -import argparse -import os -import platform -import sys -import time - -import numpy as np -import torch -from tqdm import tqdm -import natsort - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) - - -from detector.apis import get_detector -from trackers.tracker_api import Tracker -from trackers.tracker_cfg import cfg as tcfg -from trackers import track -from alphapose.models import builder -from alphapose.utils.config import update_config -from alphapose.utils.detector import DetectionLoader -from alphapose.utils.transforms import flip, flip_heatmap -from alphapose.utils.vis import getTime -from alphapose.utils.webcam_detector import WebCamDetectionLoader -from alphapose.utils.writer import DataWriter - -"""----------------------------- Demo options -----------------------------""" -parser = argparse.ArgumentParser(description='AlphaPose Demo') -parser.add_argument('--cfg', type=str, required=True, - help='experiment configure file name') -parser.add_argument('--checkpoint', type=str, required=True, - help='checkpoint file name') -parser.add_argument('--sp', default=False, action='store_true', - help='Use single process for pytorch') -parser.add_argument('--detector', dest='detector', - help='detector name', default="yolo") -parser.add_argument('--detfile', dest='detfile', - help='detection result file', default="") -parser.add_argument('--indir', dest='inputpath', - help='image-directory', default="") -parser.add_argument('--list', dest='inputlist', - help='image-list', default="") -parser.add_argument('--image', dest='inputimg', - help='image-name', default="") -parser.add_argument('--outdir', dest='outputpath', - help='output-directory', default="examples/res/") -parser.add_argument('--save_img', default=True, action='store_true', - help='save result as image') -parser.add_argument('--vis', default=False, action='store_true', - help='visualize image') -parser.add_argument('--showbox', default=False, action='store_true', - help='visualize human bbox') -parser.add_argument('--profile', default=False, action='store_true', - help='add speed profiling at screen output') -parser.add_argument('--format', type=str, - help='save in the format of cmu or coco or openpose, option: coco/cmu/open') -parser.add_argument('--min_box_area', type=int, default=0, - help='min box area to filter out') -parser.add_argument('--detbatch', type=int, default=5, - help='detection batch size PER GPU') -parser.add_argument('--posebatch', type=int, default=80, - help='pose estimation maximum batch size PER GPU') -parser.add_argument('--eval', dest='eval', default=False, action='store_true', - help='save the result json as coco format, using image index(int) instead of image name(str)') -parser.add_argument('--gpus', type=str, dest='gpus', default="0", - help='choose which cuda device to use by index and input comma to use multi gpus, e.g. 0,1,2,3. (input -1 for cpu only)') -parser.add_argument('--qsize', type=int, dest='qsize', default=1024, - help='the length of result buffer, where reducing it will lower requirement of cpu memory') -parser.add_argument('--flip', default=False, action='store_true', - help='enable flip testing') -parser.add_argument('--debug', default=False, action='store_true', - help='print detail information') -"""----------------------------- Video options -----------------------------""" -parser.add_argument('--video', dest='video', - help='video-name', default="") -parser.add_argument('--webcam', dest='webcam', type=int, - help='webcam number', default=-1) -parser.add_argument('--save_video', dest='save_video', - help='whether to save rendered video', default=True, action='store_true') -parser.add_argument('--vis_fast', dest='vis_fast', - help='use fast rendering', action='store_true', default=False) -"""----------------------------- Tracking options -----------------------------""" -parser.add_argument('--pose_flow', dest='pose_flow', - help='track humans in video with PoseFlow', action='store_true', default=False) -parser.add_argument('--pose_track', dest='pose_track', - help='track humans in video with reid', action='store_true', default=False) - -args = parser.parse_args() -cfg = update_config(args.cfg) - -if platform.system() == 'Windows': - args.sp = True - -args.gpus = [int(i) for i in args.gpus.split(',')] if torch.cuda.device_count() >= 1 else [-1] -args.device = torch.device("cuda:" + str(args.gpus[0]) if args.gpus[0] >= 0 else "cpu") -args.detbatch = args.detbatch * len(args.gpus) -args.posebatch = args.posebatch * len(args.gpus) -args.tracking = args.pose_track or args.pose_flow or args.detector=='tracker' - -if not args.sp: - torch.multiprocessing.set_start_method('forkserver', force=True) - torch.multiprocessing.set_sharing_strategy('file_system') - - -def check_input(): - # for wecam - if args.webcam != -1: - args.detbatch = 1 - return 'webcam', int(args.webcam) - - # for video - if len(args.video): - if os.path.isfile(args.video): - videofile = args.video - return 'video', videofile - else: - raise IOError('Error: --video must refer to a video file, not directory.') - - # for detection results - if len(args.detfile): - if os.path.isfile(args.detfile): - detfile = args.detfile - return 'detfile', detfile - else: - raise IOError('Error: --detfile must refer to a detection json file, not directory.') - - # for images - if len(args.inputpath) or len(args.inputlist) or len(args.inputimg): - inputpath = args.inputpath - inputlist = args.inputlist - inputimg = args.inputimg - - if len(inputlist): - im_names = open(inputlist, 'r').readlines() - elif len(inputpath) and inputpath != '/': - for root, dirs, files in os.walk(inputpath): - im_names = files - im_names = natsort.natsorted(im_names) - elif len(inputimg): - args.inputpath = os.path.split(inputimg)[0] - im_names = [os.path.split(inputimg)[1]] - - return 'image', im_names - - else: - raise NotImplementedError - - -def print_finish_info(): - print('===========================> Finish Model Running.') - if (args.save_img or args.save_video) and not args.vis_fast: - print('===========================> Rendering remaining images in the queue...') - print('===========================> If this step takes too long, you can enable the --vis_fast flag to use fast rendering (real-time).') - - -def loop(): - n = 0 - while True: - yield n - n += 1 - - -if __name__ == "__main__": - mode, input_source = check_input() - - if not os.path.exists(args.outputpath): - os.makedirs(args.outputpath) - - # Load detection loader - if mode == 'webcam': - det_loader = WebCamDetectionLoader(input_source, get_detector(args), cfg, args) - det_worker = det_loader.start() - elif mode == 'detfile': - det_loader = FileDetectionLoader(input_source, cfg, args) - det_worker = det_loader.start() - else: - det_loader = DetectionLoader(input_source, get_detector(args), cfg, args, batchSize=args.detbatch, mode=mode, queueSize=args.qsize) - det_worker = det_loader.start() - - # Load pose model - pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - - print('Loading pose model from %s...' % (args.checkpoint,)) - pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) - pose_dataset = builder.retrieve_dataset(cfg.DATASET.TRAIN) - if args.pose_track: - tracker = Tracker(tcfg, args) - if len(args.gpus) > 1: - pose_model = torch.nn.DataParallel(pose_model, device_ids=args.gpus).to(args.device) - else: - pose_model.to(args.device) - pose_model.eval() - - runtime_profile = { - 'dt': [], - 'pt': [], - 'pn': [] - } - - # Init data writer - queueSize = 2 if mode == 'webcam' else args.qsize - if args.save_video and mode != 'image': - from alphapose.utils.writer import DEFAULT_VIDEO_SAVE_OPT as video_save_opt - if mode == 'video': - video_save_opt['savepath'] = os.path.join(args.outputpath, 'AlphaPose_' + os.path.basename(input_source)) - else: - video_save_opt['savepath'] = os.path.join(args.outputpath, 'AlphaPose_webcam' + str(input_source) + '.mp4') - video_save_opt.update(det_loader.videoinfo) - writer = DataWriter(cfg, args, save_video=True, video_save_opt=video_save_opt, queueSize=queueSize).start() - else: - writer = DataWriter(cfg, args, save_video=False, queueSize=queueSize).start() - - if mode == 'webcam': - print('Starting webcam demo, press Ctrl + C to terminate...') - sys.stdout.flush() - im_names_desc = tqdm(loop()) - else: - data_len = det_loader.length - im_names_desc = tqdm(range(data_len), dynamic_ncols=True) - - batchSize = args.posebatch - if args.flip: - batchSize = int(batchSize / 2) - try: - for i in im_names_desc: - start_time = getTime() - with torch.no_grad(): - (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) = det_loader.read() - if orig_img is None: - break - if boxes is None or boxes.nelement() == 0: - writer.save(None, None, None, None, None, orig_img, im_name) - continue - if args.profile: - ckpt_time, det_time = getTime(start_time) - runtime_profile['dt'].append(det_time) - # Pose Estimation - inps = inps.to(args.device) - datalen = inps.size(0) - leftover = 0 - if (datalen) % batchSize: - leftover = 1 - num_batches = datalen // batchSize + leftover - hm = [] - for j in range(num_batches): - inps_j = inps[j * batchSize:min((j + 1) * batchSize, datalen)] - if args.flip: - inps_j = torch.cat((inps_j, flip(inps_j))) - hm_j = pose_model(inps_j) - if args.flip: - hm_j_flip = flip_heatmap(hm_j[int(len(hm_j) / 2):], pose_dataset.joint_pairs, shift=True) - hm_j = (hm_j[0:int(len(hm_j) / 2)] + hm_j_flip) / 2 - hm.append(hm_j) - hm = torch.cat(hm) - if args.profile: - ckpt_time, pose_time = getTime(ckpt_time) - runtime_profile['pt'].append(pose_time) - if args.pose_track: - boxes,scores,ids,hm,cropped_boxes = track(tracker,args,orig_img,inps,boxes,hm,cropped_boxes,im_name,scores) - hm = hm.cpu() - writer.save(boxes, scores, ids, hm, cropped_boxes, orig_img, im_name) - if args.profile: - ckpt_time, post_time = getTime(ckpt_time) - runtime_profile['pn'].append(post_time) - - if args.profile: - # TQDM - im_names_desc.set_description( - 'det time: {dt:.4f} | pose time: {pt:.4f} | post processing: {pn:.4f}'.format( - dt=np.mean(runtime_profile['dt']), pt=np.mean(runtime_profile['pt']), pn=np.mean(runtime_profile['pn'])) - ) - print_finish_info() - while(writer.running()): - time.sleep(1) - print('===========================> Rendering remaining ' + str(writer.count()) + ' images in the queue...') - writer.stop() - det_loader.stop() - except Exception as e: - print(repr(e)) - print('An error as above occurs when processing the images, please check it') - pass - except KeyboardInterrupt: - print_finish_info() - # Thread won't be killed when press Ctrl+C - if args.sp: - det_loader.terminate() - while(writer.running()): - time.sleep(1) - print('===========================> Rendering remaining ' + str(writer.count()) + ' images in the queue...') - writer.stop() - else: - # subprocesses are killed, manually clear queues - - det_loader.terminate() - writer.terminate() - writer.clear_queues() - det_loader.clear_queues() - diff --git a/cv/pose/alphapose/pytorch/scripts/trainval/validate.py b/cv/pose/alphapose/pytorch/scripts/trainval/validate.py deleted file mode 100755 index a5098337f..000000000 --- a/cv/pose/alphapose/pytorch/scripts/trainval/validate.py +++ /dev/null @@ -1,174 +0,0 @@ -"""Validation script.""" -import argparse -import json -import os -import numpy as np -import torch -from tqdm import tqdm - -from alphapose.models import builder -from alphapose.utils.config import update_config -from alphapose.utils.metrics import evaluate_mAP -from alphapose.utils.transforms import (flip, flip_heatmap, - get_func_heatmap_to_coord) -from alphapose.utils.pPose_nms import oks_pose_nms - - -parser = argparse.ArgumentParser(description='AlphaPose Validate') -parser.add_argument('--cfg', - help='experiment configure file name', - required=True, - type=str) -parser.add_argument('--checkpoint', - help='checkpoint file name', - required=True, - type=str) -parser.add_argument('--gpus', - help='gpus', - type=str) -parser.add_argument('--batch', - help='validation batch size', - type=int) -parser.add_argument('--flip-test', - default=False, - dest='flip_test', - help='flip test', - action='store_true') -parser.add_argument('--detector', dest='detector', - help='detector name', default="yolo") - -opt = parser.parse_args() -cfg = update_config(opt.cfg) - -gpus = [int(i) for i in opt.gpus.split(',')] -opt.gpus = [gpus[0]] -opt.device = torch.device("cuda:" + str(opt.gpus[0]) if opt.gpus[0] >= 0 else "cpu") - - -def validate(m, heatmap_to_coord, batch_size=20): - det_dataset = builder.build_dataset(cfg.DATASET.TEST, preset_cfg=cfg.DATA_PRESET, train=False, opt=opt) - eval_joints = det_dataset.EVAL_JOINTS - - det_loader = torch.utils.data.DataLoader( - det_dataset, batch_size=batch_size, shuffle=False, num_workers=20, drop_last=False) - kpt_json = [] - m.eval() - - norm_type = cfg.LOSS.get('NORM_TYPE', None) - hm_size = cfg.DATA_PRESET.HEATMAP_SIZE - - for inps, crop_bboxes, bboxes, img_ids, scores, imghts, imgwds in tqdm(det_loader, dynamic_ncols=True): - if isinstance(inps, list): - inps = [inp.cuda() for inp in inps] - else: - inps = inps.cuda() - output = m(inps) - if opt.flip_test: - if isinstance(inps, list): - inps_flip = [flip(inp).cuda() for inp in inps] - else: - inps_flip = flip(inps).cuda() - output_flip = flip_heatmap(m(inps_flip), det_dataset.joint_pairs, shift=True) - pred_flip = output_flip[:, eval_joints, :, :] - else: - output_flip = None - - pred = output - assert pred.dim() == 4 - pred = pred[:, eval_joints, :, :] - - for i in range(output.shape[0]): - bbox = crop_bboxes[i].tolist() - pose_coords, pose_scores = heatmap_to_coord( - pred[i], bbox, hms_flip=pred_flip[i], hm_shape=hm_size, norm_type=norm_type) - - keypoints = np.concatenate((pose_coords, pose_scores), axis=1) - keypoints = keypoints.reshape(-1).tolist() - - data = dict() - data['bbox'] = bboxes[i, 0].tolist() - data['image_id'] = int(img_ids[i]) - data['area'] = (bbox[2] - bbox[0]) * (bbox[3] - bbox[1]) - # data['score'] = float(scores[i] + np.mean(pose_scores) + np.max(pose_scores)) - data['score'] = float(scores[i]) - data['category_id'] = 1 - data['keypoints'] = keypoints - - kpt_json.append(data) - - kpt_json = oks_pose_nms(kpt_json) - - with open('./exp/json/validate_rcnn_kpt.json', 'w') as fid: - json.dump(kpt_json, fid) - res = evaluate_mAP('./exp/json/validate_rcnn_kpt.json', ann_type='keypoints', ann_file=os.path.join(cfg.DATASET.VAL.ROOT, cfg.DATASET.VAL.ANN)) - return res['AP'] - - -def validate_gt(m, cfg, heatmap_to_coord, batch_size=20): - gt_val_dataset = builder.build_dataset(cfg.DATASET.VAL, preset_cfg=cfg.DATA_PRESET, train=False) - eval_joints = gt_val_dataset.EVAL_JOINTS - - gt_val_loader = torch.utils.data.DataLoader( - gt_val_dataset, batch_size=batch_size, shuffle=False, num_workers=20, drop_last=False) - kpt_json = [] - m.eval() - - norm_type = cfg.LOSS.get('NORM_TYPE', None) - hm_size = cfg.DATA_PRESET.HEATMAP_SIZE - - for inps, labels, label_masks, img_ids, bboxes in tqdm(gt_val_loader, dynamic_ncols=True): - if isinstance(inps, list): - inps = [inp.cuda() for inp in inps] - else: - inps = inps.cuda() - output = m(inps) - if opt.flip_test: - if isinstance(inps, list): - inps_flip = [flip(inp).cuda() for inp in inps] - else: - inps_flip = flip(inps).cuda() - output_flip = flip_heatmap(m(inps_flip), gt_val_dataset.joint_pairs, shift=True) - pred_flip = output_flip[:, eval_joints, :, :] - else: - output_flip = None - - pred = output - assert pred.dim() == 4 - pred = pred[:, eval_joints, :, :] - - for i in range(output.shape[0]): - bbox = bboxes[i].tolist() - pose_coords, pose_scores = heatmap_to_coord( - pred[i], bbox, hms_flip=pred_flip[i], hm_shape=hm_size, norm_type=norm_type) - - keypoints = np.concatenate((pose_coords, pose_scores), axis=1) - keypoints = keypoints.reshape(-1).tolist() - - data = dict() - data['bbox'] = bboxes[i].tolist() - data['image_id'] = int(img_ids[i]) - data['score'] = float(np.mean(pose_scores) + np.max(pose_scores)) - data['category_id'] = 1 - data['keypoints'] = keypoints - - kpt_json.append(data) - - with open('./exp/json/validate_gt_kpt.json', 'w') as fid: - json.dump(kpt_json, fid) - res = evaluate_mAP('./exp/json/validate_gt_kpt.json', ann_type='keypoints', ann_file=os.path.join(cfg.DATASET.VAL.ROOT, cfg.DATASET.VAL.ANN)) - return res['AP'] - - -if __name__ == "__main__": - m = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) - - print(f'Loading model from {opt.checkpoint}...') - m.load_state_dict(torch.load(opt.checkpoint)) - - m = torch.nn.DataParallel(m, device_ids=gpus).cuda() - heatmap_to_coord = get_func_heatmap_to_coord(cfg) - - with torch.no_grad(): - gt_AP = validate_gt(m, cfg, heatmap_to_coord, opt.batch) - detbox_AP = validate(m, heatmap_to_coord, opt.batch) - print('##### gt box: {} mAP | det box: {} mAP #####'.format(gt_AP, detbox_AP)) diff --git a/cv/pose/alphapose/pytorch/scripts/trainval/validate.sh b/cv/pose/alphapose/pytorch/scripts/trainval/validate.sh deleted file mode 100755 index fea7adb4b..000000000 --- a/cv/pose/alphapose/pytorch/scripts/trainval/validate.sh +++ /dev/null @@ -1,29 +0,0 @@ - -# Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -set -x - -CONFIG=$1 -CKPT=$2 -BATCH=${3:-"64"} -GPUS=${4:-"0,1,2,3"} - -python ./scripts/validate.py \ - --cfg ${CONFIG} \ - --batch ${BATCH} \ - --gpus $GPUS\ - --flip-test \ - --checkpoint ${CKPT} diff --git a/cv/pose/alphapose/pytorch/scripts/videos_process/composition_frames.py b/cv/pose/alphapose/pytorch/scripts/videos_process/composition_frames.py deleted file mode 100755 index a7a46e373..000000000 --- a/cv/pose/alphapose/pytorch/scripts/videos_process/composition_frames.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 - -""" -Composition images as video -""" -import os -import cv2 -import argparse -import numpy as np - - -parser = argparse.ArgumentParser(description="Composition images as video!") -parser.add_argument("--input_dir", - type=str, - default="./pedestrian_720px10", - help="the directory of images") -parser.add_argument("--video_name", - type=str, - default="./pedestrian_720px10.avi", - help="the video path") -args = parser.parse_args() - - -class CompositionFrames: - def __init__(self, input_dir, video_name, size=(1280, 720)): - self.input_dir = input_dir - self.video_name = video_name - self.size = size - - def main(self): - assert os.path.isdir(self.input_dir), f"{self.input_dir} must be an existed directory" - imgs_name = [x for x in os.listdir(self.input_dir) if x.endswith('jpg')] - imgs_name = sorted(imgs_name, key=lambda x: int(x.split('.')[0])) - imgs_path = [os.path.join(self.input_dir, x) for x in imgs_name] - - fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G') - videowriter = cv2.VideoWriter(self.video_name, fourcc, 25, self.size) - - for img_path in imgs_path[:150]: - print(img_path) - img = cv2.imread(img_path) - videowriter.write(img) - - print('Achieve Writing!') - - -if __name__ == '__main__': - composition_frames = CompositionFrames(args.input_dir, args.video_name) - composition_frames.main() - - diff --git a/cv/pose/alphapose/pytorch/scripts/videos_process/extract_frames.py b/cv/pose/alphapose/pytorch/scripts/videos_process/extract_frames.py deleted file mode 100755 index 1bc5334d3..000000000 --- a/cv/pose/alphapose/pytorch/scripts/videos_process/extract_frames.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 - -""" -Extract frames from video -""" -import os -import cv2 -import argparse -import numpy as np - - -parser = argparse.ArgumentParser(description="Extract frames from test videos!") -parser.add_argument("--input_dir", - type=str, - default="/home/datasets/cv/testdata/videos", - help="the directory of videos") -parser.add_argument("--result_dir", - type=str, - default="/home/datasets/cv/testdata/images", - help="the saved directory of frames") -args = parser.parse_args() - - -class ExtractFrames: - def __init__(self, input_dir, result_dir): - self.input_dir = input_dir - self.result_dir = result_dir - - def _parse_input(self): - assert os.path.isdir(self.input_dir), f"{self.input_dir} must be an existed directory" - videos_name = [x for x in os.listdir(self.input_dir) if x.endswith('avi')] - videos_path = [os.path.join(self.input_dir, x) for x in videos_name] - return videos_path - - def _extract_frame(self, video_path): - assert os.path.isfile(video_path), f"{video_path} must be an existed file" - video_name = os.path.basename(video_path).split('.')[0] - print(video_name) - - images_dir = os.path.join(self.result_dir, video_name) - if not os.path.exists(images_dir): - os.mkdir(images_dir) - - video_capture = cv2.VideoCapture() - video_capture.open(video_path) - - fps = video_capture.get(cv2.CAP_PROP_FPS) - frames = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT)) - print("fps=", fps, "; frames=", frames) - - for i in range(frames): - if i % 100 == 0: - print('Process: %d / %d' % (i, frames)) - ret, frame = video_capture.read() - try: - cv2.imwrite(os.path.join(images_dir, "%d.jpg" % i), frame) - except: - break - - def main(self): - videos_path = self._parse_input() - - for video_path in videos_path: - self._extract_frame(video_path) - - -if __name__ == '__main__': - extract_frames = ExtractFrames(args.input_dir, args.result_dir) - extract_frames.main() diff --git a/cv/pose/alphapose/pytorch/setup.cfg b/cv/pose/alphapose/pytorch/setup.cfg deleted file mode 100755 index 4a59d74da..000000000 --- a/cv/pose/alphapose/pytorch/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[easy_install] -index_url=https://pypi.tuna.tsinghua.edu.cn/simple diff --git a/cv/pose/alphapose/pytorch/setup.py b/cv/pose/alphapose/pytorch/setup.py deleted file mode 100755 index 4808c8562..000000000 --- a/cv/pose/alphapose/pytorch/setup.py +++ /dev/null @@ -1,224 +0,0 @@ -# Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -import os -import platform -import subprocess -import time - -import numpy as np -from Cython.Build import cythonize -from setuptools import Extension, find_packages, setup -from torch.utils.cpp_extension import BuildExtension, CUDAExtension - -MAJOR = 0 -MINOR = 3 -PATCH = 0 -SUFFIX = '' -SHORT_VERSION = '{}.{}.{}{}'.format(MAJOR, MINOR, PATCH, SUFFIX) - -version_file = 'alphapose/version.py' - - -def readme(): - with open('README.md') as f: - content = f.read() - return content - - -def get_git_hash(): - - def _minimal_ext_cmd(cmd): - # construct minimal environment - env = {} - for k in ['SYSTEMROOT', 'PATH', 'HOME']: - v = os.environ.get(k) - if v is not None: - env[k] = v - # LANGUAGE is used on win32 - env['LANGUAGE'] = 'C' - env['LANG'] = 'C' - env['LC_ALL'] = 'C' - out = subprocess.Popen( - cmd, stdout=subprocess.PIPE, env=env).communicate()[0] - return out - - try: - out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD']) - sha = out.strip().decode('ascii') - except OSError: - sha = 'unknown' - - return sha - - -def get_hash(): - if os.path.exists('.git'): - sha = get_git_hash()[:7] - elif os.path.exists(version_file): - try: - from alphapose.version import __version__ - sha = __version__.split('+')[-1] - except ImportError: - raise ImportError('Unable to get git version') - else: - sha = 'unknown' - - return sha - - -def write_version_py(): - content = """# GENERATED VERSION FILE -# TIME: {} - -__version__ = '{}' -short_version = '{}' -""" - sha = get_hash() - VERSION = SHORT_VERSION + '+' + sha - - with open(version_file, 'w') as f: - f.write(content.format(time.asctime(), VERSION, SHORT_VERSION)) - - -def get_version(): - with open(version_file, 'r') as f: - exec(compile(f.read(), version_file, 'exec')) - return locals()['__version__'] - - -def make_cython_ext(name, module, sources): - extra_compile_args = None - if platform.system() != 'Windows': - extra_compile_args = { - 'cxx': ['-Wno-unused-function', '-Wno-write-strings'] - } - - extension = Extension( - '{}.{}'.format(module, name), - [os.path.join(*module.split('.'), p) for p in sources], - include_dirs=[np.get_include()], - language='c++', - extra_compile_args=extra_compile_args) - extension, = cythonize(extension) - return extension - - -def make_cuda_ext(name, module, sources): - - return CUDAExtension( - name='{}.{}'.format(module, name), - sources=[os.path.join(*module.split('.'), p) for p in sources], - extra_compile_args={ - 'cxx': [], - 'nvcc': [ - '-D__CUDA_NO_HALF_OPERATORS__', - '-D__CUDA_NO_HALF_CONVERSIONS__', - '-D__CUDA_NO_HALF2_OPERATORS__', - ] - }) - - -def get_ext_modules(): - ext_modules = [] - # only windows visual studio 2013+ support compile c/cuda extensions - # If you force to compile extension on Windows and ensure appropriate visual studio - # is intalled, you can try to use these ext_modules. - force_compile = False - if platform.system() != 'Windows' or force_compile: - ext_modules = [ - make_cython_ext( - name='soft_nms_cpu', - module='detector.nms', - sources=['src/soft_nms_cpu.pyx']), - make_cuda_ext( - name='nms_cpu', - module='detector.nms', - sources=['src/nms_cpu.cpp']), - make_cuda_ext( - name='nms_cuda', - module='detector.nms', - sources=['src/nms_cuda.cpp', 'src/nms_kernel.cu']), - make_cuda_ext( - name='roi_align_cuda', - module='alphapose.utils.roi_align', - sources=['src/roi_align_cuda.cpp', 'src/roi_align_kernel.cu']), - make_cuda_ext( - name='deform_conv_cuda', - module='alphapose.models.layers.dcn', - sources=[ - 'src/deform_conv_cuda.cpp', - 'src/deform_conv_cuda_kernel.cu' - ]), - make_cuda_ext( - name='deform_pool_cuda', - module='alphapose.models.layers.dcn', - sources=[ - 'src/deform_pool_cuda.cpp', - 'src/deform_pool_cuda_kernel.cu' - ]), - ] - return ext_modules - - -def get_install_requires(): - install_requires = [ - 'six', 'terminaltables', 'scipy==1.1.0', - 'opencv-python', 'matplotlib', 'visdom', - 'tqdm', 'tensorboardx', 'easydict', - 'pyyaml', - 'torch>=1.1.0', 'torchvision>=0.3.0', - 'munkres', 'timm==0.1.20', 'natsort' - ] - # official pycocotools doesn't support Windows, we will install it by third-party git repository later - if platform.system() != 'Windows': - install_requires.append('pycocotools==2.0.0') - return install_requires - - -def is_installed(package_name): - from pip._internal.utils.misc import get_installed_distributions - for p in get_installed_distributions(): - if package_name in p.egg_name(): - return True - return False - - -if __name__ == '__main__': - write_version_py() - setup( - name='alphapose', - version=get_version(), - description='Code for AlphaPose', - long_description=readme(), - keywords='computer vision, human pose estimation', - url='https://github.com/MVIG-SJTU/AlphaPose', - packages=find_packages(exclude=('data', 'exp',)), - package_data={'': ['*.json', '*.txt']}, - classifiers=[ - 'Development Status :: 4 - Beta', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - ], - license='GPLv3', - python_requires=">=3", - setup_requires=['pytest-runner', 'numpy', 'cython'], - tests_require=['pytest'], - install_requires=get_install_requires(), - ext_modules=get_ext_modules(), - cmdclass={'build_ext': BuildExtension}, - zip_safe=False) - # Windows need pycocotools here: https://github.com/philferriere/cocoapi#subdirectory=PythonAPI - if platform.system() == 'Windows' and not is_installed('pycocotools'): - print("\nInstall third-party pycocotools for Windows...") - cmd = 'python -m pip install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI' - os.system(cmd) - if not is_installed('cython_bbox'): - print("\nInstall `cython_bbox`...") - cmd = 'python -m pip install git+https://github.com/yanfengliu/cython_bbox.git' - os.system(cmd) diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/README.md b/cv/pose/alphapose/pytorch/trackers/PoseFlow/README.md deleted file mode 100755 index b6dfd86b0..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/README.md +++ /dev/null @@ -1,119 +0,0 @@ -# Pose Flow - -Official implementation of [Pose Flow: Efficient Online Pose Tracking ](https://arxiv.org/abs/1802.00977). - -

- - -

- -Results on PoseTrack Challenge validation set: - -1. Task2: Multi-Person Pose Estimation (mAP) -
- -| Method | Head mAP | Shoulder mAP | Elbow mAP | Wrist mAP | Hip mAP | Knee mAP | Ankle mAP | Total mAP | -|:-------|:-----:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:| -| Detect-and-Track(FAIR) | **67.5** | 70.2 | 62 | 51.7 | 60.7 | 58.7 | 49.8 | 60.6 | -| **AlphaPose** | 66.7 | **73.3** | **68.3** | **61.1** | **67.5** | **67.0** | **61.3** | **66.5** | - -
- -2. Task3: Pose Tracking (MOTA) -
- -| Method | Head MOTA | Shoulder MOTA | Elbow MOTA | Wrist MOTA | Hip MOTA | Knee MOTA | Ankle MOTA | Total MOTA | Total MOTP| Speed(FPS) | -|:-------|:-----:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:| -| Detect-and-Track(FAIR) | **61.7** | 65.5 | 57.3 | 45.7 | 54.3 | 53.1 | 45.7 | 55.2 | 61.5 |Unknown| -| **PoseFlow(DeepMatch)** | 59.8 | **67.0** | 59.8 | 51.6 | **60.0** | **58.4** | **50.5** | **58.3** | **67.8**|8| -| **PoseFlow(OrbMatch)** | 59.0 | 66.8 | **60.0** | **51.8** | 59.4 | **58.4** | 50.3 | 58.0 | 62.2|24| - -
- -## Latest Features -- Dec 2018: PoseFlow(General Version) released! Support ANY DATASET and pose tracking results visualization. -- Oct 2018: Support generating correspondence files with ORB(OpenCV), 3X FASTER and no need to compile DeepMatching library. - -## Requirements - -- Python 2.7.13 -- OpenCV 3.4.2.16 -- OpenCV-contrib 3.4.2.16 -- tqdm 4.19.8 - -## Installation - -1. Download PoseTrack Dataset from [PoseTrack](https://posetrack.net/) to `AlphaPose/PoseFlow/posetrack_data/` - -```shell -pip install -r requirements.txt -``` - -## For Any Datasets (General Version) - -1. Using [AlphaPose](https://github.com/MVIG-SJTU/AlphaPose) to generate multi-person pose estimation results. - -```shell -# pytorch version -python demo.py --indir ${image_dir}$ --outdir ${results_dir}$ -``` - -2. Run pose tracking - - -```shell -# pytorch version -python tracker-general.py --imgdir ${image_dir}$ - --in_json ${results_dir}$/alphapose-results.json - --out_json ${results_dir}$/alphapose-results-forvis-tracked.json - --visdir ${render_dir}$ -``` - - -## For PoseTrack Dataset Evaluation (Paper Baseline) - -1. Using [AlphaPose](https://github.com/MVIG-SJTU/AlphaPose) to generate multi-person pose estimation results on videos with format like `alpha-pose-results-sample.json`. -2. Using DeepMatching/ORB to generate correspondence files. - -```shell -# Generate correspondences by orb -python matching.py --orb=1 -``` - -3. Run pose tracking - - -```shell -python tracker-baseline.py --dataset=val/test --orb=1 -``` -4. Evaluation - -Original [poseval](https://github.com/leonid-pishchulin/poseval) has some instructions on how to convert annotation files from MAT to JSON. - -Evaluate pose tracking results on validation dataset: - -```shell -git clone https://github.com/leonid-pishchulin/poseval.git --recursive -cd poseval/py && export PYTHONPATH=$PWD/../py-motmetrics:$PYTHONPATH -cd ../../ -python poseval/py/evaluate.py --groundTruth=./posetrack_data/annotations/val \ - --predictions=./${track_result_dir}/ \ - --evalPoseTracking --evalPoseEstimation -``` - - -## Citation - -Please cite these papers in your publications if it helps your research: - - @inproceedings{xiu2018poseflow, - author = {Xiu, Yuliang and Li, Jiefeng and Wang, Haoyu and Fang, Yinghong and Lu, Cewu}, - title = {{Pose Flow}: Efficient Online Pose Tracking}, - booktitle={BMVC}, - year = {2018} - } - - - - - diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/alpha-pose-results-sample.json b/cv/pose/alphapose/pytorch/trackers/PoseFlow/alpha-pose-results-sample.json deleted file mode 100755 index 10b40b83f..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/alpha-pose-results-sample.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "images/bonn_mpii_test_5sec/24621_mpii/00000103.jpg": [ - { - "score": 8.385687289228619, - "keypoints": [ - 606.1139178059441, - 1055.7866630683084, - 0.1285074118632463, - 622, - 1016, - 1.24690842628479, - 701, - 785, - 1.3190804719924927, - 919, - 798, - 1.0360052585601807, - 622, - 1003, - 0.7249196767807007, - 600.5921057594508, - 1043.7039471202747, - 0.07363978983288405, - 747, - 785, - 1.1118680238723755, - 754, - 362, - 1.351969599723816, - 761, - 362, - 1.329826831817627, - 735.0299835119931, - 148.28635614181508, - 1.2460612274594385, - 616.8225141507821, - 775.3727265996391, - 4.076232522035756, - 648, - 613, - 2.3751518726348877, - 651.8582324380334, - 341.53551239931363, - 3.683300004030267, - 880, - 435, - 2.192237377166748, - 946, - 607, - 4.622312943140666, - 993.0232720577997, - 779, - 3.9823181915094947 - ] - }, - { - "score": 10.950873801541226, - "keypoints": [ - 1079.745663413901, - 1057.876310361107, - 0.05478342392744616, - 1085.7446022663407, - 927.8509247239244, - 3.989027662754409, - 1076.4168091495721, - 681.0010309293239, - 3.69318636501652, - 1175.751233049613, - 675.4609653408796, - 3.894998808909425, - 1168.367434746748, - 925.6795830692723, - 4.041951319921906, - 1246.736699044823, - 1057.6171141024415, - 0.35268874869071126, - 1124.9376542870104, - 674.6766129035676, - 3.103561346457346, - 1135.6961084323723, - 314.70914186846545, - 3.308468804589743, - 1127.340462592704, - 258.60926488886156, - 4.206135445215616, - 1104.7237517457497, - 110.1842839789316, - 3.7932232834089974, - 1021.6023155423281, - 685.7139033202061, - 2.1369253795349024, - 1037.0987900834948, - 514.4666027032713, - 1.3758957654789534, - 1053.185942829918, - 324.0023196992991, - 3.6865770542425436, - 1219.9910902145912, - 313.78280708471095, - 4.968025243674319, - 1242.666019724613, - 508.9999999999999, - 5.531640558590693, - 1199.6364698448594, - 672.3816554867356, - 5.188543576240203 - ] - }, - { - "score": 8.796343223208792, - "keypoints": [ - 892, - 1057, - 0.0642801970243454, - 879, - 960, - 2.7418549060821533, - 873, - 709, - 1.4490729570388794, - 976, - 709, - 2.326153039932251, - 976, - 947, - 1.8430407047271729, - 1018.3358121883978, - 1056.6669765235497, - 0.21173024539211077, - 924, - 709, - 1.6106798648834229, - 931, - 342, - 1.8503456115722656, - 944.5304231025389, - 289.8346541279278, - 2.84533776915699, - 911.8320538351469, - 133.33264423713035, - 2.8966951072816554, - 847, - 709, - 0.2632869780063629, - 1055.3791695827251, - 530.2416608345495, - 0.052683703823322964, - 868.2297245132042, - 343.1756749304577, - 1.56991625917443, - 1041.1065908708715, - 345.8934091291283, - 4.5100791598212595, - 1057.7401496489065, - 539.3480299297813, - 4.881036537158492, - 1025.9666633264292, - 694.5222411502352, - 4.941733110537884 - ] - } - ], - "images/bonn_mpii_test_5sec/24621_mpii/00000104.jpg": [ - {"score": ,"keypoints":[]}, - ... - ,{"score": ,"keypoints":[]} - ] - ... -} \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/matching.py b/cv/pose/alphapose/pytorch/trackers/PoseFlow/matching.py deleted file mode 100755 index a1369bcc9..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/matching.py +++ /dev/null @@ -1,128 +0,0 @@ -# coding: utf-8 -''' -File: matching.py -Project: AlphaPose -File Created: Monday, 1st October 2018 12:53:12 pm -Author: Yuliang Xiu (yuliangxiu@sjtu.edu.cn) -Copyright 2018 - 2018 Shanghai Jiao Tong University, Machine Vision and Intelligence Group -''' - - -import os -import cv2 -from tqdm import tqdm -import numpy as np -import time -import argparse - -def generate_fake_cor(img, out_path): - print("Generate fake correspondence files...%s"%out_path) - fd = open(out_path,"w") - height, width, channels = img.shape - - for x in range(width): - for y in range(height): - ret = fd.write("%d %d %d %d %f \n"%(x, y, x, y, 1.0)) - fd.close() - - -def orb_matching(img1_path, img2_path, vidname, img1_id, img2_id): - - out_path = "%s/%s_%s_orb.txt"%(vidname, img1_id, img2_id) - # print(out_path) - - if isinstance(img1_path, str): - img1 = cv2.cvtColor(cv2.imread(img1_path), cv2.COLOR_BGR2RGB) - else: - img1 = cv2.cvtColor(img1_path, cv2.COLOR_BGR2RGB) - if isinstance(img2_path, str): - img2 = cv2.cvtColor(cv2.imread(img2_path), cv2.COLOR_BGR2RGB) - else: - img2 = cv2.cvtColor(img2_path, cv2.COLOR_BGR2RGB) - - # Initiate ORB detector - orb = cv2.ORB_create(nfeatures=10000, scoreType=cv2.ORB_FAST_SCORE) - - # find the keypoints and descriptors with ORB - kp1, des1 = orb.detectAndCompute(img1,None) - kp2, des2 = orb.detectAndCompute(img2,None) - - if len(kp1)*len(kp2) < 400: - generate_fake_cor(img1, out_path) - return - - # FLANN parameters - FLANN_INDEX_LSH = 6 - index_params= dict(algorithm = FLANN_INDEX_LSH, - table_number = 12, # 12 - key_size = 12, # 20 - multi_probe_level = 2) #2 - - search_params = dict(checks=100) # or pass empty dictionary - - flann = cv2.FlannBasedMatcher(index_params,search_params) - - matches = flann.knnMatch(des1, des2, k=2) - - # Open file - fd = open(out_path,"w") - - # ratio test as per Lowe's paper - for i, m_n in enumerate(matches): - if len(m_n) != 2: - continue - elif m_n[0].distance < 0.80*m_n[1].distance: - ret = fd.write("%d %d %d %d %f \n"%(kp1[m_n[0].queryIdx].pt[0], kp1[m_n[0].queryIdx].pt[1], kp2[m_n[0].trainIdx].pt[0], kp2[m_n[0].trainIdx].pt[1], m_n[0].distance)) - - # Close opened file - fd.close() - - # print(os.stat(out_path).st_size) - - if os.stat(out_path).st_size<1000: - generate_fake_cor(img1, out_path) - -if __name__ == '__main__': - - parser = argparse.ArgumentParser(description='FoseFlow Matching') - parser.add_argument('--orb', type=int, default=1) - args = parser.parse_args() - - image_dir = "posetrack_data/images" - imgnames = [] - vidnames = [] - - for a,b,c in os.walk(image_dir): - if len(a.split("/")) == 4: - vidnames.append(a) - - for vidname in tqdm(sorted(vidnames)): - for a,b,c in os.walk(vidname): - c=[item for item in c if "jpg" in item] - imgnames = sorted(c) - break - for imgname in imgnames[:-1]: - if 'crop' in imgname: - continue - img1 = os.path.join(vidname,imgname) - len_name = len(imgname.split(".")[0]) - if len_name == 5: - img2 = os.path.join(vidname,"%05d.jpg"%(int(imgname.split(".")[0])+1)) - else: - img2 = os.path.join(vidname,"%08d.jpg"%(int(imgname.split(".")[0])+1)) - if not os.path.exists(img2): - continue - img1_id = img1.split(".")[0].split("/")[-1] - img2_id = img2.split(".")[0].split("/")[-1] - if args.orb: - cor_file = "%s/%s_%s_orb.txt"%(vidname,img1_id,img2_id) - else: - cor_file = "%s/%s_%s.txt"%(vidname,img1_id,img2_id) - if not os.path.exists(cor_file) or os.stat(cor_file).st_size<1000: - if args.orb: - # calc orb matching - orb_matching(img1,img2,vidname,img1_id,img2_id) - else: - # calc deep matching - cmd = "./deepmatching/deepmatching %s %s -nt 10 -downscale 3 -out %s/%s_%s.txt > cache"%(img1,img2,vidname,img1_id,img2_id) - os.system(cmd) diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/parallel_process.py b/cv/pose/alphapose/pytorch/trackers/PoseFlow/parallel_process.py deleted file mode 100755 index 138ef6b08..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/parallel_process.py +++ /dev/null @@ -1,49 +0,0 @@ -# adapted from http://danshiebler.com/2016-09-14-parallel-progress-bar/ -from tqdm import tqdm -from concurrent.futures import ProcessPoolExecutor, as_completed - -def parallel_process(array, function, n_jobs=16, use_kwargs=False, front_num=3): - """ - A parallel version of the map function with a progress bar. - - Args: - array (array-like): An array to iterate over. - function (function): A python function to apply to the elements of array - n_jobs (int, default=16): The number of cores to use - use_kwargs (boolean, default=False): Whether to consider the elements of array as dictionaries of - keyword arguments to function - front_num (int, default=3): The number of iterations to run serially before kicking off the parallel job. - Useful for catching bugs - Returns: - [function(array[0]), function(array[1]), ...] - """ - #We run the first few iterations serially to catch bugs - if front_num > 0: - front = [function(**a) if use_kwargs else function(*a) for a in array[:front_num]] - #If we set n_jobs to 1, just run a list comprehension. This is useful for benchmarking and debugging. - if n_jobs==1: - return front + [function(**a) if use_kwargs else function(*a) for a in tqdm(array[front_num:])] - #Assemble the workers - with ProcessPoolExecutor(max_workers=n_jobs) as pool: - #Pass the elements of array into function - if use_kwargs: - futures = [pool.submit(function, **a) for a in array[front_num:]] - else: - futures = [pool.submit(function, *a) for a in array[front_num:]] - kwargs = { - 'total': len(futures), - 'unit': 'it', - 'unit_scale': True, - 'leave': True - } - #Print out the progress as tasks complete - for f in tqdm(as_completed(futures), **kwargs): - pass - out = [] - #Get the results from the futures. - for i, future in enumerate(futures): - try: - out.append(future.result()) - except Exception as e: - out.append(e) - return front + out \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/poseflow_infer.py b/cv/pose/alphapose/pytorch/trackers/PoseFlow/poseflow_infer.py deleted file mode 100755 index d3051a5dd..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/poseflow_infer.py +++ /dev/null @@ -1,191 +0,0 @@ -# -*- coding: utf-8 -*- -# @Author: Chao Xu -# @Email: xuchao.19962007@sjtu.edu.cn -# @Date: 2019-10-09 17:42:10 -# @Last Modified by: Chao Xu -# @Last Modified time: 2019-10-27 20:20:45 - -import os -import numpy as np - -from .matching import orb_matching -from .utils import expand_bbox, stack_all_pids, best_matching_hungarian - -def get_box(pose, img_height, img_width): - - pose = np.array(pose).reshape(-1,3) - xmin = np.min(pose[:,0]) - xmax = np.max(pose[:,0]) - ymin = np.min(pose[:,1]) - ymax = np.max(pose[:,1]) - - return expand_bbox(xmin, xmax, ymin, ymax, img_width, img_height) - -#The wrapper of PoseFlow algorithm to be embedded in alphapose inference -class PoseFlowWrapper(): - def __init__(self, link=100, drop=2.0, num=7, - mag=30, match=0.2, save_path='.tmp/poseflow', pool_size=5): - # super parameters - # 1. look-ahead LINK_LEN frames to find tracked human bbox - # 2. bbox_IoU(deepmatching), bbox_IoU(general), pose_IoU(deepmatching), pose_IoU(general), box1_score, box2_score - # 3. bbox_IoU(deepmatching), bbox_IoU(general), pose_IoU(deepmatching), pose_IoU(general), box1_score, box2_score(Non DeepMatching) - # 4. drop low-score( self.match_thres: - self.track[frame_name][pid2+1]['new_pid'] = cur_all_pids[pid1]['new_pid'] - self.max_pid_id = max(self.max_pid_id, self.track[frame_name][pid2+1]['new_pid']) - self.track[frame_name][pid2+1]['match_score'] = match_scores[pid1][pid2] - - # add the untracked new person - for next_pid in range(1, self.track[frame_name]['num_boxes'] + 1): - if 'new_pid' not in self.track[frame_name][next_pid]: - self.max_pid_id += 1 - self.track[frame_name][next_pid]['new_pid'] = self.max_pid_id - self.track[frame_name][next_pid]['match_score'] = 0 - - self.prev_img = img.copy() - return self.final_result_by_name(frame_name) - - @property - def num_persons(self): - # calculate number of people - num_persons = 0 - frame_list = sorted(list(self.track.keys())) - for fid, frame_name in enumerate(frame_list): - for pid in range(1, self.track[frame_name]['num_boxes']+1): - num_persons = max(num_persons, self.track[frame_name][pid]['new_pid']) - return num_persons - - @property - def final_results(self): - # export tracking result into notrack json data - frame_list = sorted(list(self.track.keys())) - for fid, frame_name in enumerate(frame_list): - for pid in range(self.track[frame_name]['num_boxes']): - self.notrack[frame_name][pid]['idx'] = self.track[frame_name][pid+1]['new_pid'] - return self.notrack - - def final_result_by_name(self, frame_name): - # export tracking result into notrack json data by frame name - for pid in range(self.track[frame_name]['num_boxes']): - self.notrack[frame_name][pid]['idx'] = self.track[frame_name][pid+1]['new_pid'] - return self.notrack[frame_name] - - - - - - - - \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/posetrack_data b/cv/pose/alphapose/pytorch/trackers/PoseFlow/posetrack_data deleted file mode 100755 index f002bfe92..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/posetrack_data +++ /dev/null @@ -1 +0,0 @@ -/home/yuliang/data/posetrack_data/posetrack_data \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/poseval b/cv/pose/alphapose/pytorch/trackers/PoseFlow/poseval deleted file mode 100755 index 5ec030681..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/poseval +++ /dev/null @@ -1 +0,0 @@ -/home/yuliang/data/posetrack_data/poseval \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/requirements.txt b/cv/pose/alphapose/pytorch/trackers/PoseFlow/requirements.txt deleted file mode 100755 index 50cfd35e2..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -numpy==1.14.5 -scipy==1.1.0 -opencv_python==3.4.2.16 -opencv_contrib_python==3.4.2.16 -matplotlib==2.2.2 -tqdm==4.23.4 -Image==1.5.25 -Pillow==5.3.0 -munkres==1.0.12 diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/tracker-baseline.py b/cv/pose/alphapose/pytorch/trackers/PoseFlow/tracker-baseline.py deleted file mode 100755 index ea35c1f7a..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/tracker-baseline.py +++ /dev/null @@ -1,278 +0,0 @@ -# coding: utf-8 - -''' -File: tracker-baseline.py -Project: AlphaPose -File Created: Thursday, 1st March 2018 6:12:23 pm -Author: Yuliang Xiu (yuliangxiu@sjtu.edu.cn) ------ -Last Modified: Monday, 1st October 2018 12:53:12 pm -Modified By: Yuliang Xiu (yuliangxiu@sjtu.edu.cn>) ------ -Copyright 2018 - 2018 Shanghai Jiao Tong University, Machine Vision and Intelligence Group -''' - -import numpy as np -import os -import json -import copy -import heapq -from munkres import Munkres, print_matrix -from PIL import Image -from tqdm import tqdm -from utils import * -from matching import orb_matching -import argparse - - -# posetrack dataset path -image_dir = "./posetrack_data" - -if __name__ == '__main__': - - parser = argparse.ArgumentParser(description='FoseFlow Tracker') - parser.add_argument('--link', type=int, default=100) - parser.add_argument('--drop', type=float, default=2.0) - parser.add_argument('--num', type=int, default=7) - parser.add_argument('--mag', type=int, default=30) - parser.add_argument('--match', type=float, default=0.2) - parser.add_argument('--dataset', type=str, default='val') - parser.add_argument('--orb', type=int, default=0) - - args = parser.parse_args() - - # super parameters - # 1. look-ahead LINK_LEN frames to find tracked human bbox - # 2. bbox_IoU(deepmatching), bbox_IoU(general), pose_IoU(deepmatching), pose_IoU(general), box1_score, box2_score - # 3. bbox_IoU(deepmatching), bbox_IoU(general), pose_IoU(deepmatching), pose_IoU(general), box1_score, box2_score(Non DeepMatching) - # 4. drop low-score( match_thres: - track[video_name][next_frame_name][pid2+1]['new_pid'] = cur_all_pids[pid1]['new_pid'] - max_pid_id = max(max_pid_id, track[video_name][next_frame_name][pid2+1]['new_pid']) - track[video_name][next_frame_name][pid2+1]['match_score'] = match_scores[pid1][pid2] - - # add the untracked new person - for next_pid in range(1, track[video_name][next_frame_name]['num_boxes'] + 1): - if 'new_pid' not in track[video_name][next_frame_name][next_pid]: - max_pid_id += 1 - track[video_name][next_frame_name][next_pid]['new_pid'] = max_pid_id - track[video_name][next_frame_name][next_pid]['match_score'] = 0 - - # deal with unconsecutive frames caused by this fucking terrible dataset - gap = int(next_frame_id)-int(frame_id) - if gap>1: - for i in range(gap): - if i>0: - new_frame_name = "%08d.jpg"%(int(frame_id)+i) - track[video_name][new_frame_name] = copy.deepcopy(track[video_name][frame_name]) - - rmpe_part_ids = [0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 8, 9] - - for video_name in tqdm(track.keys()): - num_persons = 0 - frame_list = sorted(list(track[video_name].keys())) - for fid, frame_name in enumerate(frame_list): - for pid in range(1, track[video_name][frame_name]['num_boxes']+1): - new_score = copy.deepcopy(track[video_name][frame_name][pid]['box_pose_score']) - new_pose = copy.deepcopy(track[video_name][frame_name][pid]['box_pose_pos']) - track[video_name][frame_name][pid]['box_pose_score'] = new_score[rmpe_part_ids] - track[video_name][frame_name][pid]['box_pose_pos'] = new_pose[rmpe_part_ids,:] - num_persons = max(num_persons, track[video_name][frame_name][pid]['new_pid']) - track[video_name]['num_persons'] = num_persons - - np.save('track-{}.npy'.format(dataset),track) - track = np.load('track-{}.npy'.format(dataset)).item() - - for a,b,c in os.walk(anno_dir): - val_jsons = [item for item in c if 'json' in item] - break - - # export tracking result into json files - for video_name in tqdm(track.keys()): - if dataset == 'val': - name = [item for item in val_jsons if video_name.split("/")[-1] in item] - if len(name) == 0: - name = [item for item in val_jsons if video_name.split("/")[-1][1:] in item] - name = name[0] - else: - # FUCK the dirty PoseTrack dataset - name = [item for item in val_jsons if video_name.split("/")[-1].split("_")[0] == item.split("_")[0]] - if video_name.split("/")[-1].split("_")[0] == "000044": - if video_name.split("/")[-2]=='mpii_5sec': - name = ["00044_mpii_step1_relpath_5sec_testsub.json"] - elif video_name.split("/")[-2]=='bonn_5sec': - name = ["000044_mpii_relpath_5sec_testsub.json"] - - if video_name.split("/")[-1].split("_")[0] == "002279": - if video_name.split("/")[-2]=='mpii_5sec': - name = ["02279_mpii_step2_relpath_5sec_testsub.json"] - elif video_name.split("/")[-2]=='bonn_mpii_test_v2_5sec': - name = ["02279_mpii_relpath_5sec_testsub.json"] - - if video_name.split("/")[-1].split("_")[0] == "019980": - if video_name.split("/")[-2]=='bonn_5sec': - name = ["019980_mpii_relpath_5sec_testsub.json"] - elif video_name.split("/")[-2]=='mpii_5sec': - name = ["19980_mpii_step1_relpath_5sec_testsub.json"] - - if video_name.split("/")[-1].split("_")[0] == "09611": - name = ["09611_mpii_relpath_5sec_testsub.json"] - if video_name.split("/")[-1].split("_")[0] == "009611": - name = ["09611_mpii_step2_relpath_5sec_testsub.json"] - - if video_name.split("/")[-1].split("_")[0][:-1] == '00000': - name = [item for item in val_jsons if video_name.split("/")[-1].split("_")[0][1:] == item.split("_")[0]] - if len(name)==0: - name = [item for item in val_jsons if video_name.split("/")[-1].split("_")[0][1:] == item.split("_")[0]] - name = name[0] - - final = {'annolist':[]} - frame_list = list(track[video_name].keys()) - frame_list.remove('num_persons') - frame_list = sorted(frame_list) - - with open(os.path.join(anno_dir,name)) as f: - annot = json.load(f) - - imgs = [] - for img in annot['annolist']: - imgs.append(img['image'][0]['name']) - - for fid, frame_name in enumerate(frame_list): - if os.path.join(video_name,frame_name) not in imgs: - continue - final['annolist'].append({"image":[{"name":os.path.join(video_name,frame_name)}],"annorect":[]}) - for pid in range(1, track[video_name][frame_name]['num_boxes']+1): - pid_info = track[video_name][frame_name][pid] - box_pos = pid_info['box_pos'] - box_score = pid_info['box_score'] - pose_pos = pid_info['box_pose_pos'] - pose_score = pid_info['box_pose_score'] - pose_pos = add_nose(pose_pos) - pose_score = add_nose(pose_score) - new_pid = pid_info['new_pid'] - - point_struct = [] - for idx,pose in enumerate(pose_pos): - if pose_score[idx]>drop: - point_struct.append({"id":[idx],"x":[pose[0]],"y":[pose[1]],"score":[pose_score[idx]]}) - final['annolist'][fid]['annorect'].append({"x1":[box_pos[0]],\ - "x2":[box_pos[1]],\ - "y1":[box_pos[2]],\ - "y2":[box_pos[3]],\ - "score":[box_score],\ - "track_id":[new_pid-1],\ - "annopoints":[{"point":point_struct}]}) - - for rest_name in enumerate(remove_list(imgs,video_name,frame_list)): - final['annolist'].append({"image":[{"name":rest_name}],"annorect":[]}) - with open("%s/%s"%(track_dir,name),'w') as json_file: - json_file.write(json.dumps(final)) diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/tracker-general.py b/cv/pose/alphapose/pytorch/trackers/PoseFlow/tracker-general.py deleted file mode 100755 index 2811c65de..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/tracker-general.py +++ /dev/null @@ -1,242 +0,0 @@ -# coding: utf-8 - -''' -File: tracker-general.py -Project: AlphaPose -File Created: Tuesday, 18st Dec 2018 14:55:41 pm ------ -Last Modified: Thursday, 20st Dec 2018 23:24:47 pm -Modified By: Yuliang Xiu (yuliangxiu@sjtu.edu.cn>) ------ -Author: Yuliang Xiu (yuliangxiu@sjtu.edu.cn) -Copyright 2018 - 2018 Shanghai Jiao Tong University, Machine Vision and Intelligence Group -''' - -import numpy as np -import os -import json -import copy -import heapq -from munkres import Munkres, print_matrix -from PIL import Image -import matplotlib.pyplot as plt -from tqdm import tqdm -from utils import * -from matching import orb_matching -import argparse -import multiprocessing -from parallel_process import parallel_process - -# visualization -def display_pose(imgdir, visdir, tracked, cmap): - - print("Start visualization...\n") - for imgname in tqdm(tracked.keys()): - img = Image.open(os.path.join(imgdir,imgname)) - width, height = img.size - fig = plt.figure(figsize=(width/10,height/10),dpi=10) - plt.imshow(img) - for pid in range(len(tracked[imgname])): - pose = np.array(tracked[imgname][pid]['keypoints']).reshape(-1,3)[:,:3] - tracked_id = tracked[imgname][pid]['idx'] - - # keypoint scores of torch version and pytorch version are different - if np.mean(pose[:,2]) <1 : - alpha_ratio = 1.0 - else: - alpha_ratio = 5.0 - - if pose.shape[0] == 16: - mpii_part_names = ['RAnkle','RKnee','RHip','LHip','LKnee','LAnkle','Pelv','Thrx','Neck','Head','RWrist','RElbow','RShoulder','LShoulder','LElbow','LWrist'] - colors = ['m', 'b', 'b', 'r', 'r', 'b', 'b', 'r', 'r', 'm', 'm', 'm', 'r', 'r','b','b'] - pairs = [[8,9],[11,12],[11,10],[2,1],[1,0],[13,14],[14,15],[3,4],[4,5],[8,7],[7,6],[6,2],[6,3],[8,12],[8,13]] - for idx_c, color in enumerate(colors): - plt.plot(np.clip(pose[idx_c,0],0,width), np.clip(pose[idx_c,1],0,height), marker='o', - color=color, ms=80/alpha_ratio*np.mean(pose[idx_c,2]), markerfacecolor=(1, 1, 0, 0.7/alpha_ratio*pose[idx_c,2])) - for idx in range(len(pairs)): - plt.plot(np.clip(pose[pairs[idx],0],0,width),np.clip(pose[pairs[idx],1],0,height), 'r-', - color=cmap(tracked_id), linewidth=60/alpha_ratio*np.mean(pose[pairs[idx],2]), alpha=0.6/alpha_ratio*np.mean(pose[pairs[idx],2])) - elif pose.shape[0] == 17: - coco_part_names = ['Nose','LEye','REye','LEar','REar','LShoulder','RShoulder','LElbow','RElbow','LWrist','RWrist','LHip','RHip','LKnee','RKnee','LAnkle','RAnkle'] - colors = ['r', 'r', 'r', 'r', 'r', 'y', 'y', 'y', 'y', 'y', 'y', 'g', 'g', 'g','g','g','g'] - pairs = [[0,1],[0,2],[1,3],[2,4],[5,6],[5,7],[7,9],[6,8],[8,10],[11,12],[11,13],[13,15],[12,14],[14,16],[6,12],[5,11]] - for idx_c, color in enumerate(colors): - plt.plot(np.clip(pose[idx_c,0],0,width), np.clip(pose[idx_c,1],0,height), marker='o', - color=color, ms=80/alpha_ratio*np.mean(pose[idx_c,2]), markerfacecolor=(1, 1, 0, 0.7/alpha_ratio*pose[idx_c,2])) - for idx in range(len(pairs)): - plt.plot(np.clip(pose[pairs[idx],0],0,width),np.clip(pose[pairs[idx],1],0,height),'r-', - color=cmap(tracked_id), linewidth=60/alpha_ratio*np.mean(pose[pairs[idx],2]), alpha=0.6/alpha_ratio*np.mean(pose[pairs[idx],2])) - plt.axis('off') - ax = plt.gca() - ax.set_xlim([0,width]) - ax.set_ylim([height,0]) - extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted()) - if not os.path.exists(visdir): - os.mkdir(visdir) - fig.savefig(os.path.join(visdir,imgname.split()[0]+".png"), pad_inches = 0.0, bbox_inches=extent, dpi=13) - plt.close() - - -if __name__ == '__main__': - - parser = argparse.ArgumentParser(description='FoseFlow Tracker') - parser.add_argument('--imgdir', type=str, required=True, help="Must input the images dir") - parser.add_argument('--in_json', type=str, required=True, help="result json predicted by AlphaPose") - parser.add_argument('--out_json', type=str, required=True, help="output path of tracked json") - parser.add_argument('--visdir', type=str, default="", help="visulization tracked results of video sequences") - - parser.add_argument('--link', type=int, default=100) - parser.add_argument('--drop', type=float, default=2.0) - parser.add_argument('--num', type=int, default=7) - parser.add_argument('--mag', type=int, default=30) - parser.add_argument('--match', type=float, default=0.2) - - args = parser.parse_args() - - # super parameters - # 1. look-ahead LINK_LEN frames to find tracked human bbox - # 2. bbox_IoU(deepmatching), bbox_IoU(general), pose_IoU(deepmatching), pose_IoU(general), box1_score, box2_score - # 3. bbox_IoU(deepmatching), bbox_IoU(general), pose_IoU(deepmatching), pose_IoU(general), box1_score, box2_score(Non DeepMatching) - # 4. drop low-score( match_thres: - track[next_frame_name][pid2+1]['new_pid'] = cur_all_pids[pid1]['new_pid'] - max_pid_id = max(max_pid_id, track[next_frame_name][pid2+1]['new_pid']) - track[next_frame_name][pid2+1]['match_score'] = match_scores[pid1][pid2] - - # add the untracked new person - for next_pid in range(1, track[next_frame_name]['num_boxes'] + 1): - if 'new_pid' not in track[next_frame_name][next_pid]: - max_pid_id += 1 - track[next_frame_name][next_pid]['new_pid'] = max_pid_id - track[next_frame_name][next_pid]['match_score'] = 0 - - np.save('track-bl.npy',track) - # track = np.load('track-bl.npy').item() - - # calculate number of people - num_persons = 0 - for fid, frame_name in enumerate(frame_list): - for pid in range(1, track[frame_name]['num_boxes']+1): - num_persons = max(num_persons, track[frame_name][pid]['new_pid']) - print("This video contains %d people."%(num_persons)) - - # export tracking result into notrack json files - print("Export tracking results to json...\n") - for fid, frame_name in enumerate(tqdm(frame_list)): - for pid in range(track[frame_name]['num_boxes']): - notrack[frame_name][pid]['idx'] = track[frame_name][pid+1]['new_pid'] - - with open(tracked_json,'w') as json_file: - json_file.write(json.dumps(notrack)) - - if len(args.visdir)>0: - cmap = plt.cm.get_cmap("hsv", num_persons) - display_pose(image_dir, vis_dir, notrack, cmap) diff --git a/cv/pose/alphapose/pytorch/trackers/PoseFlow/utils.py b/cv/pose/alphapose/pytorch/trackers/PoseFlow/utils.py deleted file mode 100755 index 7cf2af9bb..000000000 --- a/cv/pose/alphapose/pytorch/trackers/PoseFlow/utils.py +++ /dev/null @@ -1,291 +0,0 @@ -# coding: utf-8 - -''' -File: utils.py -Project: AlphaPose -File Created: Thursday, 1st March 2018 5:32:34 pm -Author: Yuliang Xiu (yuliangxiu@sjtu.edu.cn) ------ -Last Modified: Thursday, 20th March 2018 1:18:17 am -Modified By: Yuliang Xiu (yuliangxiu@sjtu.edu.cn>) ------ -Copyright 2018 - 2018 Shanghai Jiao Tong University, Machine Vision and Intelligence Group -''' - -import numpy as np -import cv2 as cv -import os -import json -import copy -import heapq -from concurrent.futures import ProcessPoolExecutor -from munkres import Munkres, print_matrix -from PIL import Image -from tqdm import tqdm - - -# keypoint penalty weight -delta = 2*np.array([0.01388152, 0.01515228, 0.01057665, 0.01417709, 0.01497891, 0.01402144, \ - 0.03909642, 0.03686941, 0.01981803, 0.03843971, 0.03412318, 0.02415081, \ - 0.01291456, 0.01236173,0.01291456, 0.01236173]) - - -# get expand bbox surrounding single person's keypoints -def get_box(pose, imgpath): - - pose = np.array(pose).reshape(-1,3) - xmin = np.min(pose[:,0]) - xmax = np.max(pose[:,0]) - ymin = np.min(pose[:,1]) - ymax = np.max(pose[:,1]) - - img_height, img_width, _ = cv.imread(imgpath).shape - - return expand_bbox(xmin, xmax, ymin, ymax, img_width, img_height) - -# expand bbox for containing more background -def expand_bbox(left, right, top, bottom, img_width, img_height): - - width = right - left - height = bottom - top - ratio = 0.1 # expand ratio - new_left = np.clip(left - ratio * width, 0, img_width) - new_right = np.clip(right + ratio * width, 0, img_width) - new_top = np.clip(top - ratio * height, 0, img_height) - new_bottom = np.clip(bottom + ratio * height, 0, img_height) - - return [int(new_left), int(new_right), int(new_top), int(new_bottom)] - -# calculate final matching grade -def cal_grade(l, w): - return sum(np.array(l)*np.array(w)) - -# calculate IoU of two boxes(thanks @ZongweiZhou1) -def cal_bbox_iou(boxA, boxB): - - xA = max(boxA[0], boxB[0]) #xmin - yA = max(boxA[2], boxB[2]) #ymin - xB = min(boxA[1], boxB[1]) #xmax - yB = min(boxA[3], boxB[3]) #ymax - - if xA < xB and yA < yB: - interArea = (xB - xA + 1) * (yB - yA + 1) - boxAArea = (boxA[1] - boxA[0] + 1) * (boxA[3] - boxA[2] + 1) - boxBArea = (boxB[1] - boxB[0] + 1) * (boxB[3] - boxB[2] + 1) - iou = interArea / float(boxAArea + boxBArea - interArea+0.00001) - else: - iou=0.0 - - return iou - -# calculate OKS between two single poses -def compute_oks(anno, predict, delta): - - xmax = np.max(np.vstack((anno[:, 0], predict[:, 0]))) - xmin = np.min(np.vstack((anno[:, 0], predict[:, 0]))) - ymax = np.max(np.vstack((anno[:, 1], predict[:, 1]))) - ymin = np.min(np.vstack((anno[:, 1], predict[:, 1]))) - scale = (xmax - xmin) * (ymax - ymin) - dis = np.sum((anno - predict)**2, axis=1) - oks = np.mean(np.exp(-dis / 2 / delta**2 / scale)) - - return oks - -# stack all already tracked people's info together(thanks @ZongweiZhou1) -def stack_all_pids(track_vid, frame_list, idxs, max_pid_id, link_len): - - #track_vid contains track_vid[<=idx] - all_pids_info = [] - all_pids_fff = [] # boolean list, 'fff' means From Former Frame - all_pids_ids = [(item+1) for item in range(max_pid_id)] - - for idx in np.arange(idxs,max(idxs-link_len,-1),-1): - for pid in range(1, track_vid[frame_list[idx]]['num_boxes']+1): - if len(all_pids_ids) == 0: - return all_pids_info, all_pids_fff - elif track_vid[frame_list[idx]][pid]['new_pid'] in all_pids_ids: - all_pids_ids.remove(track_vid[frame_list[idx]][pid]['new_pid']) - all_pids_info.append(track_vid[frame_list[idx]][pid]) - if idx == idxs: - all_pids_fff.append(True) - else: - all_pids_fff.append(False) - return all_pids_info, all_pids_fff - -# calculate DeepMatching Pose IoU given two boxes -def find_two_pose_box_iou(pose1_box, pose2_box, all_cors): - - x1, y1, x2, y2 = [all_cors[:, col] for col in range(4)] - x_min, x_max, y_min, y_max = pose1_box - x1_region_ids = set(np.where((x1 >= x_min) & (x1 <= x_max))[0].tolist()) - y1_region_ids = set(np.where((y1 >= y_min) & (y1 <= y_max))[0].tolist()) - region_ids1 = x1_region_ids & y1_region_ids - x_min, x_max, y_min, y_max = pose2_box - x2_region_ids = set(np.where((x2 >= x_min) & (x2 <= x_max))[0].tolist()) - y2_region_ids = set(np.where((y2 >= y_min) & (y2 <= y_max))[0].tolist()) - region_ids2 = x2_region_ids & y2_region_ids - inter = region_ids1 & region_ids2 - union = region_ids1 | region_ids2 - pose_box_iou = len(inter) / (len(union) + 0.00001) - - return pose_box_iou - -# calculate general Pose IoU(only consider top NUM matched keypoints) -def cal_pose_iou(pose1_box,pose2_box, num,mag): - - pose_iou = [] - for row in range(len(pose1_box)): - x1,y1 = pose1_box[row] - x2,y2 = pose2_box[row] - box1 = [x1-mag,x1+mag,y1-mag,y1+mag] - box2 = [x2-mag,x2+mag,y2-mag,y2+mag] - pose_iou.append(cal_bbox_iou(box1,box2)) - - return np.mean(heapq.nlargest(num, pose_iou)) - -# calculate DeepMatching based Pose IoU(only consider top NUM matched keypoints) -def cal_pose_iou_dm(all_cors,pose1,pose2,num,mag): - - poses_iou = [] - for ids in range(len(pose1)): - pose1_box = [pose1[ids][0]-mag,pose1[ids][0]+mag,pose1[ids][1]-mag,pose1[ids][1]+mag] - pose2_box = [pose2[ids][0]-mag,pose2[ids][0]+mag,pose2[ids][1]-mag,pose2[ids][1]+mag] - poses_iou.append(find_two_pose_box_iou(pose1_box, pose2_box, all_cors)) - - return np.mean(heapq.nlargest(num, poses_iou)) - -# hungarian matching algorithm(thanks @ZongweiZhou1) -def _best_matching_hungarian(all_cors, all_pids_info, all_pids_fff, track_vid_next_fid, weights, weights_fff, num, mag): - - x1, y1, x2, y2 = [all_cors[:, col] for col in range(4)] - all_grades_details = [] - all_grades = [] - - box1_num = len(all_pids_info) - box2_num = track_vid_next_fid['num_boxes'] - cost_matrix = np.zeros((box1_num, box2_num)) - - for pid1 in range(box1_num): - box1_pos = all_pids_info[pid1]['box_pos'] - box1_region_ids = find_region_cors_last(box1_pos, all_cors) - box1_score = all_pids_info[pid1]['box_score'] - box1_pose = all_pids_info[pid1]['box_pose_pos'] - box1_fff = all_pids_fff[pid1] - - for pid2 in range(1, track_vid_next_fid['num_boxes'] + 1): - box2_pos = track_vid_next_fid[pid2]['box_pos'] - box2_region_ids = find_region_cors_next(box2_pos, all_cors) - box2_score = track_vid_next_fid[pid2]['box_score'] - box2_pose = track_vid_next_fid[pid2]['box_pose_pos'] - - inter = box1_region_ids & box2_region_ids - union = box1_region_ids | box2_region_ids - dm_iou = len(inter) / (len(union) + 0.00001) - box_iou = cal_bbox_iou(box1_pos, box2_pos) - pose_iou_dm = cal_pose_iou_dm(all_cors, box1_pose, box2_pose, num,mag) - pose_iou = cal_pose_iou(box1_pose, box2_pose,num,mag) - if box1_fff: - grade = cal_grade([dm_iou, box_iou, pose_iou_dm, pose_iou, box1_score, box2_score], weights) - else: - grade = cal_grade([dm_iou, box_iou, pose_iou_dm, pose_iou, box1_score, box2_score], weights_fff) - - cost_matrix[pid1, pid2 - 1] = grade - m = Munkres() - indexes = m.compute((-np.array(cost_matrix)).tolist()) - - return indexes, cost_matrix - -# multiprocessing version of hungarian matching algorithm -def best_matching_hungarian(all_cors, all_pids_info, all_pids_fff, track_vid_next_fid, weights, weights_fff, num, mag, pool_size=5): - x1, y1, x2, y2 = [all_cors[:, col] for col in range(4)] - all_grades_details = [] - all_grades = [] - - box1_num = len(all_pids_info) - box2_num = track_vid_next_fid['num_boxes'] - cost_matrix = np.zeros((box1_num, box2_num)) - - qsize = box1_num * track_vid_next_fid['num_boxes'] - pool = ProcessPoolExecutor(max_workers=pool_size) - futures = [] - for pid1 in range(box1_num): - box1_pos = all_pids_info[pid1]['box_pos'] - box1_region_ids = find_region_cors_last(box1_pos, all_cors) - box1_score = all_pids_info[pid1]['box_score'] - box1_pose = all_pids_info[pid1]['box_pose_pos'] - box1_fff = all_pids_fff[pid1] - - for pid2 in range(1, track_vid_next_fid['num_boxes'] + 1): - future = pool.submit(best_matching_hungarian_kernel, pid1, pid2, all_cors, track_vid_next_fid, weights, weights_fff, num, mag, box1_pos, box1_region_ids, box1_score, box1_pose, box1_fff) - futures.append(future) - - pool.shutdown(True) - for future in futures: - pid1, pid2, grade = future.result() - cost_matrix[pid1, pid2 - 1] = grade - m = Munkres() - indexes = m.compute((-np.array(cost_matrix)).tolist()) - - return indexes, cost_matrix - -# one iteration of hungarian matching algorithm -def best_matching_hungarian_kernel(pid1, pid2, all_cors, track_vid_next_fid, weights, weights_fff, num, mag, box1_pos, box1_region_ids, box1_score, box1_pose, box1_fff): - box2_pos = track_vid_next_fid[pid2]['box_pos'] - box2_region_ids = find_region_cors_next(box2_pos, all_cors) - box2_score = track_vid_next_fid[pid2]['box_score'] - box2_pose = track_vid_next_fid[pid2]['box_pose_pos'] - - inter = box1_region_ids & box2_region_ids - union = box1_region_ids | box2_region_ids - dm_iou = len(inter) / (len(union) + 0.00001) - box_iou = cal_bbox_iou(box1_pos, box2_pos) - pose_iou_dm = cal_pose_iou_dm(all_cors, box1_pose, box2_pose, num,mag) - pose_iou = cal_pose_iou(box1_pose, box2_pose,num,mag) - if box1_fff: - grade = cal_grade([dm_iou, box_iou, pose_iou_dm, pose_iou, box1_score, box2_score], weights) - else: - grade = cal_grade([dm_iou, box_iou, pose_iou_dm, pose_iou, box1_score, box2_score], weights_fff) - return (pid1, pid2, grade) - -# calculate number of matching points in one box from last frame -def find_region_cors_last(box_pos, all_cors): - - x1, y1, x2, y2 = [all_cors[:, col] for col in range(4)] - x_min, x_max, y_min, y_max = box_pos - x1_region_ids = set(np.where((x1 >= x_min) & (x1 <= x_max))[0].tolist()) - y1_region_ids = set(np.where((y1 >= y_min) & (y1 <= y_max))[0].tolist()) - region_ids = x1_region_ids & y1_region_ids - - return region_ids - -# calculate number of matching points in one box from next frame -def find_region_cors_next(box_pos, all_cors): - - x1, y1, x2, y2 = [all_cors[:, col] for col in range(4)] - x_min, x_max, y_min, y_max = box_pos - x2_region_ids = set(np.where((x2 >= x_min) & (x2 <= x_max))[0].tolist()) - y2_region_ids = set(np.where((y2 >= y_min) & (y2 <= y_max))[0].tolist()) - region_ids = x2_region_ids & y2_region_ids - - return region_ids - -# fill the nose keypoint by averaging head and neck -def add_nose(array): - - if min(array.shape) == 2: - head = array[-1,:] - neck = array[-2,:] - else: - head = array[-1] - neck = array[-2] - nose = (head+neck)/2.0 - - return np.insert(array,-1,nose,axis=0) - -# list remove operation -def remove_list(l1,vname,l2): - - for item in l2: - l1.remove(os.path.join(vname,item)) - - return l1 diff --git a/cv/pose/alphapose/pytorch/trackers/README.md b/cv/pose/alphapose/pytorch/trackers/README.md deleted file mode 100755 index f49395587..000000000 --- a/cv/pose/alphapose/pytorch/trackers/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Pose Tracking Module for AlphaPose - -AlphaPose provide three different tracking methods for now, you can try different method to see which one is better for you. - -## 1. Human-ReID based tracking (Recommended) -Currently the best performance tracking model. Paper coming soon. - -#### Getting started -Download [human reid model](https://mega.nz/#!YTZFnSJY!wlbo_5oa2TpDAGyWCTKTX1hh4d6DvJhh_RUA2z6i_so) ([Baidu Pan, code:6a8b](https://pan.baidu.com/s/1IoAHehdjJ0ucQl8p_4hfRw))and place it into `AlphaPose/trackers/weights/`. - -Then simply run alphapose with additional flag `--pose_track` - -You can try different person reid model by modifing `cfg.arch` and `cfg.loadmodel` in `./trackers/tracker_cfg.py`. - -If you want to train your own reid model, please refer to this [project](https://github.com/KaiyangZhou/deep-person-reid) - -#### Demo -``` bash -./scripts/inference.sh ${CONFIG} ${CHECKPOINT} ${VIDEO_NAME} ${OUTPUT_DIR}, --pose_track -``` -#### Todo -- [] Evaluation Tools for PoseTrack -- [] More Models -- [] Training code for [PoseTrack Dataset](https://posetrack.net/) - -## 2. Detector based human tracking -Use a human detecter with tracking module (JDE). Please refer to [detector/tracker/](../detector/tracker/) - -#### Getting started -Download detector [JDE-1088x608](https://github.com/Zhongdao/Towards-Realtime-MOT#pretrained-model-and-baseline-models) and place it under `AlphaPose/detector/tracker/data/` - -Enable tracking by setting the detector as tracker: `--detector tracker` -#### Demo -``` bash -./scripts/inference.sh ${CONFIG} ${CHECKPOINT} ${VIDEO_NAME} ${OUTPUT_DIR}, --detector tracker -``` - -## 3. PoseFlow human tracking -This tracker is based on our BMVC 2018 paper PoseFlow, for more info please refer to [PoseFlow/README.md](PoseFlow/) - -#### Getting started - -Simply run alphapose with additional flag `--pose_flow` diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/ResBnLin.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/ResBnLin.py deleted file mode 100755 index 18d01f794..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/ResBnLin.py +++ /dev/null @@ -1,55 +0,0 @@ -# encoding: utf-8 -""" -@author: tanghy -@contact: thutanghy@gmail.com -""" -import torch -from torch import nn -import torch.nn.functional as F -from ReidModels.ResNet import build_resnet_backbone -from ReidModels.bn_linear import BNneckLinear -class SpatialAttn(nn.Module): - """Spatial Attention Layer""" - def __init__(self): - super(SpatialAttn, self).__init__() - - def forward(self, x): - # global cross-channel averaging # e.g. 32,2048,24,8 - x = x.mean(1, keepdim=True) # e.g. 32,1,24,8 - h = x.size(2) - w = x.size(3) - x = x.view(x.size(0),-1) # e.g. 32,192 - z = x - for b in range(x.size(0)): - z[b] /= torch.sum(z[b]) - z = z.view(x.size(0),1,h,w) - return z -class ResModel(nn.Module): - - def __init__(self, n_ID): - super().__init__() - self.backbone = build_resnet_backbone() - self.head = BNneckLinear(n_ID) - self.atten = SpatialAttn() - self.conv1 = nn.Conv2d(17, 17, 1,stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros') - self.pool = nn.AvgPool2d(2, stride=2, padding=0,) - def forward(self, input,posemap,map_weight): - """ - See :class:`ReIDHeads.forward`. - """ - feat = self.backbone(input) - b,c,h,w = feat.shape - att = self.conv1(torch.mul(posemap,map_weight)) - #print('att-1-size={}'.format(att.shape)) - att = F.relu(att) - att = self.pool(att) - att = self.conv1(att) - #print('att-2-size={}'.format(att.shape)) - att = F.softmax(att) - #print('att-3-size={}'.format(att.shape)) - att = self.atten(att) - #print('att-4-size={}'.format(att.shape)) - att = att.expand(b,c,h,w) - _feat = torch.mul(feat,att) - feat = _feat + feat - return self.head(feat) \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/ResNet.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/ResNet.py deleted file mode 100755 index 1846a6121..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/ResNet.py +++ /dev/null @@ -1,189 +0,0 @@ -# encoding: utf-8 -""" -@author: tanghy -@contact: thutanghy@gmail.com -""" - -import logging -import math - -import torch -from torch import nn -from torch.utils import model_zoo - - -model_urls = { - 18: 'https://download.pytorch.org/models/resnet18-5c106cde.pth', - 34: 'https://download.pytorch.org/models/resnet34-333f7ec4.pth', - 50: 'https://download.pytorch.org/models/resnet50-19c8e357.pth', - 101: 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth', - 152: 'https://download.pytorch.org/models/resnet152-b121ed2d.pth', - # 'resnext50_32x4d': 'https://download.pytorch.org/models/resnext50_32x4d-7cdf4587.pth', - # 'resnext101_32x8d': 'https://download.pytorch.org/models/resnext101_32x8d-8ba56ff5.pth', - # 'wide_resnet50_2': 'https://download.pytorch.org/models/wide_resnet50_2-95faca4d.pth', - # 'wide_resnet101_2': 'https://download.pytorch.org/models/wide_resnet101_2-32ee1156.pth', -} - -__all__ = ['ResNet', 'Bottleneck'] - - -class IBN(nn.Module): - def __init__(self, planes): - super(IBN, self).__init__() - half1 = int(planes / 2) - self.half = half1 - half2 = planes - half1 - self.IN = nn.InstanceNorm2d(half1, affine=True) - self.BN = nn.BatchNorm2d(half2) - - def forward(self, x): - split = torch.split(x, self.half, 1) - out1 = self.IN(split[0].contiguous()) - out2 = self.BN(split[1].contiguous()) - out = torch.cat((out1, out2), 1) - return out - - -class Bottleneck(nn.Module): - expansion = 4 - - def __init__(self, inplanes, planes, with_ibn=False, stride=1, downsample=None): - super(Bottleneck, self).__init__() - self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False) - if with_ibn: - self.bn1 = IBN(planes) - else: - self.bn1 = nn.BatchNorm2d(planes) - self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, - padding=1, bias=False) - self.bn2 = nn.BatchNorm2d(planes) - self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False) - self.bn3 = nn.BatchNorm2d(planes * 4) - self.relu = nn.ReLU(inplace=True) - self.downsample = downsample - self.stride = stride - - def forward(self, x): - residual = x - - out = self.conv1(x) - out = self.bn1(out) - out = self.relu(out) - - out = self.conv2(out) - out = self.bn2(out) - out = self.relu(out) - - out = self.conv3(out) - out = self.bn3(out) - - if self.downsample is not None: - residual = self.downsample(x) - - out += residual - out = self.relu(out) - - return out - - -class ResNet(nn.Module): - def __init__(self, last_stride, with_ibn, with_se, block, layers): - scale = 64 - self.inplanes = scale - super().__init__() - self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, - bias=False) - self.bn1 = nn.BatchNorm2d(64) - self.relu = nn.ReLU(inplace=True) - self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) - self.layer1 = self._make_layer(block, scale, layers[0], with_ibn=with_ibn) - self.layer2 = self._make_layer(block, scale * 2, layers[1], stride=2, with_ibn=with_ibn) - self.layer3 = self._make_layer(block, scale * 4, layers[2], stride=2, with_ibn=with_ibn) - self.layer4 = self._make_layer(block, scale * 8, layers[3], stride=last_stride) - - self.random_init() - - def _make_layer(self, block, planes, blocks, stride=1, with_ibn=False): - downsample = None - if stride != 1 or self.inplanes != planes * block.expansion: - downsample = nn.Sequential( - nn.Conv2d(self.inplanes, planes * block.expansion, - kernel_size=1, stride=stride, bias=False), - nn.BatchNorm2d(planes * block.expansion), - ) - - layers = [] - if planes == 512: - with_ibn = False - layers.append(block(self.inplanes, planes, with_ibn, stride, downsample)) - self.inplanes = planes * block.expansion - for i in range(1, blocks): - layers.append(block(self.inplanes, planes, with_ibn)) - - return nn.Sequential(*layers) - - def forward(self, x): - x = self.conv1(x) - x = self.bn1(x) - x = self.relu(x) - x = self.maxpool(x) - - x = self.layer1(x) - x = self.layer2(x) - x = self.layer3(x) - x = self.layer4(x) - - return x - - def random_init(self): - for m in self.modules(): - if isinstance(m, nn.Conv2d): - n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels - nn.init.normal_(m.weight, 0, math.sqrt(2. / n)) - elif isinstance(m, nn.BatchNorm2d): - nn.init.constant_(m.weight, 1) - nn.init.constant_(m.bias, 0) - - -def build_resnet_backbone(pretrain_path='',last_stride=1,with_ibn=False,with_se=False,depth=50): - """ - Create a ResNet instance from config. - Returns: - ResNet: a :class:`ResNet` instance. - """ - - # fmt: off - pretrain = True - pretrain_path = pretrain_path - last_stride = last_stride - with_ibn = with_ibn - with_se = with_se - depth = depth - - num_blocks_per_stage = {18:[2,2,2,2],50: [3, 4, 6, 3], 101: [3, 4, 23, 3], 152: [3, 8, 36, 3]}[depth] - model = ResNet(last_stride, with_ibn, with_se, Bottleneck, num_blocks_per_stage) - if pretrain: - if not with_ibn: - # original resnet - state_dict = model_zoo.load_url(model_urls[depth]) - # remove fully-connected-layers - state_dict.pop('fc.weight') - state_dict.pop('fc.bias') - else: - # ibn resnet - state_dict = torch.load(pretrain_path)['state_dict'] - # remove fully-connected-layers - state_dict.pop('module.fc.weight') - state_dict.pop('module.fc.bias') - # remove module in name - new_state_dict = {} - for k in state_dict: - new_k = '.'.join(k.split('.')[1:]) - if model.state_dict()[new_k].shape == state_dict[k].shape: - new_state_dict[new_k] = state_dict[k] - state_dict = new_state_dict - res = model.load_state_dict(state_dict, strict=False) - logger = logging.getLogger(__name__) - logger.info('missing keys is {}'.format(res.missing_keys)) - logger.info('unexpected keys is {}'.format(res.unexpected_keys)) - return model \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/__init__.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/__init__.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/googlenet.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/googlenet.py deleted file mode 100755 index d618a65de..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/googlenet.py +++ /dev/null @@ -1,96 +0,0 @@ -'''GoogLeNet with PyTorch.''' -import torch -import torch.nn as nn -import torch.nn.functional as F - -from .lrn import SpatialCrossMapLRN - - -class Inception(nn.Module): - def __init__(self, in_planes, n1x1, n3x3red, n3x3, n5x5red, n5x5, pool_planes): - super(Inception, self).__init__() - # 1x1 conv branch - self.b1 = nn.Sequential( - nn.Conv2d(in_planes, n1x1, kernel_size=1), - nn.ReLU(True), - ) - - # 1x1 conv -> 3x3 conv branch - self.b2 = nn.Sequential( - nn.Conv2d(in_planes, n3x3red, kernel_size=1), - nn.ReLU(True), - nn.Conv2d(n3x3red, n3x3, kernel_size=3, padding=1), - nn.ReLU(True), - ) - - # 1x1 conv -> 5x5 conv branch - self.b3 = nn.Sequential( - nn.Conv2d(in_planes, n5x5red, kernel_size=1), - nn.ReLU(True), - - nn.Conv2d(n5x5red, n5x5, kernel_size=5, padding=2), - nn.ReLU(True), - ) - - # 3x3 pool -> 1x1 conv branch - self.b4 = nn.Sequential( - nn.MaxPool2d(3, stride=1, padding=1), - - nn.Conv2d(in_planes, pool_planes, kernel_size=1), - nn.ReLU(True), - ) - - def forward(self, x): - y1 = self.b1(x) - y2 = self.b2(x) - y3 = self.b3(x) - y4 = self.b4(x) - return torch.cat([y1,y2,y3,y4], 1) - - -class GoogLeNet(nn.Module): - - output_channels = 832 - - def __init__(self): - super(GoogLeNet, self).__init__() - self.pre_layers = nn.Sequential( - nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3), - nn.ReLU(True), - - nn.MaxPool2d(3, stride=2, ceil_mode=True), - SpatialCrossMapLRN(5), - - nn.Conv2d(64, 64, 1), - nn.ReLU(True), - - nn.Conv2d(64, 192, 3, padding=1), - nn.ReLU(True), - - SpatialCrossMapLRN(5), - nn.MaxPool2d(3, stride=2, ceil_mode=True), - ) - - self.a3 = Inception(192, 64, 96, 128, 16, 32, 32) - self.b3 = Inception(256, 128, 128, 192, 32, 96, 64) - - self.maxpool = nn.MaxPool2d(3, stride=2, ceil_mode=True) - - self.a4 = Inception(480, 192, 96, 208, 16, 48, 64) - self.b4 = Inception(512, 160, 112, 224, 24, 64, 64) - self.c4 = Inception(512, 128, 128, 256, 24, 64, 64) - self.d4 = Inception(512, 112, 144, 288, 32, 64, 64) - self.e4 = Inception(528, 256, 160, 320, 32, 128, 128) - - def forward(self, x): - out = self.pre_layers(x) - out = self.a3(out) - out = self.b3(out) - out = self.maxpool(out) - out = self.a4(out) - out = self.b4(out) - out = self.c4(out) - out = self.d4(out) - out = self.e4(out) - - return out diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/lrn.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/lrn.py deleted file mode 100755 index 39ed33066..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/lrn.py +++ /dev/null @@ -1,37 +0,0 @@ -import torch -from torch.legacy.nn import SpatialCrossMapLRN as SpatialCrossMapLRNOld -from torch.autograd import Function, Variable -from torch.nn import Module - - -# function interface, internal, do not use this one!!! -class SpatialCrossMapLRNFunc(Function): - - def __init__(self, size, alpha=1e-4, beta=0.75, k=1): - self.size = size - self.alpha = alpha - self.beta = beta - self.k = k - - def forward(self, input): - self.save_for_backward(input) - self.lrn = SpatialCrossMapLRNOld(self.size, self.alpha, self.beta, self.k) - self.lrn.type(input.type()) - return self.lrn.forward(input) - - def backward(self, grad_output): - input, = self.saved_tensors - return self.lrn.backward(input, grad_output) - - -# use this one instead -class SpatialCrossMapLRN(Module): - def __init__(self, size, alpha=1e-4, beta=0.75, k=1): - super(SpatialCrossMapLRN, self).__init__() - self.size = size - self.alpha = alpha - self.beta = beta - self.k = k - - def forward(self, input): - return SpatialCrossMapLRNFunc(self.size, self.alpha, self.beta, self.k)(input) \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/sqeezenet.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/sqeezenet.py deleted file mode 100755 index 8277c623c..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/backbone/sqeezenet.py +++ /dev/null @@ -1,64 +0,0 @@ -import torch -import torch.nn as nn -import torch.nn.functional as F -from torchvision import models - - -class DilationLayer(nn.Module): - def __init__(self, in_channels, out_channels, kernel_size=3, padding='same_padding', dilation=1, bn=False): - super(DilationLayer, self).__init__() - if padding == 'same_padding': - padding = int((kernel_size - 1) / 2 * dilation) - self.Dconv = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, - padding=padding, dilation=dilation) - self.Drelu = nn.ReLU(inplace=True) - self.Dbn = nn.BatchNorm2d(out_channels) if bn else None - - def forward(self, x): - x = self.Dconv(x) - if self.Dbn is not None: - x = self.Dbn(x) - x = self.Drelu(x) - return x - - -class FeatExtractorSqueezeNetx16(nn.Module): - n_feats = [64, 128, 256, 512] - - def __init__(self, pretrained=True): - - super(FeatExtractorSqueezeNetx16, self).__init__() - print("loading layers from squeezenet1_1...") - sq = models.squeezenet1_1(pretrained=pretrained) - - self.conv1 = nn.Sequential( - sq.features[0], - sq.features[1], - ) - self.conv2 = nn.Sequential( - nn.MaxPool2d(kernel_size=3, stride=2, padding=1), - sq.features[3], - sq.features[4], - ) - self.conv3 = nn.Sequential( - nn.MaxPool2d(kernel_size=3, stride=2, padding=1), - sq.features[6], - sq.features[7], - ) - self.conv4 = nn.Sequential( - nn.MaxPool2d(kernel_size=3, stride=2, padding=1), - sq.features[9], - sq.features[10], - sq.features[11], - sq.features[12], - ) - - self.conv1[0].padding = (1, 1) - - def forward(self, x): - x2 = self.conv1(x) - x4 = self.conv2(x2) - x8 = self.conv3(x4) - x16 = self.conv4(x8) - - return x2, x4, x8, x16 diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/bn_linear.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/bn_linear.py deleted file mode 100755 index 729e6c187..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/bn_linear.py +++ /dev/null @@ -1,63 +0,0 @@ -# encoding: utf-8 -""" -@author: tanghy -@contact: thutanghy@gmail.com -""" - -from torch import nn -import torch.nn.functional as F - -def bn_no_bias(in_features): - bn_layer = nn.BatchNorm1d(in_features) - bn_layer.bias.requires_grad_(False) - return bn_layer - -def weights_init_kaiming(m): - classname = m.__class__.__name__ - if classname.find('Linear') != -1: - nn.init.kaiming_normal_(m.weight, a=0, mode='fan_out') - if m.bias is not None: - nn.init.constant_(m.bias, 0.0) - elif classname.find('Conv') != -1: - nn.init.kaiming_normal_(m.weight, a=0, mode='fan_in') - if m.bias is not None: - nn.init.constant_(m.bias, 0.0) - elif classname.find('BatchNorm') != -1: - if m.affine: - nn.init.constant_(m.weight, 1.0) - nn.init.constant_(m.bias, 0.0) - - -def weights_init_classifier(m): - classname = m.__class__.__name__ - if classname.find('Linear') != -1: - nn.init.normal_(m.weight, std=0.001) - if m.bias is not None: - nn.init.constant_(m.bias, 0.0) - -class BNneckLinear(nn.Module): - - def __init__(self, nID): - super().__init__() - self._num_classes = nID - - self.gap = nn.AdaptiveAvgPool2d(1) - self.bnneck = bn_no_bias(2048) - self.bnneck.apply(weights_init_kaiming) - - self.classifier = nn.Linear(2048, self._num_classes, bias=False) - self.classifier.apply(weights_init_classifier) - - def forward(self, features): - """ - See :class:`ReIDHeads.forward`. - """ - global_features = self.gap(features) - global_features = global_features.view(global_features.shape[0], -1) - bn_features = self.bnneck(global_features) - - if not self.training: - return F.normalize(bn_features) - - pred_class_logits = self.classifier(bn_features) - return global_features, pred_class_logits \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/classification/__init__.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/classification/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/classification/classifier.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/classification/classifier.py deleted file mode 100755 index 9a8e7fc5f..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/classification/classifier.py +++ /dev/null @@ -1,111 +0,0 @@ -import numpy as np -import cv2 -from distutils.version import LooseVersion -import torch -from torch.autograd import Variable - -from utils import bbox as bbox_utils -from models import net_utils -from models.classification.rfcn_cls import Model as CLSModel - - -def _factor_closest(num, factor, is_ceil=True): - num = float(num) / factor - num = np.ceil(num) if is_ceil else np.floor(num) - return int(num) * factor - - -def crop_with_factor(im, dest_size, factor=32, pad_val=0, basedon='min'): - im_size_min, im_size_max = np.min(im.shape[0:2]), np.max(im.shape[0:2]) - im_base = {'min': im_size_min, - 'max': im_size_max, - 'w': im.shape[1], - 'h': im.shape[0]} - im_scale = float(dest_size) / im_base.get(basedon, im_size_min) - - # Scale the image. - im = cv2.resize(im, None, fx=im_scale, fy=im_scale) - - # Compute the padded image shape. Ensure it's divisible by factor. - h, w = im.shape[:2] - new_h, new_w = _factor_closest(h, factor), _factor_closest(w, factor) - new_shape = [new_h, new_w] if im.ndim < 3 else [new_h, new_w, im.shape[-1]] - - # Pad the image. - im_padded = np.full(new_shape, fill_value=pad_val, dtype=im.dtype) - im_padded[0:h, 0:w] = im - - return im_padded, im_scale, im.shape - - -class PatchClassifier(object): - def __init__(self, gpu=0): - self.gpu = gpu - - ckpt = 'data/squeezenet_small40_coco_mot16_ckpt_10.h5' - model = CLSModel(extractor='squeezenet') - - # from mcmtt.network.experiments.rfcn_cls2 import Model as CLSModel - # ckpt = '/extra/models/resnet50_small40_coco_kitti/ckpt_31.h5' - # model = CLSModel(extractor='resnet50') - - net_utils.load_net(ckpt, model) - model = model.eval() - self.model = model.cuda(self.gpu) - print('load cls model from: {}'.format(ckpt)) - self.score_map = None - self.im_scale = 1. - - @staticmethod - def im_preprocess(image): - # resize and padding - # real_inp_size = min_size - if min(image.shape[0:2]) > 720: - real_inp_size = 640 - else: - real_inp_size = 368 - im_pad, im_scale, real_shape = crop_with_factor(image, real_inp_size, factor=16, pad_val=0, basedon='min') - - # preprocess image - im_croped = cv2.cvtColor(im_pad, cv2.COLOR_BGR2RGB) - im_croped = im_croped.astype(np.float32) / 255. - 0.5 - - return im_croped, im_pad, real_shape, im_scale - - def update(self, image): - im_croped, im_pad, real_shape, im_scale = self.im_preprocess(image) - - self.im_scale = im_scale - self.ori_image_shape = image.shape - im_data = torch.from_numpy(im_croped).permute(2, 0, 1) - im_data = im_data.unsqueeze(0) - - # forward - if LooseVersion(torch.__version__) > LooseVersion('0.3.1'): - with torch.no_grad(): - im_var = Variable(im_data).cuda(self.gpu) - self.score_map = self.model(im_var) - else: - im_var = Variable(im_data, volatile=True).cuda(self.gpu) - self.score_map = self.model(im_var) - - return real_shape, im_scale - - def predict(self, rois): - """ - :param rois: numpy array [N, 4] ( x1, y1, x2, y2) - :return: scores [N] - """ - scaled_rois = rois * self.im_scale - cls_scores = self.model.get_cls_score_numpy(self.score_map, scaled_rois) - - # check area - rois = rois.reshape(-1, 4) - clipped_boxes = bbox_utils.clip_boxes(rois, self.ori_image_shape) - - ori_areas = (rois[:, 2] - rois[:, 0]) * (rois[:, 3] - rois[:, 1]) - areas = (clipped_boxes[:, 2] - clipped_boxes[:, 0]) * (clipped_boxes[:, 3] - clipped_boxes[:, 1]) - ratios = areas / np.clip(ori_areas, a_min=1e-4, a_max=None) - cls_scores[ratios < 0.5] = 0 - - return cls_scores diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/classification/rfcn_cls.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/classification/rfcn_cls.py deleted file mode 100755 index d8a12da3b..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/classification/rfcn_cls.py +++ /dev/null @@ -1,118 +0,0 @@ -import numpy as np -import torch -import torch.nn as nn -import torch.nn.functional as F -from torch.autograd import Variable - -from models import net_utils -from models.backbone.sqeezenet import DilationLayer, FeatExtractorSqueezeNetx16 -from models.psroi_pooling.modules.psroi_pool import PSRoIPool - - -class Model(nn.Module): - feat_stride = 4 - - def __init__(self, extractor='squeezenet', pretrained=False, transform_input=False): - super(Model, self).__init__() - - if extractor == 'squeezenet': - feature_extractor = FeatExtractorSqueezeNetx16(pretrained) - else: - assert False, 'invalid feature extractor: {}'.format(extractor) - - self.feature_extractor = feature_extractor - - in_channels = self.feature_extractor.n_feats[-1] - self.stage_0 = nn.Sequential( - nn.Dropout2d(inplace=True), - nn.Conv2d(in_channels=in_channels, out_channels=256, kernel_size=3, padding=1), - nn.ReLU(inplace=True), - ) - - n_feats = self.feature_extractor.n_feats[1:] - in_channels = 256 - out_cs = [128, 256] - for i in range(1, len(n_feats)): - out_channels = out_cs[-i] - setattr(self, 'upconv_{}'.format(i), - nn.Sequential( - nn.Conv2d(in_channels, out_channels, 3, padding=1, bias=True), - nn.BatchNorm2d(out_channels), - nn.ReLU(inplace=True), - nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False), - )) - - feat_channels = n_feats[-1-i] - setattr(self, 'proj_{}'.format(i), nn.Sequential( - net_utils.ConcatAddTable( - DilationLayer(feat_channels, out_channels // 2, 3, dilation=1), - DilationLayer(feat_channels, out_channels // 2, 5, dilation=1), - ), - nn.Conv2d(out_channels // 2, out_channels // 2, 1), - nn.BatchNorm2d(out_channels // 2), - nn.ReLU(inplace=True) - )) - in_channels = out_channels + out_channels // 2 - - roi_size = 7 - self.cls_conv = nn.Sequential( - nn.Conv2d(in_channels, in_channels, 3, padding=1), - nn.BatchNorm2d(in_channels), - nn.ReLU(inplace=True), - - nn.Conv2d(in_channels, roi_size * roi_size, 1, padding=1) - ) - self.psroipool_cls = PSRoIPool(roi_size, roi_size, 1./self.feat_stride, roi_size, 1) - self.avg_pool = nn.AvgPool2d(roi_size, roi_size) - - def get_cls_score(self, cls_feat, rois): - """ - - :param cls_feat: [N, rsize*rsize, H, W] - :param rois: [N, 5] (batch_id, x1, y1, x2, y2) - :return: [N], [N] - """ - # rois = rois / 8. - cls_scores = self.psroipool_cls(cls_feat, rois) - cls_scores = self.avg_pool(cls_scores).view(-1) - cls_probs = torch.sigmoid(cls_scores) - return cls_scores, cls_probs - - def get_cls_score_numpy(self, cls_feat, rois): - """ - - :param cls_feat: [1, rsize*rsize, H, W] - :param rois: numpy array [N, 4] ( x1, y1, x2, y2) - :return: [N], [N] - """ - n_rois = rois.shape[0] - if n_rois <= 0: - return np.empty([0]) - - _rois = np.zeros([n_rois, 5], dtype=np.float32) - _rois[:, 1:5] = rois.astype(np.float32) - _rois = Variable(torch.from_numpy(_rois)).cuda(cls_feat.get_device()) - - cls_scores = self.psroipool_cls(cls_feat, _rois) - cls_scores = self.avg_pool(cls_scores).view(-1) - cls_probs = torch.sigmoid(cls_scores).data.cpu().numpy() - - return cls_probs - - def forward(self, x, gts=None): - feats = self.feature_extractor(x) - x_in = self.stage_0(feats[-1]) - - # up conv - n_feats = self.feature_extractor.n_feats[1:] - for i in range(1, len(n_feats)): - x_depth_out = getattr(self, 'upconv_{}'.format(i))(x_in) - x_project = getattr(self, 'proj_{}'.format(i))(feats[-1-i]) - x_in = torch.cat((x_depth_out, x_project), 1) - - # cls features - x_cls_in = x_in - # x_cls_in = F.dropout2d(x_cls_in, training=self.training, inplace=True) - cls_feat = self.cls_conv(x_cls_in) - - return cls_feat diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/net_utils.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/net_utils.py deleted file mode 100755 index 24078f8c0..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/net_utils.py +++ /dev/null @@ -1,160 +0,0 @@ -import os -import collections -import torch -import torch.nn as nn -from torch.autograd import Variable -import numpy as np -from copy import deepcopy -import pickle - -from utils.log import logger - - -class ConcatAddTable(nn.Module): - def __init__(self, *args): - super(ConcatAddTable, self).__init__() - if len(args) == 1 and isinstance(args[0], collections.OrderedDict): - for key, module in args[0].items(): - self.add_module(key, module) - else: - idx = 0 - for module in args: - self.add_module(str(idx), module) - idx += 1 - - def __getitem__(self, idx): - if idx < 0 or idx >= len(self._modules): - raise IndexError('index {} is out of range'.format(idx)) - it = iter(self._modules.values()) - for i in range(idx): - next(it) - return next(it) - - def forward(self, input): - x_out = None - for module in self._modules.values(): - x = module(input) - if x_out is None: - x_out = x - else: - x_out = x_out + x - return x_out - - -def set_optimizer_state_devices(state, device_id=None): - """ - set state in optimizer to a device. move to cpu if device_id==None - :param state: optimizer.state - :param device_id: None or a number - :return: - """ - for k, v in state.items(): - for k2 in v.keys(): - if hasattr(v[k2], 'cuda'): - if device_id is None: - v[k2] = v[k2].cpu() - else: - v[k2] = v[k2].cuda(device_id) - - return state - - -def save_net(fname, net, epoch=-1, optimizers=None, rm_prev_opt=False, max_n_ckpts=-1): - import h5py - with h5py.File(fname, mode='w') as h5f: - for k, v in net.state_dict().items(): - h5f.create_dataset(k, data=v.cpu().numpy()) - h5f.attrs['epoch'] = epoch - - if optimizers is not None: - state_dicts = [] - for optimizer in optimizers: - state_dict = deepcopy(optimizer.state_dict()) - state_dict['state'] = set_optimizer_state_devices(state_dict['state'], device_id=None) - state_dicts.append(state_dict) - - state_file = fname + '.optimizer_state.pk' - with open(state_file, 'wb') as f: - pickle.dump(state_dicts, f) - - # remove - if rm_prev_opt: - root = os.path.split(fname)[0] - for filename in os.listdir(root): - filename = os.path.join(root, filename) - if filename.endswith('.optimizer_state.pk') and filename != state_file: - logger.info(('Remove {}'.format(filename))) - os.remove(filename) - - # remove ckpt - if max_n_ckpts > 0: - root = os.path.split(fname)[0] - ckpts = [fname for fname in os.listdir(root) if os.path.splitext(fname)[-1] == '.h5'] - ckpts = sorted(ckpts, key=lambda name: int(os.path.splitext(name)[0].split('_')[-1])) - if len(ckpts) > max_n_ckpts: - for ckpt in ckpts[0:-max_n_ckpts]: - filename = os.path.join(root, ckpt) - logger.info('Remove {}'.format(filename)) - os.remove(filename) - - -def load_net(fname, net, prefix='', load_state_dict=False): - import h5py - with h5py.File(fname, mode='r') as h5f: - h5f_is_module = True - for k in h5f.keys(): - if not str(k).startswith('module.'): - h5f_is_module = False - break - if prefix == '' and not isinstance(net, nn.DataParallel) and h5f_is_module: - prefix = 'module.' - - for k, v in net.state_dict().items(): - k = prefix + k - if k in h5f: - param = torch.from_numpy(np.asarray(h5f[k])) - if v.size() != param.size(): - logger.warning('Inconsistent shape: {}, {}'.format(v.size(), param.size())) - else: - v.copy_(param) - else: - logger.warning('No layer: {}'.format(k)) - - epoch = h5f.attrs['epoch'] if 'epoch' in h5f.attrs else -1 - - if not load_state_dict: - if 'learning_rates' in h5f.attrs: - lr = h5f.attrs['learning_rates'] - else: - lr = h5f.attrs.get('lr', -1) - lr = np.asarray([lr] if lr > 0 else [], dtype=np.float) - - return epoch, lr - - state_file = fname + '.optimizer_state.pk' - if os.path.isfile(state_file): - with open(state_file, 'rb') as f: - state_dicts = pickle.load(f) - if not isinstance(state_dicts, list): - state_dicts = [state_dicts] - else: - state_dicts = None - return epoch, state_dicts - - -def is_cuda(model): - p = next(model.parameters()) - return p.is_cuda - - -def get_device(model): - if is_cuda(model): - p = next(model.parameters()) - return p.get_device() - else: - return None - - -def set_trainable(model, requires_grad): - for param in model.parameters(): - param.requires_grad = requires_grad diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/osnet.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/osnet.py deleted file mode 100755 index e6273ff56..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/osnet.py +++ /dev/null @@ -1,597 +0,0 @@ -from __future__ import division, absolute_import -import warnings -import torch -from torch import nn -from torch.nn import functional as F - -__all__ = [ - 'osnet_x1_0', 'osnet_x0_75', 'osnet_x0_5', 'osnet_x0_25', 'osnet_ibn_x1_0' -] - -pretrained_urls = { - 'osnet_x1_0': - 'https://drive.google.com/uc?id=1LaG1EJpHrxdAxKnSCJ_i0u-nbxSAeiFY', - 'osnet_x0_75': - 'https://drive.google.com/uc?id=1uwA9fElHOk3ZogwbeY5GkLI6QPTX70Hq', - 'osnet_x0_5': - 'https://drive.google.com/uc?id=16DGLbZukvVYgINws8u8deSaOqjybZ83i', - 'osnet_x0_25': - 'https://drive.google.com/uc?id=1rb8UN5ZzPKRc_xvtHlyDh-cSz88YX9hs', - 'osnet_ibn_x1_0': - 'https://drive.google.com/uc?id=1sr90V6irlYYDd4_4ISU2iruoRG8J__6l' -} - - -########## -# Basic layers -########## -class ConvLayer(nn.Module): - """Convolution layer (conv + bn + relu).""" - - def __init__( - self, - in_channels, - out_channels, - kernel_size, - stride=1, - padding=0, - groups=1, - IN=False - ): - super(ConvLayer, self).__init__() - self.conv = nn.Conv2d( - in_channels, - out_channels, - kernel_size, - stride=stride, - padding=padding, - bias=False, - groups=groups - ) - if IN: - self.bn = nn.InstanceNorm2d(out_channels, affine=True) - else: - self.bn = nn.BatchNorm2d(out_channels) - self.relu = nn.ReLU(inplace=True) - - def forward(self, x): - x = self.conv(x) - x = self.bn(x) - x = self.relu(x) - return x - - -class Conv1x1(nn.Module): - """1x1 convolution + bn + relu.""" - - def __init__(self, in_channels, out_channels, stride=1, groups=1): - super(Conv1x1, self).__init__() - self.conv = nn.Conv2d( - in_channels, - out_channels, - 1, - stride=stride, - padding=0, - bias=False, - groups=groups - ) - self.bn = nn.BatchNorm2d(out_channels) - self.relu = nn.ReLU(inplace=True) - - def forward(self, x): - x = self.conv(x) - x = self.bn(x) - x = self.relu(x) - return x - - -class Conv1x1Linear(nn.Module): - """1x1 convolution + bn (w/o non-linearity).""" - - def __init__(self, in_channels, out_channels, stride=1): - super(Conv1x1Linear, self).__init__() - self.conv = nn.Conv2d( - in_channels, out_channels, 1, stride=stride, padding=0, bias=False - ) - self.bn = nn.BatchNorm2d(out_channels) - - def forward(self, x): - x = self.conv(x) - x = self.bn(x) - return x - - -class Conv3x3(nn.Module): - """3x3 convolution + bn + relu.""" - - def __init__(self, in_channels, out_channels, stride=1, groups=1): - super(Conv3x3, self).__init__() - self.conv = nn.Conv2d( - in_channels, - out_channels, - 3, - stride=stride, - padding=1, - bias=False, - groups=groups - ) - self.bn = nn.BatchNorm2d(out_channels) - self.relu = nn.ReLU(inplace=True) - - def forward(self, x): - x = self.conv(x) - x = self.bn(x) - x = self.relu(x) - return x - - -class LightConv3x3(nn.Module): - """Lightweight 3x3 convolution. - - 1x1 (linear) + dw 3x3 (nonlinear). - """ - - def __init__(self, in_channels, out_channels): - super(LightConv3x3, self).__init__() - self.conv1 = nn.Conv2d( - in_channels, out_channels, 1, stride=1, padding=0, bias=False - ) - self.conv2 = nn.Conv2d( - out_channels, - out_channels, - 3, - stride=1, - padding=1, - bias=False, - groups=out_channels - ) - self.bn = nn.BatchNorm2d(out_channels) - self.relu = nn.ReLU(inplace=True) - - def forward(self, x): - x = self.conv1(x) - x = self.conv2(x) - x = self.bn(x) - x = self.relu(x) - return x - - -########## -# Building blocks for omni-scale feature learning -########## -class ChannelGate(nn.Module): - """A mini-network that generates channel-wise gates conditioned on input tensor.""" - - def __init__( - self, - in_channels, - num_gates=None, - return_gates=False, - gate_activation='sigmoid', - reduction=16, - layer_norm=False - ): - super(ChannelGate, self).__init__() - if num_gates is None: - num_gates = in_channels - self.return_gates = return_gates - self.global_avgpool = nn.AdaptiveAvgPool2d(1) - self.fc1 = nn.Conv2d( - in_channels, - in_channels // reduction, - kernel_size=1, - bias=True, - padding=0 - ) - self.norm1 = None - if layer_norm: - self.norm1 = nn.LayerNorm((in_channels // reduction, 1, 1)) - self.relu = nn.ReLU(inplace=True) - self.fc2 = nn.Conv2d( - in_channels // reduction, - num_gates, - kernel_size=1, - bias=True, - padding=0 - ) - if gate_activation == 'sigmoid': - self.gate_activation = nn.Sigmoid() - elif gate_activation == 'relu': - self.gate_activation = nn.ReLU(inplace=True) - elif gate_activation == 'linear': - self.gate_activation = None - else: - raise RuntimeError( - "Unknown gate activation: {}".format(gate_activation) - ) - - def forward(self, x): - input = x - x = self.global_avgpool(x) - x = self.fc1(x) - if self.norm1 is not None: - x = self.norm1(x) - x = self.relu(x) - x = self.fc2(x) - if self.gate_activation is not None: - x = self.gate_activation(x) - if self.return_gates: - return x - return input * x - - -class OSBlock(nn.Module): - """Omni-scale feature learning block.""" - - def __init__( - self, - in_channels, - out_channels, - IN=False, - bottleneck_reduction=4, - **kwargs - ): - super(OSBlock, self).__init__() - mid_channels = out_channels // bottleneck_reduction - self.conv1 = Conv1x1(in_channels, mid_channels) - self.conv2a = LightConv3x3(mid_channels, mid_channels) - self.conv2b = nn.Sequential( - LightConv3x3(mid_channels, mid_channels), - LightConv3x3(mid_channels, mid_channels), - ) - self.conv2c = nn.Sequential( - LightConv3x3(mid_channels, mid_channels), - LightConv3x3(mid_channels, mid_channels), - LightConv3x3(mid_channels, mid_channels), - ) - self.conv2d = nn.Sequential( - LightConv3x3(mid_channels, mid_channels), - LightConv3x3(mid_channels, mid_channels), - LightConv3x3(mid_channels, mid_channels), - LightConv3x3(mid_channels, mid_channels), - ) - self.gate = ChannelGate(mid_channels) - self.conv3 = Conv1x1Linear(mid_channels, out_channels) - self.downsample = None - if in_channels != out_channels: - self.downsample = Conv1x1Linear(in_channels, out_channels) - self.IN = None - if IN: - self.IN = nn.InstanceNorm2d(out_channels, affine=True) - - def forward(self, x): - identity = x - x1 = self.conv1(x) - x2a = self.conv2a(x1) - x2b = self.conv2b(x1) - x2c = self.conv2c(x1) - x2d = self.conv2d(x1) - x2 = self.gate(x2a) + self.gate(x2b) + self.gate(x2c) + self.gate(x2d) - x3 = self.conv3(x2) - if self.downsample is not None: - identity = self.downsample(identity) - out = x3 + identity - if self.IN is not None: - out = self.IN(out) - return F.relu(out) - - -########## -# Network architecture -########## -class OSNet(nn.Module): - """Omni-Scale Network. - - Reference: - - Zhou et al. Omni-Scale Feature Learning for Person Re-Identification. ICCV, 2019. - - Zhou et al. Learning Generalisable Omni-Scale Representations - for Person Re-Identification. arXiv preprint, 2019. - """ - - def __init__( - self, - num_classes, - blocks, - layers, - channels, - feature_dim=512, - loss='softmax', - IN=False, - **kwargs - ): - super(OSNet, self).__init__() - num_blocks = len(blocks) - assert num_blocks == len(layers) - assert num_blocks == len(channels) - 1 - self.loss = loss - - # convolutional backbone - self.conv1 = ConvLayer(3, channels[0], 7, stride=2, padding=3, IN=IN) - self.maxpool = nn.MaxPool2d(3, stride=2, padding=1) - self.conv2 = self._make_layer( - blocks[0], - layers[0], - channels[0], - channels[1], - reduce_spatial_size=True, - IN=IN - ) - self.conv3 = self._make_layer( - blocks[1], - layers[1], - channels[1], - channels[2], - reduce_spatial_size=True - ) - self.conv4 = self._make_layer( - blocks[2], - layers[2], - channels[2], - channels[3], - reduce_spatial_size=False - ) - self.conv5 = Conv1x1(channels[3], channels[3]) - self.global_avgpool = nn.AdaptiveAvgPool2d(1) - # fully connected layer - self.fc = self._construct_fc_layer( - feature_dim, channels[3], dropout_p=None - ) - # identity classification layer - self.classifier = nn.Linear(self.feature_dim, num_classes) - - self._init_params() - - def _make_layer( - self, - block, - layer, - in_channels, - out_channels, - reduce_spatial_size, - IN=False - ): - layers = [] - - layers.append(block(in_channels, out_channels, IN=IN)) - for i in range(1, layer): - layers.append(block(out_channels, out_channels, IN=IN)) - - if reduce_spatial_size: - layers.append( - nn.Sequential( - Conv1x1(out_channels, out_channels), - nn.AvgPool2d(2, stride=2) - ) - ) - - return nn.Sequential(*layers) - - def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None): - if fc_dims is None or fc_dims < 0: - self.feature_dim = input_dim - return None - - if isinstance(fc_dims, int): - fc_dims = [fc_dims] - - layers = [] - for dim in fc_dims: - layers.append(nn.Linear(input_dim, dim)) - layers.append(nn.BatchNorm1d(dim)) - layers.append(nn.ReLU(inplace=True)) - if dropout_p is not None: - layers.append(nn.Dropout(p=dropout_p)) - input_dim = dim - - self.feature_dim = fc_dims[-1] - - return nn.Sequential(*layers) - - def _init_params(self): - for m in self.modules(): - if isinstance(m, nn.Conv2d): - nn.init.kaiming_normal_( - m.weight, mode='fan_out', nonlinearity='relu' - ) - if m.bias is not None: - nn.init.constant_(m.bias, 0) - - elif isinstance(m, nn.BatchNorm2d): - nn.init.constant_(m.weight, 1) - nn.init.constant_(m.bias, 0) - - elif isinstance(m, nn.BatchNorm1d): - nn.init.constant_(m.weight, 1) - nn.init.constant_(m.bias, 0) - - elif isinstance(m, nn.Linear): - nn.init.normal_(m.weight, 0, 0.01) - if m.bias is not None: - nn.init.constant_(m.bias, 0) - - def featuremaps(self, x): - x = self.conv1(x) - x = self.maxpool(x) - x = self.conv2(x) - x = self.conv3(x) - x = self.conv4(x) - x = self.conv5(x) - return x - - def forward(self, x, return_featuremaps=False): - x = self.featuremaps(x) - if return_featuremaps: - return x - v = self.global_avgpool(x) - v = v.view(v.size(0), -1) - if self.fc is not None: - v = self.fc(v) - if not self.training: - return v - y = self.classifier(v) - if self.loss == 'softmax': - return y - elif self.loss == 'triplet': - return y, v - else: - raise KeyError("Unsupported loss: {}".format(self.loss)) - - -def init_pretrained_weights(model, key=''): - """Initializes model with pretrained weights. - - Layers that don't match with pretrained layers in name or size are kept unchanged. - """ - import os - import errno - import gdown - from collections import OrderedDict - - def _get_torch_home(): - ENV_TORCH_HOME = 'TORCH_HOME' - ENV_XDG_CACHE_HOME = 'XDG_CACHE_HOME' - DEFAULT_CACHE_DIR = '~/.cache' - torch_home = os.path.expanduser( - os.getenv( - ENV_TORCH_HOME, - os.path.join( - os.getenv(ENV_XDG_CACHE_HOME, DEFAULT_CACHE_DIR), 'torch' - ) - ) - ) - return torch_home - - torch_home = _get_torch_home() - model_dir = os.path.join(torch_home, 'checkpoints') - try: - os.makedirs(model_dir) - except OSError as e: - if e.errno == errno.EEXIST: - # Directory already exists, ignore. - pass - else: - # Unexpected OSError, re-raise. - raise - filename = key + '_imagenet.pth' - cached_file = os.path.join(model_dir, filename) - - if not os.path.exists(cached_file): - gdown.download(pretrained_urls[key], cached_file, quiet=False) - - state_dict = torch.load(cached_file) - model_dict = model.state_dict() - new_state_dict = OrderedDict() - matched_layers, discarded_layers = [], [] - - for k, v in state_dict.items(): - if k.startswith('module.'): - k = k[7:] # discard module. - - if k in model_dict and model_dict[k].size() == v.size(): - new_state_dict[k] = v - matched_layers.append(k) - else: - discarded_layers.append(k) - - model_dict.update(new_state_dict) - model.load_state_dict(model_dict) - - if len(matched_layers) == 0: - warnings.warn( - 'The pretrained weights from "{}" cannot be loaded, ' - 'please check the key names manually ' - '(** ignored and continue **)'.format(cached_file) - ) - else: - print( - 'Successfully loaded imagenet pretrained weights from "{}"'. - format(cached_file) - ) - if len(discarded_layers) > 0: - print( - '** The following layers are discarded ' - 'due to unmatched keys or layer size: {}'. - format(discarded_layers) - ) - - -########## -# Instantiation -########## -def osnet_x1_0(num_classes=1000, pretrained=True, loss='softmax', **kwargs): - # standard size (width x1.0) - model = OSNet( - num_classes, - blocks=[OSBlock, OSBlock, OSBlock], - layers=[2, 2, 2], - channels=[64, 256, 384, 512], - loss=loss, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, key='osnet_x1_0') - return model - - -def osnet_x0_75(num_classes=1000, pretrained=True, loss='softmax', **kwargs): - # medium size (width x0.75) - model = OSNet( - num_classes, - blocks=[OSBlock, OSBlock, OSBlock], - layers=[2, 2, 2], - channels=[48, 192, 288, 384], - loss=loss, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, key='osnet_x0_75') - return model - - -def osnet_x0_5(num_classes=1000, pretrained=True, loss='softmax', **kwargs): - # tiny size (width x0.5) - model = OSNet( - num_classes, - blocks=[OSBlock, OSBlock, OSBlock], - layers=[2, 2, 2], - channels=[32, 128, 192, 256], - loss=loss, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, key='osnet_x0_5') - return model - - -def osnet_x0_25(num_classes=1000, pretrained=True, loss='softmax', **kwargs): - # very tiny size (width x0.25) - model = OSNet( - num_classes, - blocks=[OSBlock, OSBlock, OSBlock], - layers=[2, 2, 2], - channels=[16, 64, 96, 128], - loss=loss, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, key='osnet_x0_25') - return model - - -def osnet_ibn_x1_0( - num_classes=1000, pretrained=True, loss='softmax', **kwargs -): - # standard size (width x1.0) + IBN layer - # Ref: Pan et al. Two at Once: Enhancing Learning and Generalization Capacities via IBN-Net. ECCV, 2018. - model = OSNet( - num_classes, - blocks=[OSBlock, OSBlock, OSBlock], - layers=[2, 2, 2], - channels=[64, 256, 384, 512], - loss=loss, - IN=True, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, key='osnet_ibn_x1_0') - return model diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/osnet_ain.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/osnet_ain.py deleted file mode 100755 index de2505c3e..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/osnet_ain.py +++ /dev/null @@ -1,540 +0,0 @@ -from __future__ import division, absolute_import -import warnings -import torch -from torch import nn -from torch.nn import functional as F - -__all__ = ['osnet_ain_x1_0'] - -pretrained_urls = { - 'osnet_ain_x1_0': - 'https://drive.google.com/uc?id=1-CaioD9NaqbHK_kzSMW8VE4_3KcsRjEo' -} - - -########## -# Basic layers -########## -class ConvLayer(nn.Module): - """Convolution layer (conv + bn + relu).""" - - def __init__( - self, - in_channels, - out_channels, - kernel_size, - stride=1, - padding=0, - groups=1, - IN=False - ): - super(ConvLayer, self).__init__() - self.conv = nn.Conv2d( - in_channels, - out_channels, - kernel_size, - stride=stride, - padding=padding, - bias=False, - groups=groups - ) - if IN: - self.bn = nn.InstanceNorm2d(out_channels, affine=True) - else: - self.bn = nn.BatchNorm2d(out_channels) - self.relu = nn.ReLU() - - def forward(self, x): - x = self.conv(x) - x = self.bn(x) - return self.relu(x) - - -class Conv1x1(nn.Module): - """1x1 convolution + bn + relu.""" - - def __init__(self, in_channels, out_channels, stride=1, groups=1): - super(Conv1x1, self).__init__() - self.conv = nn.Conv2d( - in_channels, - out_channels, - 1, - stride=stride, - padding=0, - bias=False, - groups=groups - ) - self.bn = nn.BatchNorm2d(out_channels) - self.relu = nn.ReLU() - - def forward(self, x): - x = self.conv(x) - x = self.bn(x) - return self.relu(x) - - -class Conv1x1Linear(nn.Module): - """1x1 convolution + bn (w/o non-linearity).""" - - def __init__(self, in_channels, out_channels, stride=1, bn=True): - super(Conv1x1Linear, self).__init__() - self.conv = nn.Conv2d( - in_channels, out_channels, 1, stride=stride, padding=0, bias=False - ) - self.bn = None - if bn: - self.bn = nn.BatchNorm2d(out_channels) - - def forward(self, x): - x = self.conv(x) - if self.bn is not None: - x = self.bn(x) - return x - - -class Conv3x3(nn.Module): - """3x3 convolution + bn + relu.""" - - def __init__(self, in_channels, out_channels, stride=1, groups=1): - super(Conv3x3, self).__init__() - self.conv = nn.Conv2d( - in_channels, - out_channels, - 3, - stride=stride, - padding=1, - bias=False, - groups=groups - ) - self.bn = nn.BatchNorm2d(out_channels) - self.relu = nn.ReLU() - - def forward(self, x): - x = self.conv(x) - x = self.bn(x) - return self.relu(x) - - -class LightConv3x3(nn.Module): - """Lightweight 3x3 convolution. - 1x1 (linear) + dw 3x3 (nonlinear). - """ - - def __init__(self, in_channels, out_channels): - super(LightConv3x3, self).__init__() - self.conv1 = nn.Conv2d( - in_channels, out_channels, 1, stride=1, padding=0, bias=False - ) - self.conv2 = nn.Conv2d( - out_channels, - out_channels, - 3, - stride=1, - padding=1, - bias=False, - groups=out_channels - ) - self.bn = nn.BatchNorm2d(out_channels) - self.relu = nn.ReLU() - - def forward(self, x): - x = self.conv1(x) - x = self.conv2(x) - x = self.bn(x) - return self.relu(x) - - -class LightConvStream(nn.Module): - """Lightweight convolution stream.""" - - def __init__(self, in_channels, out_channels, depth): - super(LightConvStream, self).__init__() - assert depth >= 1, 'depth must be equal to or larger than 1, but got {}'.format( - depth - ) - layers = [] - layers += [LightConv3x3(in_channels, out_channels)] - for i in range(depth - 1): - layers += [LightConv3x3(out_channels, out_channels)] - self.layers = nn.Sequential(*layers) - - def forward(self, x): - return self.layers(x) - - -########## -# Building blocks for omni-scale feature learning -########## -class ChannelGate(nn.Module): - """A mini-network that generates channel-wise gates conditioned on input tensor.""" - - def __init__( - self, - in_channels, - num_gates=None, - return_gates=False, - gate_activation='sigmoid', - reduction=16, - layer_norm=False - ): - super(ChannelGate, self).__init__() - if num_gates is None: - num_gates = in_channels - self.return_gates = return_gates - self.global_avgpool = nn.AdaptiveAvgPool2d(1) - self.fc1 = nn.Conv2d( - in_channels, - in_channels // reduction, - kernel_size=1, - bias=True, - padding=0 - ) - self.norm1 = None - if layer_norm: - self.norm1 = nn.LayerNorm((in_channels // reduction, 1, 1)) - self.relu = nn.ReLU() - self.fc2 = nn.Conv2d( - in_channels // reduction, - num_gates, - kernel_size=1, - bias=True, - padding=0 - ) - if gate_activation == 'sigmoid': - self.gate_activation = nn.Sigmoid() - elif gate_activation == 'relu': - self.gate_activation = nn.ReLU() - elif gate_activation == 'linear': - self.gate_activation = None - else: - raise RuntimeError( - "Unknown gate activation: {}".format(gate_activation) - ) - - def forward(self, x): - input = x - x = self.global_avgpool(x) - x = self.fc1(x) - if self.norm1 is not None: - x = self.norm1(x) - x = self.relu(x) - x = self.fc2(x) - if self.gate_activation is not None: - x = self.gate_activation(x) - if self.return_gates: - return x - return input * x - - -class OSBlock(nn.Module): - """Omni-scale feature learning block.""" - - def __init__(self, in_channels, out_channels, reduction=4, T=4, **kwargs): - super(OSBlock, self).__init__() - assert T >= 1 - assert out_channels >= reduction and out_channels % reduction == 0 - mid_channels = out_channels // reduction - - self.conv1 = Conv1x1(in_channels, mid_channels) - self.conv2 = nn.ModuleList() - for t in range(1, T + 1): - self.conv2 += [LightConvStream(mid_channels, mid_channels, t)] - self.gate = ChannelGate(mid_channels) - self.conv3 = Conv1x1Linear(mid_channels, out_channels) - self.downsample = None - if in_channels != out_channels: - self.downsample = Conv1x1Linear(in_channels, out_channels) - - def forward(self, x): - identity = x - x1 = self.conv1(x) - x2 = 0 - for conv2_t in self.conv2: - x2_t = conv2_t(x1) - x2 = x2 + self.gate(x2_t) - x3 = self.conv3(x2) - if self.downsample is not None: - identity = self.downsample(identity) - out = x3 + identity - return F.relu(out) - - -class OSBlockINin(nn.Module): - """Omni-scale feature learning block with instance normalization.""" - - def __init__(self, in_channels, out_channels, reduction=4, T=4, **kwargs): - super(OSBlockINin, self).__init__() - assert T >= 1 - assert out_channels >= reduction and out_channels % reduction == 0 - mid_channels = out_channels // reduction - - self.conv1 = Conv1x1(in_channels, mid_channels) - self.conv2 = nn.ModuleList() - for t in range(1, T + 1): - self.conv2 += [LightConvStream(mid_channels, mid_channels, t)] - self.gate = ChannelGate(mid_channels) - self.conv3 = Conv1x1Linear(mid_channels, out_channels, bn=False) - self.downsample = None - if in_channels != out_channels: - self.downsample = Conv1x1Linear(in_channels, out_channels) - self.IN = nn.InstanceNorm2d(out_channels, affine=True) - - def forward(self, x): - identity = x - x1 = self.conv1(x) - x2 = 0 - for conv2_t in self.conv2: - x2_t = conv2_t(x1) - x2 = x2 + self.gate(x2_t) - x3 = self.conv3(x2) - x3 = self.IN(x3) # IN inside residual - if self.downsample is not None: - identity = self.downsample(identity) - out = x3 + identity - return F.relu(out) - - -########## -# Network architecture -########## -class OSNet(nn.Module): - """Omni-Scale Network. - - Reference: - - Zhou et al. Omni-Scale Feature Learning for Person Re-Identification. ICCV, 2019. - - Zhou et al. Learning Generalisable Omni-Scale Representations - for Person Re-Identification. arXiv preprint, 2019. - """ - - def __init__( - self, - num_classes, - blocks, - layers, - channels, - feature_dim=512, - loss='softmax', - conv1_IN=False, - **kwargs - ): - super(OSNet, self).__init__() - num_blocks = len(blocks) - assert num_blocks == len(layers) - assert num_blocks == len(channels) - 1 - self.loss = loss - self.feature_dim = feature_dim - - # convolutional backbone - self.conv1 = ConvLayer( - 3, channels[0], 7, stride=2, padding=3, IN=conv1_IN - ) - self.maxpool = nn.MaxPool2d(3, stride=2, padding=1) - self.conv2 = self._make_layer( - blocks[0], layers[0], channels[0], channels[1] - ) - self.pool2 = nn.Sequential( - Conv1x1(channels[1], channels[1]), nn.AvgPool2d(2, stride=2) - ) - self.conv3 = self._make_layer( - blocks[1], layers[1], channels[1], channels[2] - ) - self.pool3 = nn.Sequential( - Conv1x1(channels[2], channels[2]), nn.AvgPool2d(2, stride=2) - ) - self.conv4 = self._make_layer( - blocks[2], layers[2], channels[2], channels[3] - ) - self.conv5 = Conv1x1(channels[3], channels[3]) - self.global_avgpool = nn.AdaptiveAvgPool2d(1) - # fully connected layer - self.fc = self._construct_fc_layer( - self.feature_dim, channels[3], dropout_p=None - ) - # identity classification layer - self.classifier = nn.Linear(self.feature_dim, num_classes) - - self._init_params() - - def _make_layer(self, blocks, layer, in_channels, out_channels): - layers = [] - layers += [blocks[0](in_channels, out_channels)] - for i in range(1, len(blocks)): - layers += [blocks[i](out_channels, out_channels)] - return nn.Sequential(*layers) - - def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None): - if fc_dims is None or fc_dims < 0: - self.feature_dim = input_dim - return None - - if isinstance(fc_dims, int): - fc_dims = [fc_dims] - - layers = [] - for dim in fc_dims: - layers.append(nn.Linear(input_dim, dim)) - layers.append(nn.BatchNorm1d(dim)) - layers.append(nn.ReLU()) - if dropout_p is not None: - layers.append(nn.Dropout(p=dropout_p)) - input_dim = dim - - self.feature_dim = fc_dims[-1] - - return nn.Sequential(*layers) - - def _init_params(self): - for m in self.modules(): - if isinstance(m, nn.Conv2d): - nn.init.kaiming_normal_( - m.weight, mode='fan_out', nonlinearity='relu' - ) - if m.bias is not None: - nn.init.constant_(m.bias, 0) - - elif isinstance(m, nn.BatchNorm2d): - nn.init.constant_(m.weight, 1) - nn.init.constant_(m.bias, 0) - - elif isinstance(m, nn.BatchNorm1d): - nn.init.constant_(m.weight, 1) - nn.init.constant_(m.bias, 0) - - elif isinstance(m, nn.InstanceNorm2d): - nn.init.constant_(m.weight, 1) - nn.init.constant_(m.bias, 0) - - elif isinstance(m, nn.Linear): - nn.init.normal_(m.weight, 0, 0.01) - if m.bias is not None: - nn.init.constant_(m.bias, 0) - - def featuremaps(self, x): - x = self.conv1(x) - x = self.maxpool(x) - x = self.conv2(x) - x = self.pool2(x) - x = self.conv3(x) - x = self.pool3(x) - x = self.conv4(x) - x = self.conv5(x) - return x - - def forward(self, x, return_featuremaps=False): - x = self.featuremaps(x) - if return_featuremaps: - return x - v = self.global_avgpool(x) - v = v.view(v.size(0), -1) - if self.fc is not None: - v = self.fc(v) - if not self.training: - return v - y = self.classifier(v) - if self.loss == 'softmax': - return y - elif self.loss == 'triplet': - return y, v - else: - raise KeyError("Unsupported loss: {}".format(self.loss)) - - -def init_pretrained_weights(model, key=''): - """Initializes model with pretrained weights. - - Layers that don't match with pretrained layers in name or size are kept unchanged. - """ - import os - import errno - import gdown - from collections import OrderedDict - - def _get_torch_home(): - ENV_TORCH_HOME = 'TORCH_HOME' - ENV_XDG_CACHE_HOME = 'XDG_CACHE_HOME' - DEFAULT_CACHE_DIR = '~/.cache' - torch_home = os.path.expanduser( - os.getenv( - ENV_TORCH_HOME, - os.path.join( - os.getenv(ENV_XDG_CACHE_HOME, DEFAULT_CACHE_DIR), 'torch' - ) - ) - ) - return torch_home - - torch_home = _get_torch_home() - model_dir = os.path.join(torch_home, 'checkpoints') - try: - os.makedirs(model_dir) - except OSError as e: - if e.errno == errno.EEXIST: - # Directory already exists, ignore. - pass - else: - # Unexpected OSError, re-raise. - raise - filename = key + '_imagenet.pth' - cached_file = os.path.join(model_dir, filename) - - if not os.path.exists(cached_file): - gdown.download(pretrained_urls[key], cached_file, quiet=False) - - state_dict = torch.load(cached_file) - model_dict = model.state_dict() - new_state_dict = OrderedDict() - matched_layers, discarded_layers = [], [] - - for k, v in state_dict.items(): - if k.startswith('module.'): - k = k[7:] # discard module. - - if k in model_dict and model_dict[k].size() == v.size(): - new_state_dict[k] = v - matched_layers.append(k) - else: - discarded_layers.append(k) - - model_dict.update(new_state_dict) - model.load_state_dict(model_dict) - - if len(matched_layers) == 0: - warnings.warn( - 'The pretrained weights from "{}" cannot be loaded, ' - 'please check the key names manually ' - '(** ignored and continue **)'.format(cached_file) - ) - else: - print( - 'Successfully loaded imagenet pretrained weights from "{}"'. - format(cached_file) - ) - if len(discarded_layers) > 0: - print( - '** The following layers are discarded ' - 'due to unmatched keys or layer size: {}'. - format(discarded_layers) - ) - - -########## -# Instantiation -########## -def osnet_ain_x1_0( - num_classes=1000, pretrained=True, loss='softmax', **kwargs -): - model = OSNet( - num_classes, - blocks=[ - [OSBlockINin, OSBlockINin], [OSBlock, OSBlockINin], - [OSBlockINin, OSBlock] - ], - layers=[2, 2, 2], - channels=[64, 256, 384, 512], - loss=loss, - conv1_IN=True, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, key='osnet_ain_x1_0') - return model \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/__init__.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/_ext/__init__.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/_ext/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/_ext/psroi_pooling/__init__.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/_ext/psroi_pooling/__init__.py deleted file mode 100755 index 390ceb66a..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/_ext/psroi_pooling/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ - -from torch.utils.ffi import _wrap_function -from ._psroi_pooling import lib as _lib, ffi as _ffi - -__all__ = [] -def _import_symbols(locals): - for symbol in dir(_lib): - fn = getattr(_lib, symbol) - if callable(fn): - locals[symbol] = _wrap_function(fn, _ffi) - else: - locals[symbol] = fn - __all__.append(symbol) - -_import_symbols(locals()) diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/build.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/build.py deleted file mode 100755 index dcbef28e8..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/build.py +++ /dev/null @@ -1,33 +0,0 @@ -import os -import torch -from torch.utils.ffi import create_extension - -sources = [] -headers = [] -defines = [] -with_cuda = False - -if torch.cuda.is_available(): - print('Including CUDA code.') - sources += ['src/psroi_pooling_cuda.c'] - headers += ['src/psroi_pooling_cuda.h'] - defines += [('WITH_CUDA', None)] - with_cuda = True - -this_file = os.path.dirname(os.path.realpath(__file__)) -print(this_file) -extra_objects = ['src/cuda/psroi_pooling.cu.o'] -extra_objects = [os.path.join(this_file, fname) for fname in extra_objects] - -ffi = create_extension( - '_ext.psroi_pooling', - headers=headers, - sources=sources, - define_macros=defines, - relative_to=__file__, - with_cuda=with_cuda, - extra_objects=extra_objects -) - -if __name__ == '__main__': - ffi.build() diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/functions/__init__.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/functions/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/functions/psroi_pooling.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/functions/psroi_pooling.py deleted file mode 100755 index 648eed1ba..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/functions/psroi_pooling.py +++ /dev/null @@ -1,49 +0,0 @@ -import torch -from torch.autograd import Function -from .._ext import psroi_pooling - - -class PSRoIPoolingFunction(Function): - def __init__(self, pooled_height, pooled_width, spatial_scale, group_size, output_dim): - self.pooled_width = int(pooled_width) - self.pooled_height = int(pooled_height) - self.spatial_scale = float(spatial_scale) - self.group_size = int(group_size) - self.output_dim = int(output_dim) - - self.output = None - self.mappingchannel = None - self.rois = None - self.feature_size = None - - def forward(self, features, rois): - batch_size, num_channels, data_height, data_width = features.size() - num_rois = rois.size(0) - - output = features.new().resize_(num_rois, self.output_dim, self.pooled_height, self.pooled_width).zero_() - mappingchannel = torch.IntTensor(num_rois, self.output_dim, self.pooled_height, self.pooled_width).zero_().cuda(features.get_device()) - - rtn = psroi_pooling.psroi_pooling_forward_cuda(self.pooled_height, self.pooled_width, self.spatial_scale, - self.group_size, self.output_dim, - features, rois, output, mappingchannel) - assert rtn > 0 - self.output = output - self.mappingchannel = mappingchannel - self.rois = rois - self.feature_size = features.size() - # print features.max(), features.min() - # print rois.max(), rois.min() - # print output.max(), output.min() - return output - - def backward(self, grad_output): - assert (self.feature_size is not None and grad_output.is_cuda) - - batch_size, num_channels, data_height, data_width = self.feature_size - - grad_input = torch.zeros(batch_size, num_channels, data_height, data_width).cuda() - - psroi_pooling.psroi_pooling_backward_cuda(self.pooled_height, self.pooled_width, self.spatial_scale, - self.output_dim, - grad_output, self.rois, grad_input, self.mappingchannel) - return grad_input, None diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/make.sh b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/make.sh deleted file mode 100755 index 238e5725d..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/make.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -CUDA_PATH=/usr/local/cuda - -cd src/cuda -echo "Compiling psroi pooling kernels by nvcc..." -${CUDA_PATH}/bin/nvcc -c -o psroi_pooling.cu.o psroi_pooling_kernel.cu -x cu -Xcompiler -fPIC -arch=sm_52 - -cd ../../ -python build.py \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/modules/__init__.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/modules/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/modules/psroi_pool.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/modules/psroi_pool.py deleted file mode 100755 index 9a0f2e456..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/modules/psroi_pool.py +++ /dev/null @@ -1,18 +0,0 @@ -from torch.nn.modules.module import Module -import sys -from ..functions.psroi_pooling import PSRoIPoolingFunction - - -class PSRoIPool(Module): - def __init__(self, pooled_height, pooled_width, spatial_scale, group_size, output_dim): - super(PSRoIPool, self).__init__() - - self.pooled_width = int(pooled_width) - self.pooled_height = int(pooled_height) - self.spatial_scale = float(spatial_scale) - self.group_size = int(group_size) - self.output_dim = int(output_dim) - - def forward(self, features, rois): - return PSRoIPoolingFunction(self.pooled_height, self.pooled_width, self.spatial_scale, self.group_size, - self.output_dim)(features, rois) diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/cuda/psroi_pooling_kernel.cu b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/cuda/psroi_pooling_kernel.cu deleted file mode 100755 index f509671a4..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/cuda/psroi_pooling_kernel.cu +++ /dev/null @@ -1,199 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include "psroi_pooling_kernel.h" - -#define CUDA_1D_KERNEL_LOOP(i, n) \ - for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < n; \ - i += blockDim.x * gridDim.x) - - -__global__ void PSROIPoolForward(const int nthreads, const float* bottom_data, - const float spatial_scale, const int height, const int width, - const int channels, const int pooled_height, const int pooled_width, - const int group_size, const int output_dim, - const float* bottom_rois, float* top_data, int* mapping_channel) -{ - CUDA_1D_KERNEL_LOOP(index, nthreads) - { - // (n, c, ph, pw) is an element in the pooled output - int pw = index % pooled_width; - int ph = (index / pooled_width) % pooled_height; - int ctop = (index / pooled_width / pooled_height) % output_dim; - int n = index / pooled_width / pooled_height / output_dim; - - bottom_rois += n * 5; - int roi_batch_ind = bottom_rois[0]; - float roi_start_w = - static_cast(round(bottom_rois[1])) * spatial_scale; - float roi_start_h = - static_cast(round(bottom_rois[2])) * spatial_scale; - float roi_end_w = - static_cast(round(bottom_rois[3]) + 1.) * spatial_scale; - float roi_end_h = - static_cast(round(bottom_rois[4]) + 1.) * spatial_scale; - - // Force malformed ROIs to be 1x1 - float roi_width = max(roi_end_w - roi_start_w, 0.1); // avoid 0 - float roi_height = max(roi_end_h - roi_start_h, 0.1); - - float bin_size_h = (float)(roi_height) / (float)(pooled_height); - float bin_size_w = (float)(roi_width) / (float)(pooled_width); - - int hstart = floor(static_cast(ph) * bin_size_h - + roi_start_h); - int wstart = floor(static_cast(pw)* bin_size_w - + roi_start_w); - int hend = ceil(static_cast(ph + 1) * bin_size_h - + roi_start_h); - int wend = ceil(static_cast(pw + 1) * bin_size_w - + roi_start_w); - - // Add roi offsets and clip to input boundaries - hstart = min(max(hstart, 0), height); - hend = min(max(hend, 0), height); - wstart = min(max(wstart, 0), width); - wend = min(max(wend, 0), width); - bool is_empty = (hend <= hstart) || (wend <= wstart); - - int gw = pw; - int gh = ph; - int c = (ctop*group_size + gh)*group_size + gw; - - bottom_data += (roi_batch_ind * channels + c) * height * width; - float out_sum = 0; - for (int h = hstart; h < hend; ++h) { - for (int w = wstart; w < wend; ++w) { - int bottom_index = h*width + w; - out_sum += bottom_data[bottom_index]; - } - } - float bin_area = (hend - hstart)*(wend - wstart); - top_data[index] = is_empty? 0. : out_sum/bin_area; - mapping_channel[index] = c; - } -} - - -int PSROIPoolForwardLauncher( - const float* bottom_data, const float spatial_scale, const int num_rois, const int height, - const int width, const int channels, const int pooled_height, - const int pooled_width, const float* bottom_rois, - const int group_size, const int output_dim, - float* top_data, int* mapping_channel, cudaStream_t stream) -{ - const int kThreadsPerBlock = 1024; - const int output_size = output_dim * pooled_height * pooled_width * num_rois; - cudaError_t err; - - - PSROIPoolForward<<<(output_size + kThreadsPerBlock - 1) / kThreadsPerBlock, kThreadsPerBlock, 0, stream>>>( - output_size, bottom_data, spatial_scale, height, width, channels, pooled_height, - pooled_width, group_size, output_dim, bottom_rois, top_data, mapping_channel); - - err = cudaGetLastError(); - if(cudaSuccess != err) - { - fprintf( stderr, "cudaCheckError() failed : %s\n", cudaGetErrorString( err ) ); - exit( -1 ); - } - - return 1; -} - - -__global__ void PSROIPoolBackward(const int nthreads, const float* top_diff, - const int* mapping_channel, const int num_rois, const float spatial_scale, - const int height, const int width, const int channels, - const int pooled_height, const int pooled_width, const int output_dim, float* bottom_diff, - const float* bottom_rois) { - CUDA_1D_KERNEL_LOOP(index, nthreads) - { - - int pw = index % pooled_width; - int ph = (index / pooled_width) % pooled_height; - int n = index / pooled_width / pooled_height / output_dim; - - // [start, end) interval for spatial sampling - bottom_rois += n * 5; - int roi_batch_ind = bottom_rois[0]; - float roi_start_w = - static_cast(round(bottom_rois[1])) * spatial_scale; - float roi_start_h = - static_cast(round(bottom_rois[2])) * spatial_scale; - float roi_end_w = - static_cast(round(bottom_rois[3]) + 1.) * spatial_scale; - float roi_end_h = - static_cast(round(bottom_rois[4]) + 1.) * spatial_scale; - - // Force too small ROIs to be 1x1 - float roi_width = max(roi_end_w - roi_start_w, 0.1); // avoid 0 - float roi_height = max(roi_end_h - roi_start_h, 0.1); - - // Compute w and h at bottom - float bin_size_h = roi_height / static_cast(pooled_height); - float bin_size_w = roi_width / static_cast(pooled_width); - - int hstart = floor(static_cast(ph)* bin_size_h - + roi_start_h); - int wstart = floor(static_cast(pw)* bin_size_w - + roi_start_w); - int hend = ceil(static_cast(ph + 1) * bin_size_h - + roi_start_h); - int wend = ceil(static_cast(pw + 1) * bin_size_w - + roi_start_w); - // Add roi offsets and clip to input boundaries - hstart = min(max(hstart, 0), height); - hend = min(max(hend, 0), height); - wstart = min(max(wstart, 0), width); - wend = min(max(wend, 0), width); - bool is_empty = (hend <= hstart) || (wend <= wstart); - - // Compute c at bottom - int c = mapping_channel[index]; - float* offset_bottom_diff = bottom_diff + - (roi_batch_ind * channels + c) * height * width; - float bin_area = (hend - hstart)*(wend - wstart); - float diff_val = is_empty ? 0. : top_diff[index] / bin_area; - for (int h = hstart; h < hend; ++h) { - for (int w = wstart; w < wend; ++w) { - int bottom_index = h*width + w; - //caffe_gpu_atomic_add(diff_val, offset_bottom_diff + bottom_index); - atomicAdd(offset_bottom_diff + bottom_index, diff_val); - } - } - } -} - -int PSROIPoolBackwardLauncher(const float* top_diff, const int* mapping_channel, const int batch_size, const int num_rois, const float spatial_scale, const int channels, - const int height, const int width, const int pooled_width, - const int pooled_height, const int output_dim, - float* bottom_diff, const float* bottom_rois, cudaStream_t stream) -{ - const int kThreadsPerBlock = 1024; - //const int output_size = output_dim * height * width * channels; - const int output_size = output_dim * pooled_height * pooled_width * num_rois; - cudaError_t err; - - PSROIPoolBackward<<<(output_size + kThreadsPerBlock - 1) / kThreadsPerBlock, kThreadsPerBlock, 0, stream>>>( - output_size, top_diff, mapping_channel, num_rois, spatial_scale, height, width, channels, pooled_height, - pooled_width, output_dim, bottom_diff, bottom_rois); - - err = cudaGetLastError(); - if(cudaSuccess != err) - { - fprintf( stderr, "cudaCheckError() failed : %s\n", cudaGetErrorString( err ) ); - exit( -1 ); - } - - return 1; -} - - -#ifdef __cplusplus -} -#endif diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/cuda/psroi_pooling_kernel.h b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/cuda/psroi_pooling_kernel.h deleted file mode 100755 index 03a07f524..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/cuda/psroi_pooling_kernel.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef PS_ROI_POOLING_KERNEL -#define PS_ROI_POOLING_KERNEL - -#ifdef __cplusplus -extern "C" { -#endif - -int PSROIPoolForwardLauncher( - const float* bottom_data, const float spatial_scale, const int num_rois, const int height, - const int width, const int channels, const int pooled_height, const int pooled_width, - const float* bottom_rois, const int group_size, const int output_dim, float* top_data, int* mapping_channel, cudaStream_t stream); - - -int PSROIPoolBackwardLauncher(const float* top_diff, const int* mapping_channel, const int batch_size, const int num_rois, const float spatial_scale, const int channels, const int height, const int width, const int pooled_width, const int pooled_height, const int output_dim, float* bottom_diff, const float* bottom_rois, cudaStream_t stream); - -#ifdef __cplusplus -} - -#endif - -#endif diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/psroi_pooling_cuda.c b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/psroi_pooling_cuda.c deleted file mode 100755 index fbbb3d212..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/psroi_pooling_cuda.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include "cuda/psroi_pooling_kernel.h" - - - -extern THCState* state; - -int psroi_pooling_forward_cuda(int pooled_height, int pooled_width, float spatial_scale, int group_size, int output_dim,THCudaTensor *features, THCudaTensor* rois, THCudaTensor* output, THCudaIntTensor* mappingchannel){ - float* data_in = THCudaTensor_data(state, features); - float* rois_in = THCudaTensor_data(state, rois); - float* output_out = THCudaTensor_data(state, output); - int* mappingchannel_out = THCudaIntTensor_data(state, mappingchannel); - //Get # of Rois - int num_rois = THCudaTensor_size(state, rois, 0); - int size_rois = THCudaTensor_size(state, rois, 1); - if (size_rois!=5) - { - return -1; - } - - //Get # of batch_size - int batch_size = THCudaTensor_size(state, features, 0); - - int data_height = THCudaTensor_size(state, features, 2); - int data_width = THCudaTensor_size(state, features, 3); - int num_channels = THCudaTensor_size(state, features, 1); - - cudaStream_t stream = THCState_getCurrentStream(state); - - // call the gpu kernel for psroi_pooling - PSROIPoolForwardLauncher(data_in, spatial_scale, num_rois, data_height, data_width, num_channels, pooled_height, pooled_width,rois_in, group_size, - output_dim, output_out, mappingchannel_out,stream); - return 1; -} - - -int psroi_pooling_backward_cuda(int pooled_height, int pooled_width, float spatial_scale, int output_dim, -THCudaTensor* top_grad, THCudaTensor* rois, THCudaTensor* bottom_grad, THCudaIntTensor* mappingchannel) -{ - float *top_grad_flat = THCudaTensor_data(state, top_grad); - float *rois_flat = THCudaTensor_data(state, rois); - - float *bottom_grad_flat = THCudaTensor_data(state, bottom_grad); - int *mappingchannel_flat = THCudaIntTensor_data(state, mappingchannel); - - // Number of ROIs - int num_rois = THCudaTensor_size(state, rois, 0); - int size_rois = THCudaTensor_size(state, rois, 1); - if (size_rois != 5) - { - return -1; - } - // batch size - int batch_size = THCudaTensor_size(state, bottom_grad, 0); - - // data height - int data_height = THCudaTensor_size(state, bottom_grad, 2); - // data width - int data_width = THCudaTensor_size(state, bottom_grad, 3); - // Number of channels - int num_channels = THCudaTensor_size(state, bottom_grad, 1); - - cudaStream_t stream = THCState_getCurrentStream(state); - - PSROIPoolBackwardLauncher(top_grad_flat, mappingchannel_flat, batch_size, num_rois, spatial_scale, num_channels, data_height, data_width, pooled_width, pooled_height, output_dim, bottom_grad_flat, rois_flat, stream); - return 1; -} diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/psroi_pooling_cuda.h b/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/psroi_pooling_cuda.h deleted file mode 100755 index 65d8bf077..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/psroi_pooling/src/psroi_pooling_cuda.h +++ /dev/null @@ -1,5 +0,0 @@ -int psroi_pooling_forward_cuda( int pooled_height, int pooled_width, float spatial_scale,int group_size, int output_dim, - THCudaTensor * features, THCudaTensor * rois, THCudaTensor * output, THCudaIntTensor * mappingchannel); - -int psroi_pooling_backward_cuda(int pooled_height, int pooled_width, float spatial_scale, int output_dim, - THCudaTensor * top_grad, THCudaTensor * rois, THCudaTensor * bottom_grad, THCudaIntTensor * mappingchannel); diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/reid/__init__.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/reid/__init__.py deleted file mode 100755 index ce8e2189e..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/reid/__init__.py +++ /dev/null @@ -1,53 +0,0 @@ -import cv2 -import numpy as np -from distutils.version import LooseVersion -import torch -from torch.autograd import Variable - -from utils import bbox as bbox_utils -from utils.log import logger -from ReidModels import net_utils -from ReidModels.reid.image_part_aligned import Model - - -def load_reid_model(): - model = Model(n_parts=8) - model.inp_size = (80, 160) - ckpt = 'data/googlenet_part8_all_xavier_ckpt_56.h5' - - net_utils.load_net(ckpt, model) - logger.info('Load ReID model from {}'.format(ckpt)) - - model = model.cuda() - model.eval() - return model - - -def im_preprocess(image): - image = np.asarray(image, np.float32) - image -= np.array([104, 117, 123], dtype=np.float32).reshape(1, 1, -1) - image = image.transpose((2, 0, 1)) - return image - - -def extract_image_patches(image, bboxes): - bboxes = np.round(bboxes).astype(np.int) - bboxes = bbox_utils.clip_boxes(bboxes, image.shape) - patches = [image[box[1]:box[3], box[0]:box[2]] for box in bboxes] - return patches - - -def extract_reid_features(reid_model, image, tlbrs): - if len(tlbrs) == 0: - return torch.FloatTensor() - - patches = extract_image_patches(image, tlbrs) - patches = np.asarray([im_preprocess(cv2.resize(p, reid_model.inp_size)) for p in patches], dtype=np.float32) - - gpu = net_utils.get_device(reid_model) - with torch.no_grad(): - _img = torch.from_numpy(patches) - if gpu: - _img = _img.cuda() - features,id = reid_model(_img).detach() - return features diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/reid/image_part_aligned.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/reid/image_part_aligned.py deleted file mode 100755 index 4f3ae64a3..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/reid/image_part_aligned.py +++ /dev/null @@ -1,39 +0,0 @@ -import torch -import torch.nn as nn -import torch.nn.functional as F - -from models.backbone.googlenet import GoogLeNet - - -class Model(nn.Module): - def __init__(self, n_parts=8,n_ID=300): - super(Model, self).__init__() - self.n_parts = n_parts - self.nID = n_ID - - self.feat_conv = GoogLeNet() - self.conv_input_feat = nn.Conv2d(self.feat_conv.output_channels, 512, 1) - # part net - self.conv_att = nn.Conv2d(512, self.n_parts, 1) - - for i in range(self.n_parts): - setattr(self, 'linear_feature{}'.format(i+1), nn.Linear(512, 64)) - self.id_classifer = nn.Linear(512,self.nID) - def forward(self, x): - feature = self.feat_conv(x) - feature = self.conv_input_feat(feature) - - att_weights = torch.sigmoid(self.conv_att(feature)) - - linear_feautres = [] - for i in range(self.n_parts): - masked_feature = feature * torch.unsqueeze(att_weights[:, i], 1) - pooled_feature = F.avg_pool2d(masked_feature, masked_feature.size()[2:4]) - linear_feautres.append( - getattr(self, 'linear_feature{}'.format(i+1))(pooled_feature.view(pooled_feature.size(0), -1)) - ) - - concat_features = torch.cat(linear_feautres, 1) - normed_feature = concat_features / torch.clamp(torch.norm(concat_features, 2, 1, keepdim=True), min=1e-6) - out = self.id_classifer(normed_feature) - return normed_feature,out diff --git a/cv/pose/alphapose/pytorch/trackers/ReidModels/resnet_fc.py b/cv/pose/alphapose/pytorch/trackers/ReidModels/resnet_fc.py deleted file mode 100755 index 94d47189d..000000000 --- a/cv/pose/alphapose/pytorch/trackers/ReidModels/resnet_fc.py +++ /dev/null @@ -1,532 +0,0 @@ -""" -Code source: https://github.com/pytorch/vision -""" -from __future__ import division, absolute_import -import torch.utils.model_zoo as model_zoo -from torch import nn -import torch.nn.functional as F - -__all__ = [ - 'resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152', - 'resnext50_32x4d', 'resnext101_32x8d', 'resnet50_fc512' -] - -model_urls = { - 'resnet18': - 'https://download.pytorch.org/models/resnet18-5c106cde.pth', - 'resnet34': - 'https://download.pytorch.org/models/resnet34-333f7ec4.pth', - 'resnet50': - 'https://download.pytorch.org/models/resnet50-19c8e357.pth', - 'resnet101': - 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth', - 'resnet152': - 'https://download.pytorch.org/models/resnet152-b121ed2d.pth', - 'resnext50_32x4d': - 'https://download.pytorch.org/models/resnext50_32x4d-7cdf4587.pth', - 'resnext101_32x8d': - 'https://download.pytorch.org/models/resnext101_32x8d-8ba56ff5.pth', -} - - -def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1): - """3x3 convolution with padding""" - return nn.Conv2d( - in_planes, - out_planes, - kernel_size=3, - stride=stride, - padding=dilation, - groups=groups, - bias=False, - dilation=dilation - ) - - -def conv1x1(in_planes, out_planes, stride=1): - """1x1 convolution""" - return nn.Conv2d( - in_planes, out_planes, kernel_size=1, stride=stride, bias=False - ) - - -class BasicBlock(nn.Module): - expansion = 1 - - def __init__( - self, - inplanes, - planes, - stride=1, - downsample=None, - groups=1, - base_width=64, - dilation=1, - norm_layer=None - ): - super(BasicBlock, self).__init__() - if norm_layer is None: - norm_layer = nn.BatchNorm2d - if groups != 1 or base_width != 64: - raise ValueError( - 'BasicBlock only supports groups=1 and base_width=64' - ) - if dilation > 1: - raise NotImplementedError( - "Dilation > 1 not supported in BasicBlock" - ) - # Both self.conv1 and self.downsample layers downsample the input when stride != 1 - self.conv1 = conv3x3(inplanes, planes, stride) - self.bn1 = norm_layer(planes) - self.relu = nn.ReLU(inplace=True) - self.conv2 = conv3x3(planes, planes) - self.bn2 = norm_layer(planes) - self.downsample = downsample - self.stride = stride - - def forward(self, x): - identity = x - - out = self.conv1(x) - out = self.bn1(out) - out = self.relu(out) - - out = self.conv2(out) - out = self.bn2(out) - - if self.downsample is not None: - identity = self.downsample(x) - - out += identity - out = self.relu(out) - - return out - - -class Bottleneck(nn.Module): - expansion = 4 - - def __init__( - self, - inplanes, - planes, - stride=1, - downsample=None, - groups=1, - base_width=64, - dilation=1, - norm_layer=None - ): - super(Bottleneck, self).__init__() - if norm_layer is None: - norm_layer = nn.BatchNorm2d - width = int(planes * (base_width/64.)) * groups - # Both self.conv2 and self.downsample layers downsample the input when stride != 1 - self.conv1 = conv1x1(inplanes, width) - self.bn1 = norm_layer(width) - self.conv2 = conv3x3(width, width, stride, groups, dilation) - self.bn2 = norm_layer(width) - self.conv3 = conv1x1(width, planes * self.expansion) - self.bn3 = norm_layer(planes * self.expansion) - self.relu = nn.ReLU(inplace=True) - self.downsample = downsample - self.stride = stride - - def forward(self, x): - identity = x - - out = self.conv1(x) - out = self.bn1(out) - out = self.relu(out) - - out = self.conv2(out) - out = self.bn2(out) - out = self.relu(out) - - out = self.conv3(out) - out = self.bn3(out) - - if self.downsample is not None: - identity = self.downsample(x) - - out += identity - out = self.relu(out) - - return out - - -class ResNet(nn.Module): - """Residual network. - - Reference: - - He et al. Deep Residual Learning for Image Recognition. CVPR 2016. - - Xie et al. Aggregated Residual Transformations for Deep Neural Networks. CVPR 2017. - - Public keys: - - ``resnet18``: ResNet18. - - ``resnet34``: ResNet34. - - ``resnet50``: ResNet50. - - ``resnet101``: ResNet101. - - ``resnet152``: ResNet152. - - ``resnext50_32x4d``: ResNeXt50. - - ``resnext101_32x8d``: ResNeXt101. - - ``resnet50_fc512``: ResNet50 + FC. - """ - - def __init__( - self, - num_classes, - loss, - block, - layers, - zero_init_residual=False, - groups=1, - width_per_group=64, - replace_stride_with_dilation=None, - norm_layer=None, - last_stride=2, - fc_dims=None, - dropout_p=None, - **kwargs - ): - super(ResNet, self).__init__() - if norm_layer is None: - norm_layer = nn.BatchNorm2d - self._norm_layer = norm_layer - self.loss = loss - self.feature_dim = 512 * block.expansion - self.inplanes = 64 - self.dilation = 1 - if replace_stride_with_dilation is None: - # each element in the tuple indicates if we should replace - # the 2x2 stride with a dilated convolution instead - replace_stride_with_dilation = [False, False, False] - if len(replace_stride_with_dilation) != 3: - raise ValueError( - "replace_stride_with_dilation should be None " - "or a 3-element tuple, got {}". - format(replace_stride_with_dilation) - ) - self.groups = groups - self.base_width = width_per_group - self.conv1 = nn.Conv2d( - 3, self.inplanes, kernel_size=7, stride=2, padding=3, bias=False - ) - self.bn1 = norm_layer(self.inplanes) - self.relu = nn.ReLU(inplace=True) - self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) - self.layer1 = self._make_layer(block, 64, layers[0]) - self.layer2 = self._make_layer( - block, - 128, - layers[1], - stride=2, - dilate=replace_stride_with_dilation[0] - ) - self.layer3 = self._make_layer( - block, - 256, - layers[2], - stride=2, - dilate=replace_stride_with_dilation[1] - ) - self.layer4 = self._make_layer( - block, - 512, - layers[3], - stride=last_stride, - dilate=replace_stride_with_dilation[2] - ) - self.global_avgpool = nn.AdaptiveAvgPool2d((1, 1)) - self.fc = self._construct_fc_layer( - fc_dims, 512 * block.expansion, dropout_p - ) - self.classifier = nn.Linear(self.feature_dim, num_classes) - - self._init_params() - - # Zero-initialize the last BN in each residual branch, - # so that the residual branch starts with zeros, and each residual block behaves like an identity. - # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677 - if zero_init_residual: - for m in self.modules(): - if isinstance(m, Bottleneck): - nn.init.constant_(m.bn3.weight, 0) - elif isinstance(m, BasicBlock): - nn.init.constant_(m.bn2.weight, 0) - - def _make_layer(self, block, planes, blocks, stride=1, dilate=False): - norm_layer = self._norm_layer - downsample = None - previous_dilation = self.dilation - if dilate: - self.dilation *= stride - stride = 1 - if stride != 1 or self.inplanes != planes * block.expansion: - downsample = nn.Sequential( - conv1x1(self.inplanes, planes * block.expansion, stride), - norm_layer(planes * block.expansion), - ) - - layers = [] - layers.append( - block( - self.inplanes, planes, stride, downsample, self.groups, - self.base_width, previous_dilation, norm_layer - ) - ) - self.inplanes = planes * block.expansion - for _ in range(1, blocks): - layers.append( - block( - self.inplanes, - planes, - groups=self.groups, - base_width=self.base_width, - dilation=self.dilation, - norm_layer=norm_layer - ) - ) - - return nn.Sequential(*layers) - - def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None): - """Constructs fully connected layer - - Args: - fc_dims (list or tuple): dimensions of fc layers, if None, no fc layers are constructed - input_dim (int): input dimension - dropout_p (float): dropout probability, if None, dropout is unused - """ - if fc_dims is None: - self.feature_dim = input_dim - return None - - assert isinstance( - fc_dims, (list, tuple) - ), 'fc_dims must be either list or tuple, but got {}'.format( - type(fc_dims) - ) - - layers = [] - for dim in fc_dims: - layers.append(nn.Linear(input_dim, dim)) - layers.append(nn.BatchNorm1d(dim)) - layers.append(nn.ReLU(inplace=True)) - if dropout_p is not None: - layers.append(nn.Dropout(p=dropout_p)) - input_dim = dim - - self.feature_dim = fc_dims[-1] - - return nn.Sequential(*layers) - - def _init_params(self): - for m in self.modules(): - if isinstance(m, nn.Conv2d): - nn.init.kaiming_normal_( - m.weight, mode='fan_out', nonlinearity='relu' - ) - if m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.BatchNorm2d): - nn.init.constant_(m.weight, 1) - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.BatchNorm1d): - nn.init.constant_(m.weight, 1) - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.Linear): - nn.init.normal_(m.weight, 0, 0.01) - if m.bias is not None: - nn.init.constant_(m.bias, 0) - - def featuremaps(self, x): - x = self.conv1(x) - x = self.bn1(x) - x = self.relu(x) - x = self.maxpool(x) - x = self.layer1(x) - x = self.layer2(x) - x = self.layer3(x) - x = self.layer4(x) - return x - - def forward(self, x): - f = self.featuremaps(x) - v = self.global_avgpool(f) - v = v.view(v.size(0), -1) - - if self.fc is not None: - v = self.fc(v) - - if not self.training: - #return F.normalize(v) - return v - - y = self.classifier(v) - - if self.loss == 'softmax': - return y - elif self.loss == 'triplet': - return y, v - else: - raise KeyError("Unsupported loss: {}".format(self.loss)) - - -def init_pretrained_weights(model, model_url): - """Initializes model with pretrained weights. - - Layers that don't match with pretrained layers in name or size are kept unchanged. - """ - pretrain_dict = model_zoo.load_url(model_url) - model_dict = model.state_dict() - pretrain_dict = { - k: v - for k, v in pretrain_dict.items() - if k in model_dict and model_dict[k].size() == v.size() - } - model_dict.update(pretrain_dict) - model.load_state_dict(model_dict) - - -"""ResNet""" - - -def resnet18(num_classes, loss='softmax', pretrained=True, **kwargs): - model = ResNet( - num_classes=num_classes, - loss=loss, - block=BasicBlock, - layers=[2, 2, 2, 2], - last_stride=2, - fc_dims=None, - dropout_p=None, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, model_urls['resnet18']) - return model - - -def resnet34(num_classes, loss='softmax', pretrained=True, **kwargs): - model = ResNet( - num_classes=num_classes, - loss=loss, - block=BasicBlock, - layers=[3, 4, 6, 3], - last_stride=2, - fc_dims=None, - dropout_p=None, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, model_urls['resnet34']) - return model - - -def resnet50(num_classes, loss='softmax', pretrained=True, **kwargs): - model = ResNet( - num_classes=num_classes, - loss=loss, - block=Bottleneck, - layers=[3, 4, 6, 3], - last_stride=2, - fc_dims=None, - dropout_p=None, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, model_urls['resnet50']) - return model - - -def resnet101(num_classes, loss='softmax', pretrained=True, **kwargs): - model = ResNet( - num_classes=num_classes, - loss=loss, - block=Bottleneck, - layers=[3, 4, 23, 3], - last_stride=2, - fc_dims=None, - dropout_p=None, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, model_urls['resnet101']) - return model - - -def resnet152(num_classes, loss='softmax', pretrained=True, **kwargs): - model = ResNet( - num_classes=num_classes, - loss=loss, - block=Bottleneck, - layers=[3, 8, 36, 3], - last_stride=2, - fc_dims=None, - dropout_p=None, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, model_urls['resnet152']) - return model - - -"""ResNeXt""" - - -def resnext50_32x4d(num_classes, loss='softmax', pretrained=True, **kwargs): - model = ResNet( - num_classes=num_classes, - loss=loss, - block=Bottleneck, - layers=[3, 4, 6, 3], - last_stride=2, - fc_dims=None, - dropout_p=None, - groups=32, - width_per_group=4, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, model_urls['resnext50_32x4d']) - return model - - -def resnext101_32x8d(num_classes, loss='softmax', pretrained=True, **kwargs): - model = ResNet( - num_classes=num_classes, - loss=loss, - block=Bottleneck, - layers=[3, 4, 23, 3], - last_stride=2, - fc_dims=None, - dropout_p=None, - groups=32, - width_per_group=8, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, model_urls['resnext101_32x8d']) - return model - - -""" -ResNet + FC -""" - - -def resnet50_fc512(num_classes, loss='softmax', pretrained=True, **kwargs): - model = ResNet( - num_classes=num_classes, - loss=loss, - block=Bottleneck, - layers=[3, 4, 6, 3], - last_stride=1, - fc_dims=[512], - dropout_p=None, - **kwargs - ) - if pretrained: - init_pretrained_weights(model, model_urls['resnet50']) - return model diff --git a/cv/pose/alphapose/pytorch/trackers/__init__.py b/cv/pose/alphapose/pytorch/trackers/__init__.py deleted file mode 100755 index d05eff158..000000000 --- a/cv/pose/alphapose/pytorch/trackers/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -import numpy as np -import torch -def track(tracker,args,orig_img,inps,boxes,hm,cropped_boxes,im_name,scores): - hm = hm.cpu().data.numpy() - online_targets = tracker.update(orig_img,inps,boxes,hm,cropped_boxes,im_name,scores,_debug=False) - new_boxes,new_scores,new_ids,new_hm,new_crop = [],[],[],[],[] - for t in online_targets: - tlbr = t.tlbr - tid = t.track_id - thm = t.pose - tcrop = t.crop_box - tscore = t.detscore - new_boxes.append(tlbr) - new_crop.append(tcrop) - new_hm.append(thm) - new_ids.append(tid) - new_scores.append(tscore) - - new_hm = torch.Tensor(new_hm).to(args.device) - return new_boxes,new_scores,new_ids,new_hm,new_crop diff --git a/cv/pose/alphapose/pytorch/trackers/tracker_api.py b/cv/pose/alphapose/pytorch/trackers/tracker_api.py deleted file mode 100755 index 4967a496f..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracker_api.py +++ /dev/null @@ -1,368 +0,0 @@ -# ----------------------------------------------------- -# Copyright (c) Shanghai Jiao Tong University. All rights reserved. -# -# ----------------------------------------------------- - -"""API of tracker""" -import os -import sys -sys.path.insert(0, os.path.dirname(__file__)) -from abc import ABC, abstractmethod -import platform -import numpy as np -from collections import deque -import itertools -import os.path as osp -import time -import torch -import torch.nn.functional as F -import torch.nn as nn - -from utils.utils import * -from utils.log import logger -from utils.kalman_filter import KalmanFilter -from tracking.matching import * -from tracking.basetrack import BaseTrack, TrackState -from utils.transform import build_transforms -from ReidModels.ResBnLin import ResModel -from ReidModels.osnet import * -from ReidModels.osnet_ain import osnet_ain_x1_0 -from ReidModels.resnet_fc import resnet50_fc512 - -class STrack(BaseTrack): - shared_kalman = KalmanFilter() - - def __init__(self, tlwh, score, temp_feat, pose,crop_box,file_name,ps,buffer_size=30): - - # wait activate - self._tlwh = np.asarray(tlwh, dtype=np.float) - self.kalman_filter = None - self.mean, self.covariance = None, None - self.is_activated = False - - self.score = score - self.tracklet_len = 0 - - self.smooth_feat = None - self.update_features(temp_feat) - self.features = deque([], maxlen=buffer_size) - self.alpha = 0.9 - self.pose = pose - self.detscore = ps - self.crop_box = crop_box - self.file_name = file_name - - def update_features(self, feat): - feat /= np.linalg.norm(feat) - self.curr_feat = feat - if self.smooth_feat is None: - self.smooth_feat = feat - else: - self.smooth_feat = self.alpha *self.smooth_feat + (1-self.alpha) * feat - self.features.append(feat) - self.smooth_feat /= np.linalg.norm(self.smooth_feat) - - def predict(self): - mean_state = self.mean.copy() - if self.state != TrackState.Tracked: - mean_state[7] = 0 - self.mean, self.covariance = self.kalman_filter.predict(mean_state, self.covariance) - - @staticmethod - def multi_predict(stracks): - if len(stracks) > 0: - multi_mean = np.asarray([st.mean.copy() for st in stracks]) - multi_covariance = np.asarray([st.covariance for st in stracks]) - for i,st in enumerate(stracks): - if st.state != TrackState.Tracked: - multi_mean[i][7] = 0 - multi_mean, multi_covariance = STrack.shared_kalman.multi_predict(multi_mean, multi_covariance) - for i, (mean, cov) in enumerate(zip(multi_mean, multi_covariance)): - stracks[i].mean = mean - stracks[i].covariance = cov - - - def activate(self, kalman_filter, frame_id): - """Start a new tracklet""" - self.kalman_filter = kalman_filter - self.track_id = self.next_id() - self.mean, self.covariance = self.kalman_filter.initiate(self.tlwh_to_xyah(self._tlwh)) - - self.tracklet_len = 0 - self.state = TrackState.Tracked - #self.is_activated = True - self.frame_id = frame_id - self.start_frame = frame_id - - def re_activate(self, new_track, frame_id, new_id=False): - self.mean, self.covariance = self.kalman_filter.update( - self.mean, self.covariance, self.tlwh_to_xyah(new_track.tlwh) - ) - - self.update_features(new_track.curr_feat) - self.tracklet_len = 0 - self.state = TrackState.Tracked - self.is_activated = True - self.frame_id = frame_id - if new_id: - self.track_id = self.next_id() - self.pose = new_track.pose - self.detscore = new_track.detscore - self.crop_box = new_track.crop_box - self.file_name = new_track.file_name - - def update(self, new_track, frame_id, update_feature=True): - """ - Update a matched track - :type new_track: STrack - :type frame_id: int - :type update_feature: bool - :return: - """ - self.frame_id = frame_id - self.tracklet_len += 1 - self.pose = new_track.pose - self.detscore = new_track.detscore - self.crop_box = new_track.crop_box - self.file_name = new_track.file_name - new_tlwh = new_track.tlwh - self.mean, self.covariance = self.kalman_filter.update( - self.mean, self.covariance, self.tlwh_to_xyah(new_tlwh)) - self.state = TrackState.Tracked - self.is_activated = True - - self.score = new_track.score - if update_feature: - self.update_features(new_track.curr_feat) - - @property - #@jit(nopython=True) - def tlwh(self): - """Get current position in bounding box format `(top left x, top left y, - width, height)`. - """ - if self.mean is None: - return self._tlwh.copy() - ret = self.mean[:4].copy() - ret[2] *= ret[3] - ret[:2] -= ret[2:] / 2 - return ret - - @property - #@jit(nopython=True) - def tlbr(self): - """Convert bounding box to format `(min x, min y, max x, max y)`, i.e., - `(top left, bottom right)`. - """ - ret = self.tlwh.copy() - ret[2:] += ret[:2] - return ret - - @staticmethod - #@jit(nopython=True) - def tlwh_to_xyah(tlwh): - """Convert bounding box to format `(center x, center y, aspect ratio, - height)`, where the aspect ratio is `width / height`. - """ - ret = np.asarray(tlwh).copy() - ret[:2] += ret[2:] / 2 - ret[2] /= ret[3] - return ret - - def to_xyah(self): - return self.tlwh_to_xyah(self.tlwh) - - @staticmethod - #@jit(nopython=True) - def tlbr_to_tlwh(tlbr): - ret = np.asarray(tlbr).copy() - ret[2:] -= ret[:2] - return ret - - @staticmethod - #@jit(nopython=True) - def tlwh_to_tlbr(tlwh): - ret = np.asarray(tlwh).copy() - ret[2:] += ret[:2] - return ret - - def __repr__(self): - return 'OT_{}_({}-{})'.format(self.track_id, self.start_frame, self.end_frame) - - - -class Tracker(object): - def __init__(self, opt, args): - self.opt = opt - self.num_joints = 17 - self.frame_rate = opt.frame_rate - #m = ResModel(n_ID=opt.nid) - if self.opt.arch == "res50-fc512": - m = resnet50_fc512(num_classes=1,pretrained=False) - elif self.opt.arch == "osnet_ain": - m = osnet_ain_x1_0(num_classes=1,pretrained=False) - - self.model = nn.DataParallel(m,device_ids=args.gpus).to(args.device).eval() - - load_pretrained_weights(self.model,self.opt.loadmodel) - self.tracked_stracks = [] # type: list[STrack] - self.lost_stracks = [] # type: list[STrack] - self.removed_stracks = [] # type: list[STrack] - - self.frame_id = 0 - self.det_thresh = opt.conf_thres - self.buffer_size = int(self.frame_rate / 30.0 * opt.track_buffer) - self.max_time_lost = self.buffer_size - - self.kalman_filter = KalmanFilter() - - def update(self,img0,inps=None,bboxs=None,pose=None,cropped_boxes=None,file_name='',pscores=None,_debug = False): - #bboxs:[x1,y1.x2,y2] - self.frame_id += 1 - activated_starcks = [] - refind_stracks = [] - lost_stracks = [] - removed_stracks = [] - - ''' Step 1: Network forward, get human identity embedding''' - assert len(inps)==len(bboxs),'Unmatched Length Between Inps and Bboxs' - assert len(inps)==len(pose),'Unmatched Length Between Inps and Heatmaps' - with torch.no_grad(): - feats = self.model(inps).cpu().numpy() - bboxs = np.asarray(bboxs) - if len(bboxs)>0: - detections = [STrack(STrack.tlbr_to_tlwh(tlbrs[:]), 0.9, f,p,c,file_name,ps,30) for - (tlbrs, f,p,c,ps) in zip(bboxs, feats,pose,cropped_boxes,pscores)] - else: - detections = [] - ''' Add newly detected tracklets to tracked_stracks''' - unconfirmed = [] - tracked_stracks = [] # type: list[STrack] - for track in self.tracked_stracks: - if not track.is_activated: - unconfirmed.append(track) - else: - tracked_stracks.append(track) - strack_pool = joint_stracks(tracked_stracks, self.lost_stracks) - ###joint track with bbox-iou - strack_pool = joint_stracks(tracked_stracks, self.lost_stracks) - STrack.multi_predict(strack_pool) - dists_emb = embedding_distance(strack_pool, detections) - dists_emb = fuse_motion(self.kalman_filter, dists_emb, strack_pool, detections) - matches, u_track, u_detection = linear_assignment(dists_emb, thresh=0.7) - - for itracked, idet in matches: - track = strack_pool[itracked] - det = detections[idet] - if track.state == TrackState.Tracked: - track.update(det, self.frame_id) - activated_starcks.append(track) - else: - track.re_activate(det, self.frame_id, new_id=False) - refind_stracks.append(track) - - #Step 3: Second association, with IOU - detections = [detections[i] for i in u_detection] - r_tracked_stracks = [strack_pool[i] for i in u_track if strack_pool[i].state==TrackState.Tracked ] - dists_iou = iou_distance(r_tracked_stracks, detections) - matches, u_track, u_detection =linear_assignment(dists_iou, thresh=0.5) - - for itracked, idet in matches: - track = r_tracked_stracks[itracked] - det = detections[idet] - if track.state == TrackState.Tracked: - track.update(det, self.frame_id) - activated_starcks.append(track) - else: - track.re_activate(det, self.frame_id, new_id=False) - refind_stracks.append(track) - - for it in u_track: - track = r_tracked_stracks[it] - if not track.state == TrackState.Lost: - track.mark_lost() - lost_stracks.append(track) - '''Deal with unconfirmed tracks, usually tracks with only one beginning frame''' - detections = [detections[i] for i in u_detection] - dists = iou_distance(unconfirmed, detections) - matches, u_unconfirmed, u_detection = linear_assignment(dists, thresh=0.7) - for itracked, idet in matches: - unconfirmed[itracked].update(detections[idet], self.frame_id) - activated_starcks.append(unconfirmed[itracked]) - for it in u_unconfirmed: - track = unconfirmed[it] - track.mark_removed() - removed_stracks.append(track) - - """ Step 4: Init new stracks""" - for inew in u_detection: - track = detections[inew] - if track.score < self.det_thresh: - continue - track.activate(self.kalman_filter, self.frame_id) - activated_starcks.append(track) - - """ Step 5: Update state""" - for track in self.lost_stracks: - if self.frame_id - track.end_frame > self.max_time_lost: - track.mark_removed() - removed_stracks.append(track) - - self.tracked_stracks = [t for t in self.tracked_stracks if t.state == TrackState.Tracked] - self.tracked_stracks = joint_stracks(self.tracked_stracks, activated_starcks) - self.tracked_stracks = joint_stracks(self.tracked_stracks, refind_stracks) - self.lost_stracks = sub_stracks(self.lost_stracks, self.tracked_stracks) - self.lost_stracks.extend(lost_stracks) - self.lost_stracks = sub_stracks(self.lost_stracks, self.removed_stracks) - self.removed_stracks.extend(removed_stracks) - self.tracked_stracks, self.lost_stracks = remove_duplicate_stracks(self.tracked_stracks, self.lost_stracks) - - # get scores of lost tracks - output_stracks = [track for track in self.tracked_stracks] - if _debug: - logger.debug('===========Frame {}=========='.format(self.frame_id)) - logger.debug('Activated: {}'.format([track.track_id for track in activated_starcks])) - logger.debug('Refind: {}'.format([track.track_id for track in refind_stracks])) - logger.debug('Lost: {}'.format([track.track_id for track in lost_stracks])) - logger.debug('Removed: {}'.format([track.track_id for track in removed_stracks])) - return output_stracks - -def joint_stracks(tlista, tlistb): - exists = {} - res = [] - for t in tlista: - exists[t.track_id] = 1 - res.append(t) - for t in tlistb: - tid = t.track_id - if not exists.get(tid, 0): - exists[tid] = 1 - res.append(t) - return res - -def sub_stracks(tlista, tlistb): - stracks = {} - for t in tlista: - stracks[t.track_id] = t - for t in tlistb: - tid = t.track_id - if stracks.get(tid, 0): - del stracks[tid] - return list(stracks.values()) - -def remove_duplicate_stracks(stracksa, stracksb): - pdist = iou_distance(stracksa, stracksb) - pairs = np.where(pdist<0.15) - dupa, dupb = list(), list() - for p,q in zip(*pairs): - timep = stracksa[p].frame_id - stracksa[p].start_frame - timeq = stracksb[q].frame_id - stracksb[q].start_frame - if timep > timeq: - dupb.append(q) - else: - dupa.append(p) - resa = [t for i,t in enumerate(stracksa) if not i in dupa] - resb = [t for i,t in enumerate(stracksb) if not i in dupb] - return resa, resb - - diff --git a/cv/pose/alphapose/pytorch/trackers/tracker_cfg.py b/cv/pose/alphapose/pytorch/trackers/tracker_cfg.py deleted file mode 100755 index 9d6bfe525..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracker_cfg.py +++ /dev/null @@ -1,10 +0,0 @@ -from easydict import EasyDict as edict -cfg = edict() -cfg.nid = 1000 -cfg.arch = "osnet_ain" # "osnet" or "res50-fc512" -cfg.loadmodel = "trackers/weights/osnet_ain_x1_0_msmt17_256x128_amsgrad_ep50_lr0.0015_coslr_b64_fb10_softmax_labsmth_flip_jitter.pth" -cfg.frame_rate = 30 -cfg.track_buffer = 240 -cfg.conf_thres = 0.5 -cfg.nms_thres = 0.4 -cfg.iou_thres = 0.5 diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/README.md b/cv/pose/alphapose/pytorch/trackers/tracking/README.md deleted file mode 100755 index dca89ecdc..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracking/README.md +++ /dev/null @@ -1,2 +0,0 @@ -## Introduction -Track Association part adapted from [Towards-Realtime-MOT](https://github.com/Zhongdao/Towards-Realtime-MOT), many thanks to their wonderful work! diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/__init__.py b/cv/pose/alphapose/pytorch/trackers/tracking/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/basetrack.py b/cv/pose/alphapose/pytorch/trackers/tracking/basetrack.py deleted file mode 100755 index c702f13e5..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracking/basetrack.py +++ /dev/null @@ -1,53 +0,0 @@ -import numpy as np -from collections import OrderedDict - - -class TrackState(object): - New = 0 - Tracked = 1 - Lost = 2 - Removed = 3 - - -class BaseTrack(object): - _count = 0 - - track_id = 0 - is_activated = False - state = TrackState.New - - history = OrderedDict() - features = [] - curr_feature = None - score = 0 - start_frame = 0 - frame_id = 0 - time_since_update = 0 - - # multi-camera - location = (np.inf, np.inf) - - @property - def end_frame(self): - return self.frame_id - - @staticmethod - def next_id(): - BaseTrack._count += 1 - return BaseTrack._count - - def activate(self, *args): - raise NotImplementedError - - def predict(self): - raise NotImplementedError - - def update(self, *args, **kwargs): - raise NotImplementedError - - def mark_lost(self): - self.state = TrackState.Lost - - def mark_removed(self): - self.state = TrackState.Removed - diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/matching.py b/cv/pose/alphapose/pytorch/trackers/tracking/matching.py deleted file mode 100755 index 3da11d371..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracking/matching.py +++ /dev/null @@ -1,136 +0,0 @@ -import cv2 -import numpy as np -import scipy -from scipy.spatial.distance import cdist -from scipy.optimize import linear_sum_assignment - -from cython_bbox import bbox_overlaps as bbox_ious -from trackers.utils import kalman_filter -import time - -def merge_matches(m1, m2, shape): - O,P,Q = shape - m1 = np.asarray(m1) - m2 = np.asarray(m2) - - M1 = scipy.sparse.coo_matrix((np.ones(len(m1)), (m1[:, 0], m1[:, 1])), shape=(O, P)) - M2 = scipy.sparse.coo_matrix((np.ones(len(m2)), (m2[:, 0], m2[:, 1])), shape=(P, Q)) - - mask = M1*M2 - match = mask.nonzero() - match = list(zip(match[0], match[1])) - unmatched_O = tuple(set(range(O)) - set([i for i, j in match])) - unmatched_Q = tuple(set(range(Q)) - set([j for i, j in match])) - - return match, unmatched_O, unmatched_Q - - -def _indices_to_matches(cost_matrix, indices, thresh): - matched_cost = cost_matrix[tuple(zip(*indices))] - matched_mask = (matched_cost <= thresh) - - matches = indices[matched_mask] - unmatched_a = tuple(set(range(cost_matrix.shape[0])) - set(matches[:, 0])) - unmatched_b = tuple(set(range(cost_matrix.shape[1])) - set(matches[:, 1])) - - return matches, unmatched_a, unmatched_b - - -def linear_assignment(cost_matrix, thresh): - """ - Simple linear assignment - :type cost_matrix: np.ndarray - :type thresh: float - :return: matches, unmatched_a, unmatched_b - """ - if cost_matrix.size == 0: - return np.empty((0, 2), dtype=int), tuple(range(cost_matrix.shape[0])), tuple(range(cost_matrix.shape[1])) - - cost_matrix[cost_matrix > thresh] = thresh + 1e-4 - row_ind, col_ind = linear_sum_assignment(cost_matrix) - indices = np.column_stack((row_ind, col_ind)) - - return _indices_to_matches(cost_matrix, indices, thresh) - - -def ious(atlbrs, btlbrs): - """ - Compute cost based on IoU - :type atlbrs: list[tlbr] | np.ndarray - :type atlbrs: list[tlbr] | np.ndarray - - :rtype ious np.ndarray - """ - ious = np.zeros((len(atlbrs), len(btlbrs)), dtype=np.float) - if ious.size == 0: - return ious - - ious = bbox_ious( - np.ascontiguousarray(atlbrs, dtype=np.float), - np.ascontiguousarray(btlbrs, dtype=np.float) - ) - - return ious - - -def iou_distance(atracks, btracks): - """ - Compute cost based on IoU - :type atracks: list[STrack] - :type btracks: list[STrack] - - :rtype cost_matrix np.ndarray - """ - - if (len(atracks)>0 and isinstance(atracks[0], np.ndarray)) or (len(btracks) > 0 and isinstance(btracks[0], np.ndarray)): - atlbrs = atracks - btlbrs = btracks - else: - atlbrs = [track.tlbr for track in atracks] - btlbrs = [track.tlbr for track in btracks] - _ious = ious(atlbrs, btlbrs) - cost_matrix = 1 - _ious - - return cost_matrix - -def embedding_distance(tracks, detections, metric='cosine'): - """ - :param tracks: list[STrack] - :param detections: list[BaseTrack] - :param metric: - :return: cost_matrix np.ndarray - """ - - cost_matrix = np.zeros((len(tracks), len(detections)), dtype=np.float) - if cost_matrix.size == 0: - return cost_matrix - det_features = np.asarray([track.curr_feat for track in detections], dtype=np.float) - for i, track in enumerate(tracks): - cost_matrix[i, :] = np.maximum(0.0, cdist(track.smooth_feat.reshape(1,-1), det_features, metric)) - return cost_matrix - - -def gate_cost_matrix(kf, cost_matrix, tracks, detections, only_position=False): - if cost_matrix.size == 0: - return cost_matrix - gating_dim = 2 if only_position else 4 - gating_threshold = kalman_filter.chi2inv95[gating_dim] - measurements = np.asarray([det.to_xyah() for det in detections]) - for row, track in enumerate(tracks): - gating_distance = kf.gating_distance( - track.mean, track.covariance, measurements, only_position) - cost_matrix[row, gating_distance > gating_threshold] = np.inf - return cost_matrix - -def fuse_motion(kf, cost_matrix, tracks, detections, only_position=False, lambda_=0.98): - if cost_matrix.size == 0: - return cost_matrix - gating_dim = 2 if only_position else 4 - gating_threshold = kalman_filter.chi2inv95[gating_dim] - measurements = np.asarray([det.to_xyah() for det in detections]) - for row, track in enumerate(tracks): - gating_distance = kf.gating_distance( - track.mean, track.covariance, measurements, only_position, metric='maha') - cost_matrix[row, gating_distance > gating_threshold] = np.inf - cost_matrix[row] = lambda_ * cost_matrix[row] + (1-lambda_)* gating_distance - return cost_matrix diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/utils/__init__.py b/cv/pose/alphapose/pytorch/trackers/tracking/utils/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/utils/io.py b/cv/pose/alphapose/pytorch/trackers/tracking/utils/io.py deleted file mode 100755 index f70decdb2..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracking/utils/io.py +++ /dev/null @@ -1,112 +0,0 @@ -import os -from typing import Dict -import numpy as np - -from utils.log import logger - - -def write_results(filename, results_dict: Dict, data_type: str): - if not filename: - return - path = os.path.dirname(filename) - if not os.path.exists(path): - os.makedirs(path) - - if data_type in ('mot', 'mcmot', 'lab'): - save_format = '{frame},{id},{x1},{y1},{w},{h},1,-1,-1,-1\n' - elif data_type == 'kitti': - save_format = '{frame} {id} pedestrian -1 -1 -10 {x1} {y1} {x2} {y2} -1 -1 -1 -1000 -1000 -1000 -10 {score}\n' - else: - raise ValueError(data_type) - - with open(filename, 'w') as f: - for frame_id, frame_data in results_dict.items(): - if data_type == 'kitti': - frame_id -= 1 - for tlwh, track_id in frame_data: - if track_id < 0: - continue - x1, y1, w, h = tlwh - x2, y2 = x1 + w, y1 + h - line = save_format.format(frame=frame_id, id=track_id, x1=x1, y1=y1, x2=x2, y2=y2, w=w, h=h, score=1.0) - f.write(line) - logger.info('Save results to {}'.format(filename)) - - -def read_results(filename, data_type: str, is_gt=False, is_ignore=False): - if data_type in ('mot', 'lab'): - read_fun = read_mot_results - else: - raise ValueError('Unknown data type: {}'.format(data_type)) - - return read_fun(filename, is_gt, is_ignore) - - -""" -labels={'ped', ... % 1 -'person_on_vhcl', ... % 2 -'car', ... % 3 -'bicycle', ... % 4 -'mbike', ... % 5 -'non_mot_vhcl', ... % 6 -'static_person', ... % 7 -'distractor', ... % 8 -'occluder', ... % 9 -'occluder_on_grnd', ... %10 -'occluder_full', ... % 11 -'reflection', ... % 12 -'crowd' ... % 13 -}; -""" - - -def read_mot_results(filename, is_gt, is_ignore): - valid_labels = {1} - ignore_labels = {2, 7, 8, 12} - results_dict = dict() - if os.path.isfile(filename): - with open(filename, 'r') as f: - for line in f.readlines(): - linelist = line.split(',') - if len(linelist) < 7: - continue - fid = int(linelist[0]) - if fid < 1: - continue - results_dict.setdefault(fid, list()) - - if is_gt: - if 'MOT16-' in filename or 'MOT17-' in filename: - label = int(float(linelist[7])) - mark = int(float(linelist[6])) - if mark == 0 or label not in valid_labels: - continue - score = 1 - elif is_ignore: - if 'MOT16-' in filename or 'MOT17-' in filename: - label = int(float(linelist[7])) - vis_ratio = float(linelist[8]) - if label not in ignore_labels and vis_ratio >= 0: - continue - else: - continue - score = 1 - else: - score = float(linelist[6]) - - tlwh = tuple(map(float, linelist[2:6])) - target_id = int(linelist[1]) - - results_dict[fid].append((tlwh, target_id, score)) - - return results_dict - - -def unzip_objs(objs): - if len(objs) > 0: - tlwhs, ids, scores = zip(*objs) - else: - tlwhs, ids, scores = [], [], [] - tlwhs = np.asarray(tlwhs, dtype=float).reshape(-1, 4) - - return tlwhs, ids, scores \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/utils/kalman_filter.py b/cv/pose/alphapose/pytorch/trackers/tracking/utils/kalman_filter.py deleted file mode 100755 index 5b10e8d24..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracking/utils/kalman_filter.py +++ /dev/null @@ -1,229 +0,0 @@ -# vim: expandtab:ts=4:sw=4 -import numpy as np -import scipy.linalg - - -""" -Table for the 0.95 quantile of the chi-square distribution with N degrees of -freedom (contains values for N=1, ..., 9). Taken from MATLAB/Octave's chi2inv -function and used as Mahalanobis gating threshold. -""" -chi2inv95 = { - 1: 3.8415, - 2: 5.9915, - 3: 7.8147, - 4: 9.4877, - 5: 11.070, - 6: 12.592, - 7: 14.067, - 8: 15.507, - 9: 16.919} - - -class KalmanFilter(object): - """ - A simple Kalman filter for tracking bounding boxes in image space. - - The 8-dimensional state space - - x, y, a, h, vx, vy, va, vh - - contains the bounding box center position (x, y), aspect ratio a, height h, - and their respective velocities. - - Object motion follows a constant velocity model. The bounding box location - (x, y, a, h) is taken as direct observation of the state space (linear - observation model). - - """ - - def __init__(self): - ndim, dt = 4, 1. - - # Create Kalman filter model matrices. - self._motion_mat = np.eye(2 * ndim, 2 * ndim) - for i in range(ndim): - self._motion_mat[i, ndim + i] = dt - self._update_mat = np.eye(ndim, 2 * ndim) - - # Motion and observation uncertainty are chosen relative to the current - # state estimate. These weights control the amount of uncertainty in - # the model. This is a bit hacky. - self._std_weight_position = 1. / 20 - self._std_weight_velocity = 1. / 160 - - def initiate(self, measurement): - """Create track from unassociated measurement. - - Parameters - ---------- - measurement : ndarray - Bounding box coordinates (x, y, a, h) with center position (x, y), - aspect ratio a, and height h. - - Returns - ------- - (ndarray, ndarray) - Returns the mean vector (8 dimensional) and covariance matrix (8x8 - dimensional) of the new track. Unobserved velocities are initialized - to 0 mean. - - """ - mean_pos = measurement - mean_vel = np.zeros_like(mean_pos) - mean = np.r_[mean_pos, mean_vel] - - std = [ - 2 * self._std_weight_position * measurement[3], - 2 * self._std_weight_position * measurement[3], - 1e-2, - 2 * self._std_weight_position * measurement[3], - 10 * self._std_weight_velocity * measurement[3], - 10 * self._std_weight_velocity * measurement[3], - 1e-5, - 10 * self._std_weight_velocity * measurement[3]] - covariance = np.diag(np.square(std)) - return mean, covariance - - def predict(self, mean, covariance): - """Run Kalman filter prediction step. - - Parameters - ---------- - mean : ndarray - The 8 dimensional mean vector of the object state at the previous - time step. - covariance : ndarray - The 8x8 dimensional covariance matrix of the object state at the - previous time step. - - Returns - ------- - (ndarray, ndarray) - Returns the mean vector and covariance matrix of the predicted - state. Unobserved velocities are initialized to 0 mean. - - """ - std_pos = [ - self._std_weight_position * mean[3], - self._std_weight_position * mean[3], - 1e-2, - self._std_weight_position * mean[3]] - std_vel = [ - self._std_weight_velocity * mean[3], - self._std_weight_velocity * mean[3], - 1e-5, - self._std_weight_velocity * mean[3]] - motion_cov = np.diag(np.square(np.r_[std_pos, std_vel])) - - mean = np.dot(self._motion_mat, mean) - covariance = np.linalg.multi_dot(( - self._motion_mat, covariance, self._motion_mat.T)) + motion_cov - - return mean, covariance - - def project(self, mean, covariance): - """Project state distribution to measurement space. - - Parameters - ---------- - mean : ndarray - The state's mean vector (8 dimensional array). - covariance : ndarray - The state's covariance matrix (8x8 dimensional). - - Returns - ------- - (ndarray, ndarray) - Returns the projected mean and covariance matrix of the given state - estimate. - - """ - std = [ - self._std_weight_position * mean[3], - self._std_weight_position * mean[3], - 1e-1, - self._std_weight_position * mean[3]] - innovation_cov = np.diag(np.square(std)) - - mean = np.dot(self._update_mat, mean) - covariance = np.linalg.multi_dot(( - self._update_mat, covariance, self._update_mat.T)) - return mean, covariance + innovation_cov - - def update(self, mean, covariance, measurement): - """Run Kalman filter correction step. - - Parameters - ---------- - mean : ndarray - The predicted state's mean vector (8 dimensional). - covariance : ndarray - The state's covariance matrix (8x8 dimensional). - measurement : ndarray - The 4 dimensional measurement vector (x, y, a, h), where (x, y) - is the center position, a the aspect ratio, and h the height of the - bounding box. - - Returns - ------- - (ndarray, ndarray) - Returns the measurement-corrected state distribution. - - """ - projected_mean, projected_cov = self.project(mean, covariance) - - chol_factor, lower = scipy.linalg.cho_factor( - projected_cov, lower=True, check_finite=False) - kalman_gain = scipy.linalg.cho_solve( - (chol_factor, lower), np.dot(covariance, self._update_mat.T).T, - check_finite=False).T - innovation = measurement - projected_mean - - new_mean = mean + np.dot(innovation, kalman_gain.T) - new_covariance = covariance - np.linalg.multi_dot(( - kalman_gain, projected_cov, kalman_gain.T)) - return new_mean, new_covariance - - def gating_distance(self, mean, covariance, measurements, - only_position=False): - """Compute gating distance between state distribution and measurements. - - A suitable distance threshold can be obtained from `chi2inv95`. If - `only_position` is False, the chi-square distribution has 4 degrees of - freedom, otherwise 2. - - Parameters - ---------- - mean : ndarray - Mean vector over the state distribution (8 dimensional). - covariance : ndarray - Covariance of the state distribution (8x8 dimensional). - measurements : ndarray - An Nx4 dimensional matrix of N measurements, each in - format (x, y, a, h) where (x, y) is the bounding box center - position, a the aspect ratio, and h the height. - only_position : Optional[bool] - If True, distance computation is done with respect to the bounding - box center position only. - - Returns - ------- - ndarray - Returns an array of length N, where the i-th element contains the - squared Mahalanobis distance between (mean, covariance) and - `measurements[i]`. - - """ - mean, covariance = self.project(mean, covariance) - if only_position: - mean, covariance = mean[:2], covariance[:2, :2] - measurements = measurements[:, :2] - - cholesky_factor = np.linalg.cholesky(covariance) - d = measurements - mean - z = scipy.linalg.solve_triangular( - cholesky_factor, d.T, lower=True, check_finite=False, - overwrite_b=True) - squared_maha = np.sum(z * z, axis=0) - return squared_maha \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/utils/nms.py b/cv/pose/alphapose/pytorch/trackers/tracking/utils/nms.py deleted file mode 100755 index 81a0e893c..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracking/utils/nms.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -# from ._utils import _C -from utils import _C - -nms = _C.nms -# nms.__doc__ = """ -# This function performs Non-maximum suppresion""" diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/utils/parse_config.py b/cv/pose/alphapose/pytorch/trackers/tracking/utils/parse_config.py deleted file mode 100755 index ec267fabd..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracking/utils/parse_config.py +++ /dev/null @@ -1,37 +0,0 @@ -def parse_model_cfg(path): - """Parses the yolo-v3 layer configuration file and returns module definitions""" - file = open(path, 'r') - lines = file.read().split('\n') - lines = [x for x in lines if x and not x.startswith('#')] - lines = [x.rstrip().lstrip() for x in lines] # get rid of fringe whitespaces - module_defs = [] - for line in lines: - if line.startswith('['): # This marks the start of a new block - module_defs.append({}) - module_defs[-1]['type'] = line[1:-1].rstrip() - if module_defs[-1]['type'] == 'convolutional': - module_defs[-1]['batch_normalize'] = 0 - else: - key, value = line.split("=") - value = value.strip() - if value[0] == '$': - value = module_defs[0].get(value.strip('$'), None) - module_defs[-1][key.rstrip()] = value.strip() - - return module_defs - - -def parse_data_cfg(path): - """Parses the data configuration file""" - options = dict() - options['gpus'] = '0' - options['num_workers'] = '10' - with open(path, 'r') as fp: - lines = fp.readlines() - for line in lines: - line = line.strip() - if line == '' or line.startswith('#'): - continue - key, value = line.split('=') - options[key.strip()] = value.strip() - return options diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/utils/timer.py b/cv/pose/alphapose/pytorch/trackers/tracking/utils/timer.py deleted file mode 100755 index e79f1a310..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracking/utils/timer.py +++ /dev/null @@ -1,45 +0,0 @@ -# -------------------------------------------------------- -# Fast R-CNN -# Copyright (c) 2015 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ross Girshick -# -------------------------------------------------------- - -import time - - -class Timer(object): - """A simple timer.""" - def __init__(self): - self.total_time = 0. - self.calls = 0 - self.start_time = 0. - self.diff = 0. - self.average_time = 0. - - self.duration = 0. - - def tic(self): - # using time.time instead of time.clock because time time.clock - # does not normalize for multithreading - self.start_time = time.time() - - def toc(self, average=True): - self.diff = time.time() - self.start_time - self.total_time += self.diff - self.calls += 1 - self.average_time = self.total_time / self.calls - if average: - self.duration = self.average_time - else: - self.duration = self.diff - return self.duration - - def clear(self): - self.total_time = 0. - self.calls = 0 - self.start_time = 0. - self.diff = 0. - self.average_time = 0. - self.duration = 0. - diff --git a/cv/pose/alphapose/pytorch/trackers/tracking/utils/utils.py b/cv/pose/alphapose/pytorch/trackers/tracking/utils/utils.py deleted file mode 100755 index 5e73f7809..000000000 --- a/cv/pose/alphapose/pytorch/trackers/tracking/utils/utils.py +++ /dev/null @@ -1,510 +0,0 @@ -import glob -import random -import time -import os -import os.path as osp - -import cv2 -import matplotlib.pyplot as plt -import numpy as np -import torch -import torch.nn.functional as F - -import platform -if platform.system() != 'Windows': - from detector.nms import nms_wrapper - -# Set printoptions -torch.set_printoptions(linewidth=1320, precision=5, profile='long') -np.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format}) # format short g, %precision=5 - -def mkdir_if_missing(d): - if not osp.exists(d): - os.makedirs(d) - - -def float3(x): # format floats to 3 decimals - return float(format(x, '.3f')) - - -def init_seeds(seed=0): - random.seed(seed) - np.random.seed(seed) - torch.manual_seed(seed) - torch.cuda.manual_seed(seed) - torch.cuda.manual_seed_all(seed) - - -def load_classes(path): - """ - Loads class labels at 'path' - """ - fp = open(path, 'r') - names = fp.read().split('\n') - return list(filter(None, names)) # filter removes empty strings (such as last line) - - -def model_info(model): # Plots a line-by-line description of a PyTorch model - n_p = sum(x.numel() for x in model.parameters()) # number parameters - n_g = sum(x.numel() for x in model.parameters() if x.requires_grad) # number gradients - print('\n%5s %50s %9s %12s %20s %12s %12s' % ('layer', 'name', 'gradient', 'parameters', 'shape', 'mu', 'sigma')) - for i, (name, p) in enumerate(model.named_parameters()): - name = name.replace('module_list.', '') - print('%5g %50s %9s %12g %20s %12.3g %12.3g' % ( - i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std())) - print('Model Summary: %g layers, %g parameters, %g gradients\n' % (i + 1, n_p, n_g)) - - - -def plot_one_box(x, img, color=None, label=None, line_thickness=None): # Plots one bounding box on image img - tl = line_thickness or round(0.0004 * max(img.shape[0:2])) + 1 # line thickness - color = color or [random.randint(0, 255) for _ in range(3)] - c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3])) - cv2.rectangle(img, c1, c2, color, thickness=tl) - if label: - tf = max(tl - 1, 1) # font thickness - t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0] - c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3 - cv2.rectangle(img, c1, c2, color, -1) # filled - cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA) - - -def weights_init_normal(m): - classname = m.__class__.__name__ - if classname.find('Conv') != -1: - torch.nn.init.normal_(m.weight.data, 0.0, 0.03) - elif classname.find('BatchNorm2d') != -1: - torch.nn.init.normal_(m.weight.data, 1.0, 0.03) - torch.nn.init.constant_(m.bias.data, 0.0) - - -def xyxy2xywh(x): - # Convert bounding box format from [x1, y1, x2, y2] to [x, y, w, h] - y = torch.zeros(x.shape) if x.dtype is torch.float32 else np.zeros(x.shape) - y[:, 0] = (x[:, 0] + x[:, 2]) / 2 - y[:, 1] = (x[:, 1] + x[:, 3]) / 2 - y[:, 2] = x[:, 2] - x[:, 0] - y[:, 3] = x[:, 3] - x[:, 1] - return y - - -def xywh2xyxy(x): - # Convert bounding box format from [x, y, w, h] to [x1, y1, x2, y2] - y = torch.zeros(x.shape) if x.dtype is torch.float32 else np.zeros(x.shape) - y[:, 0] = (x[:, 0] - x[:, 2] / 2) - y[:, 1] = (x[:, 1] - x[:, 3] / 2) - y[:, 2] = (x[:, 0] + x[:, 2] / 2) - y[:, 3] = (x[:, 1] + x[:, 3] / 2) - return y - - -def scale_coords(img_size, coords, img0_shape): - # Rescale x1, y1, x2, y2 from 416 to image size - coords = coords.cpu().clone() - gain_w = float(img_size[0]) / img0_shape[0] # gain = old / new - gain_h = float(img_size[1]) / img0_shape[1] - gain = min(gain_w, gain_h) - pad_x = (img_size[0] - img0_shape[0] * gain) / 2 # width padding - pad_y = (img_size[1] - img0_shape[1] * gain) / 2 # height padding - coords[:, [0, 2]] -= pad_x - coords[:, [1, 3]] -= pad_y - coords[:, 0:4] /= gain - coords[:, :4] = torch.clamp(coords[:, :4], min=0) - return coords - - -def ap_per_class(tp, conf, pred_cls, target_cls): - """ Compute the average precision, given the recall and precision curves. - Method originally from https://github.com/rafaelpadilla/Object-Detection-Metrics. - # Arguments - tp: True positives (list). - conf: Objectness value from 0-1 (list). - pred_cls: Predicted object classes (list). - target_cls: True object classes (list). - # Returns - The average precision as computed in py-faster-rcnn. - """ - - # lists/pytorch to numpy - tp, conf, pred_cls, target_cls = np.array(tp), np.array(conf), np.array(pred_cls), np.array(target_cls) - - # Sort by objectness - i = np.argsort(-conf) - tp, conf, pred_cls = tp[i], conf[i], pred_cls[i] - - # Find unique classes - unique_classes = np.unique(np.concatenate((pred_cls, target_cls), 0)) - - # Create Precision-Recall curve and compute AP for each class - ap, p, r = [], [], [] - for c in unique_classes: - i = pred_cls == c - n_gt = sum(target_cls == c) # Number of ground truth objects - n_p = sum(i) # Number of predicted objects - - if (n_p == 0) and (n_gt == 0): - continue - elif (n_p == 0) or (n_gt == 0): - ap.append(0) - r.append(0) - p.append(0) - else: - # Accumulate FPs and TPs - fpc = np.cumsum(1 - tp[i]) - tpc = np.cumsum(tp[i]) - - # Recall - recall_curve = tpc / (n_gt + 1e-16) - r.append(tpc[-1] / (n_gt + 1e-16)) - - # Precision - precision_curve = tpc / (tpc + fpc) - p.append(tpc[-1] / (tpc[-1] + fpc[-1])) - - # AP from recall-precision curve - ap.append(compute_ap(recall_curve, precision_curve)) - - return np.array(ap), unique_classes.astype('int32'), np.array(r), np.array(p) - - -def compute_ap(recall, precision): - """ Compute the average precision, given the recall and precision curves. - Code originally from https://github.com/rbgirshick/py-faster-rcnn. - # Arguments - recall: The recall curve (list). - precision: The precision curve (list). - # Returns - The average precision as computed in py-faster-rcnn. - """ - # correct AP calculation - # first append sentinel values at the end - - mrec = np.concatenate(([0.], recall, [1.])) - mpre = np.concatenate(([0.], precision, [0.])) - - # compute the precision envelope - for i in range(mpre.size - 1, 0, -1): - mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i]) - - # to calculate area under PR curve, look for points - # where X axis (recall) changes value - i = np.where(mrec[1:] != mrec[:-1])[0] - - # and sum (\Delta recall) * prec - ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) - return ap - - -def bbox_iou(box1, box2, x1y1x2y2=False): - """ - Returns the IoU of two bounding boxes - """ - N, M = len(box1), len(box2) - if x1y1x2y2: - # Get the coordinates of bounding boxes - b1_x1, b1_y1, b1_x2, b1_y2 = box1[:, 0], box1[:, 1], box1[:, 2], box1[:, 3] - b2_x1, b2_y1, b2_x2, b2_y2 = box2[:, 0], box2[:, 1], box2[:, 2], box2[:, 3] - else: - # Transform from center and width to exact coordinates - b1_x1, b1_x2 = box1[:, 0] - box1[:, 2] / 2, box1[:, 0] + box1[:, 2] / 2 - b1_y1, b1_y2 = box1[:, 1] - box1[:, 3] / 2, box1[:, 1] + box1[:, 3] / 2 - b2_x1, b2_x2 = box2[:, 0] - box2[:, 2] / 2, box2[:, 0] + box2[:, 2] / 2 - b2_y1, b2_y2 = box2[:, 1] - box2[:, 3] / 2, box2[:, 1] + box2[:, 3] / 2 - - # get the coordinates of the intersection rectangle - inter_rect_x1 = torch.max(b1_x1.unsqueeze(1), b2_x1) - inter_rect_y1 = torch.max(b1_y1.unsqueeze(1), b2_y1) - inter_rect_x2 = torch.min(b1_x2.unsqueeze(1), b2_x2) - inter_rect_y2 = torch.min(b1_y2.unsqueeze(1), b2_y2) - # Intersection area - inter_area = torch.clamp(inter_rect_x2 - inter_rect_x1, 0) * torch.clamp(inter_rect_y2 - inter_rect_y1, 0) - # Union Area - b1_area = ((b1_x2 - b1_x1) * (b1_y2 - b1_y1)) - b1_area = ((b1_x2 - b1_x1) * (b1_y2 - b1_y1)).view(-1,1).expand(N,M) - b2_area = ((b2_x2 - b2_x1) * (b2_y2 - b2_y1)).view(1,-1).expand(N,M) - - return inter_area / (b1_area + b2_area - inter_area + 1e-16) - - -def build_targets_max(target, anchor_wh, nA, nC, nGh, nGw): - """ - returns nT, nCorrect, tx, ty, tw, th, tconf, tcls - """ - nB = len(target) # number of images in batch - - txy = torch.zeros(nB, nA, nGh, nGw, 2).cuda() # batch size, anchors, grid size - twh = torch.zeros(nB, nA, nGh, nGw, 2).cuda() - tconf = torch.LongTensor(nB, nA, nGh, nGw).fill_(0).cuda() - tcls = torch.ByteTensor(nB, nA, nGh, nGw, nC).fill_(0).cuda() # nC = number of classes - tid = torch.LongTensor(nB, nA, nGh, nGw, 1).fill_(-1).cuda() - for b in range(nB): - t = target[b] - t_id = t[:, 1].clone().long().cuda() - t = t[:,[0,2,3,4,5]] - nTb = len(t) # number of targets - if nTb == 0: - continue - - #gxy, gwh = t[:, 1:3] * nG, t[:, 3:5] * nG - gxy, gwh = t[: , 1:3].clone() , t[:, 3:5].clone() - gxy[:, 0] = gxy[:, 0] * nGw - gxy[:, 1] = gxy[:, 1] * nGh - gwh[:, 0] = gwh[:, 0] * nGw - gwh[:, 1] = gwh[:, 1] * nGh - gi = torch.clamp(gxy[:, 0], min=0, max=nGw -1).long() - gj = torch.clamp(gxy[:, 1], min=0, max=nGh -1).long() - - # Get grid box indices and prevent overflows (i.e. 13.01 on 13 anchors) - #gi, gj = torch.clamp(gxy.long(), min=0, max=nG - 1).t() - #gi, gj = gxy.long().t() - - # iou of targets-anchors (using wh only) - box1 = gwh - box2 = anchor_wh.unsqueeze(1) - inter_area = torch.min(box1, box2).prod(2) - iou = inter_area / (box1.prod(1) + box2.prod(2) - inter_area + 1e-16) - - # Select best iou_pred and anchor - iou_best, a = iou.max(0) # best anchor [0-2] for each target - - # Select best unique target-anchor combinations - if nTb > 1: - _, iou_order = torch.sort(-iou_best) # best to worst - - # Unique anchor selection - u = torch.stack((gi, gj, a), 0)[:, iou_order] - # _, first_unique = np.unique(u, axis=1, return_index=True) # first unique indices - first_unique = return_torch_unique_index(u, torch.unique(u, dim=1)) # torch alternative - i = iou_order[first_unique] - # best anchor must share significant commonality (iou) with target - i = i[iou_best[i] > 0.60] # TODO: examine arbitrary threshold - if len(i) == 0: - continue - - a, gj, gi, t = a[i], gj[i], gi[i], t[i] - t_id = t_id[i] - if len(t.shape) == 1: - t = t.view(1, 5) - else: - if iou_best < 0.60: - continue - - tc, gxy, gwh = t[:, 0].long(), t[:, 1:3].clone(), t[:, 3:5].clone() - gxy[:, 0] = gxy[:, 0] * nGw - gxy[:, 1] = gxy[:, 1] * nGh - gwh[:, 0] = gwh[:, 0] * nGw - gwh[:, 1] = gwh[:, 1] * nGh - - # XY coordinates - txy[b, a, gj, gi] = gxy - gxy.floor() - - # Width and height - twh[b, a, gj, gi] = torch.log(gwh / anchor_wh[a]) # yolo method - # twh[b, a, gj, gi] = torch.sqrt(gwh / anchor_wh[a]) / 2 # power method - - # One-hot encoding of label - tcls[b, a, gj, gi, tc] = 1 - tconf[b, a, gj, gi] = 1 - tid[b, a, gj, gi] = t_id.unsqueeze(1) - tbox = torch.cat([txy, twh], -1) - return tconf, tbox, tid - - - -def build_targets_thres(target, anchor_wh, nA, nC, nGh, nGw): - ID_THRESH = 0.5 - FG_THRESH = 0.5 - BG_THRESH = 0.4 - nB = len(target) # number of images in batch - assert(len(anchor_wh)==nA) - - tbox = torch.zeros(nB, nA, nGh, nGw, 4).cuda() # batch size, anchors, grid size - tconf = torch.LongTensor(nB, nA, nGh, nGw).fill_(0).cuda() - tid = torch.LongTensor(nB, nA, nGh, nGw, 1).fill_(-1).cuda() - for b in range(nB): - t = target[b] - t_id = t[:, 1].clone().long().cuda() - t = t[:,[0,2,3,4,5]] - nTb = len(t) # number of targets - if nTb == 0: - continue - - gxy, gwh = t[: , 1:3].clone() , t[:, 3:5].clone() - gxy[:, 0] = gxy[:, 0] * nGw - gxy[:, 1] = gxy[:, 1] * nGh - gwh[:, 0] = gwh[:, 0] * nGw - gwh[:, 1] = gwh[:, 1] * nGh - gxy[:, 0] = torch.clamp(gxy[:, 0], min=0, max=nGw -1) - gxy[:, 1] = torch.clamp(gxy[:, 1], min=0, max=nGh -1) - - gt_boxes = torch.cat([gxy, gwh], dim=1) # Shape Ngx4 (xc, yc, w, h) - - anchor_mesh = generate_anchor(nGh, nGw, anchor_wh) - anchor_list = anchor_mesh.permute(0,2,3,1).contiguous().view(-1, 4) # Shpae (nA x nGh x nGw) x 4 - #print(anchor_list.shape, gt_boxes.shape) - iou_pdist = bbox_iou(anchor_list, gt_boxes) # Shape (nA x nGh x nGw) x Ng - iou_max, max_gt_index = torch.max(iou_pdist, dim=1) # Shape (nA x nGh x nGw), both - - iou_map = iou_max.view(nA, nGh, nGw) - gt_index_map = max_gt_index.view(nA, nGh, nGw) - - #nms_map = pooling_nms(iou_map, 3) - - id_index = iou_map > ID_THRESH - fg_index = iou_map > FG_THRESH - bg_index = iou_map < BG_THRESH - ign_index = (iou_map < FG_THRESH) * (iou_map > BG_THRESH) - tconf[b][fg_index] = 1 - tconf[b][bg_index] = 0 - tconf[b][ign_index] = -1 - - gt_index = gt_index_map[fg_index] - gt_box_list = gt_boxes[gt_index] - gt_id_list = t_id[gt_index_map[id_index]] - #print(gt_index.shape, gt_index_map[id_index].shape, gt_boxes.shape) - if torch.sum(fg_index) > 0: - tid[b][id_index] = gt_id_list.unsqueeze(1) - fg_anchor_list = anchor_list.view(nA, nGh, nGw, 4)[fg_index] - delta_target = encode_delta(gt_box_list, fg_anchor_list) - tbox[b][fg_index] = delta_target - return tconf, tbox, tid - -def generate_anchor(nGh, nGw, anchor_wh): - nA = len(anchor_wh) - yy, xx =torch.meshgrid(torch.arange(nGh), torch.arange(nGw)) - - mesh = torch.stack([xx, yy], dim=0).to(anchor_wh) # Shape 2, nGh, nGw - mesh = mesh.unsqueeze(0).repeat(nA,1,1,1).float() # Shape nA x 2 x nGh x nGw - anchor_offset_mesh = anchor_wh.unsqueeze(-1).unsqueeze(-1).repeat(1, 1, nGh,nGw) # Shape nA x 2 x nGh x nGw - anchor_mesh = torch.cat([mesh, anchor_offset_mesh], dim=1) # Shape nA x 4 x nGh x nGw - return anchor_mesh - -def encode_delta(gt_box_list, fg_anchor_list): - px, py, pw, ph = fg_anchor_list[:, 0], fg_anchor_list[:,1], \ - fg_anchor_list[:, 2], fg_anchor_list[:,3] - gx, gy, gw, gh = gt_box_list[:, 0], gt_box_list[:, 1], \ - gt_box_list[:, 2], gt_box_list[:, 3] - dx = (gx - px) / pw - dy = (gy - py) / ph - dw = torch.log(gw/pw) - dh = torch.log(gh/ph) - return torch.stack([dx, dy, dw, dh], dim=1) - -def decode_delta(delta, fg_anchor_list): - px, py, pw, ph = fg_anchor_list[:, 0], fg_anchor_list[:,1], \ - fg_anchor_list[:, 2], fg_anchor_list[:,3] - dx, dy, dw, dh = delta[:, 0], delta[:, 1], delta[:, 2], delta[:, 3] - gx = pw * dx + px - gy = ph * dy + py - gw = pw * torch.exp(dw) - gh = ph * torch.exp(dh) - return torch.stack([gx, gy, gw, gh], dim=1) - -def decode_delta_map(delta_map, anchors): - ''' - :param: delta_map, shape (nB, nA, nGh, nGw, 4) - :param: anchors, shape (nA,4) - ''' - nB, nA, nGh, nGw, _ = delta_map.shape - anchor_mesh = generate_anchor(nGh, nGw, anchors) - anchor_mesh = anchor_mesh.permute(0,2,3,1).contiguous() # Shpae (nA x nGh x nGw) x 4 - anchor_mesh = anchor_mesh.unsqueeze(0).repeat(nB,1,1,1,1) - pred_list = decode_delta(delta_map.view(-1,4), anchor_mesh.view(-1,4)) - pred_map = pred_list.view(nB, nA, nGh, nGw, 4) - return pred_map - - -def pooling_nms(heatmap, kernel=1): - pad = (kernel -1 ) // 2 - hmax = F.max_pool2d(heatmap, (kernel, kernel), stride=1, padding=pad) - keep = (hmax == heatmap).float() - return keep * heatmap - -def soft_nms(dets, sigma=0.5, Nt=0.3, threshold=0.05, method=1): - keep = cpu_soft_nms(np.ascontiguousarray(dets, dtype=np.float32), - np.float32(sigma), np.float32(Nt), - np.float32(threshold), - np.uint8(method)) - return keep - -def non_max_suppression(prediction, conf_thres=0.5, nms_thres=0.4, method=-1): - """ - Removes detections with lower object confidence score than 'conf_thres' - Non-Maximum Suppression to further filter detections. - Returns detections with shape: - (x1, y1, x2, y2, object_conf, class_score, class_pred) - """ - - output = [None for _ in range(len(prediction))] - for image_i, pred in enumerate(prediction): - # Filter out confidence scores below threshold - # Get score and class with highest confidence - - v = pred[:, 4] > conf_thres - v = v.nonzero().squeeze() - if len(v.shape) == 0: - v = v.unsqueeze(0) - - pred = pred[v] - - # If none are remaining => process next image - nP = pred.shape[0] - if not nP: - continue - # From (center x, center y, width, height) to (x1, y1, x2, y2) - pred[:, :4] = xywh2xyxy(pred[:, :4]) - - - # Non-maximum suppression - if method == -1 and platform.system() != 'Windows': - #We use faster rcnn implementation of nms (soft nms is optional) - nms_op = getattr(nms_wrapper, 'nms') - #nms_op input:(n,(x1,y1,x2,y2,c)) - #nms_op output: input[inds,:], inds - _, nms_indices = nms_op(pred[:,:5], nms_thres) - - else: - dets = pred[:, :5].clone().contiguous().data.cpu().numpy() - nms_indices = soft_nms(dets, Nt=nms_thres, method=method) - det_max = pred[nms_indices] - - if len(det_max) > 0: - # Add max detections to outputs - output[image_i] = det_max if output[image_i] is None else torch.cat((output[image_i], det_max)) - - return output - - -def return_torch_unique_index(u, uv): - n = uv.shape[1] # number of columns - first_unique = torch.zeros(n, device=u.device).long() - for j in range(n): - first_unique[j] = (uv[:, j:j + 1] == u).all(0).nonzero()[0] - - return first_unique - - -def strip_optimizer_from_checkpoint(filename='weights/best.pt'): - # Strip optimizer from *.pt files for lighter files (reduced by 2/3 size) - - a = torch.load(filename, map_location='cpu') - a['optimizer'] = [] - torch.save(a, filename.replace('.pt', '_lite.pt')) - - -def plot_results(): - # Plot YOLO training results file 'results.txt' - # import os; os.system('wget https://storage.googleapis.com/ultralytics/yolov3/results_v1.txt') - - plt.figure(figsize=(14, 7)) - s = ['X + Y', 'Width + Height', 'Confidence', 'Classification', 'Total Loss', 'mAP', 'Recall', 'Precision'] - files = sorted(glob.glob('results*.txt')) - for f in files: - results = np.loadtxt(f, usecols=[2, 3, 4, 5, 6, 9, 10, 11]).T # column 11 is mAP - x = range(1, results.shape[1]) - for i in range(8): - plt.subplot(2, 4, i + 1) - plt.plot(x, results[i, x], marker='.', label=f) - plt.title(s[i]) - if i == 0: - plt.legend() diff --git a/cv/pose/alphapose/pytorch/trackers/utils/basetransforms.py b/cv/pose/alphapose/pytorch/trackers/utils/basetransforms.py deleted file mode 100755 index f02589672..000000000 --- a/cv/pose/alphapose/pytorch/trackers/utils/basetransforms.py +++ /dev/null @@ -1,816 +0,0 @@ -# ----------------------------------------------------- -# Copyright (c) Shanghai Jiao Tong University. All rights reserved. -# Written by Jiefeng Li (jeff.lee.sjtu@gmail.com) -# ----------------------------------------------------- - -"""Pose related transforrmation functions.""" - -import random - -import cv2 -import numpy as np -import torch -from scipy.ndimage import maximum_filter - -from .bbox import transformBoxInvert - - -def rnd(x): - return max(-2 * x, min(2 * x, np.random.randn(1)[0] * x)) - - -def box_transform(bbox, sf, imgwidth, imght, train): - """Random scaling.""" - width = bbox[2] - bbox[0] - ht = bbox[3] - bbox[1] - if train: - scaleRate = 0.25 * np.clip(np.random.randn() * sf, - sf, sf) - - bbox[0] = max(0, bbox[0] - width * scaleRate / 2) - bbox[1] = max(0, bbox[1] - ht * scaleRate / 2) - bbox[2] = min(imgwidth, bbox[2] + width * scaleRate / 2) - bbox[3] = min(imght, bbox[3] + ht * scaleRate / 2) - else: - scaleRate = 0.25 - - bbox[0] = max(0, bbox[0] - width * scaleRate / 2) - bbox[1] = max(0, bbox[1] - ht * scaleRate / 2) - bbox[2] = min(imgwidth, max(bbox[2] + width * scaleRate / 2, bbox[0] + 5)) - bbox[3] = min(imght, max(bbox[3] + ht * scaleRate / 2, bbox[1] + 5)) - - return bbox - - -def addDPG(bbox, imgwidth, imght): - """Add dpg for data augmentation, including random crop and random sample.""" - PatchScale = random.uniform(0, 1) - width = bbox[2] - bbox[0] - ht = bbox[3] - bbox[1] - - if PatchScale > 0.85: - ratio = ht / width - if (width < ht): - patchWidth = PatchScale * width - patchHt = patchWidth * ratio - else: - patchHt = PatchScale * ht - patchWidth = patchHt / ratio - - xmin = bbox[0] + random.uniform(0, 1) * (width - patchWidth) - ymin = bbox[1] + random.uniform(0, 1) * (ht - patchHt) - xmax = xmin + patchWidth + 1 - ymax = ymin + patchHt + 1 - else: - xmin = max(1, min(bbox[0] + np.random.normal(-0.0142, 0.1158) * width, imgwidth - 3)) - ymin = max(1, min(bbox[1] + np.random.normal(0.0043, 0.068) * ht, imght - 3)) - xmax = min(max(xmin + 2, bbox[2] + np.random.normal(0.0154, 0.1337) * width), imgwidth - 3) - ymax = min(max(ymin + 2, bbox[3] + np.random.normal(-0.0013, 0.0711) * ht), imght - 3) - - bbox[0] = xmin - bbox[1] = ymin - bbox[2] = xmax - bbox[3] = ymax - - return bbox - - -def im_to_torch(img): - """Transform ndarray image to torch tensor. - - Parameters - ---------- - img: numpy.ndarray - An ndarray with shape: `(H, W, 3)`. - - Returns - ------- - torch.Tensor - A tensor with shape: `(3, H, W)`. - - """ - img = np.transpose(img, (2, 0, 1)) # C*H*W - img = to_torch(img).float() - if img.max() > 1: - img /= 255 - return img - - -def torch_to_im(img): - """Transform torch tensor to ndarray image. - - Parameters - ---------- - img: torch.Tensor - A tensor with shape: `(3, H, W)`. - - Returns - ------- - numpy.ndarray - An ndarray with shape: `(H, W, 3)`. - - """ - img = to_numpy(img) - img = np.transpose(img, (1, 2, 0)) # C*H*W - return img - - -def load_image(img_path): - # H x W x C => C x H x W - return im_to_torch(cv2.cvtColor(cv2.imread(img_path), cv2.COLOR_BGR2RGB))#scipy.misc.imread(img_path, mode='RGB')) - - -def to_numpy(tensor): - # torch.Tensor => numpy.ndarray - if torch.is_tensor(tensor): - return tensor.cpu().numpy() - elif type(tensor).__module__ != 'numpy': - raise ValueError("Cannot convert {} to numpy array" - .format(type(tensor))) - return tensor - - -def to_torch(ndarray): - # numpy.ndarray => torch.Tensor - if type(ndarray).__module__ == 'numpy': - return torch.from_numpy(ndarray) - elif not torch.is_tensor(ndarray): - raise ValueError("Cannot convert {} to torch tensor" - .format(type(ndarray))) - return ndarray - - -def cv_cropBox(img, bbox, input_size): - """Crop bbox from image by Affinetransform. - - Parameters - ---------- - img: torch.Tensor - A tensor with shape: `(3, H, W)`. - bbox: list or tuple - [xmin, ymin, xmax, ymax]. - input_size: tuple - Resulting image size, as (height, width). - - Returns - ------- - torch.Tensor - A tensor with shape: `(3, height, width)`. - - """ - xmin, ymin, xmax, ymax = bbox - xmax -= 1 - ymax -= 1 - resH, resW = input_size - - lenH = max((ymax - ymin), (xmax - xmin) * resH / resW) - lenW = lenH * resW / resH - if img.dim() == 2: - img = img[np.newaxis, :, :] - - box_shape = [ymax - ymin, xmax - xmin] - pad_size = [(lenH - box_shape[0]) // 2, (lenW - box_shape[1]) // 2] - # Padding Zeros - img[:, :ymin, :], img[:, :, :xmin] = 0, 0 - img[:, ymax + 1:, :], img[:, :, xmax + 1:] = 0, 0 - - src = np.zeros((3, 2), dtype=np.float32) - dst = np.zeros((3, 2), dtype=np.float32) - - src[0, :] = np.array([xmin - pad_size[1], ymin - pad_size[0]], np.float32) - src[1, :] = np.array([xmax + pad_size[1], ymax + pad_size[0]], np.float32) - dst[0, :] = 0 - dst[1, :] = np.array([resW - 1, resH - 1], np.float32) - - src[2:, :] = get_3rd_point(src[0, :], src[1, :]) - dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :]) - - trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) - dst_img = cv2.warpAffine(torch_to_im(img), trans, - (resW, resH), flags=cv2.INTER_LINEAR) - if dst_img.ndim == 2: - dst_img = dst_img[:, :, np.newaxis] - - return im_to_torch(torch.Tensor(dst_img)) - - -def cv_cropBox_rot(img, bbox, input_size, rot): - """Crop bbox from image by Affinetransform. - - Parameters - ---------- - img: torch.Tensor - A tensor with shape: `(3, H, W)`. - bbox: list or tuple - [xmin, ymin, xmax, ymax]. - input_size: tuple - Resulting image size, as (height, width). - - Returns - ------- - torch.Tensor - A tensor with shape: `(3, height, width)`. - - """ - xmin, ymin, xmax, ymax = bbox - xmax -= 1 - ymax -= 1 - resH, resW = input_size - rot_rad = np.pi * rot / 180 - - if img.dim() == 2: - img = img[np.newaxis, :, :] - - src = np.zeros((3, 2), dtype=np.float32) - dst = np.zeros((3, 2), dtype=np.float32) - center = np.array([(xmax + xmin) / 2, (ymax + ymin) / 2]) - - src_dir = get_dir([0, (ymax - ymin) * -0.5], rot_rad) - dst_dir = np.array([0, (resH - 1) * -0.5], np.float32) - - src = np.zeros((3, 2), dtype=np.float32) - dst = np.zeros((3, 2), dtype=np.float32) - - src[0, :] = center - src[1, :] = center + src_dir - dst[0, :] = [(resW - 1) * 0.5, (resH - 1) * 0.5] - dst[1, :] = np.array([(resW - 1) * 0.5, (resH - 1) * 0.5]) + dst_dir - - src[2:, :] = get_3rd_point(src[0, :], src[1, :]) - dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :]) - - trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) - dst_img = cv2.warpAffine(torch_to_im(img), trans, - (resW, resH), flags=cv2.INTER_LINEAR) - if dst_img.ndim == 2: - dst_img = dst_img[:, :, np.newaxis] - - return im_to_torch(torch.Tensor(dst_img)) - - -def fix_cropBox(img, bbox, input_size): - """Crop bbox from image by Affinetransform. - - Parameters - ---------- - img: torch.Tensor - A tensor with shape: `(3, H, W)`. - bbox: list or tuple - [xmin, ymin, xmax, ymax]. - input_size: tuple - Resulting image size, as (height, width). - - Returns - ------- - torch.Tensor - A tensor with shape: `(3, height, width)`. - - """ - xmin, ymin, xmax, ymax = bbox - input_ratio = input_size[0] / input_size[1] - bbox_ratio = (ymax - ymin) / (xmax - xmin) - if bbox_ratio > input_ratio: - # expand width - cx = (xmax + xmin) / 2 - h = ymax - ymin - w = h / input_ratio - xmin = cx - w / 2 - xmax = cx + w / 2 - elif bbox_ratio < input_ratio: - # expand height - cy = (ymax + ymin) / 2 - w = xmax - xmin - h = w * input_ratio - ymin = cy - h / 2 - ymax = cy + h / 2 - bbox = [int(x) for x in [xmin, ymin, xmax, ymax]] - - return cv_cropBox(img, bbox, input_size), bbox - - -def fix_cropBox_rot(img, bbox, input_size, rot): - """Crop bbox from image by Affinetransform. - - Parameters - ---------- - img: torch.Tensor - A tensor with shape: `(3, H, W)`. - bbox: list or tuple - [xmin, ymin, xmax, ymax]. - input_size: tuple - Resulting image size, as (height, width). - - Returns - ------- - torch.Tensor - A tensor with shape: `(3, height, width)`. - - """ - xmin, ymin, xmax, ymax = bbox - input_ratio = input_size[0] / input_size[1] - bbox_ratio = (ymax - ymin) / (xmax - xmin) - if bbox_ratio > input_ratio: - # expand width - cx = (xmax + xmin) / 2 - h = ymax - ymin - w = h / input_ratio - xmin = cx - w / 2 - xmax = cx + w / 2 - elif bbox_ratio < input_ratio: - # expand height - cy = (ymax + ymin) / 2 - w = xmax - xmin - h = w * input_ratio - ymin = cy - h / 2 - ymax = cy + h / 2 - bbox = [int(x) for x in [xmin, ymin, xmax, ymax]] - - return cv_cropBox_rot(img, bbox, input_size, rot), bbox - - -def get_3rd_point(a, b): - """Return vector c that perpendicular to (a - b).""" - direct = a - b - return b + np.array([-direct[1], direct[0]], dtype=np.float32) - - -def get_dir(src_point, rot_rad): - """Rotate the point by `rot_rad` degree.""" - sn, cs = np.sin(rot_rad), np.cos(rot_rad) - - src_result = [0, 0] - src_result[0] = src_point[0] * cs - src_point[1] * sn - src_result[1] = src_point[0] * sn + src_point[1] * cs - - return src_result - - -def cv_cropBoxInverse(inp, bbox, img_size, output_size): - """Paste the cropped bbox to the original image. - - Parameters - ---------- - inp: torch.Tensor - A tensor with shape: `(3, height, width)`. - bbox: list or tuple - [xmin, ymin, xmax, ymax]. - img_size: tuple - Original image size, as (img_H, img_W). - output_size: tuple - Cropped input size, as (height, width). - Returns - ------- - torch.Tensor - A tensor with shape: `(3, img_H, img_W)`. - - """ - xmin, ymin, xmax, ymax = bbox - xmax -= 1 - ymax -= 1 - resH, resW = output_size - imgH, imgW = img_size - - lenH = max((ymax - ymin), (xmax - xmin) * resH / resW) - lenW = lenH * resW / resH - if inp.dim() == 2: - inp = inp[np.newaxis, :, :] - - box_shape = [ymax - ymin, xmax - xmin] - pad_size = [(lenH - box_shape[0]) // 2, (lenW - box_shape[1]) // 2] - - src = np.zeros((3, 2), dtype=np.float32) - dst = np.zeros((3, 2), dtype=np.float32) - - src[0, :] = 0 - src[1, :] = np.array([resW - 1, resH - 1], np.float32) - dst[0, :] = np.array([xmin - pad_size[1], ymin - pad_size[0]], np.float32) - dst[1, :] = np.array([xmax + pad_size[1], ymax + pad_size[0]], np.float32) - - src[2:, :] = get_3rd_point(src[0, :], src[1, :]) - dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :]) - - trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) - dst_img = cv2.warpAffine(torch_to_im(inp), trans, - (imgW, imgH), flags=cv2.INTER_LINEAR) - if dst_img.ndim == 3 and dst_img.shape[2] == 1: - dst_img = dst_img[:, :, 0] - return dst_img - elif dst_img.ndim == 2: - return dst_img - else: - return im_to_torch(torch.Tensor(dst_img)) - - -def cv_rotate(img, rot, input_size): - """Rotate image by Affinetransform. - - Parameters - ---------- - img: torch.Tensor - A tensor with shape: `(3, H, W)`. - rot: int - Rotation degree. - input_size: tuple - Resulting image size, as (height, width). - - Returns - ------- - torch.Tensor - A tensor with shape: `(3, height, width)`. - - """ - resH, resW = input_size - center = np.array((resW - 1, resH - 1)) / 2 - rot_rad = np.pi * rot / 180 - - src_dir = get_dir([0, (resH - 1) * -0.5], rot_rad) - dst_dir = np.array([0, (resH - 1) * -0.5], np.float32) - - src = np.zeros((3, 2), dtype=np.float32) - dst = np.zeros((3, 2), dtype=np.float32) - - src[0, :] = center - src[1, :] = center + src_dir - dst[0, :] = [(resW - 1) * 0.5, (resH - 1) * 0.5] - dst[1, :] = np.array([(resW - 1) * 0.5, (resH - 1) * 0.5]) + dst_dir - - src[2:, :] = get_3rd_point(src[0, :], src[1, :]) - dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :]) - - trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) - - dst_img = cv2.warpAffine(torch_to_im(img), trans, - (resW, resH), flags=cv2.INTER_LINEAR) - if dst_img.ndim == 2: - dst_img = dst_img[:, :, np.newaxis] - - return im_to_torch(torch.Tensor(dst_img)) - - -def count_visible(bbox, joints_3d): - """Count number of visible joints given bound box.""" - vis = np.logical_and.reduce(( - joints_3d[:, 0, 0] > 0, - joints_3d[:, 0, 0] > bbox[0], - joints_3d[:, 0, 0] < bbox[2], - joints_3d[:, 1, 0] > 0, - joints_3d[:, 1, 0] > bbox[1], - joints_3d[:, 1, 0] < bbox[3], - joints_3d[:, 0, 1] > 0, - joints_3d[:, 1, 1] > 0 - )) - return np.sum(vis), vis - - -def drawGaussian(img, pt, sigma): - """Draw 2d gaussian on input image. - - Parameters - ---------- - img: torch.Tensor - A tensor with shape: `(3, H, W)`. - pt: list or tuple - A point: (x, y). - sigma: int - Sigma of gaussian distribution. - - Returns - ------- - torch.Tensor - A tensor with shape: `(3, H, W)`. - - """ - img = to_numpy(img) - tmpSize = 3 * sigma - # Check that any part of the gaussian is in-bounds - ul = [int(pt[0] - tmpSize), int(pt[1] - tmpSize)] - br = [int(pt[0] + tmpSize + 1), int(pt[1] + tmpSize + 1)] - - if (ul[0] >= img.shape[1] or ul[1] >= img.shape[0] or br[0] < 0 or br[1] < 0): - # If not, just return the image as is - return to_torch(img) - - # Generate gaussian - size = 2 * tmpSize + 1 - x = np.arange(0, size, 1, float) - y = x[:, np.newaxis] - x0 = y0 = size // 2 - # The gaussian is not normalized, we want the center value to equal 1 - g = np.exp(- ((x - x0) ** 2 + (y - y0) ** 2) / (2 * sigma ** 2)) - - # Usable gaussian range - g_x = max(0, -ul[0]), min(br[0], img.shape[1]) - ul[0] - g_y = max(0, -ul[1]), min(br[1], img.shape[0]) - ul[1] - # Image range - img_x = max(0, ul[0]), min(br[0], img.shape[1]) - img_y = max(0, ul[1]), min(br[1], img.shape[0]) - - img[img_y[0]:img_y[1], img_x[0]:img_x[1]] = g[g_y[0]:g_y[1], g_x[0]:g_x[1]] - return to_torch(img) - - -def flip(x): - assert (x.dim() == 3 or x.dim() == 4) - dim = x.dim() - 1 - - return x.flip(dims=(dim,)) - - -def flip_heatmap(heatmap, joint_pairs, shift=False): - """Flip pose heatmap according to joint pairs. - - Parameters - ---------- - heatmap : numpy.ndarray - Heatmap of joints. - joint_pairs : list - List of joint pairs. - shift : bool - Whether to shift the output. - - Returns - ------- - numpy.ndarray - Flipped heatmap. - - """ - assert (heatmap.dim() == 3 or heatmap.dim() == 4) - out = flip(heatmap) - - for pair in joint_pairs: - dim0, dim1 = pair - idx = torch.Tensor((dim0, dim1)).long() - inv_idx = torch.Tensor((dim1, dim0)).long() - if out.dim() == 4: - out[:, idx] = out[:, inv_idx] - else: - out[idx] = out[inv_idx] - - if shift: - if out.dim() == 3: - out[:, :, 1:] = out[:, :, 0:-1] - else: - out[:, :, :, 1:] = out[:, :, :, 0:-1] - return out - - -def flip_joints_3d(joints_3d, width, joint_pairs): - """Flip 3d joints. - - Parameters - ---------- - joints_3d : numpy.ndarray - Joints in shape (num_joints, 3, 2) - width : int - Image width. - joint_pairs : list - List of joint pairs. - - Returns - ------- - numpy.ndarray - Flipped 3d joints with shape (num_joints, 3, 2) - - """ - joints = joints_3d.copy() - # flip horizontally - joints[:, 0, 0] = width - joints[:, 0, 0] - 1 - # change left-right parts - for pair in joint_pairs: - joints[pair[0], :, 0], joints[pair[1], :, 0] = \ - joints[pair[1], :, 0], joints[pair[0], :, 0].copy() - joints[pair[0], :, 1], joints[pair[1], :, 1] = \ - joints[pair[1], :, 1], joints[pair[0], :, 1].copy() - - joints[:, :, 0] *= joints[:, :, 1] - return joints - - -def heatmap_to_coord_rmpe(hms, bbox): - assert hms.ndim == 3 - hm_h = hms.shape[1] - hm_w = hms.shape[2] - coords, maxvals = get_max_pred(hms) - assert len(bbox) == 4 - - # post-processing - for p in range(coords.shape[0]): - hm = hms[p] - px = int(round(float(coords[p][0]))) - py = int(round(float(coords[p][1]))) - if 1 < px < hm_w - 1 and 1 < py < hm_h - 1: - diff = np.array((hm[py][px + 1] - hm[py][px - 1], hm[py + 1][px] - hm[py - 1][px])) - coords[p] += np.sign(diff) * 0.25 - - preds = np.zeros(coords.shape) - for j in range(hms.shape[0]): - preds[j] = transformBoxInvert(coords[j], bbox, hm_h, hm_w) - - return preds, maxvals - - -def heatmap_to_coord_simple(hms, bbox): - coords, maxvals = get_max_pred(hms) - - hm_h = hms.shape[1] - hm_w = hms.shape[2] - - # post-processing - for p in range(coords.shape[0]): - hm = hms[p] - px = int(round(float(coords[p][0]))) - py = int(round(float(coords[p][1]))) - if 1 < px < hm_w - 1 and 1 < py < hm_h - 1: - diff = np.array((hm[py][px + 1] - hm[py][px - 1], - hm[py + 1][px] - hm[py - 1][px])) - coords[p] += np.sign(diff) * .25 - - preds = np.zeros_like(coords) - - # transform bbox to scale - xmin, ymin, xmax, ymax = bbox - w = xmax - xmin - h = ymax - ymin - center = np.array([xmin + w * 0.5, ymin + h * 0.5]) - scale = np.array([w, h]) - # Transform back - for i in range(coords.shape[0]): - preds[i] = transform_preds(coords[i], center, scale, - [hm_w, hm_h]) - - return preds, maxvals - - -def multipeak_heatmap_to_coord(hms, bbox): - coords = get_peak(hms) - - assert hms.ndim == 3, hms.shape - - hm_h = hms.shape[1] - hm_w = hms.shape[2] - - # post-processing - for k in range(len(coords)): - coords[k] = process_peak(coords[k], hms[k], bbox, hm_h, hm_w) - - return coords, None - - -def get_peak(hms): - coords = {} - for k in range(hms.shape[0]): - hm = hms[k] - mx = maximum_filter(hm, size=5) - idx = zip(*np.where((mx == hm) * (hm > 0.1))) - candidate_points = [] - for (y, x) in idx: - candidate_points.append([x, y, hm[y][x]]) - - if len(candidate_points) == 0: - preds, maxvals = get_max_pred(hm[None, :]) - candidate_points.append([preds[0, 0], preds[0, 1], maxvals[0, 0]]) - - candidate_points = np.array(candidate_points) - candidate_points = candidate_points[np.lexsort(-candidate_points.T)] - candidate_points = torch.Tensor(candidate_points) - coords[k] = candidate_points - return coords - - -def process_peak(candidate_points, hm, bbox, hm_h, hm_w): - res_pts = [] - xmin, ymin, xmax, ymax = bbox - w = xmax - xmin - h = ymax - ymin - - center = np.array([xmin + w * 0.5, ymin + h * 0.5]) - scale = np.array([w, h]) - for x, y, maxval in candidate_points: - x, y, maxval = float(x), float(y), float(maxval) - - if bool(maxval < 0.1) and len(res_pts) > 0: - pass - else: - px = int(round(float(x))) - py = int(round(float(y))) - - if 1 < px < hm_w - 1 and 1 < py < hm_h - 1: - diff = np.array((hm[py][px + 1] - hm[py][px - 1], - hm[py + 1][px] - hm[py - 1][px])) - x += np.sign(diff)[0] * .25 - y += np.sign(diff)[1] * .25 - - pt = np.array((x, y)) - pt = transform_preds(pt, center, scale, [hm_w, hm_h]) - - res_pt = np.zeros(3) - res_pt[:2] = pt - - if bool(maxval < 0.1): - res_pt[2] = 1e-5 - else: - res_pt[2] = maxval - res_pts.append(res_pt) - return res_pts - - -def transform_preds(coords, center, scale, output_size): - target_coords = np.zeros(coords.shape) - trans = get_affine_transform(center, scale, 0, output_size, inv=1) - target_coords[0:2] = affine_transform(coords[0:2], trans) - return target_coords - - -def get_max_pred(heatmaps): - num_joints = heatmaps.shape[0] - width = heatmaps.shape[2] - heatmaps_reshaped = heatmaps.reshape((num_joints, -1)) - idx = np.argmax(heatmaps_reshaped, 1) - maxvals = np.max(heatmaps_reshaped, 1) - - maxvals = maxvals.reshape((num_joints, 1)) - idx = idx.reshape((num_joints, 1)) - - preds = np.tile(idx, (1, 2)).astype(np.float32) - - preds[:, 0] = (preds[:, 0]) % width - preds[:, 1] = np.floor((preds[:, 1]) / width) - - pred_mask = np.tile(np.greater(maxvals, 0.0), (1, 2)) - pred_mask = pred_mask.astype(np.float32) - - preds *= pred_mask - return preds, maxvals - - -def get_max_pred_batch(batch_heatmaps): - batch_size = batch_heatmaps.shape[0] - num_joints = batch_heatmaps.shape[1] - width = batch_heatmaps.shape[3] - heatmaps_reshaped = batch_heatmaps.reshape((batch_size, num_joints, -1)) - idx = np.argmax(heatmaps_reshaped, 2) - maxvals = np.max(heatmaps_reshaped, 2) - - maxvals = maxvals.reshape((batch_size, num_joints, 1)) - idx = idx.reshape((batch_size, num_joints, 1)) - - preds = np.tile(idx, (1, 1, 2)).astype(np.float32) - - preds[:, :, 0] = (preds[:, :, 0]) % width - preds[:, :, 1] = np.floor((preds[:, :, 1]) / width) - - pred_mask = np.tile(np.greater(maxvals, 0.0), (1, 1, 2)) - pred_mask = pred_mask.astype(np.float32) - - preds *= pred_mask - return preds, maxvals - - -def get_affine_transform(center, - scale, - rot, - output_size, - shift=np.array([0, 0], dtype=np.float32), - inv=0): - if not isinstance(scale, np.ndarray) and not isinstance(scale, list): - scale = np.array([scale, scale]) - - scale_tmp = scale - src_w = scale_tmp[0] - dst_w = output_size[0] - dst_h = output_size[1] - - rot_rad = np.pi * rot / 180 - src_dir = get_dir([0, src_w * -0.5], rot_rad) - dst_dir = np.array([0, dst_w * -0.5], np.float32) - - src = np.zeros((3, 2), dtype=np.float32) - dst = np.zeros((3, 2), dtype=np.float32) - src[0, :] = center + scale_tmp * shift - src[1, :] = center + src_dir + scale_tmp * shift - dst[0, :] = [dst_w * 0.5, dst_h * 0.5] - dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5]) + dst_dir - - src[2:, :] = get_3rd_point(src[0, :], src[1, :]) - dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :]) - - if inv: - trans = cv2.getAffineTransform(np.float32(dst), np.float32(src)) - else: - trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) - - return trans - - -def affine_transform(pt, t): - new_pt = np.array([pt[0], pt[1], 1.]).T - new_pt = np.dot(t, new_pt) - return new_pt[:2] - - -def get_func_heatmap_to_coord(cfg): - if cfg.MODEL.EXTRA.PRESET == 'rmpe': - return heatmap_to_coord_rmpe - elif cfg.MODEL.EXTRA.PRESET == 'simple' or cfg.MODEL.EXTRA.PRESET == 'multi_simple' or cfg.MODEL.EXTRA.PRESET == 'simple_dense': - return heatmap_to_coord_simple - else: - raise NotImplementedError diff --git a/cv/pose/alphapose/pytorch/trackers/utils/bbox.py b/cv/pose/alphapose/pytorch/trackers/utils/bbox.py deleted file mode 100755 index 7cd6c6d17..000000000 --- a/cv/pose/alphapose/pytorch/trackers/utils/bbox.py +++ /dev/null @@ -1,133 +0,0 @@ -import numpy as np -import cv2 - - -def clip_boxes(boxes, im_shape): - """ - Clip boxes to image boundaries. - """ - boxes = np.asarray(boxes) - if boxes.shape[0] == 0: - return boxes - boxes = np.copy(boxes) - # x1 >= 0 - boxes[:, 0::4] = np.maximum(np.minimum(boxes[:, 0::4], im_shape[1] - 1), 0) - # y1 >= 0 - boxes[:, 1::4] = np.maximum(np.minimum(boxes[:, 1::4], im_shape[0] - 1), 0) - # x2 < im_shape[1] - boxes[:, 2::4] = np.maximum(np.minimum(boxes[:, 2::4], im_shape[1] - 1), 0) - # y2 < im_shape[0] - boxes[:, 3::4] = np.maximum(np.minimum(boxes[:, 3::4], im_shape[0] - 1), 0) - return boxes - - -def clip_box(bbox, im_shape): - h, w = im_shape[:2] - bbox = np.copy(bbox) - bbox[0] = max(min(bbox[0], w - 1), 0) - bbox[1] = max(min(bbox[1], h - 1), 0) - bbox[2] = max(min(bbox[2], w - 1), 0) - bbox[3] = max(min(bbox[3], h - 1), 0) - - return bbox - - -def int_box(box): - box = np.asarray(box, dtype=np.float) - box = np.round(box) - return np.asarray(box, dtype=np.int) - - -# for display -############################ -def _to_color(indx, base): - """ return (b, r, g) tuple""" - base2 = base * base - b = 2 - indx / base2 - r = 2 - (indx % base2) / base - g = 2 - (indx % base2) % base - return b * 127, r * 127, g * 127 - - -def get_color(indx, cls_num=1): - if indx >= cls_num: - return (23 * indx % 255, 47 * indx % 255, 137 * indx % 255) - base = int(np.ceil(pow(cls_num, 1. / 3))) - return _to_color(indx, base) - - -def draw_detection(im, bboxes, scores=None, cls_inds=None, cls_name=None): - # draw image - bboxes = np.round(bboxes).astype(np.int) - if cls_inds is not None: - cls_inds = cls_inds.astype(np.int) - cls_num = len(cls_name) if cls_name is not None else 2 - - imgcv = np.copy(im) - h, w, _ = imgcv.shape - for i, box in enumerate(bboxes): - cls_indx = cls_inds[i] if cls_inds is not None else 1 - color = get_color(cls_indx, cls_num) - - thick = int((h + w) / 600) - cv2.rectangle(imgcv, - (box[0], box[1]), (box[2], box[3]), - color, thick) - - if cls_indx is not None: - score = scores[i] if scores is not None else 1 - name = cls_name[cls_indx] if cls_name is not None else str(cls_indx) - mess = '%s: %.3f' % (name, score) if cls_inds is not None else '%.3f' % (score, ) - cv2.putText(imgcv, mess, (box[0], box[1] - 12), - 0, 1e-3 * h, color, thick // 3) - - return imgcv -def _box_to_center_scale(x, y, w, h, aspect_ratio=1.0, scale_mult=1.25): - """Convert box coordinates to center and scale. - adapted from https://github.com/Microsoft/human-pose-estimation.pytorch - """ - pixel_std = 1 - center = np.zeros((2), dtype=np.float32) - center[0] = x + w * 0.5 - center[1] = y + h * 0.5 - - if w > aspect_ratio * h: - h = w / aspect_ratio - elif w < aspect_ratio * h: - w = h * aspect_ratio - scale = np.array( - [w * 1.0 / pixel_std, h * 1.0 / pixel_std], dtype=np.float32) - if center[0] != -1: - scale = scale * scale_mult - return center, scale - - -def _center_scale_to_box(center, scale): - pixel_std = 1.0 - w = scale[0] * pixel_std - h = scale[1] * pixel_std - xmin = center[0] - w * 0.5 - ymin = center[1] - h * 0.5 - xmax = xmin + w - ymax = ymin + h - bbox = [xmin, ymin, xmax, ymax] - return bbox -def transformBoxInvert(pt, bbox, resH, resW): - center = torch.zeros(2) - center[0] = (bbox[2] - 1 - bbox[0]) / 2 - center[1] = (bbox[3] - 1 - bbox[1]) / 2 - - lenH = max(bbox[3] - bbox[1], (bbox[2] - bbox[0]) * resH / resW) - lenW = lenH * resW / resH - - _pt = (pt * lenH) / resH - - if bool(((lenW - 1) / 2 - center[0]) > 0): - _pt[0] = _pt[0] - ((lenW - 1) / 2 - center[0]).item() - if bool(((lenH - 1) / 2 - center[1]) > 0): - _pt[1] = _pt[1] - ((lenH - 1) / 2 - center[1]).item() - - new_point = torch.zeros(2) - new_point[0] = _pt[0] + bbox[0] - new_point[1] = _pt[1] + bbox[1] - return new_point diff --git a/cv/pose/alphapose/pytorch/trackers/utils/io.py b/cv/pose/alphapose/pytorch/trackers/utils/io.py deleted file mode 100755 index f70decdb2..000000000 --- a/cv/pose/alphapose/pytorch/trackers/utils/io.py +++ /dev/null @@ -1,112 +0,0 @@ -import os -from typing import Dict -import numpy as np - -from utils.log import logger - - -def write_results(filename, results_dict: Dict, data_type: str): - if not filename: - return - path = os.path.dirname(filename) - if not os.path.exists(path): - os.makedirs(path) - - if data_type in ('mot', 'mcmot', 'lab'): - save_format = '{frame},{id},{x1},{y1},{w},{h},1,-1,-1,-1\n' - elif data_type == 'kitti': - save_format = '{frame} {id} pedestrian -1 -1 -10 {x1} {y1} {x2} {y2} -1 -1 -1 -1000 -1000 -1000 -10 {score}\n' - else: - raise ValueError(data_type) - - with open(filename, 'w') as f: - for frame_id, frame_data in results_dict.items(): - if data_type == 'kitti': - frame_id -= 1 - for tlwh, track_id in frame_data: - if track_id < 0: - continue - x1, y1, w, h = tlwh - x2, y2 = x1 + w, y1 + h - line = save_format.format(frame=frame_id, id=track_id, x1=x1, y1=y1, x2=x2, y2=y2, w=w, h=h, score=1.0) - f.write(line) - logger.info('Save results to {}'.format(filename)) - - -def read_results(filename, data_type: str, is_gt=False, is_ignore=False): - if data_type in ('mot', 'lab'): - read_fun = read_mot_results - else: - raise ValueError('Unknown data type: {}'.format(data_type)) - - return read_fun(filename, is_gt, is_ignore) - - -""" -labels={'ped', ... % 1 -'person_on_vhcl', ... % 2 -'car', ... % 3 -'bicycle', ... % 4 -'mbike', ... % 5 -'non_mot_vhcl', ... % 6 -'static_person', ... % 7 -'distractor', ... % 8 -'occluder', ... % 9 -'occluder_on_grnd', ... %10 -'occluder_full', ... % 11 -'reflection', ... % 12 -'crowd' ... % 13 -}; -""" - - -def read_mot_results(filename, is_gt, is_ignore): - valid_labels = {1} - ignore_labels = {2, 7, 8, 12} - results_dict = dict() - if os.path.isfile(filename): - with open(filename, 'r') as f: - for line in f.readlines(): - linelist = line.split(',') - if len(linelist) < 7: - continue - fid = int(linelist[0]) - if fid < 1: - continue - results_dict.setdefault(fid, list()) - - if is_gt: - if 'MOT16-' in filename or 'MOT17-' in filename: - label = int(float(linelist[7])) - mark = int(float(linelist[6])) - if mark == 0 or label not in valid_labels: - continue - score = 1 - elif is_ignore: - if 'MOT16-' in filename or 'MOT17-' in filename: - label = int(float(linelist[7])) - vis_ratio = float(linelist[8]) - if label not in ignore_labels and vis_ratio >= 0: - continue - else: - continue - score = 1 - else: - score = float(linelist[6]) - - tlwh = tuple(map(float, linelist[2:6])) - target_id = int(linelist[1]) - - results_dict[fid].append((tlwh, target_id, score)) - - return results_dict - - -def unzip_objs(objs): - if len(objs) > 0: - tlwhs, ids, scores = zip(*objs) - else: - tlwhs, ids, scores = [], [], [] - tlwhs = np.asarray(tlwhs, dtype=float).reshape(-1, 4) - - return tlwhs, ids, scores \ No newline at end of file diff --git a/cv/pose/alphapose/pytorch/trackers/utils/kalman_filter.py b/cv/pose/alphapose/pytorch/trackers/utils/kalman_filter.py deleted file mode 100755 index 5c74b7ca9..000000000 --- a/cv/pose/alphapose/pytorch/trackers/utils/kalman_filter.py +++ /dev/null @@ -1,278 +0,0 @@ -# vim: expandtab:ts=4:sw=4 -#import numba -import numpy as np -import scipy.linalg - - -""" -Table for the 0.95 quantile of the chi-square distribution with N degrees of -freedom (contains values for N=1, ..., 9). Taken from MATLAB/Octave's chi2inv -function and used as Mahalanobis gating threshold. -""" -chi2inv95 = { - 1: 3.8415, - 2: 5.9915, - 3: 7.8147, - 4: 9.4877, - 5: 11.070, - 6: 12.592, - 7: 14.067, - 8: 15.507, - 9: 16.919} - - -class KalmanFilter(object): - """ - A simple Kalman filter for tracking bounding boxes in image space. - - The 8-dimensional state space - - x, y, a, h, vx, vy, va, vh - - contains the bounding box center position (x, y), aspect ratio a, height h, - and their respective velocities. - - Object motion follows a constant velocity model. The bounding box location - (x, y, a, h) is taken as direct observation of the state space (linear - observation model). - - """ - - def __init__(self): - ndim, dt = 4, 1. - - # Create Kalman filter model matrices. - self._motion_mat = np.eye(2 * ndim, 2 * ndim) - for i in range(ndim): - self._motion_mat[i, ndim + i] = dt - self._update_mat = np.eye(ndim, 2 * ndim) - - # Motion and observation uncertainty are chosen relative to the current - # state estimate. These weights control the amount of uncertainty in - # the model. This is a bit hacky. - self._std_weight_position = 1. / 20 - self._std_weight_velocity = 1. / 160 - - def initiate(self, measurement): - """Create track from unassociated measurement. - - Parameters - ---------- - measurement : ndarray - Bounding box coordinates (x, y, a, h) with center position (x, y), - aspect ratio a, and height h. - - Returns - ------- - (ndarray, ndarray) - Returns the mean vector (8 dimensional) and covariance matrix (8x8 - dimensional) of the new track. Unobserved velocities are initialized - to 0 mean. - - """ - mean_pos = measurement - mean_vel = np.zeros_like(mean_pos) - mean = np.r_[mean_pos, mean_vel] - - std = [ - 2 * self._std_weight_position * measurement[3], - 2 * self._std_weight_position * measurement[3], - 1e-2, - 2 * self._std_weight_position * measurement[3], - 10 * self._std_weight_velocity * measurement[3], - 10 * self._std_weight_velocity * measurement[3], - 1e-5, - 10 * self._std_weight_velocity * measurement[3]] - covariance = np.diag(np.square(std)) - return mean, covariance - - def predict(self, mean, covariance): - """Run Kalman filter prediction step. - - Parameters - ---------- - mean : ndarray - The 8 dimensional mean vector of the object state at the previous - time step. - covariance : ndarray - The 8x8 dimensional covariance matrix of the object state at the - previous time step. - - Returns - ------- - (ndarray, ndarray) - Returns the mean vector and covariance matrix of the predicted - state. Unobserved velocities are initialized to 0 mean. - - """ - std_pos = [ - self._std_weight_position * mean[3], - self._std_weight_position * mean[3], - 1e-2, - self._std_weight_position * mean[3]] - std_vel = [ - self._std_weight_velocity * mean[3], - self._std_weight_velocity * mean[3], - 1e-5, - self._std_weight_velocity * mean[3]] - motion_cov = np.diag(np.square(np.r_[std_pos, std_vel])) - - mean = np.dot(mean, self._motion_mat.T) - covariance = np.linalg.multi_dot(( - self._motion_mat, covariance, self._motion_mat.T)) + motion_cov - - return mean, covariance - - def project(self, mean, covariance): - """Project state distribution to measurement space. - - Parameters - ---------- - mean : ndarray - The state's mean vector (8 dimensional array). - covariance : ndarray - The state's covariance matrix (8x8 dimensional). - - Returns - ------- - (ndarray, ndarray) - Returns the projected mean and covariance matrix of the given state - estimate. - - """ - std = [ - self._std_weight_position * mean[3], - self._std_weight_position * mean[3], - 1e-1, - self._std_weight_position * mean[3]] - innovation_cov = np.diag(np.square(std)) - - mean = np.dot(self._update_mat, mean) - covariance = np.linalg.multi_dot(( - self._update_mat, covariance, self._update_mat.T)) - return mean, covariance + innovation_cov - - def multi_predict(self, mean, covariance): - """Run Kalman filter prediction step (Vectorized version). - - Parameters - ---------- - mean : ndarray - The Nx8 dimensional mean matrix of the object states at the previous - time step. - covariance : ndarray - The Nx8x8 dimensional covariance matrics of the object states at the - previous time step. - - Returns - ------- - (ndarray, ndarray) - Returns the mean vector and covariance matrix of the predicted - state. Unobserved velocities are initialized to 0 mean. - - """ - std_pos = [ - self._std_weight_position * mean[:, 3], - self._std_weight_position * mean[:, 3], - 1e-2 * np.ones_like(mean[:, 3]), - self._std_weight_position * mean[:, 3]] - std_vel = [ - self._std_weight_velocity * mean[:, 3], - self._std_weight_velocity * mean[:, 3], - 1e-5 * np.ones_like(mean[:, 3]), - self._std_weight_velocity * mean[:, 3]] - sqr = np.square(np.r_[std_pos, std_vel]).T - - motion_cov = [] - for i in range(len(mean)): - motion_cov.append(np.diag(sqr[i])) - motion_cov = np.asarray(motion_cov) - - mean = np.dot(mean, self._motion_mat.T) - left = np.dot(self._motion_mat, covariance).transpose((1,0,2)) - covariance = np.dot(left, self._motion_mat.T) + motion_cov - - return mean, covariance - - def update(self, mean, covariance, measurement): - """Run Kalman filter correction step. - - Parameters - ---------- - mean : ndarray - The predicted state's mean vector (8 dimensional). - covariance : ndarray - The state's covariance matrix (8x8 dimensional). - measurement : ndarray - The 4 dimensional measurement vector (x, y, a, h), where (x, y) - is the center position, a the aspect ratio, and h the height of the - bounding box. - - Returns - ------- - (ndarray, ndarray) - Returns the measurement-corrected state distribution. - - """ - projected_mean, projected_cov = self.project(mean, covariance) - - chol_factor, lower = scipy.linalg.cho_factor( - projected_cov, lower=True, check_finite=False) - kalman_gain = scipy.linalg.cho_solve( - (chol_factor, lower), np.dot(covariance, self._update_mat.T).T, - check_finite=False).T - innovation = measurement - projected_mean - - new_mean = mean + np.dot(innovation, kalman_gain.T) - new_covariance = covariance - np.linalg.multi_dot(( - kalman_gain, projected_cov, kalman_gain.T)) - return new_mean, new_covariance - - def gating_distance(self, mean, covariance, measurements, - only_position=False, metric='maha'): - """Compute gating distance between state distribution and measurements. - - A suitable distance threshold can be obtained from `chi2inv95`. If - `only_position` is False, the chi-square distribution has 4 degrees of - freedom, otherwise 2. - - Parameters - ---------- - mean : ndarray - Mean vector over the state distribution (8 dimensional). - covariance : ndarray - Covariance of the state distribution (8x8 dimensional). - measurements : ndarray - An Nx4 dimensional matrix of N measurements, each in - format (x, y, a, h) where (x, y) is the bounding box center - position, a the aspect ratio, and h the height. - only_position : Optional[bool] - If True, distance computation is done with respect to the bounding - box center position only. - - Returns - ------- - ndarray - Returns an array of length N, where the i-th element contains the - squared Mahalanobis distance between (mean, covariance) and - `measurements[i]`. - - """ - mean, covariance = self.project(mean, covariance) - if only_position: - mean, covariance = mean[:2], covariance[:2, :2] - measurements = measurements[:, :2] - - d = measurements - mean - if metric == 'gaussian': - return np.sum(d * d, axis=1) - elif metric == 'maha': - cholesky_factor = np.linalg.cholesky(covariance) - z = scipy.linalg.solve_triangular( - cholesky_factor, d.T, lower=True, check_finite=False, - overwrite_b=True) - squared_maha = np.sum(z * z, axis=0) - return squared_maha - else: - raise ValueError('invalid distance metric') - diff --git a/cv/pose/alphapose/pytorch/trackers/utils/log.py b/cv/pose/alphapose/pytorch/trackers/utils/log.py deleted file mode 100755 index 394e1e8c9..000000000 --- a/cv/pose/alphapose/pytorch/trackers/utils/log.py +++ /dev/null @@ -1,18 +0,0 @@ -import logging - - -def get_logger(name='root'): - formatter = logging.Formatter( - # fmt='%(asctime)s [%(levelname)s]: %(filename)s(%(funcName)s:%(lineno)s) >> %(message)s') - fmt='%(asctime)s [%(levelname)s]: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') - - handler = logging.StreamHandler() - handler.setFormatter(formatter) - - logger = logging.getLogger(name) - logger.setLevel(logging.DEBUG) - logger.addHandler(handler) - return logger - - -logger = get_logger('root') diff --git a/cv/pose/alphapose/pytorch/trackers/utils/parse_config.py b/cv/pose/alphapose/pytorch/trackers/utils/parse_config.py deleted file mode 100755 index 70b4f4b2c..000000000 --- a/cv/pose/alphapose/pytorch/trackers/utils/parse_config.py +++ /dev/null @@ -1,37 +0,0 @@ -def parse_model_cfg(path): - """Parses the yolo-v3 layer configuration file and returns module definitions""" - file = open(path, 'r') - lines = file.read().split('\n') - lines = [x for x in lines if x and not x.startswith('#')] - lines = [x.rstrip().lstrip() for x in lines] # get rid of fringe whitespaces - module_defs = [] - for line in lines: - if line.startswith('['): # This marks the start of a new block - module_defs.append({}) - module_defs[-1]['type'] = line[1:-1].rstrip() - if module_defs[-1]['type'] == 'convolutional': - module_defs[-1]['batch_normalize'] = 0 - else: - key, value = line.split("=") - value = value.strip() - if value[0] == '$': - value = module_defs[0].get(value.strip('$'), None) - module_defs[-1][key.rstrip()] = value - - return module_defs - - -def parse_data_cfg(path): - """Parses the data configuration file""" - options = dict() - options['gpus'] = '0' - options['num_workers'] = '10' - with open(path, 'r') as fp: - lines = fp.readlines() - for line in lines: - line = line.strip() - if line == '' or line.startswith('#'): - continue - key, value = line.split('=') - options[key.strip()] = value.strip() - return options diff --git a/cv/pose/alphapose/pytorch/trackers/utils/timer.py b/cv/pose/alphapose/pytorch/trackers/utils/timer.py deleted file mode 100755 index e79f1a310..000000000 --- a/cv/pose/alphapose/pytorch/trackers/utils/timer.py +++ /dev/null @@ -1,45 +0,0 @@ -# -------------------------------------------------------- -# Fast R-CNN -# Copyright (c) 2015 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ross Girshick -# -------------------------------------------------------- - -import time - - -class Timer(object): - """A simple timer.""" - def __init__(self): - self.total_time = 0. - self.calls = 0 - self.start_time = 0. - self.diff = 0. - self.average_time = 0. - - self.duration = 0. - - def tic(self): - # using time.time instead of time.clock because time time.clock - # does not normalize for multithreading - self.start_time = time.time() - - def toc(self, average=True): - self.diff = time.time() - self.start_time - self.total_time += self.diff - self.calls += 1 - self.average_time = self.total_time / self.calls - if average: - self.duration = self.average_time - else: - self.duration = self.diff - return self.duration - - def clear(self): - self.total_time = 0. - self.calls = 0 - self.start_time = 0. - self.diff = 0. - self.average_time = 0. - self.duration = 0. - diff --git a/cv/pose/alphapose/pytorch/trackers/utils/transform.py b/cv/pose/alphapose/pytorch/trackers/utils/transform.py deleted file mode 100755 index 1017f4807..000000000 --- a/cv/pose/alphapose/pytorch/trackers/utils/transform.py +++ /dev/null @@ -1,160 +0,0 @@ -# encoding: utf-8 -import torchvision.transforms as T -import math -import random -import torch -import cv2 -import numpy as np - -#from .functional import to_tensor -#from .transforms import * - -class RandomErasing(object): - """ Randomly selects a rectangle region in an image and erases its pixels. - 'Random Erasing Data Augmentation' by Zhong et al. - See https://arxiv.org/pdf/1708.04896.pdf - Args: - probability: The probability that the Random Erasing operation will be performed. - sl: Minimum proportion of erased area against input image. - sh: Maximum proportion of erased area against input image. - r1: Minimum aspect ratio of erased area. - mean: Erasing value. - """ - - def __init__(self, probability=0.5, sl=0.02, sh=0.4, r1=0.3, mean=255 * (0.49735, 0.4822, 0.4465)): - self.probability = probability - self.mean = mean - self.sl = sl - self.sh = sh - self.r1 = r1 - - def __call__(self, img): - img = np.asarray(img, dtype=np.float32).copy() - if random.uniform(0, 1) > self.probability: - return img - - for attempt in range(100): - area = img.shape[0] * img.shape[1] - target_area = random.uniform(self.sl, self.sh) * area - aspect_ratio = random.uniform(self.r1, 1 / self.r1) - - h = int(round(math.sqrt(target_area * aspect_ratio))) - w = int(round(math.sqrt(target_area / aspect_ratio))) - - if w < img.shape[1] and h < img.shape[0]: - x1 = random.randint(0, img.shape[0] - h) - y1 = random.randint(0, img.shape[1] - w) - if img.shape[2] == 3: - img[x1:x1 + h, y1:y1 + w, 0] = self.mean[0] - img[x1:x1 + h, y1:y1 + w, 1] = self.mean[1] - img[x1:x1 + h, y1:y1 + w, 2] = self.mean[2] - else: - img[x1:x1 + h, y1:y1 + w, 0] = self.mean[0] - return img - return img -def to_tensor(pic): - """Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor. - - See ``ToTensor`` for more details. - - Args: - pic (PIL Image or numpy.ndarray): Image to be converted to tensor. - - Returns: - Tensor: Converted image. - """ - if isinstance(pic, np.ndarray): - assert len(pic.shape) in (2, 3) - # handle numpy array - if pic.ndim == 2: - pic = pic[:, :, None] - - img = torch.from_numpy(pic.transpose((2, 0, 1))) - # backward compatibility - if isinstance(img, torch.ByteTensor): - return img.float() - else: - return img - - # handle PIL Image - if pic.mode == 'I': - img = torch.from_numpy(np.array(pic, np.int32, copy=False)) - elif pic.mode == 'I;16': - img = torch.from_numpy(np.array(pic, np.int16, copy=False)) - elif pic.mode == 'F': - img = torch.from_numpy(np.array(pic, np.float32, copy=False)) - elif pic.mode == '1': - img = 255 * torch.from_numpy(np.array(pic, np.uint8, copy=False)) - else: - img = torch.ByteTensor(torch.ByteStorage.from_buffer(pic.tobytes())) - # PIL image mode: L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK - if pic.mode == 'YCbCr': - nchannel = 3 - elif pic.mode == 'I;16': - nchannel = 1 - else: - nchannel = len(pic.mode) - img = img.view(pic.size[1], pic.size[0], nchannel) - # put it from HWC to CHW format - # yikes, this transpose takes 80% of the loading time/CPU - img = img.transpose(0, 1).transpose(0, 2).contiguous() - if isinstance(img, torch.ByteTensor): - return img.float() - else: - return img -class ToTensor(object): - """Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor. - - Converts a PIL Image or numpy.ndarray (H x W x C) in the range - [0, 255] to a torch.FloatTensor of shape (C x H x W) in the range [0.0, 1.0] - if the PIL Image belongs to one of the modes (L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1) - or if the numpy.ndarray has dtype = np.uint8 - - In the other cases, tensors are returned without scaling. - """ - - def __call__(self, pic): - """ - Args: - pic (PIL Image or numpy.ndarray): Image to be converted to tensor. - - Returns: - Tensor: Converted image. - """ - return to_tensor(pic) - - def __repr__(self): - return self.__class__.__name__ + '()' -def build_transforms(cfg, is_train=True): - res = [] - res.append(T.ToPILImage(mode=None)) - if is_train: - size_train = cfg["SIZE_TRAIN"] - # filp lr - do_flip = cfg["DO_FLIP"] - flip_prob = cfg["FLIP_PROB"] - # padding - do_pad = cfg["DO_PAD"] - padding = cfg["PADDING"] - padding_mode = cfg["PADDING_MODE"] - # random erasing - do_re = cfg["RE_ENABLED"] - #re_prob = cfg["RE_PROB"] - #re_mean = cfg["RE_MEAN"] - res.append(T.Resize(size_train, interpolation=3)) - if do_flip: - res.append(T.RandomHorizontalFlip(p=flip_prob)) - if do_pad: - res.extend([T.Pad(padding, padding_mode=padding_mode), - T.RandomCrop(size_train)]) - if do_re: - #res.append(T.RandomErasing(probability=re_prob, mean=re_mean)) - res.append(RandomErasing()) - # if cfg.INPUT.CUTOUT.DO: - # res.append(Cutout(probability=cfg.INPUT.CUTOUT.PROB, size=cfg.INPUT.CUTOUT.SIZE, - # mean=cfg.INPUT.CUTOUT.MEAN)) - else: - size_test = cfg["TEST_SIZE"] - res.append(T.Resize(size_test, interpolation=3)) - res.append(ToTensor()) - return T.Compose(res) diff --git a/cv/pose/alphapose/pytorch/trackers/utils/utils.py b/cv/pose/alphapose/pytorch/trackers/utils/utils.py deleted file mode 100755 index 97b8fb96d..000000000 --- a/cv/pose/alphapose/pytorch/trackers/utils/utils.py +++ /dev/null @@ -1,750 +0,0 @@ -import glob -import random -import time -import os -import os.path as osp - -import cv2 -import warnings -from functools import partial -from collections import OrderedDict -import matplotlib.pyplot as plt -import numpy as np -import torch -import pickle -import torch.nn.functional as F -from torchvision.ops import nms -#import maskrcnn_benchmark.layers.nms as nms - -def mkdir_if_missing(d): - if not osp.exists(d): - os.makedirs(d) - - -def float3(x): # format floats to 3 decimals - return float(format(x, '.3f')) - - -def init_seeds(seed=0): - random.seed(seed) - np.random.seed(seed) - torch.manual_seed(seed) - torch.cuda.manual_seed(seed) - torch.cuda.manual_seed_all(seed) - - -def load_classes(path): - """ - Loads class labels at 'path' - """ - fp = open(path, 'r') - names = fp.read().split('\n') - return list(filter(None, names)) # filter removes empty strings (such as last line) - - -def model_info(model): # Plots a line-by-line description of a PyTorch model - n_p = sum(x.numel() for x in model.parameters()) # number parameters - n_g = sum(x.numel() for x in model.parameters() if x.requires_grad) # number gradients - print('\n%5s %50s %9s %12s %20s %12s %12s' % ('layer', 'name', 'gradient', 'parameters', 'shape', 'mu', 'sigma')) - for i, (name, p) in enumerate(model.named_parameters()): - name = name.replace('module_list.', '') - print('%5g %50s %9s %12g %20s %12.3g %12.3g' % ( - i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std())) - print('Model Summary: %g layers, %g parameters, %g gradients\n' % (i + 1, n_p, n_g)) - - - -def plot_one_box(x, img, color=None, label=None, line_thickness=None): # Plots one bounding box on image img - tl = line_thickness or round(0.0004 * max(img.shape[0:2])) + 1 # line thickness - color = color or [random.randint(0, 255) for _ in range(3)] - c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3])) - cv2.rectangle(img, c1, c2, color, thickness=tl) - if label: - tf = max(tl - 1, 1) # font thickness - t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0] - c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3 - cv2.rectangle(img, c1, c2, color, -1) # filled - cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA) - - -def weights_init_normal(m): - classname = m.__class__.__name__ - if classname.find('Conv') != -1: - torch.nn.init.normal_(m.weight.data, 0.0, 0.03) - elif classname.find('BatchNorm2d') != -1: - torch.nn.init.normal_(m.weight.data, 1.0, 0.03) - torch.nn.init.constant_(m.bias.data, 0.0) - - -def xyxy2xywh(x): - # Convert bounding box format from [x1, y1, x2, y2] to [x, y, w, h] - y = torch.zeros(x.shape) if x.dtype is torch.float32 else np.zeros(x.shape) - y[:, 0] = (x[:, 0] + x[:, 2]) / 2 - y[:, 1] = (x[:, 1] + x[:, 3]) / 2 - y[:, 2] = x[:, 2] - x[:, 0] - y[:, 3] = x[:, 3] - x[:, 1] - return y - - -def xywh2xyxy(x): - # Convert bounding box format from [x, y, w, h] to [x1, y1, x2, y2] - y = torch.zeros(x.shape) if x.dtype is torch.float32 else np.zeros(x.shape) - y[:, 0] = (x[:, 0] - x[:, 2] / 2) - y[:, 1] = (x[:, 1] - x[:, 3] / 2) - y[:, 2] = (x[:, 0] + x[:, 2] / 2) - y[:, 3] = (x[:, 1] + x[:, 3] / 2) - return y -def x1y1x2y2_to_xywh(det): - x1, y1, x2, y2 = det - w, h = int(x2) - int(x1), int(y2) - int(y1) - return [x1, y1, w, h] -def xywh_to_x1y1x2y2(det): - x1, y1, w, h = det - x2, y2 = x1 + w, y1 + h - return [x1, y1, x2, y2] -def expandBbox(xywh,width,height): - scale = 0.05 - if isinstance(xywh, (tuple, list)): - if not len(xywh) == 4: - raise IndexError( - "Bounding boxes must have 4 elements, given {}".format(len(xywh))) - center_x = xywh[0] + xywh[2]/2 - center_y = xywh[1] + xywh[3]/2 - img_width,img_height = xywh[2]+scale*width,xywh[3]+scale*height - x1 = np.minimum(width - 1, np.maximum(0, center_x-img_width/2)) - y1 = np.minimum(height - 1, np.maximum(0, center_y-img_height/2)) - x2 = np.minimum(width - 1, np.maximum(0, center_x+img_width/2)) - y2 = np.minimum(height - 1, np.maximum(0, center_y+img_height/2)) - return (x1, y1, x2, y2) - else: - raise TypeError( - 'Expect input xywh a list or tuple, given {}'.format(type(xywh))) -def bbox_clip_xyxy(xyxy, width, height): - """Clip bounding box with format (xmin, ymin, xmax, ymax) to specified boundary. - - All bounding boxes will be clipped to the new region `(0, 0, width, height)`. - - Parameters - ---------- - xyxy : list, tuple or numpy.ndarray - The bbox in format (xmin, ymin, xmax, ymax). - If numpy.ndarray is provided, we expect multiple bounding boxes with - shape `(N, 4)`. - width : int or float - Boundary width. - height : int or float - Boundary height. - - Returns - ------- - type - Description of returned object. - - """ - if isinstance(xyxy, (tuple, list)): - if not len(xyxy) == 4: - raise IndexError( - "Bounding boxes must have 4 elements, given {}".format(len(xyxy))) - x1 = np.minimum(width - 1, np.maximum(0, xyxy[0])) - y1 = np.minimum(height - 1, np.maximum(0, xyxy[1])) - x2 = np.minimum(width - 1, np.maximum(0, xyxy[2])) - y2 = np.minimum(height - 1, np.maximum(0, xyxy[3])) - return (x1, y1, x2, y2) - elif isinstance(xyxy, np.ndarray): - if not xyxy.size % 4 == 0: - raise IndexError( - "Bounding boxes must have n * 4 elements, given {}".format(xyxy.shape)) - x1 = np.minimum(width - 1, np.maximum(0, xyxy[:, 0])) - y1 = np.minimum(height - 1, np.maximum(0, xyxy[:, 1])) - x2 = np.minimum(width - 1, np.maximum(0, xyxy[:, 2])) - y2 = np.minimum(height - 1, np.maximum(0, xyxy[:, 3])) - return np.hstack((x1, y1, x2, y2)) - else: - raise TypeError( - 'Expect input xywh a list, tuple or numpy.ndarray, given {}'.format(type(xyxy))) - -def scale_coords(img_size, coords, img0_shape): - # Rescale x1, y1, x2, y2 from 416 to image size - gain_w = float(img_size[0]) / img0_shape[1] # gain = old / new - gain_h = float(img_size[1]) / img0_shape[0] - gain = min(gain_w, gain_h) - pad_x = (img_size[0] - img0_shape[1] * gain) / 2 # width padding - pad_y = (img_size[1] - img0_shape[0] * gain) / 2 # height padding - coords[:, [0, 2]] -= pad_x - coords[:, [1, 3]] -= pad_y - coords[:, 0:4] /= gain - coords[:, :4] = torch.clamp(coords[:, :4], min=0) - return coords - - -def ap_per_class(tp, conf, pred_cls, target_cls): - """ Compute the average precision, given the recall and precision curves. - Method originally from https://github.com/rafaelpadilla/Object-Detection-Metrics. - # Arguments - tp: True positives (list). - conf: Objectness value from 0-1 (list). - pred_cls: Predicted object classes (list). - target_cls: True object classes (list). - # Returns - The average precision as computed in py-faster-rcnn. - """ - - # lists/pytorch to numpy - tp, conf, pred_cls, target_cls = np.array(tp), np.array(conf), np.array(pred_cls), np.array(target_cls) - - # Sort by objectness - i = np.argsort(-conf) - tp, conf, pred_cls = tp[i], conf[i], pred_cls[i] - - # Find unique classes - unique_classes = np.unique(np.concatenate((pred_cls, target_cls), 0)) - - # Create Precision-Recall curve and compute AP for each class - ap, p, r = [], [], [] - for c in unique_classes: - i = pred_cls == c - n_gt = sum(target_cls == c) # Number of ground truth objects - n_p = sum(i) # Number of predicted objects - - if (n_p == 0) and (n_gt == 0): - continue - elif (n_p == 0) or (n_gt == 0): - ap.append(0) - r.append(0) - p.append(0) - else: - # Accumulate FPs and TPs - fpc = np.cumsum(1 - tp[i]) - tpc = np.cumsum(tp[i]) - - # Recall - recall_curve = tpc / (n_gt + 1e-16) - r.append(tpc[-1] / (n_gt + 1e-16)) - - # Precision - precision_curve = tpc / (tpc + fpc) - p.append(tpc[-1] / (tpc[-1] + fpc[-1])) - - # AP from recall-precision curve - ap.append(compute_ap(recall_curve, precision_curve)) - - return np.array(ap), unique_classes.astype('int32'), np.array(r), np.array(p) - - -def compute_ap(recall, precision): - """ Compute the average precision, given the recall and precision curves. - Code originally from https://github.com/rbgirshick/py-faster-rcnn. - # Arguments - recall: The recall curve (list). - precision: The precision curve (list). - # Returns - The average precision as computed in py-faster-rcnn. - """ - # correct AP calculation - # first append sentinel values at the end - - mrec = np.concatenate(([0.], recall, [1.])) - mpre = np.concatenate(([0.], precision, [0.])) - - # compute the precision envelope - for i in range(mpre.size - 1, 0, -1): - mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i]) - - # to calculate area under PR curve, look for points - # where X axis (recall) changes value - i = np.where(mrec[1:] != mrec[:-1])[0] - - # and sum (\Delta recall) * prec - ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) - return ap - - -def bbox_iou(box1, box2, x1y1x2y2=False): - """ - Returns the IoU of two bounding boxes - """ - N, M = len(box1), len(box2) - if x1y1x2y2: - # Get the coordinates of bounding boxes - b1_x1, b1_y1, b1_x2, b1_y2 = box1[:, 0], box1[:, 1], box1[:, 2], box1[:, 3] - b2_x1, b2_y1, b2_x2, b2_y2 = box2[:, 0], box2[:, 1], box2[:, 2], box2[:, 3] - else: - # Transform from center and width to exact coordinates - b1_x1, b1_x2 = box1[:, 0] - box1[:, 2] / 2, box1[:, 0] + box1[:, 2] / 2 - b1_y1, b1_y2 = box1[:, 1] - box1[:, 3] / 2, box1[:, 1] + box1[:, 3] / 2 - b2_x1, b2_x2 = box2[:, 0] - box2[:, 2] / 2, box2[:, 0] + box2[:, 2] / 2 - b2_y1, b2_y2 = box2[:, 1] - box2[:, 3] / 2, box2[:, 1] + box2[:, 3] / 2 - - # get the coordinates of the intersection rectangle - inter_rect_x1 = torch.max(b1_x1.unsqueeze(1), b2_x1) - inter_rect_y1 = torch.max(b1_y1.unsqueeze(1), b2_y1) - inter_rect_x2 = torch.min(b1_x2.unsqueeze(1), b2_x2) - inter_rect_y2 = torch.min(b1_y2.unsqueeze(1), b2_y2) - # Intersection area - inter_area = torch.clamp(inter_rect_x2 - inter_rect_x1, 0) * torch.clamp(inter_rect_y2 - inter_rect_y1, 0) - # Union Area - b1_area = ((b1_x2 - b1_x1) * (b1_y2 - b1_y1)) - b1_area = ((b1_x2 - b1_x1) * (b1_y2 - b1_y1)).view(-1,1).expand(N,M) - b2_area = ((b2_x2 - b2_x1) * (b2_y2 - b2_y1)).view(1,-1).expand(N,M) - - return inter_area / (b1_area + b2_area - inter_area + 1e-16) - - -def build_targets_max(target, anchor_wh, nA, nC, nGh, nGw): - """ - returns nT, nCorrect, tx, ty, tw, th, tconf, tcls - """ - nB = len(target) # number of images in batch - - txy = torch.zeros(nB, nA, nGh, nGw, 2).cuda() # batch size, anchors, grid size - twh = torch.zeros(nB, nA, nGh, nGw, 2).cuda() - tconf = torch.LongTensor(nB, nA, nGh, nGw).fill_(0).cuda() - tcls = torch.ByteTensor(nB, nA, nGh, nGw, nC).fill_(0).cuda() # nC = number of classes - tid = torch.LongTensor(nB, nA, nGh, nGw, 1).fill_(-1).cuda() - for b in range(nB): - t = target[b] - t_id = t[:, 1].clone().long().cuda() - t = t[:,[0,2,3,4,5]] - nTb = len(t) # number of targets - if nTb == 0: - continue - - #gxy, gwh = t[:, 1:3] * nG, t[:, 3:5] * nG - gxy, gwh = t[: , 1:3].clone() , t[:, 3:5].clone() - gxy[:, 0] = gxy[:, 0] * nGw - gxy[:, 1] = gxy[:, 1] * nGh - gwh[:, 0] = gwh[:, 0] * nGw - gwh[:, 1] = gwh[:, 1] * nGh - gi = torch.clamp(gxy[:, 0], min=0, max=nGw -1).long() - gj = torch.clamp(gxy[:, 1], min=0, max=nGh -1).long() - - # Get grid box indices and prevent overflows (i.e. 13.01 on 13 anchors) - #gi, gj = torch.clamp(gxy.long(), min=0, max=nG - 1).t() - #gi, gj = gxy.long().t() - - # iou of targets-anchors (using wh only) - box1 = gwh - box2 = anchor_wh.unsqueeze(1) - inter_area = torch.min(box1, box2).prod(2) - iou = inter_area / (box1.prod(1) + box2.prod(2) - inter_area + 1e-16) - - # Select best iou_pred and anchor - iou_best, a = iou.max(0) # best anchor [0-2] for each target - - # Select best unique target-anchor combinations - if nTb > 1: - _, iou_order = torch.sort(-iou_best) # best to worst - - # Unique anchor selection - u = torch.stack((gi, gj, a), 0)[:, iou_order] - # _, first_unique = np.unique(u, axis=1, return_index=True) # first unique indices - first_unique = return_torch_unique_index(u, torch.unique(u, dim=1)) # torch alternative - i = iou_order[first_unique] - # best anchor must share significant commonality (iou) with target - i = i[iou_best[i] > 0.60] # TODO: examine arbitrary threshold - if len(i) == 0: - continue - - a, gj, gi, t = a[i], gj[i], gi[i], t[i] - t_id = t_id[i] - if len(t.shape) == 1: - t = t.view(1, 5) - else: - if iou_best < 0.60: - continue - - tc, gxy, gwh = t[:, 0].long(), t[:, 1:3].clone(), t[:, 3:5].clone() - gxy[:, 0] = gxy[:, 0] * nGw - gxy[:, 1] = gxy[:, 1] * nGh - gwh[:, 0] = gwh[:, 0] * nGw - gwh[:, 1] = gwh[:, 1] * nGh - - # XY coordinates - txy[b, a, gj, gi] = gxy - gxy.floor() - - # Width and height - twh[b, a, gj, gi] = torch.log(gwh / anchor_wh[a]) # yolo method - # twh[b, a, gj, gi] = torch.sqrt(gwh / anchor_wh[a]) / 2 # power method - - # One-hot encoding of label - tcls[b, a, gj, gi, tc] = 1 - tconf[b, a, gj, gi] = 1 - tid[b, a, gj, gi] = t_id.unsqueeze(1) - tbox = torch.cat([txy, twh], -1) - return tconf, tbox, tid - - - -def build_targets_thres(target, anchor_wh, nA, nC, nGh, nGw): - ID_THRESH = 0.5 - FG_THRESH = 0.5 - BG_THRESH = 0.4 - nB = len(target) # number of images in batch - assert(len(anchor_wh)==nA) - - tbox = torch.zeros(nB, nA, nGh, nGw, 4).cuda() # batch size, anchors, grid size - tconf = torch.LongTensor(nB, nA, nGh, nGw).fill_(0).cuda() - tid = torch.LongTensor(nB, nA, nGh, nGw, 1).fill_(-1).cuda() - for b in range(nB): - t = target[b] - t_id = t[:, 1].clone().long().cuda() - t = t[:,[0,2,3,4,5]] - nTb = len(t) # number of targets - if nTb == 0: - continue - - gxy, gwh = t[: , 1:3].clone() , t[:, 3:5].clone() - gxy[:, 0] = gxy[:, 0] * nGw - gxy[:, 1] = gxy[:, 1] * nGh - gwh[:, 0] = gwh[:, 0] * nGw - gwh[:, 1] = gwh[:, 1] * nGh - gxy[:, 0] = torch.clamp(gxy[:, 0], min=0, max=nGw -1) - gxy[:, 1] = torch.clamp(gxy[:, 1], min=0, max=nGh -1) - - gt_boxes = torch.cat([gxy, gwh], dim=1) # Shape Ngx4 (xc, yc, w, h) - - anchor_mesh = generate_anchor(nGh, nGw, anchor_wh) - anchor_list = anchor_mesh.permute(0,2,3,1).contiguous().view(-1, 4) # Shpae (nA x nGh x nGw) x 4 - #print(anchor_list.shape, gt_boxes.shape) - iou_pdist = bbox_iou(anchor_list, gt_boxes) # Shape (nA x nGh x nGw) x Ng - iou_max, max_gt_index = torch.max(iou_pdist, dim=1) # Shape (nA x nGh x nGw), both - - iou_map = iou_max.view(nA, nGh, nGw) - gt_index_map = max_gt_index.view(nA, nGh, nGw) - - #nms_map = pooling_nms(iou_map, 3) - - id_index = iou_map > ID_THRESH - fg_index = iou_map > FG_THRESH - bg_index = iou_map < BG_THRESH - ign_index = (iou_map < FG_THRESH) * (iou_map > BG_THRESH) - tconf[b][fg_index] = 1 - tconf[b][bg_index] = 0 - tconf[b][ign_index] = -1 - - gt_index = gt_index_map[fg_index] - gt_box_list = gt_boxes[gt_index] - gt_id_list = t_id[gt_index_map[id_index]] - #print(gt_index.shape, gt_index_map[id_index].shape, gt_boxes.shape) - if torch.sum(fg_index) > 0: - tid[b][id_index] = gt_id_list.unsqueeze(1) - fg_anchor_list = anchor_list.view(nA, nGh, nGw, 4)[fg_index] - delta_target = encode_delta(gt_box_list, fg_anchor_list) - tbox[b][fg_index] = delta_target - return tconf, tbox, tid - -def generate_anchor(nGh, nGw, anchor_wh): - nA = len(anchor_wh) - yy, xx =torch.meshgrid(torch.arange(nGh), torch.arange(nGw)) - xx, yy = xx.cuda(), yy.cuda() - - mesh = torch.stack([xx, yy], dim=0) # Shape 2, nGh, nGw - mesh = mesh.unsqueeze(0).repeat(nA,1,1,1).float() # Shape nA x 2 x nGh x nGw - anchor_offset_mesh = anchor_wh.unsqueeze(-1).unsqueeze(-1).repeat(1, 1, nGh,nGw) # Shape nA x 2 x nGh x nGw - anchor_mesh = torch.cat([mesh, anchor_offset_mesh], dim=1) # Shape nA x 4 x nGh x nGw - return anchor_mesh - -def encode_delta(gt_box_list, fg_anchor_list): - px, py, pw, ph = fg_anchor_list[:, 0], fg_anchor_list[:,1], \ - fg_anchor_list[:, 2], fg_anchor_list[:,3] - gx, gy, gw, gh = gt_box_list[:, 0], gt_box_list[:, 1], \ - gt_box_list[:, 2], gt_box_list[:, 3] - dx = (gx - px) / pw - dy = (gy - py) / ph - dw = torch.log(gw/pw) - dh = torch.log(gh/ph) - return torch.stack([dx, dy, dw, dh], dim=1) - -def decode_delta(delta, fg_anchor_list): - px, py, pw, ph = fg_anchor_list[:, 0], fg_anchor_list[:,1], \ - fg_anchor_list[:, 2], fg_anchor_list[:,3] - dx, dy, dw, dh = delta[:, 0], delta[:, 1], delta[:, 2], delta[:, 3] - gx = pw * dx + px - gy = ph * dy + py - gw = pw * torch.exp(dw) - gh = ph * torch.exp(dh) - return torch.stack([gx, gy, gw, gh], dim=1) - -def decode_delta_map(delta_map, anchors): - ''' - :param: delta_map, shape (nB, nA, nGh, nGw, 4) - :param: anchors, shape (nA,4) - ''' - nB, nA, nGh, nGw, _ = delta_map.shape - anchor_mesh = generate_anchor(nGh, nGw, anchors) - anchor_mesh = anchor_mesh.permute(0,2,3,1).contiguous() # Shpae (nA x nGh x nGw) x 4 - anchor_mesh = anchor_mesh.unsqueeze(0).repeat(nB,1,1,1,1) - pred_list = decode_delta(delta_map.view(-1,4), anchor_mesh.view(-1,4)) - pred_map = pred_list.view(nB, nA, nGh, nGw, 4) - return pred_map - - -def pooling_nms(heatmap, kernel=1): - pad = (kernel -1 ) // 2 - hmax = F.max_pool2d(heatmap, (kernel, kernel), stride=1, padding=pad) - keep = (hmax == heatmap).float() - return keep * heatmap - -def non_max_suppression(prediction, conf_thres=0.5, nms_thres=0.4, method='standard'): - """ - Removes detections with lower object confidence score than 'conf_thres' - Non-Maximum Suppression to further filter detections. - Returns detections with shape: - (x1, y1, x2, y2, object_conf, class_score, class_pred) - Args: - prediction, - conf_thres, - nms_thres, - method = 'standard' or 'fast' - """ - - output = [None for _ in range(len(prediction))] - for image_i, pred in enumerate(prediction): - # Filter out confidence scores below threshold - # Get score and class with highest confidence - - v = pred[:, 4] > conf_thres - v = v.nonzero().squeeze() - if len(v.shape) == 0: - v = v.unsqueeze(0) - - pred = pred[v] - - # If none are remaining => process next image - nP = pred.shape[0] - if not nP: - continue - # From (center x, center y, width, height) to (x1, y1, x2, y2) - pred[:, :4] = xywh2xyxy(pred[:, :4]) - - - # Non-maximum suppression - if method == 'standard': - nms_indices = nms(pred[:, :4], pred[:, 4], nms_thres) - elif method == 'fast': - nms_indices = fast_nms(pred[:, :4], pred[:, 4], iou_thres=nms_thres, conf_thres=conf_thres) - else: - raise ValueError('Invalid NMS type!') - det_max = pred[nms_indices] - - if len(det_max) > 0: - # Add max detections to outputs - output[image_i] = det_max if output[image_i] is None else torch.cat((output[image_i], det_max)) - - return output - -def fast_nms(boxes, scores, iou_thres:float=0.5, top_k:int=200, second_threshold:bool=False, conf_thres:float=0.5): - ''' - Vectorized, approximated, fast NMS, adopted from YOLACT: - https://github.com/dbolya/yolact/blob/master/layers/functions/detection.py - The original version is for multi-class NMS, here we simplify the code for single-class NMS - ''' - scores, idx = scores.sort(0, descending=True) - - idx = idx[:top_k].contiguous() - scores = scores[:top_k] - num_dets = idx.size() - - boxes = boxes[idx, :] - - iou = jaccard(boxes, boxes) - iou.triu_(diagonal=1) - iou_max, _ = iou.max(dim=0) - - keep = (iou_max <= iou_thres) - - if second_threshold: - keep *= (scores > self.conf_thresh) - - return idx[keep] - - - -@torch.jit.script -def intersect(box_a, box_b): - """ We resize both tensors to [A,B,2] without new malloc: - [A,2] -> [A,1,2] -> [A,B,2] - [B,2] -> [1,B,2] -> [A,B,2] - Then we compute the area of intersect between box_a and box_b. - Args: - box_a: (tensor) bounding boxes, Shape: [n,A,4]. - box_b: (tensor) bounding boxes, Shape: [n,B,4]. - Return: - (tensor) intersection area, Shape: [n,A,B]. - """ - n = box_a.size(0) - A = box_a.size(1) - B = box_b.size(1) - max_xy = torch.min(box_a[:, :, 2:].unsqueeze(2).expand(n, A, B, 2), - box_b[:, :, 2:].unsqueeze(1).expand(n, A, B, 2)) - min_xy = torch.max(box_a[:, :, :2].unsqueeze(2).expand(n, A, B, 2), - box_b[:, :, :2].unsqueeze(1).expand(n, A, B, 2)) - inter = torch.clamp((max_xy - min_xy), min=0) - return inter[:, :, :, 0] * inter[:, :, :, 1] - - - -def jaccard(box_a, box_b, iscrowd:bool=False): - """Compute the jaccard overlap of two sets of boxes. The jaccard overlap - is simply the intersection over union of two boxes. Here we operate on - ground truth boxes and default boxes. If iscrowd=True, put the crowd in box_b. - E.g.: - A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B) - Args: - box_a: (tensor) Ground truth bounding boxes, Shape: [num_objects,4] - box_b: (tensor) Prior boxes from priorbox layers, Shape: [num_priors,4] - Return: - jaccard overlap: (tensor) Shape: [box_a.size(0), box_b.size(0)] - """ - use_batch = True - if box_a.dim() == 2: - use_batch = False - box_a = box_a[None, ...] - box_b = box_b[None, ...] - - inter = intersect(box_a, box_b) - area_a = ((box_a[:, :, 2]-box_a[:, :, 0]) * - (box_a[:, :, 3]-box_a[:, :, 1])).unsqueeze(2).expand_as(inter) # [A,B] - area_b = ((box_b[:, :, 2]-box_b[:, :, 0]) * - (box_b[:, :, 3]-box_b[:, :, 1])).unsqueeze(1).expand_as(inter) # [A,B] - union = area_a + area_b - inter - - out = inter / area_a if iscrowd else inter / union - return out if use_batch else out.squeeze(0) - - - - -def return_torch_unique_index(u, uv): - n = uv.shape[1] # number of columns - first_unique = torch.zeros(n, device=u.device).long() - for j in range(n): - first_unique[j] = (uv[:, j:j + 1] == u).all(0).nonzero()[0] - - return first_unique - - -def strip_optimizer_from_checkpoint(filename='weights/best.pt'): - # Strip optimizer from *.pt files for lighter files (reduced by 2/3 size) - - a = torch.load(filename, map_location='cpu') - a['optimizer'] = [] - torch.save(a, filename.replace('.pt', '_lite.pt')) - - -def plot_results(): - # Plot YOLO training results file 'results.txt' - # import os; os.system('wget https://storage.googleapis.com/ultralytics/yolov3/results_v1.txt') - - plt.figure(figsize=(14, 7)) - s = ['X + Y', 'Width + Height', 'Confidence', 'Classification', 'Total Loss', 'mAP', 'Recall', 'Precision'] - files = sorted(glob.glob('results*.txt')) - for f in files: - results = np.loadtxt(f, usecols=[2, 3, 4, 5, 6, 9, 10, 11]).T # column 11 is mAP - x = range(1, results.shape[1]) - for i in range(8): - plt.subplot(2, 4, i + 1) - plt.plot(x, results[i, x], marker='.', label=f) - plt.title(s[i]) - if i == 0: - plt.legend() -def load_checkpoint(fpath): - r"""Loads checkpoint. - - ``UnicodeDecodeError`` can be well handled, which means - python2-saved files can be read from python3. - - Args: - fpath (str): path to checkpoint. - - Returns: - dict - - Examples:: - >>> from torchreid.utils import load_checkpoint - >>> fpath = 'log/my_model/model.pth.tar-10' - >>> checkpoint = load_checkpoint(fpath) - """ - if fpath is None: - raise ValueError('File path is None') - if not osp.exists(fpath): - raise FileNotFoundError('File is not found at "{}"'.format(fpath)) - map_location = None if torch.cuda.is_available() else 'cpu' - try: - checkpoint = torch.load(fpath, map_location=map_location) - except UnicodeDecodeError: - pickle.load = partial(pickle.load, encoding="latin1") - pickle.Unpickler = partial(pickle.Unpickler, encoding="latin1") - checkpoint = torch.load( - fpath, pickle_module=pickle, map_location=map_location - ) - except Exception: - print('Unable to load checkpoint from "{}"'.format(fpath)) - raise - return checkpoint -def load_pretrained_weights(model, weight_path): - r"""Loads pretrianed weights to model. - - Features:: - - Incompatible layers (unmatched in name or size) will be ignored. - - Can automatically deal with keys containing "module.". - - Args: - model (nn.Module): network model. - weight_path (str): path to pretrained weights. - - Examples:: - >>> from torchreid.utils import load_pretrained_weights - >>> weight_path = 'log/my_model/model-best.pth.tar' - >>> load_pretrained_weights(model, weight_path) - """ - checkpoint = load_checkpoint(weight_path) - if 'state_dict' in checkpoint: - state_dict = checkpoint['state_dict'] - else: - state_dict = checkpoint - - model_dict = model.state_dict() - new_state_dict = OrderedDict() - matched_layers, discarded_layers = [], [] - #show weight keys - ''' - print('keys of loaded model:') - for k, v in state_dict.items(): - print(k) - print('keys of model archs:') - for k, v in model_dict.items(): - print(k) - ''' - for k, v in state_dict.items(): - if not k.startswith('module.'): - k = 'module.' + k - - if k in model_dict and model_dict[k].size() == v.size(): - new_state_dict[k] = v - matched_layers.append(k) - else: - discarded_layers.append(k) - - model_dict.update(new_state_dict) - model.load_state_dict(model_dict) - - if len(matched_layers) == 0: - warnings.warn( - 'The pretrained weights "{}" cannot be loaded, ' - 'please check the key names manually ' - '(** ignored and continue **)'.format(weight_path) - ) - else: - print( - 'loading reid model from {}...'. - format(weight_path) - ) - ''' - if len(discarded_layers) > 0: - print( - '** The following layers are discarded ' - 'due to unmatched keys or layer size: {}'. - format(discarded_layers) - ) - ''' -- Gitee