bgremove / graphicProcessor.py
andevs's picture
Update graphicProcessor.py
83cfd49 verified
Raw
History Blame Contribute Delete
3.12 kB
# 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))