Skip to content

Image Utils

ImageSink

Source code in supervision/utils/image.py
class ImageSink:
    def __init__(
        self,
        target_dir_path: str,
        overwrite: bool = False,
        image_name_pattern: str = "image_{:05d}.png",
    ):
        """
        Initialize a context manager for saving images.

        Args:
            target_dir_path (str): The target directory where images will be saved.
            overwrite (bool, optional): Whether to overwrite the existing directory.
                Defaults to False.
            image_name_pattern (str, optional): The image file name pattern.
                Defaults to "image_{:05d}.png".

        Examples:
            ```python
            import supervision as sv

            with sv.ImageSink(target_dir_path='target/directory/path',
                              overwrite=True) as sink:
                for image in sv.get_video_frames_generator(
                    source_path='source_video.mp4', stride=2):
                    sink.save_image(image=image)
            ```
        """

        self.target_dir_path = target_dir_path
        self.overwrite = overwrite
        self.image_name_pattern = image_name_pattern
        self.image_count = 0

    def __enter__(self):
        if os.path.exists(self.target_dir_path):
            if self.overwrite:
                shutil.rmtree(self.target_dir_path)
                os.makedirs(self.target_dir_path)
        else:
            os.makedirs(self.target_dir_path)

        return self

    def save_image(self, image: np.ndarray, image_name: Optional[str] = None):
        """
        Save a given image in the target directory.

        Args:
            image (np.ndarray): The image to be saved.
            image_name (str, optional): The name to use for the saved image.
                If not provided, a name will be
                generated using the `image_name_pattern`.
        """
        if image_name is None:
            image_name = self.image_name_pattern.format(self.image_count)

        image_path = os.path.join(self.target_dir_path, image_name)
        cv2.imwrite(image_path, image)
        self.image_count += 1

    def __exit__(self, exc_type, exc_value, exc_traceback):
        pass

Functions

__init__(target_dir_path, overwrite=False, image_name_pattern='image_{:05d}.png')

Initialize a context manager for saving images.

Parameters:

Name Type Description Default
target_dir_path str

The target directory where images will be saved.

required
overwrite bool

Whether to overwrite the existing directory. Defaults to False.

False
image_name_pattern str

The image file name pattern. Defaults to "image_{:05d}.png".

'image_{:05d}.png'

Examples:

import supervision as sv

with sv.ImageSink(target_dir_path='target/directory/path',
                  overwrite=True) as sink:
    for image in sv.get_video_frames_generator(
        source_path='source_video.mp4', stride=2):
        sink.save_image(image=image)
Source code in supervision/utils/image.py
def __init__(
    self,
    target_dir_path: str,
    overwrite: bool = False,
    image_name_pattern: str = "image_{:05d}.png",
):
    """
    Initialize a context manager for saving images.

    Args:
        target_dir_path (str): The target directory where images will be saved.
        overwrite (bool, optional): Whether to overwrite the existing directory.
            Defaults to False.
        image_name_pattern (str, optional): The image file name pattern.
            Defaults to "image_{:05d}.png".

    Examples:
        ```python
        import supervision as sv

        with sv.ImageSink(target_dir_path='target/directory/path',
                          overwrite=True) as sink:
            for image in sv.get_video_frames_generator(
                source_path='source_video.mp4', stride=2):
                sink.save_image(image=image)
        ```
    """

    self.target_dir_path = target_dir_path
    self.overwrite = overwrite
    self.image_name_pattern = image_name_pattern
    self.image_count = 0

save_image(image, image_name=None)

Save a given image in the target directory.

Parameters:

Name Type Description Default
image ndarray

The image to be saved.

required
image_name str

The name to use for the saved image. If not provided, a name will be generated using the image_name_pattern.

None
Source code in supervision/utils/image.py
def save_image(self, image: np.ndarray, image_name: Optional[str] = None):
    """
    Save a given image in the target directory.

    Args:
        image (np.ndarray): The image to be saved.
        image_name (str, optional): The name to use for the saved image.
            If not provided, a name will be
            generated using the `image_name_pattern`.
    """
    if image_name is None:
        image_name = self.image_name_pattern.format(self.image_count)

    image_path = os.path.join(self.target_dir_path, image_name)
    cv2.imwrite(image_path, image)
    self.image_count += 1

crop_image

Crops the given image based on the given bounding box.

Parameters:

Name Type Description Default
image ndarray

The image to be cropped, represented as a numpy array.

required
xyxy ndarray

A numpy array containing the bounding box coordinates in the format (x1, y1, x2, y2).

required

Returns:

Type Description
ndarray

The cropped image as a numpy array.

Examples:

import supervision as sv

detection = sv.Detections(...)
with sv.ImageSink(target_dir_path='target/directory/path') as sink:
    for xyxy in detection.xyxy:
        cropped_image = sv.crop_image(image=image, xyxy=xyxy)
        sink.save_image(image=cropped_image)
Source code in supervision/utils/image.py
def crop_image(image: np.ndarray, xyxy: np.ndarray) -> np.ndarray:
    """
    Crops the given image based on the given bounding box.

    Args:
        image (np.ndarray): The image to be cropped, represented as a numpy array.
        xyxy (np.ndarray): A numpy array containing the bounding box coordinates
            in the format (x1, y1, x2, y2).

    Returns:
        (np.ndarray): The cropped image as a numpy array.

    Examples:
        ```python
        import supervision as sv

        detection = sv.Detections(...)
        with sv.ImageSink(target_dir_path='target/directory/path') as sink:
            for xyxy in detection.xyxy:
                cropped_image = sv.crop_image(image=image, xyxy=xyxy)
                sink.save_image(image=cropped_image)
        ```
    """

    xyxy = np.round(xyxy).astype(int)
    x1, y1, x2, y2 = xyxy
    return image[y1:y2, x1:x2]

resize_image

Resizes an image by a given scale factor using cv2.INTER_LINEAR interpolation.

Parameters:

Name Type Description Default
image ndarray

The input image to be resized.

required
scale_factor float

The factor by which the image will be scaled. Scale factor

1.0 zooms in, < 1.0 zooms out.

required

Returns:

Type Description
ndarray

np.ndarray: The resized image.

Raises:

Type Description
ValueError

If the scale factor is non-positive.

Source code in supervision/utils/image.py
def resize_image(image: np.ndarray, scale_factor: float) -> np.ndarray:
    """
    Resizes an image by a given scale factor using cv2.INTER_LINEAR interpolation.

    Args:
        image (np.ndarray): The input image to be resized.
        scale_factor (float): The factor by which the image will be scaled. Scale factor
            > 1.0 zooms in, < 1.0 zooms out.

    Returns:
        np.ndarray: The resized image.

    Raises:
        ValueError: If the scale factor is non-positive.
    """
    if scale_factor <= 0:
        raise ValueError("Scale factor must be positive.")

    old_width, old_height = image.shape[1], image.shape[0]
    nwe_width = int(old_width * scale_factor)
    new_height = int(old_height * scale_factor)

    return cv2.resize(image, (nwe_width, new_height), interpolation=cv2.INTER_LINEAR)

place_image

Places an image onto a scene at a given anchor point, handling cases where the image's position is partially or completely outside the scene's bounds.

Parameters:

Name Type Description Default
scene ndarray

The background scene onto which the image is placed.

required
image ndarray

The image to be placed onto the scene.

required
anchor Tuple[int, int]

The (x, y) coordinates in the scene where the top-left corner of the image will be placed.

required

Returns:

Type Description
ndarray

np.ndarray: The modified scene with the image placed at the anchor point, or unchanged if the image placement is completely outside the scene.

Source code in supervision/utils/image.py
def place_image(
    scene: np.ndarray, image: np.ndarray, anchor: Tuple[int, int]
) -> np.ndarray:
    """
    Places an image onto a scene at a given anchor point, handling cases where
    the image's position is partially or completely outside the scene's bounds.

    Args:
        scene (np.ndarray): The background scene onto which the image is placed.
        image (np.ndarray): The image to be placed onto the scene.
        anchor (Tuple[int, int]): The (x, y) coordinates in the scene where the
            top-left corner of the image will be placed.

    Returns:
        np.ndarray: The modified scene with the image placed at the anchor point,
            or unchanged if the image placement is completely outside the scene.
    """
    scene_height, scene_width = scene.shape[:2]
    image_height, image_width = image.shape[:2]
    anchor_x, anchor_y = anchor

    is_out_horizontally = anchor_x + image_width <= 0 or anchor_x >= scene_width
    is_out_vertically = anchor_y + image_height <= 0 or anchor_y >= scene_height

    if is_out_horizontally or is_out_vertically:
        return scene

    start_y = max(anchor_y, 0)
    start_x = max(anchor_x, 0)
    end_y = min(scene_height, anchor_y + image_height)
    end_x = min(scene_width, anchor_x + image_width)

    crop_start_y = max(-anchor_y, 0)
    crop_start_x = max(-anchor_x, 0)
    crop_end_y = image_height - max((anchor_y + image_height) - scene_height, 0)
    crop_end_x = image_width - max((anchor_x + image_width) - scene_width, 0)

    scene[start_y:end_y, start_x:end_x] = image[
        crop_start_y:crop_end_y, crop_start_x:crop_end_x
    ]

    return scene

Comments