Spaces:
Sleeping
Sleeping
""" | |
Source url: https://github.com/OPHoperHPO/image-background-remove-tool | |
Author: Nikita Selin (OPHoperHPO)[https://github.com/OPHoperHPO]. | |
License: Apache License 2.0 | |
""" | |
import PIL.Image | |
import torch | |
from carvekit.utils.image_utils import to_tensor | |
def composite( | |
foreground: PIL.Image.Image, | |
background: PIL.Image.Image, | |
alpha: PIL.Image.Image, | |
device="cpu", | |
): | |
""" | |
Composites foreground with background by following | |
https://pymatting.github.io/intro.html#alpha-matting math formula. | |
Args: | |
device: Processing device | |
foreground: Image that will be pasted to background image with following alpha mask. | |
background: Background image | |
alpha: Alpha Image | |
Returns: | |
Composited image as PIL.Image instance. | |
""" | |
foreground = foreground.convert("RGBA") | |
background = background.convert("RGBA") | |
alpha_rgba = alpha.convert("RGBA") | |
alpha_l = alpha.convert("L") | |
fg = to_tensor(foreground).to(device) | |
alpha_rgba = to_tensor(alpha_rgba).to(device) | |
alpha_l = to_tensor(alpha_l).to(device) | |
bg = to_tensor(background).to(device) | |
alpha_l = alpha_l / 255 | |
alpha_rgba = alpha_rgba / 255 | |
bg = torch.where(torch.logical_not(alpha_rgba >= 1), bg, fg) | |
bg[:, :, 0] = alpha_l[:, :] * fg[:, :, 0] + (1 - alpha_l[:, :]) * bg[:, :, 0] | |
bg[:, :, 1] = alpha_l[:, :] * fg[:, :, 1] + (1 - alpha_l[:, :]) * bg[:, :, 1] | |
bg[:, :, 2] = alpha_l[:, :] * fg[:, :, 2] + (1 - alpha_l[:, :]) * bg[:, :, 2] | |
bg[:, :, 3] = alpha_l[:, :] * 255 | |
del alpha_l, alpha_rgba, fg | |
return PIL.Image.fromarray(bg.cpu().numpy()).convert("RGBA") | |
def apply_mask( | |
image: PIL.Image.Image, mask: PIL.Image.Image, device="cpu" | |
) -> PIL.Image.Image: | |
""" | |
Applies mask to foreground. | |
Args: | |
device: Processing device. | |
image: Image with background. | |
mask: Alpha Channel mask for this image. | |
Returns: | |
Image without background, where mask was black. | |
""" | |
background = PIL.Image.new("RGBA", image.size, color=(130, 130, 130, 0)) | |
return composite(image, background, mask, device=device).convert("RGBA") | |
def extract_alpha_channel(image: PIL.Image.Image) -> PIL.Image.Image: | |
""" | |
Extracts alpha channel from the RGBA image. | |
Args: | |
image: RGBA PIL image | |
Returns: | |
RGBA alpha channel image | |
""" | |
alpha = image.split()[-1] | |
bg = PIL.Image.new("RGBA", image.size, (0, 0, 0, 255)) | |
bg.paste(alpha, mask=alpha) | |
return bg.convert("RGBA") | |