Skip to content

Converters Utils

supervision.detection.utils.converters.xyxy_to_xywh(xyxy: npt.NDArray[np.number]) -> npt.NDArray[np.number]

Converts bounding box coordinates from (x_min, y_min, x_max, y_max) format to (x, y, width, height) format.

Parameters:

Name Type Description Default

xyxy

ndarray

A numpy array of shape (N, 4) where each row corresponds to a bounding box in the format (x_min, y_min, x_max, y_max).

required

Returns:

Type Description
NDArray[number]

np.ndarray: A numpy array of shape (N, 4) where each row corresponds to a bounding box in the format (x, y, width, height).

Examples:

>>> import numpy as np
>>> import supervision as sv
>>> xyxy = np.array([
...     [10, 20, 40, 60],
...     [15, 25, 50, 70]
... ])
>>> sv.xyxy_to_xywh(xyxy=xyxy)
array([[10, 20, 30, 40],
       [15, 25, 35, 45]])
Source code in src/supervision/detection/utils/converters.py
def xyxy_to_xywh(xyxy: npt.NDArray[np.number]) -> npt.NDArray[np.number]:
    """
    Converts bounding box coordinates from `(x_min, y_min, x_max, y_max)`
    format to `(x, y, width, height)` format.

    Args:
        xyxy (np.ndarray): A numpy array of shape `(N, 4)` where each row
            corresponds to a bounding box in the format `(x_min, y_min, x_max,
            y_max)`.

    Returns:
        np.ndarray: A numpy array of shape `(N, 4)` where each row corresponds
            to a bounding box in the format `(x, y, width, height)`.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> xyxy = np.array([
        ...     [10, 20, 40, 60],
        ...     [15, 25, 50, 70]
        ... ])
        >>> sv.xyxy_to_xywh(xyxy=xyxy)
        array([[10, 20, 30, 40],
               [15, 25, 35, 45]])

        ```
    """
    xywh = xyxy.copy()
    xywh[:, 2] = xyxy[:, 2] - xyxy[:, 0]
    xywh[:, 3] = xyxy[:, 3] - xyxy[:, 1]
    return xywh

supervision.detection.utils.converters.xywh_to_xyxy(xywh: npt.NDArray[np.number]) -> npt.NDArray[np.number]

Converts bounding box coordinates from (x, y, width, height) format to (x_min, y_min, x_max, y_max) format.

Parameters:

Name Type Description Default

xywh

ndarray

A numpy array of shape (N, 4) where each row corresponds to a bounding box in the format (x, y, width, height).

required

Returns:

Type Description
NDArray[number]

np.ndarray: A numpy array of shape (N, 4) where each row corresponds to a bounding box in the format (x_min, y_min, x_max, y_max).

Examples:

>>> import numpy as np
>>> import supervision as sv
>>> xywh = np.array([
...     [10, 20, 30, 40],
...     [15, 25, 35, 45]
... ])
>>> sv.xywh_to_xyxy(xywh=xywh)
array([[10, 20, 40, 60],
       [15, 25, 50, 70]])
Source code in src/supervision/detection/utils/converters.py
def xywh_to_xyxy(xywh: npt.NDArray[np.number]) -> npt.NDArray[np.number]:
    """
    Converts bounding box coordinates from `(x, y, width, height)`
    format to `(x_min, y_min, x_max, y_max)` format.

    Args:
        xywh (np.ndarray): A numpy array of shape `(N, 4)` where each row
            corresponds to a bounding box in the format `(x, y, width, height)`.

    Returns:
        np.ndarray: A numpy array of shape `(N, 4)` where each row corresponds
            to a bounding box in the format `(x_min, y_min, x_max, y_max)`.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> xywh = np.array([
        ...     [10, 20, 30, 40],
        ...     [15, 25, 35, 45]
        ... ])
        >>> sv.xywh_to_xyxy(xywh=xywh)
        array([[10, 20, 40, 60],
               [15, 25, 50, 70]])

        ```
    """
    xyxy = xywh.copy()
    xyxy[:, 2] = xywh[:, 0] + xywh[:, 2]
    xyxy[:, 3] = xywh[:, 1] + xywh[:, 3]
    return xyxy

supervision.detection.utils.converters.xyxy_to_xcycarh(xyxy: npt.NDArray[np.number]) -> npt.NDArray[np.floating]

Converts bounding box coordinates from (x_min, y_min, x_max, y_max) into measurement space to format (center x, center y, aspect ratio, height), where the aspect ratio is width / height.

Parameters:

Name Type Description Default

xyxy

ndarray

Bounding box in format (x1, y1, x2, y2). Expected shape is (N, 4).

required

Returns: np.ndarray: Bounding box in format (center x, center y, aspect ratio, height). Shape (N, 4).

Examples:

>>> import numpy as np
>>> import supervision as sv
>>> xyxy = np.array([
...     [10, 20, 40, 60],
...     [15, 25, 50, 70]
... ])
>>> sv.xyxy_to_xcycarh(xyxy=xyxy)  # doctest: +ELLIPSIS
array([[25.        , 40.        ,  0.75      , 40.        ],
       [32.5       , 47.5       ,  0.77..., 45.        ]])
Source code in src/supervision/detection/utils/converters.py
def xyxy_to_xcycarh(xyxy: npt.NDArray[np.number]) -> npt.NDArray[np.floating]:
    """
    Converts bounding box coordinates from `(x_min, y_min, x_max, y_max)`
    into measurement space to format `(center x, center y, aspect ratio, height)`,
    where the aspect ratio is `width / height`.

    Args:
        xyxy (np.ndarray): Bounding box in format `(x1, y1, x2, y2)`.
            Expected shape is `(N, 4)`.
    Returns:
        np.ndarray: Bounding box in format
            `(center x, center y, aspect ratio, height)`. Shape `(N, 4)`.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> xyxy = np.array([
        ...     [10, 20, 40, 60],
        ...     [15, 25, 50, 70]
        ... ])
        >>> sv.xyxy_to_xcycarh(xyxy=xyxy)  # doctest: +ELLIPSIS
        array([[25.        , 40.        ,  0.75      , 40.        ],
               [32.5       , 47.5       ,  0.77..., 45.        ]])

        ```

    """
    if xyxy.size == 0:
        return np.empty((0, 4), dtype=float)

    x1, y1, x2, y2 = xyxy.T
    width = x2 - x1
    height = y2 - y1
    center_x = x1 + width / 2
    center_y = y1 + height / 2

    aspect_ratio = np.divide(
        width,
        height,
        out=np.zeros_like(width, dtype=float),
        where=height != 0,
    )
    result = np.column_stack((center_x, center_y, aspect_ratio, height))
    return result.astype(float)

supervision.detection.utils.converters.xcycwh_to_xyxy(xcycwh: npt.NDArray[np.number]) -> npt.NDArray[np.number]

Converts bounding box coordinates from (center_x, center_y, width, height) format to (x_min, y_min, x_max, y_max) format.

Parameters:

Name Type Description Default

xcycwh

ndarray

A numpy array of shape (N, 4) where each row corresponds to a bounding box in the format (center_x, center_y, width, height).

required

Returns:

Type Description
NDArray[number]

np.ndarray: A numpy array of shape (N, 4) where each row corresponds to a bounding box in the format (x_min, y_min, x_max, y_max).

Examples:

>>> import numpy as np
>>> import supervision as sv
>>> xcycwh = np.array([
...     [50.0, 50.0, 20.0, 30.0],
...     [30.0, 40.0, 10.0, 15.0]
... ])
>>> sv.xcycwh_to_xyxy(xcycwh=xcycwh)
array([[40. , 35. , 60. , 65. ],
       [25. , 32.5, 35. , 47.5]])
Source code in src/supervision/detection/utils/converters.py
def xcycwh_to_xyxy(xcycwh: npt.NDArray[np.number]) -> npt.NDArray[np.number]:
    """
    Converts bounding box coordinates from `(center_x, center_y, width, height)`
    format to `(x_min, y_min, x_max, y_max)` format.

    Args:
        xcycwh (np.ndarray): A numpy array of shape `(N, 4)` where each row
            corresponds to a bounding box in the format `(center_x, center_y, width,
            height)`.

    Returns:
        np.ndarray: A numpy array of shape `(N, 4)` where each row corresponds
            to a bounding box in the format `(x_min, y_min, x_max, y_max)`.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> xcycwh = np.array([
        ...     [50.0, 50.0, 20.0, 30.0],
        ...     [30.0, 40.0, 10.0, 15.0]
        ... ])
        >>> sv.xcycwh_to_xyxy(xcycwh=xcycwh)
        array([[40. , 35. , 60. , 65. ],
               [25. , 32.5, 35. , 47.5]])

        ```
    """
    xyxy = xcycwh.copy()
    xyxy[:, 0] = xcycwh[:, 0] - xcycwh[:, 2] / 2
    xyxy[:, 1] = xcycwh[:, 1] - xcycwh[:, 3] / 2
    xyxy[:, 2] = xcycwh[:, 0] + xcycwh[:, 2] / 2
    xyxy[:, 3] = xcycwh[:, 1] + xcycwh[:, 3] / 2
    return xyxy

supervision.detection.utils.converters.xyxy_to_polygons(box: npt.NDArray[np.number]) -> npt.NDArray[np.number]

Convert an array of boxes to an array of polygons. Retains the input datatype.

Parameters:

Name Type Description Default

box

ndarray

An array of boxes (N, 4), where each box is represented as a list of four coordinates in the format (x_min, y_min, x_max, y_max).

required

Returns:

Type Description
NDArray[number]

np.ndarray: An array of polygons (N, 4, 2), where each polygon is represented as a list of four coordinates in the format (x, y).

Source code in src/supervision/detection/utils/converters.py
def xyxy_to_polygons(box: npt.NDArray[np.number]) -> npt.NDArray[np.number]:
    """
    Convert an array of boxes to an array of polygons.
    Retains the input datatype.

    Args:
        box (np.ndarray): An array of boxes (N, 4), where each box is represented as a
            list of four coordinates in the format `(x_min, y_min, x_max, y_max)`.

    Returns:
        np.ndarray: An array of polygons (N, 4, 2), where each polygon is
            represented as a list of four coordinates in the format `(x, y)`.
    """
    polygon = np.zeros((box.shape[0], 4, 2), dtype=box.dtype)
    polygon[:, :, 0] = box[:, [0, 2, 2, 0]]
    polygon[:, :, 1] = box[:, [1, 1, 3, 3]]
    return polygon

supervision.detection.utils.converters.mask_to_xyxy(masks: npt.NDArray[np.bool_]) -> npt.NDArray[np.int_]

Converts a 3D np.array of 2D bool masks into a 2D np.array of bounding boxes.

Parameters:

Name Type Description Default

masks

NDArray[bool_]

A 3D np.array of shape (N, W, H) containing 2D bool masks.

required

Returns:

Type Description
NDArray[int_]

A 2D np.array of shape (N, 4) containing the bounding boxes (x_min, y_min, x_max, y_max) for each mask.

Source code in src/supervision/detection/utils/converters.py
def mask_to_xyxy(masks: npt.NDArray[np.bool_]) -> npt.NDArray[np.int_]:
    """
    Converts a 3D `np.array` of 2D bool masks into a 2D `np.array` of bounding boxes.

    Args:
        masks: A 3D `np.array` of shape `(N, W, H)` containing 2D bool masks.

    Returns:
        A 2D `np.array` of shape `(N, 4)` containing the bounding boxes
            `(x_min, y_min, x_max, y_max)` for each mask.
    """
    n = masks.shape[0]
    xyxy = np.zeros((n, 4), dtype=int)

    for i, mask in enumerate(masks):
        rows, cols = np.where(mask)

        if len(rows) > 0 and len(cols) > 0:
            x_min, x_max = int(np.min(cols)), int(np.max(cols))
            y_min, y_max = int(np.min(rows)), int(np.max(rows))
            xyxy[i, :] = [x_min, y_min, x_max, y_max]

    return xyxy

supervision.detection.utils.converters.mask_to_polygons(mask: npt.NDArray[np.bool_]) -> list[npt.NDArray[np.int32]]

Converts a binary mask to a list of polygons.

Parameters:

Name Type Description Default

mask

NDArray[bool_]

A binary mask represented as a 2D NumPy array of shape (H, W), where H and W are the height and width of the mask, respectively.

required

Returns:

Type Description
list[NDArray[int32]]

A list of polygons, where each polygon is represented by a NumPy array of shape (N, 2), containing the x, y coordinates of the points. Polygons with fewer points than MIN_POLYGON_POINT_COUNT = 3 are excluded from the output.

Source code in src/supervision/detection/utils/converters.py
def mask_to_polygons(mask: npt.NDArray[np.bool_]) -> list[npt.NDArray[np.int32]]:
    """
    Converts a binary mask to a list of polygons.

    Args:
        mask: A binary mask represented as a 2D NumPy array of shape `(H, W)`,
            where H and W are the height and width of the mask, respectively.

    Returns:
        A list of polygons, where each polygon is represented by a NumPy array
            of shape `(N, 2)`, containing the `x`, `y` coordinates of the
            points. Polygons with fewer points than `MIN_POLYGON_POINT_COUNT = 3`
            are excluded from the output.
    """

    contours, _ = cv2.findContours(
        mask.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE
    )
    return [
        np.squeeze(contour, axis=1)
        for contour in contours
        if contour.shape[0] >= MIN_POLYGON_POINT_COUNT
    ]

supervision.detection.utils.converters.polygon_to_mask(polygon: npt.NDArray[np.number], resolution_wh: tuple[int, int]) -> npt.NDArray[np.uint8]

Generate a mask from a polygon.

Parameters:

Name Type Description Default

polygon

ndarray

The polygon for which the mask should be generated, given as a list of vertices.

required

resolution_wh

Tuple[int, int]

The width and height of the desired resolution.

required

Returns:

Type Description
NDArray[uint8]

np.ndarray: The generated 2D mask, where the polygon is marked with 1's and the rest is filled with 0's.

Source code in src/supervision/detection/utils/converters.py
def polygon_to_mask(
    polygon: npt.NDArray[np.number],
    resolution_wh: tuple[int, int],
) -> npt.NDArray[np.uint8]:
    """Generate a mask from a polygon.

    Args:
        polygon (np.ndarray): The polygon for which the mask should be generated,
            given as a list of vertices.
        resolution_wh (Tuple[int, int]): The width and height of the desired resolution.

    Returns:
        np.ndarray: The generated 2D mask, where the polygon is marked with
            `1`'s and the rest is filled with `0`'s.
    """
    width, height = map(int, resolution_wh)
    mask = np.zeros((height, width), dtype=np.uint8)
    cv2.fillPoly(mask, [polygon.astype(np.int32)], color=1)
    return mask

supervision.detection.utils.converters.polygon_to_xyxy(polygon: npt.NDArray[np.number]) -> npt.NDArray[np.number]

Converts a polygon represented by a NumPy array into a bounding box.

Parameters:

Name Type Description Default

polygon

NDArray[number]

A polygon represented by a NumPy array of shape (N, 2), containing the x, y coordinates of the points.

required

Returns:

Type Description
NDArray[number]

A 1D NumPy array containing the bounding box (x_min, y_min, x_max, y_max) of the input polygon.

Source code in src/supervision/detection/utils/converters.py
def polygon_to_xyxy(polygon: npt.NDArray[np.number]) -> npt.NDArray[np.number]:
    """
    Converts a polygon represented by a NumPy array into a bounding box.

    Args:
        polygon: A polygon represented by a NumPy array of shape `(N, 2)`,
            containing the `x`, `y` coordinates of the points.

    Returns:
        A 1D NumPy array containing the bounding box
            `(x_min, y_min, x_max, y_max)` of the input polygon.
    """
    x_min, y_min = np.min(polygon, axis=0)
    x_max, y_max = np.max(polygon, axis=0)
    return np.array([x_min, y_min, x_max, y_max])

supervision.detection.utils.converters.xyxy_to_mask(boxes: npt.NDArray[np.number], resolution_wh: tuple[int, int]) -> npt.NDArray[np.bool_]

Converts a 2D np.ndarray of bounding boxes into a 3D np.ndarray of bool masks.

Parameters:

Name Type Description Default

boxes

NDArray[number]

A 2D np.ndarray of shape (N, 4) containing bounding boxes (x_min, y_min, x_max, y_max).

required

resolution_wh

tuple[int, int]

A tuple (width, height) specifying the resolution of the output masks.

required

Returns:

Type Description
NDArray[bool_]

A 3D np.ndarray of shape (N, height, width) containing 2D bool masks for each bounding box.

Examples:

>>> import numpy as np
>>> import supervision as sv
>>> boxes = np.array([[0, 0, 2, 2]])
>>> sv.xyxy_to_mask(boxes, (5, 5))
array([[[ True,  True,  True, False, False],
        [ True,  True,  True, False, False],
        [ True,  True,  True, False, False],
        [False, False, False, False, False],
        [False, False, False, False, False]]])
>>> boxes = np.array([[0, 0, 1, 1], [3, 3, 4, 4]])
>>> sv.xyxy_to_mask(boxes, (5, 5))
array([[[ True,  True, False, False, False],
        [ True,  True, False, False, False],
        [False, False, False, False, False],
        [False, False, False, False, False],
        [False, False, False, False, False]],
<BLANKLINE>
       [[False, False, False, False, False],
        [False, False, False, False, False],
        [False, False, False, False, False],
        [False, False, False,  True,  True],
        [False, False, False,  True,  True]]])
Source code in src/supervision/detection/utils/converters.py
def xyxy_to_mask(
    boxes: npt.NDArray[np.number], resolution_wh: tuple[int, int]
) -> npt.NDArray[np.bool_]:
    """
    Converts a 2D `np.ndarray` of bounding boxes into a 3D `np.ndarray` of bool masks.

    Args:
        boxes: A 2D `np.ndarray` of shape `(N, 4)` containing bounding boxes
            `(x_min, y_min, x_max, y_max)`.
        resolution_wh: A tuple `(width, height)` specifying the resolution of
            the output masks.

    Returns:
        A 3D `np.ndarray` of shape `(N, height, width)` containing 2D bool masks
            for each bounding box.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> boxes = np.array([[0, 0, 2, 2]])
        >>> sv.xyxy_to_mask(boxes, (5, 5))
        array([[[ True,  True,  True, False, False],
                [ True,  True,  True, False, False],
                [ True,  True,  True, False, False],
                [False, False, False, False, False],
                [False, False, False, False, False]]])
        >>> boxes = np.array([[0, 0, 1, 1], [3, 3, 4, 4]])
        >>> sv.xyxy_to_mask(boxes, (5, 5))
        array([[[ True,  True, False, False, False],
                [ True,  True, False, False, False],
                [False, False, False, False, False],
                [False, False, False, False, False],
                [False, False, False, False, False]],
        <BLANKLINE>
               [[False, False, False, False, False],
                [False, False, False, False, False],
                [False, False, False, False, False],
                [False, False, False,  True,  True],
                [False, False, False,  True,  True]]])

        ```
    """
    width, height = resolution_wh
    n = boxes.shape[0]
    masks = np.zeros((n, height, width), dtype=bool)

    for i, (x_min, y_min, x_max, y_max) in enumerate(boxes):
        x_min = max(0, int(x_min))
        y_min = max(0, int(y_min))
        x_max = min(width - 1, int(x_max))
        y_max = min(height - 1, int(y_max))

        if x_max >= x_min and y_max >= y_min:
            masks[i, y_min : y_max + 1, x_min : x_max + 1] = True

    return masks

Comments