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 |
|---|---|---|---|
|
NDArray[number]
|
A numpy array of shape |
required |
Returns:
| Type | Description |
|---|---|
NDArray[number]
|
A numpy array of shape |
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
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 |
|---|---|---|---|
|
NDArray[number]
|
A numpy array of shape |
required |
Returns:
| Type | Description |
|---|---|
NDArray[number]
|
A numpy array of shape |
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
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 |
|---|---|---|---|
|
NDArray[number]
|
Bounding box in format |
required |
Returns:
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
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 |
|---|---|---|---|
|
NDArray[number]
|
A numpy array of shape |
required |
Returns:
| Type | Description |
|---|---|
NDArray[number]
|
A numpy array of shape |
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
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 |
|---|---|---|---|
|
NDArray[number]
|
An array of boxes (N, 4), where each box is represented as a
list of four coordinates in the format |
required |
Returns:
| Type | Description |
|---|---|
NDArray[number]
|
An array of polygons (N, 4, 2), where each polygon is
represented as a list of four coordinates in the format |
Examples:
>>> import numpy as np
>>> import supervision as sv
>>> box = np.array([[10, 20, 30, 40]])
>>> sv.xyxy_to_polygons(box)
array([[[10, 20],
[30, 20],
[30, 40],
[10, 40]]])
Source code in src/supervision/detection/utils/converters.py
supervision.detection.utils.converters.mask_to_xyxy(masks: npt.NDArray[np.bool_], coordinate_convention: CoordinateConvention = 'inclusive') -> 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 |
|---|---|---|---|
|
NDArray[bool_]
|
A 3D |
required |
|
CoordinateConvention
|
How to interpret the returned max corner.
Use |
'inclusive'
|
Returns:
| Type | Description |
|---|---|
NDArray[int_]
|
A 2D |
Examples:
>>> import numpy as np
>>> import supervision as sv
>>> masks = np.array([
... [[False, False, False],
... [False, True, True],
... [False, True, True]],
... ])
>>> sv.mask_to_xyxy(masks)
array([[1, 1, 2, 2]])
Source code in src/supervision/detection/utils/converters.py
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 |
|---|---|---|---|
|
NDArray[bool_]
|
A binary mask represented as a 2D NumPy array of shape |
required |
Returns:
| Type | Description |
|---|---|
list[NDArray[int32]]
|
A list of polygons, where each polygon is represented by a NumPy array
of shape |
Examples:
>>> import numpy as np
>>> import supervision as sv
>>> mask = np.zeros((10, 10), dtype=bool)
>>> mask[2:6, 2:6] = True
>>> sv.mask_to_polygons(mask)
[array([[2, 2],
[2, 5],
[5, 5],
[5, 2]], dtype=int32)]
Source code in src/supervision/detection/utils/converters.py
supervision.detection.utils.converters.polygon_to_mask(polygon: npt.NDArray[np.number] | Sequence[Sequence[float]], resolution_wh: tuple[int, int]) -> npt.NDArray[np.uint8]
¶
Generate a mask from a polygon.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
NDArray[number] | Sequence[Sequence[float]]
|
The polygon for which the mask should be generated, given as
an |
required |
|
tuple[int, int]
|
The width and height of the desired resolution. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[uint8]
|
The generated 2D mask, where the polygon is marked with
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> import numpy as np
>>> import supervision as sv
>>> polygon = np.array([[2, 2], [6, 2], [6, 6], [2, 6]])
>>> mask = sv.polygon_to_mask(polygon, resolution_wh=(10, 10))
>>> int(mask.sum())
25
>>> vertices = [[2, 2], [6, 2], [6, 6], [2, 6]]
>>> int(sv.polygon_to_mask(vertices, resolution_wh=(10, 10)).sum())
25
>>> int(sv.polygon_to_mask([], resolution_wh=(4, 4)).sum())
0
Source code in src/supervision/detection/utils/converters.py
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 |
|---|---|---|---|
|
NDArray[number]
|
A polygon represented by a NumPy array of shape |
required |
Returns:
| Type | Description |
|---|---|
NDArray[number]
|
A 1D NumPy array containing the bounding box
|
Examples:
>>> import numpy as np
>>> import supervision as sv
>>> polygon = np.array([[10, 20], [30, 20], [30, 40], [10, 40]])
>>> sv.polygon_to_xyxy(polygon)
array([10, 20, 30, 40])
Source code in src/supervision/detection/utils/converters.py
supervision.detection.utils.converters.xyxy_to_mask(boxes: npt.NDArray[np.number], resolution_wh: tuple[int, int], coordinate_convention: CoordinateConvention = 'inclusive') -> 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 |
|---|---|---|---|
|
NDArray[number]
|
A 2D |
required |
|
tuple[int, int]
|
A tuple |
required |
|
CoordinateConvention
|
How to interpret |
'inclusive'
|
Returns:
| Type | Description |
|---|---|
NDArray[bool_]
|
A 3D |
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
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | |
supervision.detection.utils.converters.rle_to_mask(rle: npt.NDArray[np.integer[Any]] | list[int] | str | bytes, resolution_wh: tuple[int, int]) -> npt.NDArray[np.bool_]
¶
Converts a COCO run-length encoding (RLE) to a binary mask.
Implements the COCO RLE format used by pycocotools: pixels are counted
in column-major (Fortran) order — top-to-bottom within each column,
left-to-right across columns. This is the opposite of the row-major order
used by NumPy's default 'C' layout. Passing RLE data produced by a
different row-major convention will yield an incorrect mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
NDArray[integer[Any]] | list[int] | str | bytes
|
The COCO RLE data in one of the following formats:
|
required |
|
tuple[int, int]
|
The width (w) and height (h) of the desired binary mask. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[bool_]
|
The generated 2D Boolean mask of shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the sum of pixels encoded in RLE differs from the number of pixels in the expected mask (computed based on resolution_wh). |
Examples:
>>> import numpy as np
>>> import supervision as sv
>>> mask = sv.rle_to_mask([5, 2, 2, 2, 5], (4, 4))
>>> mask # doctest: +NORMALIZE_WHITESPACE
array([[False, False, False, False],
[False, True, True, False],
[False, True, True, False],
[False, False, False, False]])
>>> mask = sv.rle_to_mask("52203", (4, 4))
>>> mask # doctest: +NORMALIZE_WHITESPACE
array([[False, False, False, False],
[False, True, True, False],
[False, True, True, False],
[False, False, False, False]])
Source code in src/supervision/detection/utils/converters.py
supervision.detection.utils.converters.mask_to_rle(mask: npt.NDArray[np.bool_], compressed: bool = False) -> list[int] | str
¶
Converts a binary mask into a COCO run-length encoding (RLE).
Produces RLE in the COCO format used by pycocotools: pixels are counted
in column-major (Fortran) order — top-to-bottom within each column,
left-to-right across columns. The output is directly compatible with
pycocotools.mask.decode and COCO annotation JSON files.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
NDArray[bool_]
|
2D binary mask where |
required |
|
bool
|
If |
False
|
Returns:
| Type | Description |
|---|---|
list[int] | str
|
The COCO run-length encoded mask. When |
Raises:
| Type | Description |
|---|---|
ValueError
|
If input mask is not 2D or is empty. |
Examples:
>>> import numpy as np
>>> import supervision as sv
>>> mask = np.array([
... [True, True, True, True],
... [True, True, True, True],
... [True, True, True, True],
... [True, True, True, True],
... ])
>>> rle = sv.mask_to_rle(mask)
>>> [int(x) for x in rle]
[0, 16]
>>> import numpy as np
>>> import supervision as sv
>>> mask = np.array([
... [False, False, False, False],
... [False, True, True, False],
... [False, True, True, False],
... [False, False, False, False],
... ])
>>> rle = sv.mask_to_rle(mask)
>>> [int(x) for x in rle]
[5, 2, 2, 2, 5]
>>> sv.mask_to_rle(mask, compressed=True)
'52203'

Source code in src/supervision/detection/utils/converters.py
supervision.detection.utils.converters.is_compressed_rle(rle: object) -> bool
¶
Return True if rle is a COCO compressed RLE (str or bytes).
Use this to branch between the compressed-string pipeline
(:func:~supervision.detection.utils.converters._base48_decode →
:func:~supervision.detection.utils.converters._delta_decode) and the
uncompressed integer-list / array pipeline before calling
:func:~supervision.detection.utils.converters.rle_to_mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
object
|
Candidate RLE value to inspect. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Examples:
>>> from supervision.detection.utils.converters import is_compressed_rle
>>> is_compressed_rle("52203")
True
>>> is_compressed_rle([5, 2, 2, 2, 5])
False