Towsif7's picture
firrst commit
59e40e1
"""
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")