Skip to content

Register now for

# Reference for `ultralytics/utils/instance.py`

Note

This file is available at https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/instance.py. If you spot a problem please help fix it by contributing a Pull Request 🛠️. Thank you 🙏!

## `` ultralytics.utils.instance.Bboxes

    Bboxes(bboxes: ndarray, format: str = 'xyxy')

A class for handling bounding boxes in multiple formats.

The class supports various bounding box formats like 'xyxy', 'xywh', and 'ltwh' and provides methods for format conversion, scaling, and area calculation. Bounding box data should be provided as numpy arrays.

Attributes:

Name | Type | Description
--- | --- | ---
`bboxes` | `ndarray` | The bounding boxes stored in a 2D numpy array with shape (N, 4).
`format` | `str` | The format of the bounding boxes ('xyxy', 'xywh', or 'ltwh').

Methods:

Name | Description
--- | ---
`convert` | Convert bounding box format from one type to another.
`areas` | Calculate the area of bounding boxes.
`mul` | Multiply bounding box coordinates by scale factor(s).
`add` | Add offset to bounding box coordinates.
`concatenate` | Concatenate multiple Bboxes objects.

Examples:

Create bounding boxes in YOLO format

    >>> bboxes = Bboxes(np.array([[100, 50, 150, 100]]), format="xywh")
    >>> bboxes.convert("xyxy")
    >>> print(bboxes.areas())

Notes

This class does not handle normalization or denormalization of bounding boxes.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`bboxes` | `ndarray` | Array of bounding boxes with shape (N, 4) or (4,). | required
`format` | `str` | Format of the bounding boxes, one of 'xyxy', 'xywh', or 'ltwh'. | `'xyxy'`

Source code in `ultralytics/utils/instance.py`

    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    def __init__(self, bboxes: np.ndarray, format: str = "xyxy") -> None:
        """
        Initialize the Bboxes class with bounding box data in a specified format.

        Args:
            bboxes (np.ndarray): Array of bounding boxes with shape (N, 4) or (4,).
            format (str): Format of the bounding boxes, one of 'xyxy', 'xywh', or 'ltwh'.
        """
        assert format in _formats, f"Invalid bounding box format: {format}, format must be one of {_formats}"
        bboxes = bboxes[None, :] if bboxes.ndim == 1 else bboxes
        assert bboxes.ndim == 2
        assert bboxes.shape[1] == 4
        self.bboxes = bboxes
        self.format = format

### `` __getitem__

    __getitem__(index: int | ndarray | slice) -> Bboxes

Retrieve a specific bounding box or a set of bounding boxes using indexing.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`index` | `int | slice | ndarray` | The index, slice, or boolean array to select the desired bounding boxes. | required

Returns:

Type | Description
--- | ---
`Bboxes` | A new Bboxes object containing the selected bounding boxes.

Notes

When using boolean indexing, make sure to provide a boolean array with the same length as the number of bounding boxes.

Source code in `ultralytics/utils/instance.py`

    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    def __getitem__(self, index: int | np.ndarray | slice) -> Bboxes:
        """
        Retrieve a specific bounding box or a set of bounding boxes using indexing.

        Args:
            index (int | slice | np.ndarray): The index, slice, or boolean array to select the desired bounding boxes.

        Returns:
            (Bboxes): A new Bboxes object containing the selected bounding boxes.

        Notes:
            When using boolean indexing, make sure to provide a boolean array with the same length as the number of
            bounding boxes.
        """
        if isinstance(index, int):
            return Bboxes(self.bboxes[index].reshape(1, -1))
        b = self.bboxes[index]
        assert b.ndim == 2, f"Indexing on Bboxes with {index} failed to return a matrix!"
        return Bboxes(b)

### `` __len__

    __len__() -> int

Return the number of bounding boxes.

Source code in `ultralytics/utils/instance.py`

    139
    140
    141
    def __len__(self) -> int:
        """Return the number of bounding boxes."""
        return len(self.bboxes)

### `` add

    add(offset: int | tuple | list) -> None

Add offset to bounding box coordinates.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`offset` | `int | tuple | list` | Offset(s) for four coordinates. If int, the same offset is applied to all coordinates. | required

Source code in `ultralytics/utils/instance.py`

    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    def add(self, offset: int | tuple | list) -> None:
        """
        Add offset to bounding box coordinates.

        Args:
            offset (int | tuple | list): Offset(s) for four coordinates. If int, the same offset is applied to
                all coordinates.
        """
        if isinstance(offset, Number):
            offset = to_4tuple(offset)
        assert isinstance(offset, (tuple, list))
        assert len(offset) == 4
        self.bboxes[:, 0] += offset[0]
        self.bboxes[:, 1] += offset[1]
        self.bboxes[:, 2] += offset[2]
        self.bboxes[:, 3] += offset[3]

### `` areas

    areas() -> np.ndarray

Calculate the area of bounding boxes.

Source code in `ultralytics/utils/instance.py`

     97
     98
     99
    100
    101
    102
    103
    def areas(self) -> np.ndarray:
        """Calculate the area of bounding boxes."""
        return (
            (self.bboxes[:, 2] - self.bboxes[:, 0]) * (self.bboxes[:, 3] - self.bboxes[:, 1])  # format xyxy
            if self.format == "xyxy"
            else self.bboxes[:, 3] * self.bboxes[:, 2]  # format xywh or ltwh
        )

### `` concatenate `classmethod`

    concatenate(boxes_list: list[Bboxes], axis: int = 0) -> Bboxes

Concatenate a list of Bboxes objects into a single Bboxes object.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`boxes_list` | `list[Bboxes]` | A list of Bboxes objects to concatenate. | required
`axis` | `int` | The axis along which to concatenate the bounding boxes. | `0`

Returns:

Type | Description
--- | ---
`Bboxes` | A new Bboxes object containing the concatenated bounding boxes.

Notes

The input should be a list or tuple of Bboxes objects.

Source code in `ultralytics/utils/instance.py`

    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    @classmethod
    def concatenate(cls, boxes_list: list[Bboxes], axis: int = 0) -> Bboxes:
        """
        Concatenate a list of Bboxes objects into a single Bboxes object.

        Args:
            boxes_list (list[Bboxes]): A list of Bboxes objects to concatenate.
            axis (int, optional): The axis along which to concatenate the bounding boxes.

        Returns:
            (Bboxes): A new Bboxes object containing the concatenated bounding boxes.

        Notes:
            The input should be a list or tuple of Bboxes objects.
        """
        assert isinstance(boxes_list, (list, tuple))
        if not boxes_list:
            return cls(np.empty(0))
        assert all(isinstance(box, Bboxes) for box in boxes_list)

        if len(boxes_list) == 1:
            return boxes_list[0]
        return cls(np.concatenate([b.bboxes for b in boxes_list], axis=axis))

### `` convert

    convert(format: str) -> None

Convert bounding box format from one type to another.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`format` | `str` | Target format for conversion, one of 'xyxy', 'xywh', or 'ltwh'. | required

Source code in `ultralytics/utils/instance.py`

    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    def convert(self, format: str) -> None:
        """
        Convert bounding box format from one type to another.

        Args:
            format (str): Target format for conversion, one of 'xyxy', 'xywh', or 'ltwh'.
        """
        assert format in _formats, f"Invalid bounding box format: {format}, format must be one of {_formats}"
        if self.format == format:
            return
        elif self.format == "xyxy":
            func = xyxy2xywh if format == "xywh" else xyxy2ltwh
        elif self.format == "xywh":
            func = xywh2xyxy if format == "xyxy" else xywh2ltwh
        else:
            func = ltwh2xyxy if format == "xyxy" else ltwh2xywh
        self.bboxes = func(self.bboxes)
        self.format = format

### `` mul

    mul(scale: int | tuple | list) -> None

Multiply bounding box coordinates by scale factor(s).

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`scale` | `int | tuple | list` | Scale factor(s) for four coordinates. If int, the same scale is applied to all coordinates. | required

Source code in `ultralytics/utils/instance.py`

    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    def mul(self, scale: int | tuple | list) -> None:
        """
        Multiply bounding box coordinates by scale factor(s).

        Args:
            scale (int | tuple | list): Scale factor(s) for four coordinates. If int, the same scale is applied to
                all coordinates.
        """
        if isinstance(scale, Number):
            scale = to_4tuple(scale)
        assert isinstance(scale, (tuple, list))
        assert len(scale) == 4
        self.bboxes[:, 0] *= scale[0]
        self.bboxes[:, 1] *= scale[1]
        self.bboxes[:, 2] *= scale[2]
        self.bboxes[:, 3] *= scale[3]

## `` ultralytics.utils.instance.Instances

    Instances(
        bboxes: ndarray,
        segments: ndarray = None,
        keypoints: ndarray = None,
        bbox_format: str = "xywh",
        normalized: bool = True,
    )

Container for bounding boxes, segments, and keypoints of detected objects in an image.

This class provides a unified interface for handling different types of object annotations including bounding boxes, segmentation masks, and keypoints. It supports various operations like scaling, normalization, clipping, and format conversion.

Attributes:

Name | Type | Description
--- | --- | ---
`_bboxes` | `Bboxes` | Internal object for handling bounding box operations.
`keypoints` | `ndarray` | Keypoints with shape (N, 17, 3) in format (x, y, visible).
`normalized` | `bool` | Flag indicating whether the bounding box coordinates are normalized.
`segments` | `ndarray` | Segments array with shape (N, M, 2) after resampling.

Methods:

Name | Description
--- | ---
`convert_bbox` | Convert bounding box format.
`scale` | Scale coordinates by given factors.
`denormalize` | Convert normalized coordinates to absolute coordinates.
`normalize` | Convert absolute coordinates to normalized coordinates.
`add_padding` | Add padding to coordinates.
`flipud` | Flip coordinates vertically.
`fliplr` | Flip coordinates horizontally.
`clip` | Clip coordinates to stay within image boundaries.
`remove_zero_area_boxes` | Remove boxes with zero area.
`update` | Update instance variables.
`concatenate` | Concatenate multiple Instances objects.

Examples:

Create instances with bounding boxes and segments

    >>> instances = Instances(
    ...     bboxes=np.array([[10, 10, 30, 30], [20, 20, 40, 40]]),
    ...     segments=[np.array([[5, 5], [10, 10]]), np.array([[15, 15], [20, 20]])],
    ...     keypoints=np.array([[[5, 5, 1], [10, 10, 1]], [[15, 15, 1], [20, 20, 1]]]),
    ... )

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`bboxes` | `ndarray` | Bounding boxes with shape (N, 4). | required
`segments` | `ndarray` | Segmentation masks. | `None`
`keypoints` | `ndarray` | Keypoints with shape (N, 17, 3) in format (x, y, visible). | `None`
`bbox_format` | `str` | Format of bboxes. | `'xywh'`
`normalized` | `bool` | Whether the coordinates are normalized. | `True`

Source code in `ultralytics/utils/instance.py`

    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    def __init__(
        self,
        bboxes: np.ndarray,
        segments: np.ndarray = None,
        keypoints: np.ndarray = None,
        bbox_format: str = "xywh",
        normalized: bool = True,
    ) -> None:
        """
        Initialize the Instances object with bounding boxes, segments, and keypoints.

        Args:
            bboxes (np.ndarray): Bounding boxes with shape (N, 4).
            segments (np.ndarray, optional): Segmentation masks.
            keypoints (np.ndarray, optional): Keypoints with shape (N, 17, 3) in format (x, y, visible).
            bbox_format (str): Format of bboxes.
            normalized (bool): Whether the coordinates are normalized.
        """
        self._bboxes = Bboxes(bboxes=bboxes, format=bbox_format)
        self.keypoints = keypoints
        self.normalized = normalized
        self.segments = segments

### `` bbox_areas `property`

    bbox_areas: ndarray

Calculate the area of bounding boxes.

### `` bboxes `property`

    bboxes: ndarray

Return bounding boxes.

### `` __getitem__

    __getitem__(index: int | ndarray | slice) -> Instances

Retrieve a specific instance or a set of instances using indexing.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`index` | `int | slice | ndarray` | The index, slice, or boolean array to select the desired instances. | required

Returns:

Type | Description
--- | ---
`Instances` | A new Instances object containing the selected boxes, segments, and keypoints if present.

Notes

When using boolean indexing, make sure to provide a boolean array with the same length as the number of instances.

Source code in `ultralytics/utils/instance.py`

    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
    def __getitem__(self, index: int | np.ndarray | slice) -> Instances:
        """
        Retrieve a specific instance or a set of instances using indexing.

        Args:
            index (int | slice | np.ndarray): The index, slice, or boolean array to select the desired instances.

        Returns:
            (Instances): A new Instances object containing the selected boxes, segments, and keypoints if present.

        Notes:
            When using boolean indexing, make sure to provide a boolean array with the same length as the number of
            instances.
        """
        segments = self.segments[index] if len(self.segments) else self.segments
        keypoints = self.keypoints[index] if self.keypoints is not None else None
        bboxes = self.bboxes[index]
        bbox_format = self._bboxes.format
        return Instances(
            bboxes=bboxes,
            segments=segments,
            keypoints=keypoints,
            bbox_format=bbox_format,
            normalized=self.normalized,
        )

### `` __len__

    __len__() -> int

Return the number of instances.

Source code in `ultralytics/utils/instance.py`

    451
    452
    453
    def __len__(self) -> int:
        """Return the number of instances."""
        return len(self.bboxes)

### `` add_padding

    add_padding(padw: int, padh: int) -> None

Add padding to coordinates.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`padw` | `int` | Padding width. | required
`padh` | `int` | Padding height. | required

Source code in `ultralytics/utils/instance.py`

    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    def add_padding(self, padw: int, padh: int) -> None:
        """
        Add padding to coordinates.

        Args:
            padw (int): Padding width.
            padh (int): Padding height.
        """
        assert not self.normalized, "you should add padding with absolute coordinates."
        self._bboxes.add(offset=(padw, padh, padw, padh))
        self.segments[..., 0] += padw
        self.segments[..., 1] += padh
        if self.keypoints is not None:
            self.keypoints[..., 0] += padw
            self.keypoints[..., 1] += padh

### `` clip

    clip(w: int, h: int) -> None

Clip coordinates to stay within image boundaries.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`w` | `int` | Image width. | required
`h` | `int` | Image height. | required

Source code in `ultralytics/utils/instance.py`

    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    def clip(self, w: int, h: int) -> None:
        """
        Clip coordinates to stay within image boundaries.

        Args:
            w (int): Image width.
            h (int): Image height.
        """
        ori_format = self._bboxes.format
        self.convert_bbox(format="xyxy")
        self.bboxes[:, [0, 2]] = self.bboxes[:, [0, 2]].clip(0, w)
        self.bboxes[:, [1, 3]] = self.bboxes[:, [1, 3]].clip(0, h)
        if ori_format != "xyxy":
            self.convert_bbox(format=ori_format)
        self.segments[..., 0] = self.segments[..., 0].clip(0, w)
        self.segments[..., 1] = self.segments[..., 1].clip(0, h)
        if self.keypoints is not None:
            # Set out of bounds visibility to zero
            self.keypoints[..., 2][
                (self.keypoints[..., 0] < 0)
                | (self.keypoints[..., 0] > w)
                | (self.keypoints[..., 1] < 0)
                | (self.keypoints[..., 1] > h)
            ] = 0.0
            self.keypoints[..., 0] = self.keypoints[..., 0].clip(0, w)
            self.keypoints[..., 1] = self.keypoints[..., 1].clip(0, h)

### `` concatenate `classmethod`

    concatenate(instances_list: list[Instances], axis=0) -> Instances

Concatenate a list of Instances objects into a single Instances object.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`instances_list` | `list[Instances]` | A list of Instances objects to concatenate. | required
`axis` | `int` | The axis along which the arrays will be concatenated. | `0`

Returns:

Type | Description
--- | ---
`Instances` | A new Instances object containing the concatenated bounding boxes, segments, and keypoints if present.

Notes

The `Instances` objects in the list should have the same properties, such as the format of the bounding boxes, whether keypoints are present, and if the coordinates are normalized.

Source code in `ultralytics/utils/instance.py`

    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    @classmethod
    def concatenate(cls, instances_list: list[Instances], axis=0) -> Instances:
        """
        Concatenate a list of Instances objects into a single Instances object.

        Args:
            instances_list (list[Instances]): A list of Instances objects to concatenate.
            axis (int, optional): The axis along which the arrays will be concatenated.

        Returns:
            (Instances): A new Instances object containing the concatenated bounding boxes, segments, and keypoints
                if present.

        Notes:
            The `Instances` objects in the list should have the same properties, such as the format of the bounding
            boxes, whether keypoints are present, and if the coordinates are normalized.
        """
        assert isinstance(instances_list, (list, tuple))
        if not instances_list:
            return cls(np.empty(0))
        assert all(isinstance(instance, Instances) for instance in instances_list)

        if len(instances_list) == 1:
            return instances_list[0]

        use_keypoint = instances_list[0].keypoints is not None
        bbox_format = instances_list[0]._bboxes.format
        normalized = instances_list[0].normalized

        cat_boxes = np.concatenate([ins.bboxes for ins in instances_list], axis=axis)
        seg_len = [b.segments.shape[1] for b in instances_list]
        if len(frozenset(seg_len)) > 1:  # resample segments if there's different length
            max_len = max(seg_len)
            cat_segments = np.concatenate(
                [
                    resample_segments(list(b.segments), max_len)
                    if len(b.segments)
                    else np.zeros((0, max_len, 2), dtype=np.float32)  # re-generating empty segments
                    for b in instances_list
                ],
                axis=axis,
            )
        else:
            cat_segments = np.concatenate([b.segments for b in instances_list], axis=axis)
        cat_keypoints = np.concatenate([b.keypoints for b in instances_list], axis=axis) if use_keypoint else None
        return cls(cat_boxes, cat_segments, cat_keypoints, bbox_format, normalized)

### `` convert_bbox

    convert_bbox(format: str) -> None

Convert bounding box format.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`format` | `str` | Target format for conversion, one of 'xyxy', 'xywh', or 'ltwh'. | required

Source code in `ultralytics/utils/instance.py`

    247
    248
    249
    250
    251
    252
    253
    254
    def convert_bbox(self, format: str) -> None:
        """
        Convert bounding box format.

        Args:
            format (str): Target format for conversion, one of 'xyxy', 'xywh', or 'ltwh'.
        """
        self._bboxes.convert(format=format)

### `` denormalize

    denormalize(w: int, h: int) -> None

Convert normalized coordinates to absolute coordinates.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`w` | `int` | Image width. | required
`h` | `int` | Image height. | required

Source code in `ultralytics/utils/instance.py`

    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    def denormalize(self, w: int, h: int) -> None:
        """
        Convert normalized coordinates to absolute coordinates.

        Args:
            w (int): Image width.
            h (int): Image height.
        """
        if not self.normalized:
            return
        self._bboxes.mul(scale=(w, h, w, h))
        self.segments[..., 0] *= w
        self.segments[..., 1] *= h
        if self.keypoints is not None:
            self.keypoints[..., 0] *= w
            self.keypoints[..., 1] *= h
        self.normalized = False

### `` fliplr

    fliplr(w: int) -> None

Flip coordinates horizontally.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`w` | `int` | Image width. | required

Source code in `ultralytics/utils/instance.py`

    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    def fliplr(self, w: int) -> None:
        """
        Flip coordinates horizontally.

        Args:
            w (int): Image width.
        """
        if self._bboxes.format == "xyxy":
            x1 = self.bboxes[:, 0].copy()
            x2 = self.bboxes[:, 2].copy()
            self.bboxes[:, 0] = w - x2
            self.bboxes[:, 2] = w - x1
        else:
            self.bboxes[:, 0] = w - self.bboxes[:, 0]
        self.segments[..., 0] = w - self.segments[..., 0]
        if self.keypoints is not None:
            self.keypoints[..., 0] = w - self.keypoints[..., 0]

### `` flipud

    flipud(h: int) -> None

Flip coordinates vertically.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`h` | `int` | Image height. | required

Source code in `ultralytics/utils/instance.py`

    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    def flipud(self, h: int) -> None:
        """
        Flip coordinates vertically.

        Args:
            h (int): Image height.
        """
        if self._bboxes.format == "xyxy":
            y1 = self.bboxes[:, 1].copy()
            y2 = self.bboxes[:, 3].copy()
            self.bboxes[:, 1] = h - y2
            self.bboxes[:, 3] = h - y1
        else:
            self.bboxes[:, 1] = h - self.bboxes[:, 1]
        self.segments[..., 1] = h - self.segments[..., 1]
        if self.keypoints is not None:
            self.keypoints[..., 1] = h - self.keypoints[..., 1]

### `` normalize

    normalize(w: int, h: int) -> None

Convert absolute coordinates to normalized coordinates.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`w` | `int` | Image width. | required
`h` | `int` | Image height. | required

Source code in `ultralytics/utils/instance.py`

    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    def normalize(self, w: int, h: int) -> None:
        """
        Convert absolute coordinates to normalized coordinates.

        Args:
            w (int): Image width.
            h (int): Image height.
        """
        if self.normalized:
            return
        self._bboxes.mul(scale=(1 / w, 1 / h, 1 / w, 1 / h))
        self.segments[..., 0] /= w
        self.segments[..., 1] /= h
        if self.keypoints is not None:
            self.keypoints[..., 0] /= w
            self.keypoints[..., 1] /= h
        self.normalized = True

### `` remove_zero_area_boxes

    remove_zero_area_boxes() -> np.ndarray

Remove zero-area boxes, i.e. after clipping some boxes may have zero width or height.

Returns:

Type | Description
--- | ---
`ndarray` | Boolean array indicating which boxes were kept.

Source code in `ultralytics/utils/instance.py`

    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    def remove_zero_area_boxes(self) -> np.ndarray:
        """
        Remove zero-area boxes, i.e. after clipping some boxes may have zero width or height.

        Returns:
            (np.ndarray): Boolean array indicating which boxes were kept.
        """
        good = self.bbox_areas > 0
        if not all(good):
            self._bboxes = self._bboxes[good]
            if len(self.segments):
                self.segments = self.segments[good]
            if self.keypoints is not None:
                self.keypoints = self.keypoints[good]
        return good

### `` scale

    scale(scale_w: float, scale_h: float, bbox_only: bool = False)

Scale coordinates by given factors.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`scale_w` | `float` | Scale factor for width. | required
`scale_h` | `float` | Scale factor for height. | required
`bbox_only` | `bool` | Whether to scale only bounding boxes. | `False`

Source code in `ultralytics/utils/instance.py`

    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    def scale(self, scale_w: float, scale_h: float, bbox_only: bool = False):
        """
        Scale coordinates by given factors.

        Args:
            scale_w (float): Scale factor for width.
            scale_h (float): Scale factor for height.
            bbox_only (bool, optional): Whether to scale only bounding boxes.
        """
        self._bboxes.mul(scale=(scale_w, scale_h, scale_w, scale_h))
        if bbox_only:
            return
        self.segments[..., 0] *= scale_w
        self.segments[..., 1] *= scale_h
        if self.keypoints is not None:
            self.keypoints[..., 0] *= scale_w
            self.keypoints[..., 1] *= scale_h

### `` update

    update(bboxes: ndarray, segments: ndarray = None, keypoints: ndarray = None)

Update instance variables.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`bboxes` | `ndarray` | New bounding boxes. | required
`segments` | `ndarray` | New segments. | `None`
`keypoints` | `ndarray` | New keypoints. | `None`

Source code in `ultralytics/utils/instance.py`

    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    def update(self, bboxes: np.ndarray, segments: np.ndarray = None, keypoints: np.ndarray = None):
        """
        Update instance variables.

        Args:
            bboxes (np.ndarray): New bounding boxes.
            segments (np.ndarray, optional): New segments.
            keypoints (np.ndarray, optional): New keypoints.
        """
        self._bboxes = Bboxes(bboxes, format=self._bboxes.format)
        if segments is not None:
            self.segments = segments
        if keypoints is not None:
            self.keypoints = keypoints

## `` ultralytics.utils.instance._ntuple

    _ntuple(n)

Create a function that converts input to n-tuple by repeating singleton values.

Source code in `ultralytics/utils/instance.py`

    14
    15
    16
    17
    18
    19
    20
    21
    def _ntuple(n):
        """Create a function that converts input to n-tuple by repeating singleton values."""

        def parse(x):
            """Parse input to return n-tuple by repeating singleton values n times."""
            return x if isinstance(x, abc.Iterable) else tuple(repeat(x, n))

        return parse

📅 Created 1 year ago ✏️ Updated 1 year ago