Rembg / app.py
ankandrew's picture
Update app.py
f8a3f01 verified
Raw
History Blame Contribute Delete
5.43 kB
import cv2
import gradio as gr
import numpy as np
from functools import lru_cache
from rembg import new_session, remove
GOOD_MODELS = [
"u2net_human_seg",
"silueta",
"u2netp",
"isnet-general-use",
"bria-rmbg",
"birefnet-general-lite",
"birefnet-portrait",
]
MODEL_NOTES = {
"u2net_human_seg": "Fast human-specific baseline. Good for full body/person masks.",
"silueta": "Small and fast. Lower quality, useful for latency testing.",
"u2netp": "Very light U2Net variant. Fastest baseline, lower quality.",
"isnet-general-use": "General-purpose background removal fallback.",
"bria-rmbg": "High-quality general background remover. Check license for your use.",
"birefnet-general-lite": "Lighter BiRefNet. Better quality than tiny models, slower than U2Net variants.",
"birefnet-portrait": "Best BiRefNet choice for portraits / people, usually slower.",
}
@lru_cache(maxsize=3)
def get_session(model_name: str):
return new_session(model_name)
def ensure_uint8_rgb(image: np.ndarray) -> np.ndarray:
if image is None:
raise gr.Error("Please upload an image.")
image = np.asarray(image)
if image.ndim == 2:
image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
if image.shape[-1] == 4:
image = image[:, :, :3]
if image.dtype != np.uint8:
image = np.clip(image, 0, 255).astype(np.uint8)
return image
def normalize_mask(mask, width: int, height: int) -> np.ndarray:
mask = np.asarray(mask)
if mask.ndim == 3:
mask = mask[:, :, 0]
if mask.shape[:2] != (height, width):
mask = cv2.resize(
mask,
(width, height),
interpolation=cv2.INTER_LANCZOS4,
)
if mask.dtype != np.uint8:
mask = np.clip(mask, 0, 255).astype(np.uint8)
return mask
def composite_on_white(
image_rgb: np.ndarray,
mask_u8: np.ndarray,
edge_blur: float,
) -> np.ndarray:
alpha = mask_u8.astype(np.float32) / 255.0
if edge_blur > 0:
alpha = cv2.GaussianBlur(alpha, (0, 0), sigmaX=edge_blur)
alpha = np.clip(alpha, 0.0, 1.0)
alpha = alpha[:, :, None]
white = np.full_like(image_rgb, 255)
result = (
image_rgb.astype(np.float32) * alpha
+ white.astype(np.float32) * (1.0 - alpha)
)
return np.clip(result, 0, 255).astype(np.uint8)
def inference(
image,
model,
post_process_mask,
alpha_matting,
edge_blur,
):
image_rgb = ensure_uint8_rgb(image)
height, width = image_rgb.shape[:2]
session = get_session(model)
mask = remove(
image_rgb,
session=session,
only_mask=True,
post_process_mask=post_process_mask,
alpha_matting=alpha_matting,
)
mask_u8 = normalize_mask(mask, width=width, height=height)
white_result = composite_on_white(
image_rgb=image_rgb,
mask_u8=mask_u8,
edge_blur=edge_blur,
)
return white_result, mask_u8, MODEL_NOTES.get(model, "")
def compare_all(
image,
post_process_mask,
alpha_matting,
edge_blur,
):
image_rgb = ensure_uint8_rgb(image)
outputs = []
for model in GOOD_MODELS:
result, _, _ = inference(
image=image_rgb,
model=model,
post_process_mask=post_process_mask,
alpha_matting=alpha_matting,
edge_blur=edge_blur,
)
outputs.append((result, model))
return outputs
with gr.Blocks() as app:
gr.Markdown("# Person Background Removal Benchmark")
gr.Markdown(
"""
Remove background with [Rembg](https://github.com/danielgatis/rembg) models.
"""
)
with gr.Row():
input_image = gr.Image(type="numpy", label="Input Image")
with gr.Column():
output_image = gr.Image(type="numpy", label="White Background Result")
output_mask = gr.Image(type="numpy", label="Mask")
model_note = gr.Textbox(label="Model note", interactive=False)
with gr.Row():
model_selector = gr.Dropdown(
GOOD_MODELS,
value="u2net_human_seg",
label="Model",
)
edge_blur = gr.Slider(
minimum=0.0,
maximum=3.0,
value=0.0,
step=0.25,
label="Edge blur",
)
with gr.Row():
post_process_mask = gr.Checkbox(
value=False,
label="Post-process mask",
)
alpha_matting = gr.Checkbox(
value=False,
label="Alpha matting",
)
with gr.Row():
process_button = gr.Button("Process selected model", variant="primary")
compare_button = gr.Button("Compare all models")
gallery = gr.Gallery(
label="Compare all models",
columns=3,
height="auto",
object_fit="contain",
)
process_button.click(
inference,
inputs=[
input_image,
model_selector,
post_process_mask,
alpha_matting,
edge_blur,
],
outputs=[
output_image,
output_mask,
model_note,
],
)
compare_button.click(
compare_all,
inputs=[
input_image,
post_process_mask,
alpha_matting,
edge_blur,
],
outputs=gallery,
)
app.launch()