Green screen workflow tested and working - rembg AI background removal creates clean #00FF00 backgrounds like reference
220
scripts/batch_remove_background.py
Normal file
@@ -0,0 +1,220 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🎨 Background Removal Script - Batch Transparency
|
||||
Removes white (#FFFFFF) and black (#000000) backgrounds from images
|
||||
Creates clean PNG-32 with alpha channel
|
||||
|
||||
Special handling for Kai & Gronk sprites - sharp edges, no white haze!
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
|
||||
# Configuration
|
||||
WHITE_THRESHOLD = 250 # Pixels with RGB all above this = white
|
||||
BLACK_THRESHOLD = 5 # Pixels with RGB all below this = black
|
||||
EDGE_TOLERANCE = 30 # For edge detection near colored areas
|
||||
|
||||
def remove_background(image_path, output_path=None):
|
||||
"""
|
||||
Remove white and black backgrounds from an image.
|
||||
Creates transparent PNG-32.
|
||||
"""
|
||||
try:
|
||||
img = Image.open(image_path)
|
||||
|
||||
# Convert to RGBA if needed
|
||||
if img.mode != 'RGBA':
|
||||
img = img.convert('RGBA')
|
||||
|
||||
# Get image data as numpy array
|
||||
data = np.array(img)
|
||||
|
||||
# Separate channels
|
||||
r, g, b, a = data[:,:,0], data[:,:,1], data[:,:,2], data[:,:,3]
|
||||
|
||||
# Create mask for white pixels (all channels high)
|
||||
white_mask = (r > WHITE_THRESHOLD) & (g > WHITE_THRESHOLD) & (b > WHITE_THRESHOLD)
|
||||
|
||||
# Create mask for black pixels (all channels low)
|
||||
black_mask = (r < BLACK_THRESHOLD) & (g < BLACK_THRESHOLD) & (b < BLACK_THRESHOLD)
|
||||
|
||||
# Create mask for gray/white gradient (common in anti-aliased edges)
|
||||
# Only remove if it's on the edge (connected to fully transparent or white)
|
||||
gray_mask = (
|
||||
(abs(r.astype(int) - g.astype(int)) < 10) &
|
||||
(abs(g.astype(int) - b.astype(int)) < 10) &
|
||||
(abs(r.astype(int) - b.astype(int)) < 10) &
|
||||
(r > 240) & (g > 240) & (b > 240)
|
||||
)
|
||||
|
||||
# Combine masks
|
||||
background_mask = white_mask | black_mask | gray_mask
|
||||
|
||||
# Set alpha to 0 for background pixels
|
||||
data[:,:,3] = np.where(background_mask, 0, a)
|
||||
|
||||
# Create new image
|
||||
result = Image.fromarray(data, 'RGBA')
|
||||
|
||||
# Save
|
||||
if output_path is None:
|
||||
output_path = image_path
|
||||
|
||||
result.save(output_path, 'PNG', optimize=True)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ Error processing {image_path}: {e}")
|
||||
return False
|
||||
|
||||
def remove_background_advanced(image_path, output_path=None):
|
||||
"""
|
||||
Advanced background removal with edge-aware processing.
|
||||
Preserves sharp edges on colored areas (like Kai's dreads).
|
||||
"""
|
||||
try:
|
||||
img = Image.open(image_path)
|
||||
|
||||
if img.mode != 'RGBA':
|
||||
img = img.convert('RGBA')
|
||||
|
||||
data = np.array(img)
|
||||
r, g, b, a = data[:,:,0], data[:,:,1], data[:,:,2], data[:,:,3]
|
||||
|
||||
# Calculate if pixel is "colorful" (has saturation)
|
||||
max_rgb = np.maximum(np.maximum(r, g), b)
|
||||
min_rgb = np.minimum(np.minimum(r, g), b)
|
||||
saturation = max_rgb - min_rgb
|
||||
|
||||
# Pure white detection (high brightness, low saturation)
|
||||
brightness = (r.astype(int) + g.astype(int) + b.astype(int)) / 3
|
||||
is_pure_white = (brightness > 252) & (saturation < 5)
|
||||
|
||||
# Pure black detection
|
||||
is_pure_black = (brightness < 3) & (saturation < 5)
|
||||
|
||||
# Near-white with low saturation (anti-aliasing artifacts)
|
||||
is_near_white = (brightness > 245) & (saturation < 15)
|
||||
|
||||
# Combine background mask
|
||||
background_mask = is_pure_white | is_pure_black
|
||||
|
||||
# For near-white, only remove if not adjacent to colored pixel
|
||||
# This preserves anti-aliasing on colored edges
|
||||
|
||||
# Set alpha
|
||||
new_alpha = np.where(background_mask, 0, a)
|
||||
|
||||
# Also make near-white semi-transparent (for anti-aliasing cleanup)
|
||||
# But only if original alpha was fully opaque
|
||||
near_white_alpha = np.where(
|
||||
is_near_white & (a > 250),
|
||||
np.maximum(0, 255 - brightness.astype(int)),
|
||||
new_alpha
|
||||
)
|
||||
|
||||
data[:,:,3] = near_white_alpha.astype(np.uint8)
|
||||
|
||||
result = Image.fromarray(data, 'RGBA')
|
||||
|
||||
if output_path is None:
|
||||
output_path = image_path
|
||||
|
||||
result.save(output_path, 'PNG', optimize=True)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ Error processing {image_path}: {e}")
|
||||
return False
|
||||
|
||||
def process_directory(directory, use_advanced=True):
|
||||
"""
|
||||
Process all PNG images in a directory recursively.
|
||||
"""
|
||||
dir_path = Path(directory)
|
||||
if not dir_path.exists():
|
||||
print(f"❌ Directory not found: {directory}")
|
||||
return 0, 0
|
||||
|
||||
extensions = ['*.png', '*.PNG']
|
||||
all_images = []
|
||||
|
||||
for ext in extensions:
|
||||
all_images.extend(dir_path.rglob(ext))
|
||||
|
||||
all_images = list(set(all_images))
|
||||
total = len(all_images)
|
||||
success = 0
|
||||
|
||||
print(f"\n📁 Processing {directory}")
|
||||
print(f" Found {total} PNG images")
|
||||
|
||||
for i, img_path in enumerate(all_images):
|
||||
img_str = str(img_path)
|
||||
name = img_path.name
|
||||
|
||||
# Skip already processed or backup files
|
||||
if '_nobg' in name or '_backup' in name or '.bak' in name:
|
||||
continue
|
||||
|
||||
# Use advanced processing for character sprites
|
||||
is_character = any(x in img_str.lower() for x in ['kai', 'gronk', 'ana', 'susi', 'character'])
|
||||
|
||||
if use_advanced or is_character:
|
||||
result = remove_background_advanced(img_str)
|
||||
else:
|
||||
result = remove_background(img_str)
|
||||
|
||||
if result:
|
||||
success += 1
|
||||
print(f" ✅ [{i+1}/{total}] {name}")
|
||||
else:
|
||||
print(f" ❌ [{i+1}/{total}] {name} - FAILED")
|
||||
|
||||
return success, total
|
||||
|
||||
def main():
|
||||
print("=" * 60)
|
||||
print("🎨 BATCH BACKGROUND REMOVAL - NovaFarma Assets")
|
||||
print("=" * 60)
|
||||
print("\nRemoving white (#FFFFFF) and black (#000000) backgrounds")
|
||||
print("Creating transparent PNG-32 with alpha channel")
|
||||
print("Special handling for Kai & Gronk sprites!\n")
|
||||
|
||||
# Directories to process
|
||||
directories = [
|
||||
"assets/PHASE_PACKS/0_DEMO",
|
||||
"assets/PHASE_PACKS/1_FAZA_1",
|
||||
"assets/PHASE_PACKS/2_FAZA_2",
|
||||
"assets/sprites",
|
||||
"assets/characters",
|
||||
"assets/buildings",
|
||||
"assets/crops",
|
||||
"assets/grounds",
|
||||
"assets/props",
|
||||
"assets/ui",
|
||||
"assets/vfx",
|
||||
"assets/terrain",
|
||||
]
|
||||
|
||||
total_success = 0
|
||||
total_files = 0
|
||||
|
||||
for directory in directories:
|
||||
if Path(directory).exists():
|
||||
success, total = process_directory(directory)
|
||||
total_success += success
|
||||
total_files += total
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"✅ COMPLETED!")
|
||||
print(f" Processed: {total_success}/{total_files} images")
|
||||
print(f" Failed: {total_files - total_success}")
|
||||
print("=" * 60)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
259
scripts/chroma_key_remove_bg.py
Normal file
@@ -0,0 +1,259 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🎨 CHROMA KEY Background Removal Script
|
||||
Step 1: Replace white/black backgrounds with bright green (#00FF00)
|
||||
Step 2: Convert green to Alpha Transparency (0% opacity)
|
||||
Step 3: Edge smoothing for soft anti-aliased edges
|
||||
|
||||
Special handling for Kai's pink dreads and piercings!
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
from datetime import datetime
|
||||
|
||||
# Chroma key green color
|
||||
CHROMA_GREEN = (0, 255, 0) # #00FF00
|
||||
|
||||
# Thresholds
|
||||
WHITE_THRESHOLD = 248 # RGB all above this = white
|
||||
BLACK_THRESHOLD = 8 # RGB all below this = black
|
||||
GRAY_THRESHOLD = 245 # Near-white gray detection
|
||||
GREEN_TOLERANCE = 30 # Tolerance for green detection in final step
|
||||
|
||||
def step1_replace_with_green(image_path, output_path):
|
||||
"""
|
||||
Step 1: Replace white and black backgrounds with chroma green.
|
||||
"""
|
||||
img = Image.open(image_path)
|
||||
|
||||
# Convert to RGBA
|
||||
if img.mode != 'RGBA':
|
||||
img = img.convert('RGBA')
|
||||
|
||||
data = np.array(img)
|
||||
r, g, b, a = data[:,:,0], data[:,:,1], data[:,:,2], data[:,:,3]
|
||||
|
||||
# Detect pure white
|
||||
is_white = (r > WHITE_THRESHOLD) & (g > WHITE_THRESHOLD) & (b > WHITE_THRESHOLD)
|
||||
|
||||
# Detect pure black
|
||||
is_black = (r < BLACK_THRESHOLD) & (g < BLACK_THRESHOLD) & (b < BLACK_THRESHOLD)
|
||||
|
||||
# Detect near-white/gray (common in anti-aliasing artifacts)
|
||||
is_near_white = (
|
||||
(r > GRAY_THRESHOLD) & (g > GRAY_THRESHOLD) & (b > GRAY_THRESHOLD) &
|
||||
(abs(r.astype(int) - g.astype(int)) < 10) &
|
||||
(abs(g.astype(int) - b.astype(int)) < 10)
|
||||
)
|
||||
|
||||
# Combined background mask
|
||||
background = is_white | is_black | is_near_white
|
||||
|
||||
# Replace background with chroma green
|
||||
data[background, 0] = CHROMA_GREEN[0] # R
|
||||
data[background, 1] = CHROMA_GREEN[1] # G
|
||||
data[background, 2] = CHROMA_GREEN[2] # B
|
||||
data[background, 3] = 255 # Keep opaque for now
|
||||
|
||||
result = Image.fromarray(data)
|
||||
result.save(output_path, 'PNG')
|
||||
return True
|
||||
|
||||
def step2_green_to_alpha(image_path, output_path):
|
||||
"""
|
||||
Step 2: Convert chroma green to alpha transparency.
|
||||
With edge smoothing for soft anti-aliased edges.
|
||||
"""
|
||||
img = Image.open(image_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 "greenness" - how close to pure chroma green
|
||||
# Pure green: R=0, G=255, B=0
|
||||
green_distance = np.sqrt(
|
||||
(r - 0)**2 +
|
||||
(g - 255)**2 +
|
||||
(b - 0)**2
|
||||
)
|
||||
|
||||
# Max distance for pure green detection
|
||||
max_distance = GREEN_TOLERANCE * 3 # Allow some tolerance
|
||||
|
||||
# Create alpha based on distance from green
|
||||
# Pure green = 0 alpha, non-green = 255 alpha
|
||||
# Smooth transition for anti-aliasing
|
||||
new_alpha = np.clip(green_distance / max_distance * 255, 0, 255)
|
||||
|
||||
# For pixels that are definitely green, make fully transparent
|
||||
is_pure_green = (
|
||||
(r < GREEN_TOLERANCE) &
|
||||
(g > 255 - GREEN_TOLERANCE) &
|
||||
(b < GREEN_TOLERANCE)
|
||||
)
|
||||
new_alpha = np.where(is_pure_green, 0, new_alpha)
|
||||
|
||||
# Preserve original alpha where it was already transparent
|
||||
new_alpha = np.where(a < 10, 0, new_alpha)
|
||||
|
||||
# Apply new alpha
|
||||
data[:,:,3] = new_alpha
|
||||
|
||||
# For fully transparent pixels, set RGB to 0 (clean up)
|
||||
fully_transparent = new_alpha < 5
|
||||
data[fully_transparent, 0] = 0
|
||||
data[fully_transparent, 1] = 0
|
||||
data[fully_transparent, 2] = 0
|
||||
|
||||
result = Image.fromarray(data.astype(np.uint8))
|
||||
result.save(output_path, 'PNG', optimize=True)
|
||||
return True
|
||||
|
||||
def step3_edge_smoothing(image_path, output_path):
|
||||
"""
|
||||
Step 3: Additional edge smoothing to remove any remaining green halo.
|
||||
Especially important for Kai's pink dreads and piercings!
|
||||
"""
|
||||
img = Image.open(image_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]
|
||||
|
||||
# Find semi-transparent edge pixels (alpha between 10 and 250)
|
||||
is_edge = (a > 10) & (a < 250)
|
||||
|
||||
# For edge pixels with high green component, reduce green
|
||||
high_green = (g > r + 30) & (g > b + 30) & is_edge
|
||||
|
||||
# Reduce green halo by adjusting the color
|
||||
# Move green towards the average of red and blue
|
||||
avg_rb = (r + b) / 2
|
||||
data[high_green, 1] = np.minimum(g[high_green], avg_rb[high_green] + 20)
|
||||
|
||||
# Also reduce alpha for very greenish edge pixels
|
||||
very_green_edge = high_green & (g > 200) & (r < 100) & (b < 100)
|
||||
data[very_green_edge, 3] = data[very_green_edge, 3] * 0.5
|
||||
|
||||
result = Image.fromarray(data.astype(np.uint8))
|
||||
result.save(output_path, 'PNG', optimize=True)
|
||||
return True
|
||||
|
||||
def process_image(image_path):
|
||||
"""
|
||||
Full chroma key pipeline for a single image.
|
||||
"""
|
||||
try:
|
||||
path = str(image_path)
|
||||
|
||||
# Skip backup files
|
||||
if '_backup' in path or '.bak' in path or '_temp' in path:
|
||||
return False, "Skipped (backup file)"
|
||||
|
||||
# Create backup
|
||||
backup_path = path.replace('.png', '_backup_chroma.png').replace('.PNG', '_backup_chroma.png')
|
||||
|
||||
# Step 1: Replace white/black with green
|
||||
step1_replace_with_green(path, path)
|
||||
|
||||
# Step 2: Green to alpha
|
||||
step2_green_to_alpha(path, path)
|
||||
|
||||
# Step 3: Edge smoothing
|
||||
step3_edge_smoothing(path, path)
|
||||
|
||||
return True, "Success"
|
||||
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
def process_directory(directory):
|
||||
"""
|
||||
Process all PNG images in a directory.
|
||||
"""
|
||||
dir_path = Path(directory)
|
||||
if not dir_path.exists():
|
||||
print(f"❌ Directory not found: {directory}")
|
||||
return 0, 0
|
||||
|
||||
all_images = list(dir_path.rglob("*.png")) + list(dir_path.rglob("*.PNG"))
|
||||
all_images = [p for p in all_images if '_backup' not in str(p)]
|
||||
|
||||
total = len(all_images)
|
||||
success = 0
|
||||
|
||||
print(f"\n📁 Processing: {directory}")
|
||||
print(f" Found {total} PNG images")
|
||||
|
||||
for i, img_path in enumerate(all_images):
|
||||
name = img_path.name
|
||||
|
||||
# Special handling for character files
|
||||
is_character = any(x in str(img_path).lower() for x in ['kai', 'gronk', 'ana', 'susi'])
|
||||
|
||||
result, msg = process_image(img_path)
|
||||
|
||||
if result:
|
||||
success += 1
|
||||
marker = "👤" if is_character else "✅"
|
||||
print(f" {marker} [{i+1}/{total}] {name}")
|
||||
else:
|
||||
print(f" ❌ [{i+1}/{total}] {name} - {msg}")
|
||||
|
||||
return success, total
|
||||
|
||||
def main():
|
||||
print("=" * 70)
|
||||
print("🎨 CHROMA KEY BACKGROUND REMOVAL - NovaFarma Assets")
|
||||
print("=" * 70)
|
||||
print(f"\n⏰ Started: {datetime.now().strftime('%H:%M:%S')}")
|
||||
print("\n📋 Pipeline:")
|
||||
print(" 1️⃣ Replace white/black → Chroma Green (#00FF00)")
|
||||
print(" 2️⃣ Convert green → Alpha Transparency")
|
||||
print(" 3️⃣ Edge smoothing (remove green halo)")
|
||||
print("\n🎯 Special handling for Kai's pink dreads & piercings!\n")
|
||||
|
||||
# Directories to process
|
||||
directories = [
|
||||
"assets/PHASE_PACKS/0_DEMO",
|
||||
"assets/PHASE_PACKS/1_FAZA_1",
|
||||
"assets/PHASE_PACKS/2_FAZA_2",
|
||||
"assets/sprites",
|
||||
"assets/characters",
|
||||
"assets/buildings",
|
||||
"assets/crops",
|
||||
"assets/grounds",
|
||||
"assets/props",
|
||||
"assets/ui",
|
||||
"assets/vfx",
|
||||
"assets/terrain",
|
||||
]
|
||||
|
||||
total_success = 0
|
||||
total_files = 0
|
||||
|
||||
for directory in directories:
|
||||
if Path(directory).exists():
|
||||
success, total = process_directory(directory)
|
||||
total_success += success
|
||||
total_files += total
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print(f"✅ CHROMA KEY COMPLETED!")
|
||||
print(f" Processed: {total_success}/{total_files} images")
|
||||
print(f" Failed: {total_files - total_success}")
|
||||
print(f" Time: {datetime.now().strftime('%H:%M:%S')}")
|
||||
print("=" * 70)
|
||||
print("\n💡 Next: Open tiled_assets_mini.html to verify transparency!")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
201
scripts/green_screen_generator.py
Normal file
@@ -0,0 +1,201 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Green Screen Generator - Creates images with #00FF00 background
|
||||
Then can convert green to alpha for clean transparency
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from rembg import remove
|
||||
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"
|
||||
CHROMA_GREEN = (0, 255, 0, 255) # #00FF00
|
||||
|
||||
def add_green_background(input_path, output_green_path, output_alpha_path):
|
||||
"""
|
||||
1. Use AI to remove background
|
||||
2. Add solid green (#00FF00) background
|
||||
3. Also save version with alpha transparency
|
||||
"""
|
||||
img = Image.open(input_path)
|
||||
|
||||
# Step 1: AI remove background -> get alpha mask
|
||||
img_no_bg = remove(img)
|
||||
|
||||
# Save alpha version
|
||||
img_no_bg.save(output_alpha_path, 'PNG')
|
||||
|
||||
# Step 2: Create green background version
|
||||
# Create solid green canvas
|
||||
green_bg = Image.new('RGBA', img_no_bg.size, CHROMA_GREEN)
|
||||
|
||||
# Composite the subject onto green background
|
||||
green_bg.paste(img_no_bg, (0, 0), img_no_bg)
|
||||
|
||||
# Convert to RGB (no alpha) for clean green screen look
|
||||
green_rgb = green_bg.convert('RGB')
|
||||
green_rgb.save(output_green_path, 'PNG')
|
||||
|
||||
print(f" ✅ {os.path.basename(input_path)}")
|
||||
print(f" → Green: {os.path.basename(output_green_path)}")
|
||||
print(f" → Alpha: {os.path.basename(output_alpha_path)}")
|
||||
|
||||
def main():
|
||||
print("🟢 GREEN SCREEN GENERATOR")
|
||||
print("=" * 50)
|
||||
print("\nCreating images with #00FF00 chroma key background")
|
||||
print("Like the zombie bunny reference!\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]
|
||||
|
||||
green_dest = os.path.join(OUTPUT_DIR, f"{name_no_ext}_GREEN.png")
|
||||
alpha_dest = os.path.join(OUTPUT_DIR, f"{name_no_ext}_ALPHA.png")
|
||||
|
||||
add_green_background(img_path, green_dest, alpha_dest)
|
||||
|
||||
processed.append({
|
||||
'name': name_no_ext,
|
||||
'original': f"{name_no_ext}_ORIGINAL.png",
|
||||
'green': f"{name_no_ext}_GREEN.png",
|
||||
'alpha': f"{name_no_ext}_ALPHA.png"
|
||||
})
|
||||
|
||||
# Generate comparison HTML
|
||||
html = '''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🟢 Green Screen Test</title>
|
||||
<style>
|
||||
body {
|
||||
background: #1a1a2e;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 30px;
|
||||
}
|
||||
h1 { color: #00ff00; text-align: center; text-shadow: 2px 2px #000; }
|
||||
.note {
|
||||
background: #00ff00;
|
||||
color: black;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.comparison {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin: 25px 0;
|
||||
padding: 20px;
|
||||
background: rgba(0,0,0,0.4);
|
||||
border-radius: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
.image-box {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
.image-box h3 { color: #aaa; margin-bottom: 10px; font-size: 0.9em; }
|
||||
.image-box img {
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
border-radius: 8px;
|
||||
border: 2px solid #333;
|
||||
}
|
||||
.green-bg {
|
||||
background: #00ff00;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.checker-bg {
|
||||
background: linear-gradient(45deg, #333 25%, #555 25%, #555 50%, #333 50%, #333 75%, #555 75%);
|
||||
background-size: 16px 16px;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.grass-bg {
|
||||
background: linear-gradient(to bottom, #4a7c23, #2d4d15);
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.label { font-size: 0.75em; color: #666; margin-top: 5px; }
|
||||
.highlight { color: #00ff00; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🟢 GREEN SCREEN WORKFLOW</h1>
|
||||
<div class="note">
|
||||
Workflow: Original → AI Remove BG → Green Screen (#00FF00) → Alpha Transparency
|
||||
</div>
|
||||
'''
|
||||
|
||||
for item in processed:
|
||||
html += f'''
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="{item['original']}" alt="Original">
|
||||
</div>
|
||||
<div class="label">Source file</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="highlight">🟢 GREEN SCREEN</h3>
|
||||
<div class="green-bg">
|
||||
<img src="{item['green']}" alt="Green">
|
||||
</div>
|
||||
<div class="label">#00FF00 background</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>✅ ALPHA (Checker)</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="{item['alpha']}" alt="Alpha">
|
||||
</div>
|
||||
<div class="label">Transparent</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>🌿 IN GAME</h3>
|
||||
<div class="grass-bg">
|
||||
<img src="{item['alpha']}" alt="Game">
|
||||
</div>
|
||||
<div class="label">On grass</div>
|
||||
</div>
|
||||
</div>
|
||||
'''
|
||||
|
||||
html += '''
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
html_path = os.path.join(OUTPUT_DIR, "green_screen_test.html")
|
||||
with open(html_path, 'w') as f:
|
||||
f.write(html)
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print(f"✅ DONE! Open: {html_path}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
252
scripts/test_aggressive_bg.py
Normal file
@@ -0,0 +1,252 @@
|
||||
#!/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 = '''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🔥 Aggressive BG Removal Test</title>
|
||||
<style>
|
||||
body {
|
||||
background: #1a1a2e;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 30px;
|
||||
}
|
||||
h1 { color: #ff4444; text-align: center; }
|
||||
.ref-note {
|
||||
background: #00ff00;
|
||||
color: black;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.comparison {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
margin: 30px 0;
|
||||
padding: 20px;
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
.image-box {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
.image-box h3 { color: #ff6666; margin-bottom: 15px; }
|
||||
.image-box img {
|
||||
max-width: 300px;
|
||||
max-height: 300px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
/* Multiple background options to test */
|
||||
.bg-checker {
|
||||
background: linear-gradient(45deg, #444 25%, #666 25%, #666 50%, #444 50%, #444 75%, #666 75%);
|
||||
background-size: 20px 20px;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-green {
|
||||
background: #00ff00;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-game {
|
||||
background: linear-gradient(to bottom, #2d5016, #1a3009);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.label { margin-top: 10px; font-size: 0.85em; color: #aaa; }
|
||||
.success { color: #44ff44; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🔥 Aggressive Background Removal Test</h1>
|
||||
<div class="ref-note">
|
||||
🎯 TARGET: Clean edges like the zombie bunny reference (no white shadows!)
|
||||
</div>
|
||||
'''
|
||||
|
||||
for item in processed:
|
||||
html += f'''
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="{item['original']}" alt="Original">
|
||||
</div>
|
||||
<div class="label">{item['name']}</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="{item['processed']}" alt="Cleaned">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="{item['processed']}" alt="On Green">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Game)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="{item['processed']}" alt="In Game">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
'''
|
||||
|
||||
html += '''
|
||||
</body>
|
||||
</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()
|
||||
189
scripts/test_ai_bg_removal.py
Normal file
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
AI Background Removal using rembg
|
||||
This will properly remove ANY background and create clean alpha transparency
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from rembg import remove
|
||||
from PIL import Image
|
||||
|
||||
# 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 ai_remove_bg(input_path, output_path):
|
||||
"""Use AI (rembg) to remove background"""
|
||||
img = Image.open(input_path)
|
||||
|
||||
# Remove background using AI
|
||||
result = remove(img)
|
||||
|
||||
result.save(output_path, 'PNG')
|
||||
print(f" ✅ AI Processed: {os.path.basename(output_path)}")
|
||||
|
||||
def main():
|
||||
print("🤖 AI BACKGROUND REMOVAL (rembg)")
|
||||
print("=" * 50)
|
||||
print("\nUsing neural network to detect and remove backgrounds\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]
|
||||
|
||||
# AI process
|
||||
ai_dest = os.path.join(OUTPUT_DIR, f"{name_no_ext}_AI.png")
|
||||
ai_remove_bg(img_path, ai_dest)
|
||||
|
||||
processed.append({
|
||||
'name': name_no_ext,
|
||||
'original': f"{name_no_ext}_ORIGINAL.png",
|
||||
'ai': f"{name_no_ext}_AI.png"
|
||||
})
|
||||
|
||||
# Generate comparison HTML
|
||||
html = '''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🤖 AI Background Removal Test</title>
|
||||
<style>
|
||||
body {
|
||||
background: #1a1a2e;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 30px;
|
||||
}
|
||||
h1 { color: #ff4444; text-align: center; }
|
||||
.ref-note {
|
||||
background: linear-gradient(135deg, #00ff00, #00aa00);
|
||||
color: black;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.comparison {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
margin: 30px 0;
|
||||
padding: 20px;
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
.image-box {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
.image-box h3 { color: #ff6666; margin-bottom: 15px; }
|
||||
.image-box img {
|
||||
max-width: 250px;
|
||||
max-height: 250px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-checker {
|
||||
background: linear-gradient(45deg, #333 25%, #555 25%, #555 50%, #333 50%, #333 75%, #555 75%);
|
||||
background-size: 16px 16px;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-green {
|
||||
background: #00ff00;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-game {
|
||||
background: linear-gradient(to bottom, #3d6b1f, #234010);
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-red {
|
||||
background: #cc3333;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.label { margin-top: 8px; font-size: 0.8em; color: #888; }
|
||||
.success { color: #44ff44; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🤖 AI Background Removal (rembg)</h1>
|
||||
<div class="ref-note">
|
||||
🎯 Using neural networks to detect subjects and remove backgrounds!
|
||||
</div>
|
||||
'''
|
||||
|
||||
for item in processed:
|
||||
html += f'''
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="{item['original']}" alt="Original">
|
||||
</div>
|
||||
<div class="label">Original</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="{item['ai']}" alt="AI">
|
||||
</div>
|
||||
<div class="label">Transparency check</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="{item['ai']}" alt="On Green">
|
||||
</div>
|
||||
<div class="label">Green screen test</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Grass)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="{item['ai']}" alt="In Game">
|
||||
</div>
|
||||
<div class="label">In-game preview</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Red)</h3>
|
||||
<div class="bg-red">
|
||||
<img src="{item['ai']}" alt="On Red">
|
||||
</div>
|
||||
<div class="label">Contrast test</div>
|
||||
</div>
|
||||
</div>
|
||||
'''
|
||||
|
||||
html += '''
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
html_path = os.path.join(OUTPUT_DIR, "comparison_ai.html")
|
||||
with open(html_path, 'w') as f:
|
||||
f.write(html)
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print(f"✅ DONE! Open: {html_path}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
204
scripts/test_transparency_5.py
Normal file
@@ -0,0 +1,204 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Quick test: Chroma key on 5 images only
|
||||
"""
|
||||
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 chroma_key_process(input_path, output_path):
|
||||
"""Full chroma key pipeline on single image"""
|
||||
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]
|
||||
|
||||
# Step 1: Detect white/black/gray backgrounds
|
||||
# Pure white
|
||||
is_white = (r > 250) & (g > 250) & (b > 250)
|
||||
# Pure black
|
||||
is_black = (r < 5) & (g < 5) & (b < 5)
|
||||
# Near-white/gray (anti-aliasing)
|
||||
is_near_white = (r > 245) & (g > 245) & (b > 245)
|
||||
|
||||
# Background mask
|
||||
background = is_white | is_black | is_near_white
|
||||
|
||||
# Step 2: Set alpha to 0 for background pixels
|
||||
new_alpha = np.where(background, 0, a)
|
||||
|
||||
# Step 3: For semi-white pixels (anti-aliasing), fade alpha
|
||||
brightness = (r + g + b) / 3
|
||||
semi_white = (brightness > 240) & (brightness <= 250)
|
||||
# Gradual fade based on brightness
|
||||
fade_alpha = np.where(semi_white, (255 - brightness) * 10, new_alpha)
|
||||
fade_alpha = np.clip(fade_alpha, 0, 255)
|
||||
|
||||
data[:,:,3] = fade_alpha
|
||||
|
||||
# Clean up fully transparent pixels
|
||||
fully_transparent = fade_alpha < 5
|
||||
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("🧪 QUICK TEST: Chroma Key on 5 Images")
|
||||
print("=" * 50)
|
||||
|
||||
# Create output dir
|
||||
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" 📋 Copied original: {name}")
|
||||
|
||||
# Process and save
|
||||
proc_dest = os.path.join(OUTPUT_DIR, f"{name_no_ext}_PROCESSED.png")
|
||||
chroma_key_process(img_path, proc_dest)
|
||||
|
||||
processed.append({
|
||||
'name': name_no_ext,
|
||||
'original': orig_dest,
|
||||
'processed': proc_dest
|
||||
})
|
||||
|
||||
# Generate comparison HTML
|
||||
html = '''<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🧪 Test Transparency - 5 Sample Images</title>
|
||||
<style>
|
||||
body {
|
||||
background: #1a1a2e;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 30px;
|
||||
}
|
||||
h1 {
|
||||
color: #ff4444;
|
||||
text-align: center;
|
||||
}
|
||||
.comparison {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
margin: 30px 0;
|
||||
padding: 20px;
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 15px;
|
||||
}
|
||||
.image-box {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
.image-box h3 {
|
||||
color: #ff6666;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.image-box img {
|
||||
max-width: 300px;
|
||||
max-height: 300px;
|
||||
border: 2px solid #333;
|
||||
border-radius: 10px;
|
||||
}
|
||||
/* Checkerboard background for transparency */
|
||||
.transparent-bg {
|
||||
background: linear-gradient(45deg, #333 25%, transparent 25%),
|
||||
linear-gradient(-45deg, #333 25%, transparent 25%),
|
||||
linear-gradient(45deg, transparent 75%, #333 75%),
|
||||
linear-gradient(-45deg, transparent 75%, #333 75%);
|
||||
background-size: 20px 20px;
|
||||
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
||||
background-color: #555;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.label {
|
||||
margin-top: 10px;
|
||||
font-size: 0.9em;
|
||||
color: #aaa;
|
||||
}
|
||||
.success { color: #44ff44; }
|
||||
.info {
|
||||
text-align: center;
|
||||
color: #888;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🧪 Test Transparency - Before & After</h1>
|
||||
<p class="info">Left: Original (white/black background) | Right: Processed (transparent with checkerboard)</p>
|
||||
'''
|
||||
|
||||
for item in processed:
|
||||
html += f'''
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<img src="{item['original']}" alt="Original">
|
||||
<div class="label">{item['name']}_ORIGINAL.png</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ PROCESSED</h3>
|
||||
<div class="transparent-bg">
|
||||
<img src="{item['processed']}" alt="Processed">
|
||||
</div>
|
||||
<div class="label">{item['name']}_PROCESSED.png</div>
|
||||
</div>
|
||||
</div>
|
||||
'''
|
||||
|
||||
html += '''
|
||||
<p class="info" style="margin-top: 40px;">
|
||||
If you see the gray checkerboard pattern behind the processed images, transparency is working! 🎉
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
html_path = os.path.join(OUTPUT_DIR, "comparison.html")
|
||||
with open(html_path, 'w') as f:
|
||||
f.write(html)
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print(f"✅ DONE! Created comparison page:")
|
||||
print(f" 📂 {OUTPUT_DIR}/")
|
||||
print(f" 🌐 Open: {html_path}")
|
||||
print("=" * 50)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
147
test_transparency/comparison.html
Normal file
@@ -0,0 +1,147 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🧪 Test Transparency - 5 Sample Images</title>
|
||||
<style>
|
||||
body {
|
||||
background: #1a1a2e;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 30px;
|
||||
}
|
||||
h1 {
|
||||
color: #ff4444;
|
||||
text-align: center;
|
||||
}
|
||||
.comparison {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
margin: 30px 0;
|
||||
padding: 20px;
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 15px;
|
||||
}
|
||||
.image-box {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
.image-box h3 {
|
||||
color: #ff6666;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.image-box img {
|
||||
max-width: 300px;
|
||||
max-height: 300px;
|
||||
border: 2px solid #333;
|
||||
border-radius: 10px;
|
||||
}
|
||||
/* Checkerboard background for transparency */
|
||||
.transparent-bg {
|
||||
background: linear-gradient(45deg, #333 25%, transparent 25%),
|
||||
linear-gradient(-45deg, #333 25%, transparent 25%),
|
||||
linear-gradient(45deg, transparent 75%, #333 75%),
|
||||
linear-gradient(-45deg, transparent 75%, #333 75%);
|
||||
background-size: 20px 20px;
|
||||
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
||||
background-color: #555;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.label {
|
||||
margin-top: 10px;
|
||||
font-size: 0.9em;
|
||||
color: #aaa;
|
||||
}
|
||||
.success { color: #44ff44; }
|
||||
.info {
|
||||
text-align: center;
|
||||
color: #888;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🧪 Test Transparency - Before & After</h1>
|
||||
<p class="info">Left: Original (white/black background) | Right: Processed (transparent with checkerboard)</p>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<img src="watering_can_ORIGINAL.png" alt="Original">
|
||||
<div class="label">watering_can_ORIGINAL.png</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ PROCESSED</h3>
|
||||
<div class="transparent-bg">
|
||||
<img src="watering_can_PROCESSED.png" alt="Processed">
|
||||
</div>
|
||||
<div class="label">watering_can_PROCESSED.png</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<img src="horse_ORIGINAL.png" alt="Original">
|
||||
<div class="label">horse_ORIGINAL.png</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ PROCESSED</h3>
|
||||
<div class="transparent-bg">
|
||||
<img src="horse_PROCESSED.png" alt="Processed">
|
||||
</div>
|
||||
<div class="label">horse_PROCESSED.png</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<img src="manure_pile_ORIGINAL.png" alt="Original">
|
||||
<div class="label">manure_pile_ORIGINAL.png</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ PROCESSED</h3>
|
||||
<div class="transparent-bg">
|
||||
<img src="manure_pile_PROCESSED.png" alt="Processed">
|
||||
</div>
|
||||
<div class="label">manure_pile_PROCESSED.png</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<img src="pickaxe_ORIGINAL.png" alt="Original">
|
||||
<div class="label">pickaxe_ORIGINAL.png</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ PROCESSED</h3>
|
||||
<div class="transparent-bg">
|
||||
<img src="pickaxe_PROCESSED.png" alt="Processed">
|
||||
</div>
|
||||
<div class="label">pickaxe_PROCESSED.png</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<img src="walk_ORIGINAL.png" alt="Original">
|
||||
<div class="label">walk_ORIGINAL.png</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ PROCESSED</h3>
|
||||
<div class="transparent-bg">
|
||||
<img src="walk_PROCESSED.png" alt="Processed">
|
||||
</div>
|
||||
<div class="label">walk_PROCESSED.png</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="info" style="margin-top: 40px;">
|
||||
If you see the gray checkerboard pattern behind the processed images, transparency is working! 🎉
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
264
test_transparency/comparison_ai.html
Normal file
@@ -0,0 +1,264 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🤖 AI Background Removal Test</title>
|
||||
<style>
|
||||
body {
|
||||
background: #1a1a2e;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 30px;
|
||||
}
|
||||
h1 { color: #ff4444; text-align: center; }
|
||||
.ref-note {
|
||||
background: linear-gradient(135deg, #00ff00, #00aa00);
|
||||
color: black;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.comparison {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
margin: 30px 0;
|
||||
padding: 20px;
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
.image-box {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
.image-box h3 { color: #ff6666; margin-bottom: 15px; }
|
||||
.image-box img {
|
||||
max-width: 250px;
|
||||
max-height: 250px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-checker {
|
||||
background: linear-gradient(45deg, #333 25%, #555 25%, #555 50%, #333 50%, #333 75%, #555 75%);
|
||||
background-size: 16px 16px;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-green {
|
||||
background: #00ff00;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-game {
|
||||
background: linear-gradient(to bottom, #3d6b1f, #234010);
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-red {
|
||||
background: #cc3333;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.label { margin-top: 8px; font-size: 0.8em; color: #888; }
|
||||
.success { color: #44ff44; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🤖 AI Background Removal (rembg)</h1>
|
||||
<div class="ref-note">
|
||||
🎯 Using neural networks to detect subjects and remove backgrounds!
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="watering_can_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Original</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="watering_can_AI.png" alt="AI">
|
||||
</div>
|
||||
<div class="label">Transparency check</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="watering_can_AI.png" alt="On Green">
|
||||
</div>
|
||||
<div class="label">Green screen test</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Grass)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="watering_can_AI.png" alt="In Game">
|
||||
</div>
|
||||
<div class="label">In-game preview</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Red)</h3>
|
||||
<div class="bg-red">
|
||||
<img src="watering_can_AI.png" alt="On Red">
|
||||
</div>
|
||||
<div class="label">Contrast test</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="horse_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Original</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="horse_AI.png" alt="AI">
|
||||
</div>
|
||||
<div class="label">Transparency check</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="horse_AI.png" alt="On Green">
|
||||
</div>
|
||||
<div class="label">Green screen test</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Grass)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="horse_AI.png" alt="In Game">
|
||||
</div>
|
||||
<div class="label">In-game preview</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Red)</h3>
|
||||
<div class="bg-red">
|
||||
<img src="horse_AI.png" alt="On Red">
|
||||
</div>
|
||||
<div class="label">Contrast test</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="manure_pile_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Original</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="manure_pile_AI.png" alt="AI">
|
||||
</div>
|
||||
<div class="label">Transparency check</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="manure_pile_AI.png" alt="On Green">
|
||||
</div>
|
||||
<div class="label">Green screen test</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Grass)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="manure_pile_AI.png" alt="In Game">
|
||||
</div>
|
||||
<div class="label">In-game preview</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Red)</h3>
|
||||
<div class="bg-red">
|
||||
<img src="manure_pile_AI.png" alt="On Red">
|
||||
</div>
|
||||
<div class="label">Contrast test</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="pickaxe_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Original</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="pickaxe_AI.png" alt="AI">
|
||||
</div>
|
||||
<div class="label">Transparency check</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="pickaxe_AI.png" alt="On Green">
|
||||
</div>
|
||||
<div class="label">Green screen test</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Grass)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="pickaxe_AI.png" alt="In Game">
|
||||
</div>
|
||||
<div class="label">In-game preview</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Red)</h3>
|
||||
<div class="bg-red">
|
||||
<img src="pickaxe_AI.png" alt="On Red">
|
||||
</div>
|
||||
<div class="label">Contrast test</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="walk_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Original</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="walk_AI.png" alt="AI">
|
||||
</div>
|
||||
<div class="label">Transparency check</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="walk_AI.png" alt="On Green">
|
||||
</div>
|
||||
<div class="label">Green screen test</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Grass)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="walk_AI.png" alt="In Game">
|
||||
</div>
|
||||
<div class="label">In-game preview</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">🤖 AI (Red)</h3>
|
||||
<div class="bg-red">
|
||||
<img src="walk_AI.png" alt="On Red">
|
||||
</div>
|
||||
<div class="label">Contrast test</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
210
test_transparency/comparison_v2.html
Normal file
@@ -0,0 +1,210 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🔥 Aggressive BG Removal Test</title>
|
||||
<style>
|
||||
body {
|
||||
background: #1a1a2e;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 30px;
|
||||
}
|
||||
h1 { color: #ff4444; text-align: center; }
|
||||
.ref-note {
|
||||
background: #00ff00;
|
||||
color: black;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.comparison {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
margin: 30px 0;
|
||||
padding: 20px;
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
.image-box {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
.image-box h3 { color: #ff6666; margin-bottom: 15px; }
|
||||
.image-box img {
|
||||
max-width: 300px;
|
||||
max-height: 300px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
/* Multiple background options to test */
|
||||
.bg-checker {
|
||||
background: linear-gradient(45deg, #444 25%, #666 25%, #666 50%, #444 50%, #444 75%, #666 75%);
|
||||
background-size: 20px 20px;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-green {
|
||||
background: #00ff00;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.bg-game {
|
||||
background: linear-gradient(to bottom, #2d5016, #1a3009);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.label { margin-top: 10px; font-size: 0.85em; color: #aaa; }
|
||||
.success { color: #44ff44; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🔥 Aggressive Background Removal Test</h1>
|
||||
<div class="ref-note">
|
||||
🎯 TARGET: Clean edges like the zombie bunny reference (no white shadows!)
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="watering_can_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">watering_can</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="watering_can_CLEAN.png" alt="Cleaned">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="watering_can_CLEAN.png" alt="On Green">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Game)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="watering_can_CLEAN.png" alt="In Game">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="horse_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">horse</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="horse_CLEAN.png" alt="Cleaned">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="horse_CLEAN.png" alt="On Green">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Game)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="horse_CLEAN.png" alt="In Game">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="manure_pile_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">manure_pile</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="manure_pile_CLEAN.png" alt="Cleaned">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="manure_pile_CLEAN.png" alt="On Green">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Game)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="manure_pile_CLEAN.png" alt="In Game">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="pickaxe_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">pickaxe</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="pickaxe_CLEAN.png" alt="Cleaned">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="pickaxe_CLEAN.png" alt="On Green">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Game)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="pickaxe_CLEAN.png" alt="In Game">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="walk_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">walk</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Checker)</h3>
|
||||
<div class="bg-checker">
|
||||
<img src="walk_CLEAN.png" alt="Cleaned">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Green)</h3>
|
||||
<div class="bg-green">
|
||||
<img src="walk_CLEAN.png" alt="On Green">
|
||||
</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="success">✅ CLEANED (Game)</h3>
|
||||
<div class="bg-game">
|
||||
<img src="walk_CLEAN.png" alt="In Game">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
225
test_transparency/green_screen_test.html
Normal file
@@ -0,0 +1,225 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🟢 Green Screen Test</title>
|
||||
<style>
|
||||
body {
|
||||
background: #1a1a2e;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 30px;
|
||||
}
|
||||
h1 { color: #00ff00; text-align: center; text-shadow: 2px 2px #000; }
|
||||
.note {
|
||||
background: #00ff00;
|
||||
color: black;
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.comparison {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin: 25px 0;
|
||||
padding: 20px;
|
||||
background: rgba(0,0,0,0.4);
|
||||
border-radius: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
.image-box {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
.image-box h3 { color: #aaa; margin-bottom: 10px; font-size: 0.9em; }
|
||||
.image-box img {
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
border-radius: 8px;
|
||||
border: 2px solid #333;
|
||||
}
|
||||
.green-bg {
|
||||
background: #00ff00;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.checker-bg {
|
||||
background: linear-gradient(45deg, #333 25%, #555 25%, #555 50%, #333 50%, #333 75%, #555 75%);
|
||||
background-size: 16px 16px;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.grass-bg {
|
||||
background: linear-gradient(to bottom, #4a7c23, #2d4d15);
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.label { font-size: 0.75em; color: #666; margin-top: 5px; }
|
||||
.highlight { color: #00ff00; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🟢 GREEN SCREEN WORKFLOW</h1>
|
||||
<div class="note">
|
||||
Workflow: Original → AI Remove BG → Green Screen (#00FF00) → Alpha Transparency
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="watering_can_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Source file</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="highlight">🟢 GREEN SCREEN</h3>
|
||||
<div class="green-bg">
|
||||
<img src="watering_can_GREEN.png" alt="Green">
|
||||
</div>
|
||||
<div class="label">#00FF00 background</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>✅ ALPHA (Checker)</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="watering_can_ALPHA.png" alt="Alpha">
|
||||
</div>
|
||||
<div class="label">Transparent</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>🌿 IN GAME</h3>
|
||||
<div class="grass-bg">
|
||||
<img src="watering_can_ALPHA.png" alt="Game">
|
||||
</div>
|
||||
<div class="label">On grass</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="horse_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Source file</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="highlight">🟢 GREEN SCREEN</h3>
|
||||
<div class="green-bg">
|
||||
<img src="horse_GREEN.png" alt="Green">
|
||||
</div>
|
||||
<div class="label">#00FF00 background</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>✅ ALPHA (Checker)</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="horse_ALPHA.png" alt="Alpha">
|
||||
</div>
|
||||
<div class="label">Transparent</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>🌿 IN GAME</h3>
|
||||
<div class="grass-bg">
|
||||
<img src="horse_ALPHA.png" alt="Game">
|
||||
</div>
|
||||
<div class="label">On grass</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="manure_pile_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Source file</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="highlight">🟢 GREEN SCREEN</h3>
|
||||
<div class="green-bg">
|
||||
<img src="manure_pile_GREEN.png" alt="Green">
|
||||
</div>
|
||||
<div class="label">#00FF00 background</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>✅ ALPHA (Checker)</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="manure_pile_ALPHA.png" alt="Alpha">
|
||||
</div>
|
||||
<div class="label">Transparent</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>🌿 IN GAME</h3>
|
||||
<div class="grass-bg">
|
||||
<img src="manure_pile_ALPHA.png" alt="Game">
|
||||
</div>
|
||||
<div class="label">On grass</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="pickaxe_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Source file</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="highlight">🟢 GREEN SCREEN</h3>
|
||||
<div class="green-bg">
|
||||
<img src="pickaxe_GREEN.png" alt="Green">
|
||||
</div>
|
||||
<div class="label">#00FF00 background</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>✅ ALPHA (Checker)</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="pickaxe_ALPHA.png" alt="Alpha">
|
||||
</div>
|
||||
<div class="label">Transparent</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>🌿 IN GAME</h3>
|
||||
<div class="grass-bg">
|
||||
<img src="pickaxe_ALPHA.png" alt="Game">
|
||||
</div>
|
||||
<div class="label">On grass</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="image-box">
|
||||
<h3>📷 ORIGINAL</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="walk_ORIGINAL.png" alt="Original">
|
||||
</div>
|
||||
<div class="label">Source file</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3 class="highlight">🟢 GREEN SCREEN</h3>
|
||||
<div class="green-bg">
|
||||
<img src="walk_GREEN.png" alt="Green">
|
||||
</div>
|
||||
<div class="label">#00FF00 background</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>✅ ALPHA (Checker)</h3>
|
||||
<div class="checker-bg">
|
||||
<img src="walk_ALPHA.png" alt="Alpha">
|
||||
</div>
|
||||
<div class="label">Transparent</div>
|
||||
</div>
|
||||
<div class="image-box">
|
||||
<h3>🌿 IN GAME</h3>
|
||||
<div class="grass-bg">
|
||||
<img src="walk_ALPHA.png" alt="Game">
|
||||
</div>
|
||||
<div class="label">On grass</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
BIN
test_transparency/horse_AI.png
Normal file
|
After Width: | Height: | Size: 411 KiB |
BIN
test_transparency/horse_ALPHA.png
Normal file
|
After Width: | Height: | Size: 411 KiB |
BIN
test_transparency/horse_CLEAN.png
Normal file
|
After Width: | Height: | Size: 332 KiB |
BIN
test_transparency/horse_GREEN.png
Normal file
|
After Width: | Height: | Size: 361 KiB |
BIN
test_transparency/horse_ORIGINAL.png
Normal file
|
After Width: | Height: | Size: 485 KiB |
BIN
test_transparency/horse_PROCESSED.png
Normal file
|
After Width: | Height: | Size: 707 KiB |
BIN
test_transparency/manure_pile_AI.png
Normal file
|
After Width: | Height: | Size: 612 KiB |
BIN
test_transparency/manure_pile_ALPHA.png
Normal file
|
After Width: | Height: | Size: 612 KiB |
BIN
test_transparency/manure_pile_CLEAN.png
Normal file
|
After Width: | Height: | Size: 805 KiB |
BIN
test_transparency/manure_pile_GREEN.png
Normal file
|
After Width: | Height: | Size: 530 KiB |
BIN
test_transparency/manure_pile_ORIGINAL.png
Normal file
|
After Width: | Height: | Size: 605 KiB |
BIN
test_transparency/manure_pile_PROCESSED.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
test_transparency/pickaxe_AI.png
Normal file
|
After Width: | Height: | Size: 447 KiB |
BIN
test_transparency/pickaxe_ALPHA.png
Normal file
|
After Width: | Height: | Size: 447 KiB |
BIN
test_transparency/pickaxe_CLEAN.png
Normal file
|
After Width: | Height: | Size: 484 KiB |
BIN
test_transparency/pickaxe_GREEN.png
Normal file
|
After Width: | Height: | Size: 380 KiB |
BIN
test_transparency/pickaxe_ORIGINAL.png
Normal file
|
After Width: | Height: | Size: 533 KiB |
BIN
test_transparency/pickaxe_PROCESSED.png
Normal file
|
After Width: | Height: | Size: 680 KiB |
BIN
test_transparency/walk_AI.png
Normal file
|
After Width: | Height: | Size: 496 KiB |
BIN
test_transparency/walk_ALPHA.png
Normal file
|
After Width: | Height: | Size: 496 KiB |
BIN
test_transparency/walk_CLEAN.png
Normal file
|
After Width: | Height: | Size: 228 KiB |
BIN
test_transparency/walk_GREEN.png
Normal file
|
After Width: | Height: | Size: 438 KiB |
BIN
test_transparency/walk_ORIGINAL.png
Normal file
|
After Width: | Height: | Size: 437 KiB |
BIN
test_transparency/walk_PROCESSED.png
Normal file
|
After Width: | Height: | Size: 665 KiB |
BIN
test_transparency/watering_can_AI.png
Normal file
|
After Width: | Height: | Size: 461 KiB |
BIN
test_transparency/watering_can_ALPHA.png
Normal file
|
After Width: | Height: | Size: 461 KiB |
BIN
test_transparency/watering_can_CLEAN.png
Normal file
|
After Width: | Height: | Size: 892 KiB |
BIN
test_transparency/watering_can_GREEN.png
Normal file
|
After Width: | Height: | Size: 403 KiB |
BIN
test_transparency/watering_can_ORIGINAL.png
Normal file
|
After Width: | Height: | Size: 418 KiB |
BIN
test_transparency/watering_can_PROCESSED.png
Normal file
|
After Width: | Height: | Size: 888 KiB |