Download graphicProcessor.py from andevs/bgremove: direct link, hf CLI and curl.
- Browser
- Download file 3.12 kB
-
https://huggingface.co/spaces/andevs/bgremove/resolve/main/graphicProcessor.py
- Command line
-
hf download hf://spaces/andevs/bgremove/graphicProcessor.py
-
curl -L -o graphicProcessor.py https://huggingface.co/spaces/andevs/bgremove/resolve/main/graphicProcessor.py
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)) |