File size: 3,118 Bytes
da0e0ac 83cfd49 da0e0ac | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | # graphicProcessor.py - Classical Fallback for Graphics
# FROZEN - DO NOT MODIFY
import numpy as np
from PIL import Image
from collections import deque, Counter
class GraphicProcessor:
"""Classical fallback for simple graphics - FROZEN."""
def __init__(self):
self.tolerance = 25
def remove_background(self, image: Image.Image) -> Image.Image:
"""Remove background using flood fill."""
if image.mode != 'RGBA':
image = image.convert('RGBA')
np_img = np.array(image)
h, w = np_img.shape[:2]
# Find background colors
bg_colors = self._find_background_colors(np_img)
# Create mask
mask = np.ones((h, w), dtype=np.uint8) * 255
# Flood fill from border with each color
for bg_color in bg_colors:
self._flood_fill_from_border(np_img, mask, bg_color)
# Check if mask is suspicious
fg_ratio = np.sum(mask > 128) / (h * w)
if fg_ratio < 0.05 or fg_ratio > 0.95:
# Try with different tolerance
mask = np.ones((h, w), dtype=np.uint8) * 255
for bg_color in bg_colors:
self._flood_fill_from_border(np_img, mask, bg_color, tolerance=15)
# Apply mask
result = np_img.copy()
result[mask == 0, 3] = 0
return Image.fromarray(result, 'RGBA')
def _find_background_colors(self, np_img: np.ndarray) -> list:
h, w = np_img.shape[:2]
border_pixels = []
for x in range(w):
border_pixels.append(tuple(np_img[0, x][:3]))
border_pixels.append(tuple(np_img[h-1, x][:3]))
for y in range(h):
border_pixels.append(tuple(np_img[y, 0][:3]))
border_pixels.append(tuple(np_img[y, w-1][:3]))
counter = Counter(border_pixels)
return [color for color, _ in counter.most_common(3)]
def _flood_fill_from_border(self, np_img: np.ndarray, mask: np.ndarray, bg_color: tuple, tolerance: int = 25):
h, w = np_img.shape[:2]
queue = deque()
visited = set()
for x in range(w):
queue.append((0, x))
queue.append((h-1, x))
visited.add((0, x))
visited.add((h-1, x))
for y in range(h):
queue.append((y, 0))
queue.append((y, w-1))
visited.add((y, 0))
visited.add((y, w-1))
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
br, bg, bb = bg_color
while queue:
y, x = queue.popleft()
r, g, b = np_img[y, x][:3]
color_diff = np.sqrt((r - br)**2 + (g - bg)**2 + (b - bb)**2)
if color_diff < tolerance:
mask[y, x] = 0
for dy, dx in dirs:
ny, nx = y + dy, x + dx
if 0 <= ny < h and 0 <= nx < w and (ny, nx) not in visited:
queue.append((ny, nx))
visited.add((ny, nx)) |