|
import gradio as gr |
|
import rembg |
|
from rembg import remove, new_session |
|
from PIL import Image |
|
import numpy as np |
|
import logging |
|
import time |
|
from hashlib import md5 |
|
import json |
|
from pathlib import Path |
|
import tempfile |
|
import os |
|
|
|
|
|
logging.basicConfig(level=logging.INFO, filename="user_activity.log", filemode="a") |
|
logging.info(f"rembg version: {rembg.__version__}") |
|
|
|
|
|
counter_file = Path("user_count.json") |
|
def init_counter(): |
|
if not counter_file.exists(): |
|
with open(counter_file, "w") as f: |
|
json.dump({"total_requests": 0, "unique_sessions": []}, f) |
|
|
|
def log_user_interaction(): |
|
init_counter() |
|
|
|
user_id = md5(str(time.time()).encode()).hexdigest() |
|
|
|
try: |
|
with open(counter_file, "r") as f: |
|
content = f.read().strip() |
|
if not content: |
|
data = {"total_requests": 0, "unique_sessions": []} |
|
else: |
|
data = json.loads(content) |
|
except (json.JSONDecodeError, FileNotFoundError): |
|
|
|
data = {"total_requests": 0, "unique_sessions": []} |
|
|
|
data["total_requests"] += 1 |
|
if user_id not in data["unique_sessions"]: |
|
data["unique_sessions"].append(user_id) |
|
|
|
try: |
|
with open(counter_file, "w") as f: |
|
json.dump(data, f) |
|
except Exception as e: |
|
logging.error(f"Failed to write counter file: {e}") |
|
|
|
|
|
logging.info(f"Request #{data['total_requests']} at {time.strftime('%Y%m%d-%H%M%S')}") |
|
return data["total_requests"], len(data["unique_sessions"]) |
|
|
|
|
|
MODEL_OPTIONS = { |
|
"": "Select a model", |
|
"u2net": "A pre-trained model for general use cases (default)", |
|
"isnet-general-use": "A new pre-trained model for general use cases", |
|
"isnet-anime": "High-accuracy segmentation for anime characters", |
|
"silueta": "A reduced-size version of u2net (43MB)", |
|
"unet": "Lightweight version of u2net model", |
|
"u2netp": "A lightweight version of u2net model", |
|
"u2net_human_seg": "A pre-trained model for human segmentation", |
|
"u2net_cloth_seg": "A pre-trained model for cloth parsing in human portraits", |
|
} |
|
|
|
def hex_to_rgba(hex_color): |
|
if not hex_color: |
|
return None |
|
hex_color = hex_color.lstrip('#') |
|
if len(hex_color) == 6: |
|
hex_color += 'FF' |
|
return tuple(int(hex_color[i:i + 2], 16) for i in (0, 2, 4, 6)) |
|
|
|
def remove_background(input_path, bg_color=None, transparent_bg=True, model_choice="", alpha_matting=False, post_process_mask=False, only_mask=False): |
|
print(f"DEBUG: Function called with input_path: {input_path}") |
|
print(f"DEBUG: Parameters - bg_color: {bg_color}, transparent_bg: {transparent_bg}, model_choice: {model_choice}") |
|
|
|
try: |
|
|
|
if not input_path or not os.path.exists(input_path): |
|
print(f"ERROR: Invalid input path: {input_path}") |
|
return None |
|
|
|
print("DEBUG: Starting background removal...") |
|
|
|
|
|
try: |
|
log_user_interaction() |
|
except Exception as e: |
|
print(f"WARNING: Failed to log user interaction: {e}") |
|
|
|
|
|
|
|
input_image = Image.open(input_path) |
|
print(f"DEBUG: Opened image with size: {input_image.size}, mode: {input_image.mode}") |
|
|
|
|
|
original_filename = os.path.splitext(os.path.basename(input_path))[0] |
|
|
|
output_filename = f"{original_filename}_removebg.png" |
|
print(f"DEBUG: Output filename will be: {output_filename}") |
|
|
|
|
|
model_name = model_choice.split(' | ')[0] if model_choice and ' | ' in model_choice else model_choice |
|
print(f"DEBUG: Using model: {model_name if model_name else 'default'}") |
|
|
|
|
|
session = new_session(model_name) if model_name else None |
|
|
|
|
|
bg_color_rgba = None if transparent_bg else hex_to_rgba(bg_color) |
|
print(f"DEBUG: Background color RGBA: {bg_color_rgba}") |
|
|
|
|
|
remove_kwargs = {} |
|
|
|
|
|
if session is not None: |
|
remove_kwargs["session"] = session |
|
|
|
|
|
if bg_color_rgba is not None: |
|
remove_kwargs["bgcolor"] = bg_color_rgba |
|
|
|
|
|
if alpha_matting: |
|
remove_kwargs.update({ |
|
"alpha_matting": True, |
|
"alpha_matting_foreground_threshold": 270, |
|
"alpha_matting_background_threshold": 20, |
|
"alpha_matting_erode_size": 11 |
|
}) |
|
|
|
if post_process_mask: |
|
remove_kwargs["post_process_mask"] = True |
|
|
|
if only_mask: |
|
remove_kwargs["only_mask"] = True |
|
|
|
print(f"DEBUG: Remove kwargs: {remove_kwargs}") |
|
|
|
|
|
input_array = np.array(input_image) |
|
print(f"DEBUG: Input array shape: {input_array.shape}") |
|
|
|
|
|
print("DEBUG: Calling rembg.remove()...") |
|
output_array = remove(input_array, **remove_kwargs) |
|
print(f"DEBUG: Output array shape: {output_array.shape}") |
|
|
|
|
|
output_image = Image.fromarray(output_array) |
|
print(f"DEBUG: Output image size: {output_image.size}, mode: {output_image.mode}") |
|
|
|
|
|
if transparent_bg or only_mask: |
|
if output_image.mode != 'RGBA': |
|
output_image = output_image.convert('RGBA') |
|
print("DEBUG: Converted to RGBA mode") |
|
elif output_image.mode != 'RGB': |
|
output_image = output_image.convert('RGB') |
|
print("DEBUG: Converted to RGB mode") |
|
|
|
|
|
temp_dir = tempfile.mkdtemp() |
|
output_path = os.path.join(temp_dir, output_filename) |
|
output_image.save(output_path, format="PNG") |
|
print(f"DEBUG: Saved output to: {output_path}") |
|
|
|
|
|
if os.path.exists(output_path): |
|
file_size = os.path.getsize(output_path) |
|
print(f"DEBUG: Output file created successfully, size: {file_size} bytes") |
|
return output_path |
|
else: |
|
print("ERROR: Output file was not created") |
|
return None |
|
|
|
except Exception as e: |
|
print(f"ERROR: Exception occurred: {str(e)}") |
|
import traceback |
|
traceback.print_exc() |
|
logging.error(f"An error occurred: {e}") |
|
return None |
|
|
|
|
|
examples = [ |
|
[ |
|
'scifi_man1.jpg', |
|
"#FFFFFF", |
|
True, |
|
"", |
|
False, |
|
False, |
|
False |
|
] |
|
] |
|
|
|
|
|
iface = gr.Interface( |
|
fn=remove_background, |
|
inputs=[ |
|
gr.Image(type="filepath", label="Input Image"), |
|
gr.ColorPicker(label="Background Color (ignored if transparent is selected)", value="#FFFFFF"), |
|
gr.Checkbox(label="Transparent Background", value=False), |
|
gr.Dropdown( |
|
choices=[""] + [f"{k} | {v}" for k, v in MODEL_OPTIONS.items() if k != ""], |
|
label="Model Selection", |
|
value="", |
|
allow_custom_value=False |
|
), |
|
gr.Checkbox(label="Enable Alpha Matting", value=False), |
|
gr.Checkbox(label="Post-Process Mask", value=False), |
|
gr.Checkbox(label="Only Return Mask", value=False) |
|
], |
|
outputs=[ |
|
gr.Image(type="filepath", label="Output Image (PNG)") |
|
], |
|
examples=examples, |
|
title="Background Remover v2.9", |
|
description="Upload an image to remove the background. Choose a solid color or transparent background, select a model, and customize with alpha matting and other options. Right-click the output image to save as PNG.", |
|
allow_flagging="never", |
|
) |
|
|
|
if __name__ == "__main__": |
|
print("Starting Background Remover app...") |
|
iface.launch() |