#!/usr/bin/env python3 """ AGGRESSIVE Background Removal - Match Green Screen Reference Style Target: Remove ALL white/gray/light pixels around the object Result: Clean edges like the zombie bunny reference """ import os import shutil from pathlib import Path from PIL import Image import numpy as np # Test images TEST_IMAGES = [ "assets/PHASE_PACKS/1_FAZA_1/tools/wood/watering_can.png", "assets/PHASE_PACKS/1_FAZA_1/animals/horse.png", "assets/PHASE_PACKS/1_FAZA_1/infrastructure/farm_elements/manure_pile.png", "assets/PHASE_PACKS/1_FAZA_1/tools/iron/pickaxe.png", "assets/PHASE_PACKS/1_FAZA_1/animals/sheep/walk.png", ] OUTPUT_DIR = "test_transparency" def aggressive_bg_removal(input_path, output_path): """ Aggressively remove ALL light/white backgrounds. Also removes white shadows and glows. """ img = Image.open(input_path) if img.mode != 'RGBA': img = img.convert('RGBA') data = np.array(img).astype(np.float32) r, g, b, a = data[:,:,0], data[:,:,1], data[:,:,2], data[:,:,3] # Calculate brightness (0-255) brightness = (r + g + b) / 3 # Calculate saturation (how colorful) max_rgb = np.maximum(np.maximum(r, g), b) min_rgb = np.minimum(np.minimum(r, g), b) saturation = max_rgb - min_rgb # ===== AGGRESSIVE RULES ===== # 1. Remove pure white (threshold 250+) pure_white = (r > 250) & (g > 250) & (b > 250) # 2. Remove pure black (threshold 5-) pure_black = (r < 5) & (g < 5) & (b < 5) # 3. Remove near-white with low saturation (the shadows!) # This catches white glows and shadows near_white_low_sat = (brightness > 230) & (saturation < 30) # 4. Remove light gray (common in anti-aliased edges to white bg) light_gray = (brightness > 200) & (saturation < 20) # 5. Remove checkered pattern pixels (if present) # Checkered = alternating gray shades checkered_light = (brightness > 180) & (brightness < 220) & (saturation < 15) checkered_dark = (brightness > 100) & (brightness < 160) & (saturation < 15) # Combine all background criteria is_background = ( pure_white | pure_black | near_white_low_sat | light_gray | checkered_light | checkered_dark ) # ===== PROTECT COLORED PIXELS ===== # Don't remove pixels with high saturation (actual colored parts) is_colored = saturation > 40 is_background = is_background & ~is_colored # ===== APPLY TRANSPARENCY ===== new_alpha = np.where(is_background, 0, a) # For semi-background (transitional), use graduated alpha # based on how "background-like" the pixel is semi_bg = (brightness > 180) & (saturation < 50) & ~is_colored fade_factor = np.clip((brightness - 180) / 70, 0, 1) # 0-1 scale new_alpha = np.where(semi_bg, new_alpha * (1 - fade_factor * 0.8), new_alpha) # Apply new alpha data[:,:,3] = np.clip(new_alpha, 0, 255) # Clean up transparent pixels (set RGB to 0) fully_transparent = data[:,:,3] < 10 data[fully_transparent, 0] = 0 data[fully_transparent, 1] = 0 data[fully_transparent, 2] = 0 data[fully_transparent, 3] = 0 result = Image.fromarray(data.astype(np.uint8)) result.save(output_path, 'PNG') print(f" ✅ Processed: {os.path.basename(output_path)}") def main(): print("🔥 AGGRESSIVE BG REMOVAL - Match Green Screen Style") print("=" * 55) print("\nTarget: Clean edges like the zombie bunny reference!") print("Removing: white, shadows, glows, checkered patterns\n") os.makedirs(OUTPUT_DIR, exist_ok=True) processed = [] for img_path in TEST_IMAGES: if not os.path.exists(img_path): print(f" ❌ Not found: {img_path}") continue name = os.path.basename(img_path) name_no_ext = os.path.splitext(name)[0] # Copy original orig_dest = os.path.join(OUTPUT_DIR, f"{name_no_ext}_ORIGINAL.png") shutil.copy(img_path, orig_dest) print(f" 📋 Original: {name}") # Process with aggressive removal proc_dest = os.path.join(OUTPUT_DIR, f"{name_no_ext}_CLEAN.png") aggressive_bg_removal(img_path, proc_dest) processed.append({ 'name': name_no_ext, 'original': f"{name_no_ext}_ORIGINAL.png", 'processed': f"{name_no_ext}_CLEAN.png" }) # Generate comparison HTML html = ''' 🔥 Aggressive BG Removal Test

🔥 Aggressive Background Removal Test

🎯 TARGET: Clean edges like the zombie bunny reference (no white shadows!)
''' for item in processed: html += f'''

📷 ORIGINAL

Original
{item['name']}

✅ CLEANED (Checker)

Cleaned

✅ CLEANED (Green)

On Green

✅ CLEANED (Game)

In Game
''' html += ''' ''' html_path = os.path.join(OUTPUT_DIR, "comparison_v2.html") with open(html_path, 'w') as f: f.write(html) print("\n" + "=" * 55) print(f"✅ DONE! Open: {html_path}") if __name__ == '__main__': main()