Skip to content

Manage white borders

fill_with_white(im, image_ratio)

Fills an image with white such that it respects a wanted ratio

Parameters:

Name Type Description Default
im Image

Image to be processed

required

Kwargs: image_ratio (float): Wanted image ratio Returns: Image: Transformed image

Source code in template_vision/preprocessing/manage_white_borders.py
def fill_with_white(im: Image, image_ratio: float) -> Image:
    '''Fills an image with white such that it respects a wanted ratio

    Args:
        im (Image): Image to be processed
    Kwargs:
        image_ratio (float): Wanted image ratio
    Returns:
        Image: Transformed image
    '''
    width, height = im.size
    ratio = width / height
    if ratio > image_ratio:
        # Increase height
        wanted_height = round(width / image_ratio)
        new_size = (width, wanted_height)
        old_size = (width, height)
        # Set new image
        new_im = Image.new("RGB", new_size, (255, 255, 255))
        # Fill it with the old image, centered
        # (use floor to ensure the old image fits into the new one)
        x_pos = 0
        y_pos = floor((new_size[1] - old_size[1]) / 2)
        new_im.paste(im, (x_pos, y_pos))
    elif ratio < image_ratio:
        # Increase width
        wanted_width = round(height * image_ratio)
        new_size = (wanted_width, height)
        old_size = (width, height)
        # Set new image
        new_im = Image.new("RGB", new_size, (255, 255, 255))
        # Fill it with the old image, centered
        # (use floor to ensure the old image fits into the new one)
        x_pos = floor((new_size[0] - old_size[0]) / 2)
        y_pos = 0
        new_im.paste(im, (x_pos, y_pos))
    else:  # Already correct ratio
        new_im = im
    return new_im

remove_white_borders(images, image_ratio_strategy=None, image_ratio=0.75, with_rotation=True)

Removes white border Also change the image ratio and rotate (if wanted) along largest dim. (i.e. portrait mode)

Parameters:

Name Type Description Default
images list

Images to be processed

required

Kwargs: image_ratio_strategy (str): wanted strategy to apply new image_ratio - None: no change in image ratio - 'fill': add white borders on the smallest dimension - 'stretch': stretch the images such that they have the wanted ratio image_ratio (float): Wanted final image ratio (unused if image_ratio_strategy is None) with_rotation (bool): If the images must be rotated along largest dim. (i.e. portrait mode) Raises: ValueError: If image_ratio_strategy value is not a valid option ([None, 'fill', 'stretch']) Returns: list: Images sans les marges blanches

Source code in template_vision/preprocessing/manage_white_borders.py
def remove_white_borders(images: list, image_ratio_strategy: Union[str, None] = None, image_ratio: float = 0.75, with_rotation: bool = True) -> list:
    '''Removes white border
    Also change the image ratio and rotate (if wanted) along largest dim. (i.e. portrait mode)

    Args:
        images (list): Images to be processed
    Kwargs:
        image_ratio_strategy (str): wanted strategy to apply new image_ratio
            - None: no change in image ratio
            - 'fill': add white borders on the smallest dimension
            - 'stretch': stretch the images such that they have the wanted ratio
        image_ratio (float): Wanted final image ratio (unused if image_ratio_strategy is None)
        with_rotation (bool): If the images must be rotated along largest dim. (i.e. portrait mode)
    Raises:
        ValueError: If image_ratio_strategy value is not a valid option ([None, 'fill', 'stretch'])
    Returns:
        list: Images sans les marges blanches
    '''
    if image_ratio_strategy not in [None, 'fill', 'stretch']:
        raise ValueError(f"image ratio strategy (image_ratio_strategy) '{image_ratio_strategy}' is not a valid option ([None, 'fill', 'stretch'])")
    # Get 'True' white
    # TODO : to be improved !
    true_white = _rgb2gray(np.array([255, 255, 255]))
    # Process each image, one by one
    results = []
    for i, im in enumerate(tqdm.tqdm(images)):
        # Remove white borders
        pixels = _rgb2gray(np.array(im))
        # x : horizontal
        # y : vertical
        first_x = _get_first_x(pixels, true_white)  # Left
        first_y = _get_first_y(pixels, true_white)  # Upper
        last_x = _get_last_x(pixels, true_white)  # Right
        last_y = _get_last_y(pixels, true_white)  # Lower
        # If first_x -1 -> no 'non-white' pixel, do nothing
        if first_x == -1:
            continue
        else:
            # Crop image (left, upper, right, lower)
            im = im.crop((first_x, first_y, last_x + 1, last_y + 1))
            # Rotate image if wanted
            if with_rotation:
                im = rotate_image_largest_dim(im)
            # Manage new ratio strategy
            if image_ratio_strategy == 'fill':  # fill with white borders to get correct format
                im = fill_with_white(im, image_ratio)
            elif image_ratio_strategy == 'stretch':
                im = stretch_image(im, image_ratio)
            # If None, do nothign
        # Update list
        results.append(im)
    # Return
    return results

rotate_image_largest_dim(im)

Rotates an image along largest dim. (i.e. portrait mode)

Parameters:

Name Type Description Default
im Image

Image to be processed

required

Returns: Image: Rotated image

Source code in template_vision/preprocessing/manage_white_borders.py
def rotate_image_largest_dim(im: Image) -> Image:
    '''Rotates an image along largest dim. (i.e. portrait mode)

    Args:
        im (Image): Image to be processed
    Returns:
        Image: Rotated image
    '''
    orientation = _get_orientation(im)
    if orientation != 0:
        im = im.rotate(orientation, expand=True)
    return im

stretch_image(im, image_ratio)

Stretch an image such that it respects a wanted ratio

Parameters:

Name Type Description Default
im Image

Image to be processed

required

Kwargs: image_ratio (float): Wanted image ratio Returns: Image: Transformed image

Source code in template_vision/preprocessing/manage_white_borders.py
def stretch_image(im: Image, image_ratio: float) -> Image:
    '''Stretch an image such that it respects a wanted ratio

    Args:
        im (Image): Image to be processed
    Kwargs:
        image_ratio (float): Wanted image ratio
    Returns:
        Image: Transformed image
    '''
    width, height = im.size
    ratio = width / height
    if ratio > image_ratio:
        # Increase height
        wanted_height = round(width / image_ratio)
        new_size = (width, wanted_height)
        new_im = im.resize(new_size)
    elif ratio < image_ratio:
        # Increase width
        wanted_width = round(height * image_ratio)
        new_size = (wanted_width, height)
        new_im = im.resize(new_size)
    else:  # Already correct ratio
        new_im = im
    return new_im