File size: 2,677 Bytes
65f8e0f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec066b0
 
65f8e0f
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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()