Ejemplo n.º 1
0
def cutout(image_path, trimap_path, cutout_path):
    """
    Generate a cutout image from an input image and an input trimap.
    This method is using closed-form alpha matting as proposed by :cite:`levin2007closed` and multi-level foreground extraction :cite:`germer2020multilevel`.

    Parameters
    ----------
    image_path: str
        Path of input image
    trimap_path: str
        Path of input trimap
    cutout_path: str
        Path of output cutout image

    Example
    -------
    >>> cutout("../data/lemur.png", "../data/lemur_trimap.png", "lemur_cutout.png")
    """
    image = load_image(image_path, "RGB")
    trimap = load_image(trimap_path, "GRAY")

    if image.shape[:2] != trimap.shape[:2]:
        raise ValueError("Input image and trimap must have same size")

    alpha = estimate_alpha_cf(image, trimap)

    foreground = estimate_foreground_ml(image, alpha)

    cutout = stack_images(foreground, alpha)

    save_image(cutout_path, cutout)
Ejemplo n.º 2
0
def alpha_matting_cutout(
    img,
    mask,
    foreground_threshold,
    background_threshold,
    erode_structure_size,
):
    base_size = (1000, 1000)
    size = img.size

    img.thumbnail(base_size, Image.LANCZOS)
    mask = mask.resize(img.size, Image.LANCZOS)

    img = np.asarray(img)
    mask = np.asarray(mask)

    # guess likely foreground/background
    is_foreground = mask > foreground_threshold
    is_background = mask < background_threshold

    # erode foreground/background
    structure = None
    if erode_structure_size > 0:
        structure = np.ones((erode_structure_size, erode_structure_size),
                            dtype=np.int)

    is_foreground = binary_erosion(is_foreground, structure=structure)
    is_background = binary_erosion(is_background,
                                   structure=structure,
                                   border_value=1)

    # build trimap
    # 0   = background
    # 128 = unknown
    # 255 = foreground
    trimap = np.full(mask.shape, dtype=np.uint8, fill_value=128)
    trimap[is_foreground] = 255
    trimap[is_background] = 0

    # build the cutout image
    img_normalized = img / 255.0
    trimap_normalized = trimap / 255.0

    alpha = estimate_alpha_cf(img_normalized, trimap_normalized)
    foreground = estimate_foreground_ml(img_normalized, alpha)
    cutout = stack_images(foreground, alpha)

    cutout = np.clip(cutout * 255, 0, 255).astype(np.uint8)
    cutout = Image.fromarray(cutout)
    cutout = cutout.resize(size, Image.LANCZOS)

    return cutout
Ejemplo n.º 3
0
    def alpha_matting_cutout(
        self,
        foreground_threshold=240,
        background_threshold=10,
        erode_structure_size=10,
    ) -> Image:
        base_size = (1000, 1000)
        size = self.__image.size

        self.__image.thumbnail(base_size, Image.LANCZOS)
        mask = self.__mask.resize(self.__image.size, Image.LANCZOS)

        img = numpy.asarray(self.__image)
        mask = numpy.asarray(mask)

        self.__image.close()
        self.__mask.close()

        # Guess likely foreground/background
        is_foreground = mask > foreground_threshold
        is_background = mask < background_threshold

        # Erode foreground/background
        structure = None
        if erode_structure_size > 0:
            structure = numpy.ones(
                (erode_structure_size, erode_structure_size), dtype=numpy.int)

        is_foreground = binary_erosion(is_foreground, structure=structure)
        is_background = binary_erosion(is_background,
                                       structure=structure,
                                       border_value=1)

        trimap = numpy.full(mask.shape, dtype=numpy.uint8, fill_value=128)
        trimap[is_foreground] = 255
        trimap[is_background] = 0

        # Build the cutout image
        img_normalized = img / 255.0
        trimap_normalized = trimap / 255.0

        alpha = estimate_alpha_cf(img_normalized, trimap_normalized)
        foreground = estimate_foreground_ml(img_normalized, alpha)
        cutout = stack_images(foreground, alpha)

        cutout = numpy.clip(cutout * 255, 0, 255).astype(numpy.uint8)
        cutout = Image.fromarray(cutout)
        cutout = cutout.resize(size, Image.LANCZOS)

        return cutout