diff --git a/examples/imx500/imx500_object_detection_demo.py b/examples/imx500/imx500_object_detection_demo.py index 55f7bb29..8e868cb5 100755 --- a/examples/imx500/imx500_object_detection_demo.py +++ b/examples/imx500/imx500_object_detection_demo.py @@ -25,6 +25,7 @@ def parse_detections(metadata: dict): """Parse the output tensor into a number of detected objects, scaled to the ISP output.""" global last_detections bbox_normalization = intrinsics.bbox_normalization + bbox_order = intrinsics.bbox_order threshold = args.threshold iou = args.iou max_detections = args.max_detections @@ -44,6 +45,8 @@ def parse_detections(metadata: dict): if bbox_normalization: boxes = boxes / input_h + if bbox_order == "xy": + boxes = boxes[:, [1, 0, 3, 2]] boxes = np.array_split(boxes, 4, axis=1) boxes = zip(*boxes) @@ -113,6 +116,8 @@ def get_args(): default="/usr/share/imx500-models/imx500_network_ssd_mobilenetv2_fpnlite_320x320_pp.rpk") parser.add_argument("--fps", type=int, help="Frames per second") parser.add_argument("--bbox-normalization", action=argparse.BooleanOptionalAction, help="Normalize bbox") + parser.add_argument("--bbox-order", choices=["yx", "xy"], default="yx", + help="Set bbox order yx -> (y0, x0, y1, x1) xy -> (x0, y0, x1, y1)") parser.add_argument("--threshold", type=float, default=0.55, help="Detection threshold") parser.add_argument("--iou", type=float, default=0.65, help="Set iou threshold") parser.add_argument("--max-detections", type=int, default=10, help="Set max detections") diff --git a/picamera2/devices/imx500/imx500.py b/picamera2/devices/imx500/imx500.py index 24748497..debec96e 100644 --- a/picamera2/devices/imx500/imx500.py +++ b/picamera2/devices/imx500/imx500.py @@ -67,6 +67,7 @@ def __init__(self, val=None): "type": "object", "properties": { "bbox_normalization": {"type": "boolean"}, + "bbox_order": {"type": "string", "enum": ["xy", "yx"]}, "softmax": {"type": "boolean"}, "post_processing": {"type": "string"}, }, @@ -181,6 +182,18 @@ def bbox_normalization(self, val: Optional[bool]): if self.__intrinsics_has_key('cpu') and len(self.__intrinsics['cpu']) == 0: self.__intrinsics.pop('cpu') + @property + def bbox_order(self) -> Optional[str]: + return self.__get_cpu('bbox_order') + + @bbox_order.setter + def bbox_order(self, val: str): + if val not in ["xy", "yx"]: + raise ValueError("bbox_order must be either 'xy' or 'yx'") + self.__set_cpu({'bbox_order': val}) + if self.__intrinsics_has_key('cpu') and len(self.__intrinsics['cpu']) == 0: + self.__intrinsics.pop('cpu') + @property def softmax(self) -> Optional[bool]: return self.__get_cpu('softmax')