Spaces:
Running
Running
matrixglitch
commited on
Commit
•
65f8e0f
1
Parent(s):
7a75878
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import cv2
|
3 |
+
from scipy.ndimage import label, binary_dilation
|
4 |
+
import gradio as gr
|
5 |
+
|
6 |
+
def create_bridged_stencil(image, min_bridges=2, bridge_width=2):
|
7 |
+
# Convert the image to grayscale if it's not already
|
8 |
+
if len(image.shape) == 3:
|
9 |
+
img = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
|
10 |
+
else:
|
11 |
+
img = image
|
12 |
+
|
13 |
+
# Threshold the image to create a binary image
|
14 |
+
_, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
|
15 |
+
|
16 |
+
# Find connected components (islands)
|
17 |
+
labeled, num_features = label(binary)
|
18 |
+
|
19 |
+
# Create a copy of the binary image for adding bridges
|
20 |
+
bridged = binary.copy()
|
21 |
+
|
22 |
+
# Function to add a bridge between two points
|
23 |
+
def add_bridge(start, end):
|
24 |
+
cv2.line(bridged, start, end, 255, bridge_width)
|
25 |
+
|
26 |
+
# For each island
|
27 |
+
for i in range(1, num_features + 1):
|
28 |
+
island = (labeled == i)
|
29 |
+
|
30 |
+
# Find the contour of the island
|
31 |
+
contours, _ = cv2.findContours((island * 255).astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
32 |
+
contour = contours[0]
|
33 |
+
|
34 |
+
# Get the convex hull of the contour
|
35 |
+
hull = cv2.convexHull(contour)
|
36 |
+
|
37 |
+
# Find the center of the island
|
38 |
+
M = cv2.moments(contour)
|
39 |
+
if M["m00"] != 0:
|
40 |
+
cx = int(M["m10"] / M["m00"])
|
41 |
+
cy = int(M["m01"] / M["m00"])
|
42 |
+
else:
|
43 |
+
cx, cy = np.mean(contour, axis=0)[0]
|
44 |
+
|
45 |
+
# Add bridges from the center to the convex hull points
|
46 |
+
num_bridges = 0
|
47 |
+
for point in hull:
|
48 |
+
if num_bridges >= min_bridges:
|
49 |
+
break
|
50 |
+
add_bridge((cx, cy), tuple(point[0]))
|
51 |
+
num_bridges += 1
|
52 |
+
|
53 |
+
# Dilate the bridged image to make bridges more prominent
|
54 |
+
bridged = binary_dilation(bridged, iterations=1)
|
55 |
+
|
56 |
+
# Convert back to RGB for Gradio output
|
57 |
+
return cv2.cvtColor((bridged * 255).astype(np.uint8), cv2.COLOR_GRAY2RGB)
|
58 |
+
|
59 |
+
def process_image(input_image, min_bridges, bridge_width):
|
60 |
+
result = create_bridged_stencil(input_image, min_bridges, bridge_width)
|
61 |
+
return result
|
62 |
+
|
63 |
+
# Create the Gradio interface
|
64 |
+
iface = gr.Interface(
|
65 |
+
fn=process_image,
|
66 |
+
inputs=[
|
67 |
+
gr.Image(type="numpy", label="Input Image"),
|
68 |
+
gr.Slider(minimum=1, maximum=5, step=1, default=2, label="Minimum Bridges"),
|
69 |
+
gr.Slider(minimum=1, maximum=5, step=1, default=2, label="Bridge Width")
|
70 |
+
],
|
71 |
+
outputs=gr.Image(type="numpy", label="Bridged Stencil"),
|
72 |
+
title="Bridged Stencil Generator",
|
73 |
+
description="Upload an image to create a bridged stencil. Adjust the minimum number of bridges and bridge width as needed."
|
74 |
+
)
|
75 |
+
|
76 |
+
# Launch the interface
|
77 |
+
iface.launch()
|