Spaces:
Running
on
Zero
Running
on
Zero
import io | |
import os | |
import tempfile | |
import cv2 | |
import gradio as gr | |
import numpy as np | |
from PIL import Image, ImageSequence | |
def image_to_sketch_gif(input_image: Image.Image): | |
# Convert PIL image to OpenCV format | |
open_cv_image = np.array(input_image.convert("RGB")) | |
open_cv_image = cv2.cvtColor(open_cv_image, cv2.COLOR_RGB2BGR) | |
# Convert to grayscale | |
grayscale_image = cv2.cvtColor(open_cv_image, cv2.COLOR_BGR2GRAY) | |
# Apply Gaussian blur | |
blurred_image = cv2.GaussianBlur(grayscale_image, (5, 5), 0) | |
# Use Canny Edge Detection | |
edges = cv2.Canny(blurred_image, threshold1=50, threshold2=150) | |
# Ensure binary format | |
_, binary_sketch = cv2.threshold(edges, 128, 255, cv2.THRESH_BINARY) | |
# Find connected components | |
num_labels, labels, stats, _ = cv2.connectedComponentsWithStats( | |
binary_sketch, connectivity=8 | |
) | |
# Sort components by size (excluding the background, which is label 0) | |
components = sorted( | |
[(i, stats[i, cv2.CC_STAT_AREA]) for i in range(1, num_labels)], | |
key=lambda x: x[1], | |
reverse=True, | |
) | |
# Initialize an empty canvas for accumulation | |
accumulated_image = np.zeros_like(binary_sketch, dtype=np.uint8) | |
# Store frames | |
frames = [] | |
for label, _ in components: | |
# Add the current component to the accumulation | |
accumulated_image[labels == label] = 255 | |
# Convert OpenCV image to PIL image and append to frames | |
pil_frame = Image.fromarray(255 - accumulated_image) | |
frames.append(pil_frame.copy()) | |
# Add the input_input as the final frame | |
frames.append(input_image.copy()) | |
# Save GIF to a temporary file | |
tmp_dir = tempfile.gettempdir() # Get system temp directory | |
tmp_gif_path = os.path.join(tmp_dir, "sketch_animation.gif") | |
frames[0].save( | |
tmp_gif_path, | |
format="GIF", | |
save_all=True, | |
append_images=frames[1:], | |
duration=100, | |
loop=0, | |
) | |
return ( | |
tmp_gif_path, | |
frames, | |
gr.Slider( | |
minimum=0, | |
maximum=len(frames) - 1, | |
value=0, | |
step=1, | |
visible=False, | |
scale=4, | |
label="Frame Selector", | |
interactive=True, | |
), | |
gr.Button("Stop", scale=1, visible=True), | |
) | |