```python:inference/core/workflows/core_steps/common/serializers.py
from typing import Dict, Optional, Union

import cv2
import numpy as np
import supervision as sv
from inference.core import logger
from inference.core.workflows.execution_engine.constants import (
    AREA_CONVERTED_KEY_IN_INFERENCE_RESPONSE,
    AREA_CONVERTED_KEY_IN_SV_DETECTIONS, AREA_KEY_IN_INFERENCE_RESPONSE,
    AREA_KEY_IN_SV_DETECTIONS, BOUNDING_RECT_ANGLE_KEY_IN_INFERENCE_RESPONSE,
    BOUNDING_RECT_ANGLE_KEY_IN_SV_DETECTIONS,
    BOUNDING_RECT_HEIGHT_KEY_IN_INFERENCE_RESPONSE,
    BOUNDING_RECT_HEIGHT_KEY_IN_SV_DETECTIONS,
    BOUNDING_RECT_RECT_KEY_IN_INFERENCE_RESPONSE,
    BOUNDING_RECT_RECT_KEY_IN_SV_DETECTIONS,
    BOUNDING_RECT_WIDTH_KEY_IN_INFERENCE_RESPONSE,
    BOUNDING_RECT_WIDTH_KEY_IN_SV_DETECTIONS, CLASS_ID_KEY, CLASS_NAME_KEY,
    CONFIDENCE_KEY, DETECTED_CODE_KEY, DETECTION_ID_KEY, HEIGHT_KEY,
    IMAGE_DIMENSIONS_KEY, KEYPOINTS_CLASS_ID_KEY_IN_SV_DETECTIONS,
    KEYPOINTS_CLASS_NAME_KEY_IN_SV_DETECTIONS,
    KEYPOINTS_CONFIDENCE_KEY_IN_SV_DETECTIONS,
    KEYPOINTS_KEY_IN_INFERENCE_RESPONSE)
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as __KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ___KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ____KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _____KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ______KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _______KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as __________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ___________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ____________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _____________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ______________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _______________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as __________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ___________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ____________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _____________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ______________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _______________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as __________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ___________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ____________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _____________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ______________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _______________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as ________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as _________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    __________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    ___________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    ____________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    _____________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    ______________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    _______________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    ________________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    _________________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    __________________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    ___________________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    ____________________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    _____________________________________________KP_XY
from inference.core.workflows.execution_engine.constants import \
    KEYPOINTS_XY_KEY_IN_SV_DETECTIONS as \
    ______________________________________________KP_XY
from inference.core.workflows.execution_engine.entities.base import \
    ParentOrigin

MIN_POLYGON_POINT_COUNT = 3


def serialise_sv_detections(detections: sv.Detections) -> dict:
    serialized_detections = []
    image_dimensions = None
    for xyxy, mask, confidence, class_id, tracker_id, data in detections:
        detection_dict = {}
        image_dimensions = data.get(IMAGE_DIMENSIONS_KEY)

        # Avoid creating an intermediate Python list from a numpy array:
        # cast coordinates directly to float scalars.
        try:
            # This will work for sequences (lists/tuples) and numpy arrays via indexing.
            x1 = float(xyxy[0])
            y1 = float(xyxy[1])
            x2 = float(xyxy[2])
            y2 = float(xyxy[3])
        except Exception:
            # Fall back to original behavior if indexing fails (keeps behavior identical).
            if isinstance(xyxy, np.ndarray):
                xyxy = xyxy.astype(float).tolist()
            x1, y1, x2, y2 = xyxy  # type: ignore[assignment]

        detection_dict[WIDTH_KEY] = abs(x2 - x1)
        detection_dict[HEIGHT_KEY] = abs(y2 - y1)
        detection_dict[X_KEY] = x1 + detection_dict[WIDTH_KEY] / 2
        detection_dict[Y_KEY] = y1 + detection_dict[HEIGHT_KEY] / 2

        detection_dict[CONFIDENCE_KEY] = float(confidence)
        detection_dict[CLASS_ID_KEY] = int(class_id)
        if mask is not None:
            poly_in_data = data.get(POLYGON_KEY_IN_SV_DETECTIONS)
            if (
                poly_in_data is not None
                and not isinstance(poly_in_data, type(None))
                and len(poly_in_data) > 2
            ):
                polygon = poly_in_data
            else:
                polygon = mask_to_polygon(mask=mask)
            if polygon is None:
                # ignoring the whole instance
                continue
            # Build polygon list via comprehension to avoid repeated append calls.
            detection_dict[POLYGON_KEY] = [
                {X_KEY: float(x), Y_KEY: float(y)} for x, y in polygon
            ]
        if tracker_id is not None:
            detection_dict[TRACKER_ID_KEY] = int(tracker_id)
        detection_dict[CLASS_NAME_KEY] = str(data["class_name"])
        detection_dict[DETECTION_ID_KEY] = str(data[DETECTION_ID_KEY])
        if PATH_DEVIATION_KEY_IN_SV_DETECTIONS in data:
            detection_dict[PATH_DEVIATION_KEY_IN_INFERENCE_RESPONSE] = data[
                PATH_DEVIATION_KEY_IN_SV_DETECTIONS
            ]
        if TIME_IN_ZONE_KEY_IN_SV_DETECTIONS in data:
            detection_dict[TIME_IN_ZONE_KEY_IN_INFERENCE_RESPONSE] = data[
                TIME_IN_ZONE_KEY_IN_SV_DETECTIONS
            ]
        if POLYGON_KEY_IN_SV_DETECTIONS in data:
            detection_dict[POLYGON_KEY_IN_INFERENCE_RESPONSE] = (
                data[POLYGON_KEY_IN_SV_DETECTIONS]
                .astype(float)
                .round()
                .astype(int)
                .tolist()
            )
        if (
            BOUNDING_RECT_ANGLE_KEY_IN_SV_DETECTIONS in data
            and BOUNDING_RECT_RECT_KEY_IN_SV_DETECTIONS in data
            and BOUNDING_RECT_HEIGHT_KEY_IN_SV_DETECTIONS in data
            and BOUNDING_RECT_WIDTH_KEY_IN_SV_DETECTIONS in data
        ):
            detection_dict[BOUNDING_RECT_ANGLE_KEY_IN_INFERENCE_RESPONSE] = data[
                BOUNDING_RECT_ANGLE_KEY_IN_SV_DETECTIONS
            ]
            detection_dict[BOUNDING_RECT_RECT_KEY_IN_INFERENCE_RESPONSE] = data[
                BOUNDING_RECT_RECT_KEY_IN_SV_DETECTIONS
            ]
            detection_dict[BOUNDING_RECT_HEIGHT_KEY_IN_INFERENCE_RESPONSE] = data[
                BOUNDING_RECT_HEIGHT_KEY_IN_SV_DETECTIONS
            ]
            detection_dict[BOUNDING_RECT_WIDTH_KEY_IN_INFERENCE_RESPONSE] = data[
                BOUNDING_RECT_WIDTH_KEY_IN_SV_DETECTIONS
            ]

        if PARENT_ID_KEY in data:
            detection_dict[PARENT_ID_KEY] = str(data[PARENT_ID_KEY])

        # Add parent origin metadata if detection is based on a crop/slice
        if (
            PARENT_ID_KEY in data
            and ROOT_PARENT_ID_KEY in data
            and str(data[PARENT_ID_KEY]) != str(data[ROOT_PARENT_ID_KEY])
        ):
            _attach_parent_metadata_to_detection_dict(
                detection_dict=detection_dict,
                data=data,
                coordinates_key=PARENT_COORDINATES_KEY,
                dimensions_key=PARENT_DIMENSIONS_KEY,
                origin_key=PARENT_ORIGIN_KEY,
            )

            detection_dict[ROOT_PARENT_ID_KEY] = str(data[ROOT_PARENT_ID_KEY])

            _attach_parent_metadata_to_detection_dict(
                detection_dict=detection_dict,
                data=data,
                coordinates_key=ROOT_PARENT_COORDINATES_KEY,
                dimensions_key=ROOT_PARENT_DIMENSIONS_KEY,
                origin_key=ROOT_PARENT_ORIGIN_KEY,
            )

        if (
            KEYPOINTS_CLASS_ID_KEY_IN_SV_DETECTIONS in data
            and KEYPOINTS_CLASS_NAME_KEY_IN_SV_DETECTIONS in data
            and KEYPOINTS_CONFIDENCE_KEY_IN_SV_DETECTIONS in data
            and KEYPOINTS_XY_KEY_IN_SV_DETECTIONS in data
        ):
            kp_class_id = data[KEYPOINTS_CLASS_ID_KEY_IN_SV_DETECTIONS]
            kp_class_name = data[KEYPOINTS_CLASS_NAME_KEY_IN_SV_DETECTIONS]
            kp_confidence = data[KEYPOINTS_CONFIDENCE_KEY_IN_SV_DETECTIONS]
            kp_xy = data[KEYPOINTS_XY_KEY_IN_SV_DETECTIONS]
            # build keypoints list via comprehension
            detection_dict[KEYPOINTS_KEY_IN_INFERENCE_RESPONSE] = [
                {
                    "class_id": int(keypoint_class_id),
                    "class": str(keypoint_class_name),
                    "confidence": float(keypoint_confidence),
                    "x": float(xy[0]),
                    "y": float(xy[1]),
                }
                for keypoint_class_id, keypoint_class_name, keypoint_confidence, xy in zip(
                    kp_class_id, kp_class_name, kp_confidence, kp_xy
                )
            ]

        if DETECTED_CODE_KEY in data:
            detection_dict[DETECTED_CODE_KEY] = data[DETECTED_CODE_KEY]
        if VELOCITY_KEY_IN_SV_DETECTIONS in data:
            detection_dict[VELOCITY_KEY_IN_INFERENCE_RESPONSE] = data[
                VELOCITY_KEY_IN_SV_DETECTIONS
            ].tolist()
        if SPEED_KEY_IN_SV_DETECTIONS in data:
            detection_dict[SPEED_KEY_IN_INFERENCE_RESPONSE] = data[
                SPEED_KEY_IN_SV_DETECTIONS
            ].astype(float)
        if SMOOTHED_VELOCITY_KEY_IN_SV_DETECTIONS in data:
            detection_dict[SMOOTHED_VELOCITY_KEY_IN_INFERENCE_RESPONSE] = data[
                SMOOTHED_VELOCITY_KEY_IN_SV_DETECTIONS
            ].tolist()
        if SMOOTHED_SPEED_KEY_IN_SV_DETECTIONS in data:
            detection_dict[SMOOTHED_SPEED_KEY_IN_INFERENCE_RESPONSE] = data[
                SMOOTHED_SPEED_KEY_IN_SV_DETECTIONS
            ].astype(float)
        if AREA_KEY_IN_SV_DETECTIONS in data:
            detection_dict[AREA_KEY_IN_INFERENCE_RESPONSE] = float(
                data[AREA_KEY_IN_SV_DETECTIONS]
            )
        if AREA_CONVERTED_KEY_IN_SV_DETECTIONS in data:
            detection_dict[AREA_CONVERTED_KEY_IN_INFERENCE_RESPONSE] = float(
                data[AREA_CONVERTED_KEY_IN_SV_DETECTIONS]
            )
        serialized_detections.append(detection_dict)
    image_metadata = {
        "width": None,
        "height": None,
    }  # TODO: this breaks the contract of
    # standard inference, but to fix that problem, we would need sv.Detections to provide
    # detection-level metadata.
    if image_dimensions is not None:
        image_metadata = {
            "width": image_dimensions[1].item(),
            "height": image_dimensions[0].item(),
        }
    return {"image": image_metadata, "predictions": serialized_detections}


def _attach_parent_metadata_to_detection_dict(
    detection_dict: dict,
    data: Dict[str, Union[np.ndarray, list]],
    coordinates_key: str,
    dimensions_key: str,
    origin_key: str,
) -> None:
    if coordinates_key in data and dimensions_key in data:
        parent_coords = data[coordinates_key]
        parent_dims = data[dimensions_key]
        if isinstance(parent_coords, np.ndarray):
            parent_coords = parent_coords.astype(float).round().astype(int).tolist()
        if isinstance(parent_dims, np.ndarray):
            parent_dims = parent_dims.astype(float).round().astype(int).tolist()
        detection_dict[origin_key] = ParentOrigin(
            offset_x=parent_coords[0],
            offset_y=parent_coords[1],
            width=parent_dims[1],
            height=parent_dims[0],
        ).model_dump()


def mask_to_polygon(mask: np.ndarray) -> Optional[np.ndarray]:
    # masks here should be predicted by instance segmentation
    # model and in theory can only present SINGLE!!! shape
    # our response schema for InstanceSegmentationPrediction
    # (see `inference.core.entities.responses.inference.InstanceSegmentationPrediction`)
    # FROM THE BEGINNING were allowing to serialise single polygon that belongs to mask,
    # no hierarchy respected and multiple polygons are not taken into account
    contours, _ = cv2.findContours(
        # avoid an extra copy if mask is already uint8
        mask.astype(np.uint8) if mask.dtype != np.uint8 else mask,
        cv2.RETR_TREE,
        cv2.CHAIN_APPROX_SIMPLE,
    )
    if len(contours) == 0:
        # nothing found - instance should be rejected
        return None
    if len(contours) > 1:
        logger.warning(
            f"Detected instance segmentation that has {len(contours)} in the mask, which by convention "
            "should not happen. We are taking the first polygon to avoid exceptions, but if you see this "
            "warning - it may indicate that some model producing instance segmentation result works under "
            "different assumptions that models historically added into inference and that should be a signal "
            "to figure out more generic representation for instance seg predictions."
        )
    contour = np.squeeze(contours[0], axis=1)
    contour_padding = max(MIN_POLYGON_POINT_COUNT - contour.shape[0], 0)
    if contour_padding > 0:
        padding = np.repeat(
            np.expand_dims(contour[-1], axis=0), repeats=contour_padding, axis=0
        )
        return np.append(contour, padding, axis=0)
    return contour
```