| """ |
| Background removal using rembg and background scene selection. |
| """ |
|
|
| from PIL import Image |
| from rembg import remove |
| import os |
| import random |
|
|
| BACKGROUNDS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "backgrounds") |
|
|
| SCENE_PREFERENCES = { |
| "Dog": ["backyard", "park", "porch", "meadow"], |
| "Cat": ["living_room", "couch", "garden", "porch"], |
| "Other": ["park", "garden", "meadow", "backyard"], |
| } |
|
|
|
|
| def remove_background(image: Image.Image) -> Image.Image: |
| return remove(image) |
|
|
|
|
| def get_available_backgrounds() -> list[str]: |
| if not os.path.isdir(BACKGROUNDS_DIR): |
| return [] |
| return [ |
| os.path.splitext(f)[0] |
| for f in os.listdir(BACKGROUNDS_DIR) |
| if f.endswith(".png") |
| ] |
|
|
|
|
| def select_background(animal_type: str, custom_bg: Image.Image | None = None) -> Image.Image: |
| if custom_bg is not None: |
| return custom_bg.convert("RGB") |
|
|
| available = get_available_backgrounds() |
| if not available: |
| return _generate_fallback_background() |
|
|
| preferences = SCENE_PREFERENCES.get(animal_type, SCENE_PREFERENCES["Other"]) |
| candidates = [name for name in preferences if name in available] |
|
|
| if not candidates: |
| candidates = available |
|
|
| chosen = random.choice(candidates) |
| path = os.path.join(BACKGROUNDS_DIR, f"{chosen}.png") |
| return Image.open(path).convert("RGB") |
|
|
|
|
| def _generate_fallback_background() -> Image.Image: |
| from PIL import ImageDraw |
| img = Image.new("RGB", (1024, 1024)) |
| draw = ImageDraw.Draw(img) |
| for y in range(1024): |
| t = y / 1024 |
| r = int(135 + (185 - 135) * t) |
| g = int(195 + (220 - 195) * t) |
| b = int(235 + (245 - 235) * t) |
| draw.line([(0, y), (1024, y)], fill=(r, g, b)) |
| return img |