Spaces:
Running
Running
import numpy as np | |
import cv2 | |
from scipy.ndimage import label, binary_dilation | |
import gradio as gr | |
def create_bridged_stencil(image, min_bridges=2, bridge_width=2): | |
# Convert the image to grayscale if it's not already | |
if len(image.shape) == 3: | |
img = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) | |
else: | |
img = image | |
# Threshold the image to create a binary image | |
_, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV) | |
# Find connected components (islands) | |
labeled, num_features = label(binary) | |
# Create a copy of the binary image for adding bridges | |
bridged = binary.copy() | |
# Function to add a bridge between two points | |
def add_bridge(start, end): | |
cv2.line(bridged, start, end, 255, bridge_width) | |
# For each island | |
for i in range(1, num_features + 1): | |
island = (labeled == i) | |
# Find the contour of the island | |
contours, _ = cv2.findContours((island * 255).astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | |
contour = contours[0] | |
# Get the convex hull of the contour | |
hull = cv2.convexHull(contour) | |
# Find the center of the island | |
M = cv2.moments(contour) | |
if M["m00"] != 0: | |
cx = int(M["m10"] / M["m00"]) | |
cy = int(M["m01"] / M["m00"]) | |
else: | |
cx, cy = np.mean(contour, axis=0)[0] | |
# Add bridges from the center to the convex hull points | |
num_bridges = 0 | |
for point in hull: | |
if num_bridges >= min_bridges: | |
break | |
add_bridge((cx, cy), tuple(point[0])) | |
num_bridges += 1 | |
# Dilate the bridged image to make bridges more prominent | |
bridged = binary_dilation(bridged, iterations=1) | |
# Convert back to RGB for Gradio output | |
return cv2.cvtColor((bridged * 255).astype(np.uint8), cv2.COLOR_GRAY2RGB) | |
def process_image(input_image, min_bridges, bridge_width): | |
result = create_bridged_stencil(input_image, min_bridges, bridge_width) | |
return result | |
# Create the Gradio interface | |
iface = gr.Interface( | |
fn=process_image, | |
inputs=[ | |
gr.Image(type="numpy", label="Input Image"), | |
gr.Slider(minimum=1, maximum=5, step=1, value=2, label="Minimum Bridges"), | |
gr.Slider(minimum=1, maximum=5, step=1, value=2, label="Bridge Width") | |
], | |
outputs=gr.Image(type="numpy", label="Bridged Stencil"), | |
title="Bridged Stencil Generator", | |
description="Upload an image to create a bridged stencil. Adjust the minimum number of bridges and bridge width as needed." | |
) | |
# Launch the interface | |
iface.launch() |