From af0f3f514fe6328a544b2c800737a3dc835ceee0 Mon Sep 17 00:00:00 2001 From: jkbmrz Date: Thu, 17 Apr 2025 18:50:22 +0200 Subject: [PATCH 1/6] feat: generate_script_content remove rvc2/4 differentiation --- .../node/utils/detection_config_generator.py | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/depthai_nodes/node/utils/detection_config_generator.py b/depthai_nodes/node/utils/detection_config_generator.py index 55d5d954..428e3ec8 100644 --- a/depthai_nodes/node/utils/detection_config_generator.py +++ b/depthai_nodes/node/utils/detection_config_generator.py @@ -2,9 +2,9 @@ def generate_script_content( - platform: str, resize_width: int, resize_height: int, + resize_mode: str = "STRETCH", padding: float = 0, valid_labels: Optional[List[int]] = None, ) -> str: @@ -14,12 +14,13 @@ def generate_script_content( also work with padding around the detection bounding box and filter detections by labels. - @param platform: Target platform for the script. Supported values: 'rvc2', 'rvc4' - @type platform: str @param resize_width: Target width for the resized image @type resize_width: int @param resize_height: Target height for the resized image @type resize_height: int + @param resize_mode: Resize mode for the image. Supported values: 'LETTERBOX', + 'CENTER_CROP', and 'STRETCH' + @type resize_mode: str @param padding: Additional padding around the detection in normalized coordinates (0-1) @type padding: float @@ -30,15 +31,10 @@ def generate_script_content( @rtype: str """ - if platform.lower() == "rvc2": - cfg_content = f""" - cfg = ImageManipConfig() - cfg.setCropRect(det.xmin - {padding}, det.ymin - {padding}, det.xmax + {padding}, det.ymax + {padding}) - cfg.setResize({resize_width}, {resize_height}) - cfg.setKeepAspectRatio(False) - """ - elif platform.lower() == "rvc4": - cfg_content = f""" + if resize_mode not in ["LETTERBOX", "CENTER_CROP", "STRETCH"]: + raise ValueError("Unsupported resize mode") + + cfg_content = f""" cfg = ImageManipConfigV2() rect = RotatedRect() rect.center.x = (det.xmin + det.xmax) / 2 @@ -49,11 +45,9 @@ def generate_script_content( rect.size.height = rect.size.height + {padding} * 2 rect.angle = 0 - cfg.addCropRotatedRect(rect=rect, normalizedCoords=True) - cfg.setOutputSize({resize_width}, {resize_height}) + cfg.addCropRotatedRect(rect, True) + cfg.setOutputSize({resize_width}, {resize_height}, ImageManipConfigV2.ResizeMode.{resize_mode}) """ - else: - raise ValueError("Unsupported platform") validate_label = ( f""" if det.label not in {valid_labels}: From 9cf08c8e22a0b7277aef53fac69b5271bfc7cc0b Mon Sep 17 00:00:00 2001 From: jkbmrz Date: Thu, 17 Apr 2025 18:50:32 +0200 Subject: [PATCH 2/6] fix: unittests --- .../test_detection_config_generator.py | 60 +++---------------- 1 file changed, 7 insertions(+), 53 deletions(-) diff --git a/tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py b/tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py index 45b27430..fa172871 100644 --- a/tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py +++ b/tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py @@ -168,7 +168,6 @@ def node_input_detections(node) -> List[dai.ImgDetections]: return node.inputs[Node.INPUT_DETECTIONS_KEY].items -@pytest.mark.parametrize("platform", ["rvc2", "rvc4"]) def test_passthrough( node, node_input_detections, @@ -177,7 +176,7 @@ def test_passthrough( resize_width, resize_height, ): - script = generate_script_content(platform, resize_width, resize_height) + script = generate_script_content(resize_width, resize_height) expected_frames = [] for frame, detections in zip(node_input_frames, node_input_detections): for _ in detections.detections: @@ -191,7 +190,7 @@ def test_passthrough( assert len(get_output_config(node)) == len(expected_frames) -@pytest.mark.parametrize(("platform", "labels"), [("rvc2", [1]), ("rvc4", [1, 2])]) +@pytest.mark.parametrize("labels", [[1], [1, 2]]) def test_label_validation( node, node_input_detections, @@ -207,9 +206,7 @@ def test_label_validation( if detection.label not in labels: continue expected_frames.append(frame) - script = generate_script_content( - platform, resize_width, resize_height, valid_labels=labels - ) + script = generate_script_content(resize_width, resize_height, valid_labels=labels) try: run_script(node, script) except Warning: @@ -217,20 +214,8 @@ def test_label_validation( @pytest.mark.parametrize("resize", [(128, 128), (128, 256), (256, 256)]) -def test_rvc2_output_size(node, resize): - script = generate_script_content("rvc2", *resize) - try: - run_script(node, script) - except Warning: - output_cfg = get_output_config(node) - for cfg in output_cfg: - assert isinstance(cfg, dai.ImageManipConfig) - assert cfg.getResizeWidth(), cfg.getResizeHeight() == resize - - -@pytest.mark.parametrize("resize", [(128, 128), (128, 256), (256, 256)]) -def test_rvc4_output_size(node, resize): - script = generate_script_content("rvc4", *resize) +def test_output_size(node, resize): + script = generate_script_content(*resize) try: run_script(node, script) except Warning: @@ -241,36 +226,7 @@ def test_rvc4_output_size(node, resize): @pytest.mark.parametrize("padding", [0, 0.1, 0.2, -0.1, -0.2]) -def test_rvc2_crop(node, node_input_detections, padding, resize_width, resize_height): - expected_rects: List[dai.ImageManipConfig.CropRect] = [] - for input_dets in node_input_detections: - for detection in input_dets.detections: - rect = dai.ImageManipConfig.CropRect() - rect.xmin = max(detection.xmin - padding, 0) - rect.xmax = min(detection.xmax + padding, 1) - rect.ymin = max(detection.ymin - padding, 0) - rect.ymax = min(detection.ymax + padding, 1) - expected_rects.append(rect) - script = generate_script_content( - "rvc2", resize_width, resize_height, padding=padding - ) - try: - run_script(node, script) - except Warning: - output_cfg = get_output_config(node) - for cfg, expected_rect in zip(output_cfg, expected_rects): - assert isinstance(cfg, dai.ImageManipConfig) - crop_rect = cfg.getCropConfig().cropRect - assert (crop_rect.xmin, crop_rect.xmax, crop_rect.ymin, crop_rect.ymax) == ( - expected_rect.xmin, - expected_rect.xmax, - expected_rect.ymin, - expected_rect.ymax, - ) - - -@pytest.mark.parametrize("padding", [0, 0.1, 0.2, -0.1, -0.2]) -def test_rvc4_crop(node, node_input_detections, padding, resize_width, resize_height): +def test_crop(node, node_input_detections, padding, resize_width, resize_height): ANGLE = 0 expected_rects: List[dai.RotatedRect] = [] for input_dets in node_input_detections: @@ -283,9 +239,7 @@ def test_rvc4_crop(node, node_input_detections, padding, resize_width, resize_he rect.size.width = detection.xmax - detection.xmin + rect_padding rect.size.height = detection.ymax - detection.ymin + rect_padding expected_rects.append(rect) - script = generate_script_content( - "rvc4", resize_width, resize_height, padding=padding - ) + script = generate_script_content(resize_width, resize_height, padding=padding) try: run_script(node, script) except Warning: From 9c94feccb2fd5e5026854d41a99bcc432bd4ad1c Mon Sep 17 00:00:00 2001 From: jkbmrz Date: Fri, 18 Apr 2025 14:41:05 +0200 Subject: [PATCH 3/6] fix: unittests 2 --- .../test_detection_config_generator.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py b/tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py index fa172871..7b3774e3 100644 --- a/tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py +++ b/tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Union +from typing import List, Optional import depthai as dai import pytest @@ -16,11 +16,6 @@ def resize_height(): return 256 -def test_rvc3_unsupported(resize_width, resize_height): - with pytest.raises(ValueError, match="Unsupported"): - generate_script_content("rvc3", resize_width, resize_height) - - class ImageManipConfigV2(dai.ImageManipConfigV2): def __init__(self): super().__init__() @@ -172,7 +167,6 @@ def test_passthrough( node, node_input_detections, node_input_frames, - platform, resize_width, resize_height, ): @@ -195,7 +189,6 @@ def test_label_validation( node, node_input_detections, node_input_frames, - platform, labels, resize_width, resize_height, @@ -264,7 +257,6 @@ def run_script(node, script): { "node": node, "ImageManipConfigV2": ImageManipConfigV2, - "ImageManipConfig": dai.ImageManipConfig, "RotatedRect": dai.RotatedRect, }, ) @@ -276,5 +268,5 @@ def get_output_frames(node: Node) -> List[Frame]: def get_output_config( node: Node, -) -> Union[List[dai.ImageManipConfig], List[ImageManipConfigV2]]: +) -> List[ImageManipConfigV2]: return node.outputs[Node.OUTPUT_CONFIG_KEY].items From 2841a9c140dba8d899206348bad52dc944ab7640 Mon Sep 17 00:00:00 2001 From: jkbmrz Date: Fri, 18 Apr 2025 14:41:31 +0200 Subject: [PATCH 4/6] feat: generate_script_content extend resize_mode options --- depthai_nodes/node/utils/detection_config_generator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/depthai_nodes/node/utils/detection_config_generator.py b/depthai_nodes/node/utils/detection_config_generator.py index 428e3ec8..eb51da10 100644 --- a/depthai_nodes/node/utils/detection_config_generator.py +++ b/depthai_nodes/node/utils/detection_config_generator.py @@ -4,7 +4,7 @@ def generate_script_content( resize_width: int, resize_height: int, - resize_mode: str = "STRETCH", + resize_mode: str = "NONE", padding: float = 0, valid_labels: Optional[List[int]] = None, ) -> str: @@ -18,8 +18,8 @@ def generate_script_content( @type resize_width: int @param resize_height: Target height for the resized image @type resize_height: int - @param resize_mode: Resize mode for the image. Supported values: 'LETTERBOX', - 'CENTER_CROP', and 'STRETCH' + @param resize_mode: Resize mode for the image. Supported values: "CENTER_CROP", + "LETTERBOX", "NONE", "STRETCH". Default: "NONE" @type resize_mode: str @param padding: Additional padding around the detection in normalized coordinates (0-1) @@ -31,7 +31,7 @@ def generate_script_content( @rtype: str """ - if resize_mode not in ["LETTERBOX", "CENTER_CROP", "STRETCH"]: + if resize_mode not in ["CENTER_CROP", "LETTERBOX", "NONE", "STRETCH"]: raise ValueError("Unsupported resize mode") cfg_content = f""" From 0514b942d0635aff3be9cd92af69909685487498 Mon Sep 17 00:00:00 2001 From: jkbmrz <74824974+jkbmrz@users.noreply.github.com> Date: Tue, 22 Apr 2025 09:38:20 +0200 Subject: [PATCH 5/6] Update depthai_nodes/node/utils/detection_config_generator.py Co-authored-by: KlemenSkrlj <47853619+klemen1999@users.noreply.github.com> --- depthai_nodes/node/utils/detection_config_generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depthai_nodes/node/utils/detection_config_generator.py b/depthai_nodes/node/utils/detection_config_generator.py index eb51da10..0061ad2b 100644 --- a/depthai_nodes/node/utils/detection_config_generator.py +++ b/depthai_nodes/node/utils/detection_config_generator.py @@ -45,7 +45,7 @@ def generate_script_content( rect.size.height = rect.size.height + {padding} * 2 rect.angle = 0 - cfg.addCropRotatedRect(rect, True) + cfg.addCropRotatedRect(rect, normalizedCoords=True) cfg.setOutputSize({resize_width}, {resize_height}, ImageManipConfigV2.ResizeMode.{resize_mode}) """ validate_label = ( From 0695f81a7e9c234a6e87dffd320874cfdcecdc12 Mon Sep 17 00:00:00 2001 From: jkbmrz Date: Tue, 22 Apr 2025 09:51:40 +0200 Subject: [PATCH 6/6] feat: rename generate_script_content unittests file --- ...ection_config_generator.py => test_generate_script_content.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/unittests/test_nodes/test_host_nodes/{test_detection_config_generator.py => test_generate_script_content.py} (100%) diff --git a/tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py b/tests/unittests/test_nodes/test_host_nodes/test_generate_script_content.py similarity index 100% rename from tests/unittests/test_nodes/test_host_nodes/test_detection_config_generator.py rename to tests/unittests/test_nodes/test_host_nodes/test_generate_script_content.py