From 13a7695040fcbb6f5a0131a60b3dbcb890722608 Mon Sep 17 00:00:00 2001 From: Hardik Dava <39372750+hardikdava@users.noreply.github.com> Date: Thu, 13 Jul 2023 09:18:10 +0200 Subject: [PATCH 01/11] Create main.py --- .../pytorch/ultralytics/yolov8/nuclio/main.py | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 serverless/pytorch/ultralytics/yolov8/nuclio/main.py diff --git a/serverless/pytorch/ultralytics/yolov8/nuclio/main.py b/serverless/pytorch/ultralytics/yolov8/nuclio/main.py new file mode 100644 index 000000000000..4e2659e18805 --- /dev/null +++ b/serverless/pytorch/ultralytics/yolov8/nuclio/main.py @@ -0,0 +1,58 @@ +import json +import base64 +from PIL import Image +import io +import torch +from ultralytics import YOLO +import supervision as sv + + +def init_context(context): + context.logger.info("Init context... 0%") + + model_path = "yolov8m.pt" + + model = YOLO(model_path) + + # Read the DL model + context.user_data.model = model + + context.logger.info("Init context...100%") + + +def handler(context, event): + context.logger.info("Run yolo-v8 model") + data = event.body + buf = io.BytesIO(base64.b64decode(data["image"])) + threshold = float(data.get("threshold", 0.5)) + context.user_data.model.conf = threshold + image = Image.open(buf) + + yolo_results = context.user_data.model(image, conf=threshold)[0] + labels = yolo_results.names + detections = sv.Detections.from_yolov8(yolo_results) + + detections = detections[detections.confidence > threshold] + boxes = detections.xyxy + conf = detections.confidence + class_ids = detections.class_id + + results = [] + + if boxes.shape[0] > 0: + + for label, score, box in zip(class_ids, conf, boxes): + + xtl = int(box[0]) + ytl = int(box[1]) + xbr = int(box[2]) + ybr = int(box[3]) + + results.append({ + "confidence": str(score), + "label": labels.get(label, "unknown"), + "points": [xtl, ytl, xbr, ybr], + "type": "rectangle",}) + + return context.Response(body=json.dumps(results), headers={}, + content_type='application/json', status_code=200) From 1b6470c4f3296b46c68447cc0e9eb5601d173a6e Mon Sep 17 00:00:00 2001 From: Hardik Dava <39372750+hardikdava@users.noreply.github.com> Date: Thu, 13 Jul 2023 09:19:56 +0200 Subject: [PATCH 02/11] Create function.yaml --- .../ultralytics/yolov8/nuclio/function.yaml | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 serverless/pytorch/ultralytics/yolov8/nuclio/function.yaml diff --git a/serverless/pytorch/ultralytics/yolov8/nuclio/function.yaml b/serverless/pytorch/ultralytics/yolov8/nuclio/function.yaml new file mode 100644 index 000000000000..d425e18c9cd2 --- /dev/null +++ b/serverless/pytorch/ultralytics/yolov8/nuclio/function.yaml @@ -0,0 +1,126 @@ +metadata: + name: pth-ultralytics-yolov8 + namespace: cvat + annotations: + name: YOLO v8 + type: detector + framework: pytorch + spec: | + [ + { "id": 0, "name": "person" }, + { "id": 1, "name": "bicycle" }, + { "id": 2, "name": "car" }, + { "id": 3, "name": "motorbike" }, + { "id": 4, "name": "aeroplane" }, + { "id": 5, "name": "bus" }, + { "id": 6, "name": "train" }, + { "id": 7, "name": "truck" }, + { "id": 8, "name": "boat" }, + { "id": 9, "name": "traffic light" }, + { "id": 10, "name": "fire hydrant" }, + { "id": 11, "name": "stop sign" }, + { "id": 12, "name": "parking meter" }, + { "id": 13, "name": "bench" }, + { "id": 14, "name": "bird" }, + { "id": 15, "name": "cat" }, + { "id": 16, "name": "dog" }, + { "id": 17, "name": "horse" }, + { "id": 18, "name": "sheep" }, + { "id": 19, "name": "cow" }, + { "id": 20, "name": "elephant" }, + { "id": 21, "name": "bear" }, + { "id": 22, "name": "zebra" }, + { "id": 23, "name": "giraffe" }, + { "id": 24, "name": "backpack" }, + { "id": 25, "name": "umbrella" }, + { "id": 26, "name": "handbag" }, + { "id": 27, "name": "tie" }, + { "id": 28, "name": "suitcase" }, + { "id": 29, "name": "frisbee" }, + { "id": 30, "name": "skis" }, + { "id": 31, "name": "snowboard" }, + { "id": 32, "name": "sports ball" }, + { "id": 33, "name": "kite" }, + { "id": 34, "name": "baseball bat" }, + { "id": 35, "name": "baseball glove" }, + { "id": 36, "name": "skateboard" }, + { "id": 37, "name": "surfboard" }, + { "id": 38, "name": "tennis racket" }, + { "id": 39, "name": "bottle" }, + { "id": 40, "name": "wine glass" }, + { "id": 41, "name": "cup" }, + { "id": 42, "name": "fork" }, + { "id": 43, "name": "knife" }, + { "id": 44, "name": "spoon" }, + { "id": 45, "name": "bowl" }, + { "id": 46, "name": "banana" }, + { "id": 47, "name": "apple" }, + { "id": 48, "name": "sandwich" }, + { "id": 49, "name": "orange" }, + { "id": 50, "name": "broccoli" }, + { "id": 51, "name": "carrot" }, + { "id": 52, "name": "hot dog" }, + { "id": 53, "name": "pizza" }, + { "id": 54, "name": "donut" }, + { "id": 55, "name": "cake" }, + { "id": 56, "name": "chair" }, + { "id": 57, "name": "sofa" }, + { "id": 58, "name": "pottedplant" }, + { "id": 59, "name": "bed" }, + { "id": 60, "name": "diningtable" }, + { "id": 61, "name": "toilet" }, + { "id": 62, "name": "tvmonitor" }, + { "id": 63, "name": "laptop" }, + { "id": 64, "name": "mouse" }, + { "id": 65, "name": "remote" }, + { "id": 66, "name": "keyboard" }, + { "id": 67, "name": "cell phone" }, + { "id": 68, "name": "microwave" }, + { "id": 69, "name": "oven" }, + { "id": 70, "name": "toaster" }, + { "id": 71, "name": "sink" }, + { "id": 72, "name": "refrigerator" }, + { "id": 73, "name": "book" }, + { "id": 74, "name": "clock" }, + { "id": 75, "name": "vase" }, + { "id": 76, "name": "scissors" }, + { "id": 77, "name": "teddy bear" }, + { "id": 78, "name": "hair drier" }, + { "id": 79, "name": "toothbrush" } + ] + +spec: + description: YOLO v8 via Ultralytics Pytorch + runtime: 'python:3.8' + handler: main:handler + eventTimeout: 30s + build: + + image: vat.pth.ultralytics.yolov8 + baseImage: ultralytics/ultralytics:latest-cpu + + directives: + preCopy: + - kind: USER + value: root + - kind: RUN + value: apt update && apt install --no-install-recommends -y libglib2.0-0 + - kind: RUN + value: pip install supervision + - kind: WORKDIR + value: /opt/nuclio + + triggers: + myHttpTrigger: + maxWorkers: 1 + kind: 'http' + workerAvailabilityTimeoutMilliseconds: 10000 + attributes: + maxRequestBodySize: 33554432 # 32MB + + platform: + attributes: + restartPolicy: + name: always + maximumRetryCount: 3 + mountMode: volume From f037a2b629e629706c0bfa5cec4918bb93d8b372 Mon Sep 17 00:00:00 2001 From: Hardik Dava <39372750+hardikdava@users.noreply.github.com> Date: Thu, 13 Jul 2023 09:21:40 +0200 Subject: [PATCH 03/11] Update function.yaml --- serverless/pytorch/ultralytics/yolov8/nuclio/function.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serverless/pytorch/ultralytics/yolov8/nuclio/function.yaml b/serverless/pytorch/ultralytics/yolov8/nuclio/function.yaml index d425e18c9cd2..654a8b01290e 100644 --- a/serverless/pytorch/ultralytics/yolov8/nuclio/function.yaml +++ b/serverless/pytorch/ultralytics/yolov8/nuclio/function.yaml @@ -96,7 +96,7 @@ spec: eventTimeout: 30s build: - image: vat.pth.ultralytics.yolov8 + image: cvat.pth.ultralytics.yolov8 baseImage: ultralytics/ultralytics:latest-cpu directives: From e0ba841f3484938ad397909ed2685623115eb3f1 Mon Sep 17 00:00:00 2001 From: Hardik Dava <39372750+hardikdava@users.noreply.github.com> Date: Thu, 13 Jul 2023 09:22:47 +0200 Subject: [PATCH 04/11] Create function-gpu.yaml --- .../yolov8/nuclio/function-gpu.yaml | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 serverless/pytorch/ultralytics/yolov8/nuclio/function-gpu.yaml diff --git a/serverless/pytorch/ultralytics/yolov8/nuclio/function-gpu.yaml b/serverless/pytorch/ultralytics/yolov8/nuclio/function-gpu.yaml new file mode 100644 index 000000000000..9d99ff1e3e36 --- /dev/null +++ b/serverless/pytorch/ultralytics/yolov8/nuclio/function-gpu.yaml @@ -0,0 +1,127 @@ +metadata: + name: pth-ultralytics-yolov8 + namespace: cvat + annotations: + name: YOLO v8 + type: detector + framework: pytorch + spec: | + [ + { "id": 0, "name": "person" }, + { "id": 1, "name": "bicycle" }, + { "id": 2, "name": "car" }, + { "id": 3, "name": "motorbike" }, + { "id": 4, "name": "aeroplane" }, + { "id": 5, "name": "bus" }, + { "id": 6, "name": "train" }, + { "id": 7, "name": "truck" }, + { "id": 8, "name": "boat" }, + { "id": 9, "name": "traffic light" }, + { "id": 10, "name": "fire hydrant" }, + { "id": 11, "name": "stop sign" }, + { "id": 12, "name": "parking meter" }, + { "id": 13, "name": "bench" }, + { "id": 14, "name": "bird" }, + { "id": 15, "name": "cat" }, + { "id": 16, "name": "dog" }, + { "id": 17, "name": "horse" }, + { "id": 18, "name": "sheep" }, + { "id": 19, "name": "cow" }, + { "id": 20, "name": "elephant" }, + { "id": 21, "name": "bear" }, + { "id": 22, "name": "zebra" }, + { "id": 23, "name": "giraffe" }, + { "id": 24, "name": "backpack" }, + { "id": 25, "name": "umbrella" }, + { "id": 26, "name": "handbag" }, + { "id": 27, "name": "tie" }, + { "id": 28, "name": "suitcase" }, + { "id": 29, "name": "frisbee" }, + { "id": 30, "name": "skis" }, + { "id": 31, "name": "snowboard" }, + { "id": 32, "name": "sports ball" }, + { "id": 33, "name": "kite" }, + { "id": 34, "name": "baseball bat" }, + { "id": 35, "name": "baseball glove" }, + { "id": 36, "name": "skateboard" }, + { "id": 37, "name": "surfboard" }, + { "id": 38, "name": "tennis racket" }, + { "id": 39, "name": "bottle" }, + { "id": 40, "name": "wine glass" }, + { "id": 41, "name": "cup" }, + { "id": 42, "name": "fork" }, + { "id": 43, "name": "knife" }, + { "id": 44, "name": "spoon" }, + { "id": 45, "name": "bowl" }, + { "id": 46, "name": "banana" }, + { "id": 47, "name": "apple" }, + { "id": 48, "name": "sandwich" }, + { "id": 49, "name": "orange" }, + { "id": 50, "name": "broccoli" }, + { "id": 51, "name": "carrot" }, + { "id": 52, "name": "hot dog" }, + { "id": 53, "name": "pizza" }, + { "id": 54, "name": "donut" }, + { "id": 55, "name": "cake" }, + { "id": 56, "name": "chair" }, + { "id": 57, "name": "sofa" }, + { "id": 58, "name": "pottedplant" }, + { "id": 59, "name": "bed" }, + { "id": 60, "name": "diningtable" }, + { "id": 61, "name": "toilet" }, + { "id": 62, "name": "tvmonitor" }, + { "id": 63, "name": "laptop" }, + { "id": 64, "name": "mouse" }, + { "id": 65, "name": "remote" }, + { "id": 66, "name": "keyboard" }, + { "id": 67, "name": "cell phone" }, + { "id": 68, "name": "microwave" }, + { "id": 69, "name": "oven" }, + { "id": 70, "name": "toaster" }, + { "id": 71, "name": "sink" }, + { "id": 72, "name": "refrigerator" }, + { "id": 73, "name": "book" }, + { "id": 74, "name": "clock" }, + { "id": 75, "name": "vase" }, + { "id": 76, "name": "scissors" }, + { "id": 77, "name": "teddy bear" }, + { "id": 78, "name": "hair drier" }, + { "id": 79, "name": "toothbrush" } + ] + +spec: + description: YOLO v8 via Ultralytics Pytorch + runtime: 'python:3.8' + handler: main:handler + eventTimeout: 30s + build: + image: cvat.pth.ultralytics.yolov8 + baseImage: ultralytics/yolov5:latest + + directives: + preCopy: + - kind: USER + value: root + - kind: RUN + value: apt update && apt install --no-install-recommends -y libglib2.0-0 + - kind: WORKDIR + value: /opt/nuclio + + triggers: + myHttpTrigger: + maxWorkers: 1 + kind: 'http' + workerAvailabilityTimeoutMilliseconds: 10000 + attributes: + maxRequestBodySize: 33554432 # 32MB + + resources: + limits: + nvidia.com/gpu: 1 + + platform: + attributes: + restartPolicy: + name: always + maximumRetryCount: 3 + mountMode: volume From 9b8d9e8f494336369683c2583e90df92bf342dc4 Mon Sep 17 00:00:00 2001 From: Hardik Dava <39372750+hardikdava@users.noreply.github.com> Date: Thu, 13 Jul 2023 09:25:27 +0200 Subject: [PATCH 05/11] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3192c62a898a..36e8e2c53566 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,7 @@ up to 10x. Here is a list of the algorithms we support, and the platforms they c | [Semantic segmentation for ADAS](/serverless/openvino/omz/intel/semantic-segmentation-adas-0001/nuclio) | detector | OpenVINO | ✔️ | | | [Text detection v4](/serverless/openvino/omz/intel/text-detection-0004/nuclio) | detector | OpenVINO | ✔️ | | | [YOLO v5](/serverless/pytorch/ultralytics/yolov5/nuclio) | detector | PyTorch | ✔️ | | +| [YOLO v8](/serverless/pytorch/ultralytics/yolov8/nuclio) | detector | PyTorch | ✔️ | ✔️ | | [SiamMask](/serverless/pytorch/foolwood/siammask/nuclio) | tracker | PyTorch | ✔️ | ✔️ | | [TransT](/serverless/pytorch/dschoerk/transt/nuclio) | tracker | PyTorch | ✔️ | ✔️ | | [f-BRS](/serverless/pytorch/saic-vul/fbrs/nuclio) | interactor | PyTorch | ✔️ | | From 93b30510bf2615b4713a6e15a8bbd99309a2a4f6 Mon Sep 17 00:00:00 2001 From: Hardik Dava <39372750+hardikdava@users.noreply.github.com> Date: Thu, 13 Jul 2023 09:27:10 +0200 Subject: [PATCH 06/11] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a08bcdf77f02..0aae832c9458 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## \[Unreleased] ### Added - Multi-line text attributes supported () +- Added YoloV8 serverless support for semi/automatic annotation ### Changed - TDB From 32312fec5b8e80c041a2939d11b97afaff946d0a Mon Sep 17 00:00:00 2001 From: Nikita Manovich Date: Thu, 13 Jul 2023 16:40:39 +0300 Subject: [PATCH 07/11] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aae832c9458..d7a3d2300975 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## \[Unreleased] ### Added - Multi-line text attributes supported () -- Added YoloV8 serverless support for semi/automatic annotation +- Added YoloV8 serverless support for semi/automatic annotation () ### Changed - TDB From f63d51ccbe44cb5a6bbe68b4a34fd99aad700a8c Mon Sep 17 00:00:00 2001 From: Nikita Manovich Date: Thu, 13 Jul 2023 16:44:59 +0300 Subject: [PATCH 08/11] Update serverless/pytorch/ultralytics/yolov8/nuclio/main.py --- serverless/pytorch/ultralytics/yolov8/nuclio/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/serverless/pytorch/ultralytics/yolov8/nuclio/main.py b/serverless/pytorch/ultralytics/yolov8/nuclio/main.py index 4e2659e18805..a66f7a41f72a 100644 --- a/serverless/pytorch/ultralytics/yolov8/nuclio/main.py +++ b/serverless/pytorch/ultralytics/yolov8/nuclio/main.py @@ -2,7 +2,6 @@ import base64 from PIL import Image import io -import torch from ultralytics import YOLO import supervision as sv From ba675e54b2eb12732f3d721c018f6eedda2d16f6 Mon Sep 17 00:00:00 2001 From: Hardik Dava <39372750+hardikdava@users.noreply.github.com> Date: Thu, 13 Jul 2023 17:56:51 +0200 Subject: [PATCH 09/11] Update function-gpu.yaml --- .../pytorch/ultralytics/yolov8/nuclio/function-gpu.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/serverless/pytorch/ultralytics/yolov8/nuclio/function-gpu.yaml b/serverless/pytorch/ultralytics/yolov8/nuclio/function-gpu.yaml index 9d99ff1e3e36..adaade216bf8 100644 --- a/serverless/pytorch/ultralytics/yolov8/nuclio/function-gpu.yaml +++ b/serverless/pytorch/ultralytics/yolov8/nuclio/function-gpu.yaml @@ -106,6 +106,10 @@ spec: value: apt update && apt install --no-install-recommends -y libglib2.0-0 - kind: WORKDIR value: /opt/nuclio + - kind: RUN + value: pip install supervision + - kind: WORKDIR + value: /opt/nuclio triggers: myHttpTrigger: From c30b9718b2b9a6d3d4017c8f831197258c70d8ea Mon Sep 17 00:00:00 2001 From: Hardik Dava <39372750+hardikdava@users.noreply.github.com> Date: Thu, 13 Jul 2023 18:02:35 +0200 Subject: [PATCH 10/11] Update ai-tools.md --- site/content/en/docs/manual/advanced/ai-tools.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/site/content/en/docs/manual/advanced/ai-tools.md b/site/content/en/docs/manual/advanced/ai-tools.md index 3c355eb745dd..3e093d1fa2a5 100644 --- a/site/content/en/docs/manual/advanced/ai-tools.md +++ b/site/content/en/docs/manual/advanced/ai-tools.md @@ -204,7 +204,8 @@ see [Automatic annotation](/docs/manual/advanced/automatic-annotation/). | Mask RCNN | The model generates polygons for each instance of an object in the image.

For more information, see:
  • [GitHub: Mask RCNN](https://github.com/matterport/Mask_RCNN)
  • [Paper: Mask RCNN](https://arxiv.org/pdf/1703.06870.pdf) | | Faster RCNN | The model generates bounding boxes for each instance of an object in the image.
    In this model, RPN and Fast R-CNN are combined into a single network.

    For more information, see:
  • [GitHub: Faster RCNN](https://github.com/ShaoqingRen/faster_rcnn)
  • [Paper: Faster RCNN](https://arxiv.org/pdf/1506.01497.pdf) | | YOLO v3 | YOLO v3 is a family of object detection architectures and models pre-trained on the COCO dataset.

    For more information, see:
  • [GitHub: YOLO v3](https://github.com/ultralytics/yolov3)
  • [Site: YOLO v3](https://docs.ultralytics.com/#yolov3)
  • [Paper: YOLO v3](https://arxiv.org/pdf/1804.02767v1.pdf) | -| YOLO v5 | YOLO v5 is a family of object detection architectures and models based on the Pytorch framework.

    For more information, see:
  • [GitHub: YOLO v5](https://github.com/ultralytics/yolov5)
  • [Site: YOLO v5](https://docs.ultralytics.com/#yolov5) | +| YOLO v5 | YOLO v5 is a family of object detection architectures and models based on the Pytorch framework.

    For more information, see:
  • [GitHub: YOLO v5](https://github.com/ultralytics/yolov5)
  • [Site: YOLO v5](https://docs.ultralytics.com/#yolov5) +| YOLO v8 | YOLO v8 is a family of object detection architectures and models based on the Pytorch and Ultralytics framework.

    For more information, see:
  • [GitHub: YOLO v8](https://github.com/ultralytics/ultralytics)
  • [Site: YOLO v8](https://docs.ultralytics.com/models/yolov8/) | | Semantic segmentation for ADAS | This is a segmentation network to classify each pixel into 20 classes.

    For more information, see:
  • [Site: ADAS](https://docs.openvino.ai/2019_R1/_semantic_segmentation_adas_0001_description_semantic_segmentation_adas_0001.html) | | Mask RCNN with Tensorflow | Mask RCNN version with Tensorflow. The model generates polygons for each instance of an object in the image.

    For more information, see:
  • [GitHub: Mask RCNN](https://github.com/matterport/Mask_RCNN)
  • [Paper: Mask RCNN](https://arxiv.org/pdf/1703.06870.pdf) | | Faster RCNN with Tensorflow | Faster RCNN version with Tensorflow. The model generates bounding boxes for each instance of an object in the image.
    In this model, RPN and Fast R-CNN are combined into a single network.

    For more information, see:
  • [Site: Faster RCNN with Tensorflow](https://docs.openvino.ai/2021.4/omz_models_model_faster_rcnn_inception_v2_coco.html)
  • [Paper: Faster RCNN](https://arxiv.org/pdf/1506.01497.pdf) | From 35538eb1cfb6231e96fd05bd1bacffacd7a0ce0b Mon Sep 17 00:00:00 2001 From: Hardik Dava <39372750+hardikdava@users.noreply.github.com> Date: Thu, 20 Jul 2023 12:23:31 +0200 Subject: [PATCH 11/11] Update main.py --- .../pytorch/ultralytics/yolov8/nuclio/main.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/serverless/pytorch/ultralytics/yolov8/nuclio/main.py b/serverless/pytorch/ultralytics/yolov8/nuclio/main.py index a66f7a41f72a..3249993e31dd 100644 --- a/serverless/pytorch/ultralytics/yolov8/nuclio/main.py +++ b/serverless/pytorch/ultralytics/yolov8/nuclio/main.py @@ -5,20 +5,15 @@ from ultralytics import YOLO import supervision as sv - def init_context(context): context.logger.info("Init context... 0%") - + # Change model path for custom model model_path = "yolov8m.pt" - model = YOLO(model_path) - # Read the DL model context.user_data.model = model - context.logger.info("Init context...100%") - def handler(context, event): context.logger.info("Run yolo-v8 model") data = event.body @@ -26,22 +21,17 @@ def handler(context, event): threshold = float(data.get("threshold", 0.5)) context.user_data.model.conf = threshold image = Image.open(buf) - yolo_results = context.user_data.model(image, conf=threshold)[0] labels = yolo_results.names detections = sv.Detections.from_yolov8(yolo_results) - detections = detections[detections.confidence > threshold] boxes = detections.xyxy conf = detections.confidence class_ids = detections.class_id - - results = [] + results = [] if boxes.shape[0] > 0: - - for label, score, box in zip(class_ids, conf, boxes): - + for label, score, box in zip(class_ids, conf, boxes): xtl = int(box[0]) ytl = int(box[1]) xbr = int(box[2])