Spaces:
Running
Running
| """ | |
| 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") | |