Update app.py
Browse files
app.py
CHANGED
|
@@ -5,7 +5,6 @@ from skimage.transform import resize
|
|
| 5 |
from skimage.draw import line
|
| 6 |
import gradio as gr
|
| 7 |
import tempfile
|
| 8 |
-
import os
|
| 9 |
|
| 10 |
def preprocess_image(image, size=(200, 200)):
|
| 11 |
if image.ndim == 3:
|
|
@@ -38,22 +37,37 @@ def generate_connections(img, pins, num_connections):
|
|
| 38 |
connections = []
|
| 39 |
current_pin = 0
|
| 40 |
used = set()
|
|
|
|
|
|
|
| 41 |
for _ in range(num_connections):
|
| 42 |
best_score = -1
|
| 43 |
best_pin = None
|
|
|
|
| 44 |
for next_pin in range(num_pins):
|
| 45 |
if next_pin == current_pin:
|
| 46 |
continue
|
| 47 |
if (current_pin, next_pin) in used or (next_pin, current_pin) in used:
|
| 48 |
continue
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
if score > best_score:
|
| 51 |
best_score = score
|
| 52 |
best_pin = next_pin
|
|
|
|
| 53 |
if best_pin is None:
|
| 54 |
break
|
| 55 |
connections.append((current_pin, best_pin))
|
| 56 |
used.add((current_pin, best_pin))
|
|
|
|
|
|
|
| 57 |
current_pin = best_pin
|
| 58 |
return connections
|
| 59 |
|
|
@@ -67,13 +81,12 @@ def draw_string_art(image, num_pins, num_connections):
|
|
| 67 |
ax.axis("off")
|
| 68 |
for c in connections:
|
| 69 |
p1, p2 = pins[c[0]], pins[c[1]]
|
| 70 |
-
ax.plot([p1[0], p2[0]], [p1[1], p2[1]], 'k-', linewidth=0.7, alpha=0.
|
| 71 |
ax.scatter(pins[:,0], pins[:,1], c='red', s=16) # Red pins, moderate size
|
| 72 |
plt.tight_layout(pad=0)
|
| 73 |
plt.close(fig)
|
| 74 |
# Prepare connections file (1-based indexing)
|
| 75 |
connections_1_based = [str(c[0]+1) for c in connections]
|
| 76 |
-
# Make continuous: start at pin 1, then next, etc.
|
| 77 |
connections_str = ', '.join(connections_1_based)
|
| 78 |
# Save to temporary file
|
| 79 |
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode="w", encoding="utf-8")
|
|
@@ -97,7 +110,7 @@ demo = gr.Interface(
|
|
| 97 |
gr.File(label="Connections File")
|
| 98 |
],
|
| 99 |
title="String Art Generator",
|
| 100 |
-
description="Upload an image, set the number of pins and connections, and generate circular string art with a downloadable connection file."
|
| 101 |
)
|
| 102 |
|
| 103 |
if __name__ == "__main__":
|
|
|
|
| 5 |
from skimage.draw import line
|
| 6 |
import gradio as gr
|
| 7 |
import tempfile
|
|
|
|
| 8 |
|
| 9 |
def preprocess_image(image, size=(200, 200)):
|
| 10 |
if image.ndim == 3:
|
|
|
|
| 37 |
connections = []
|
| 38 |
current_pin = 0
|
| 39 |
used = set()
|
| 40 |
+
img_work = img.copy() # Work on a copy so we can lighten pixels
|
| 41 |
+
|
| 42 |
for _ in range(num_connections):
|
| 43 |
best_score = -1
|
| 44 |
best_pin = None
|
| 45 |
+
best_rr, best_cc = None, None
|
| 46 |
for next_pin in range(num_pins):
|
| 47 |
if next_pin == current_pin:
|
| 48 |
continue
|
| 49 |
if (current_pin, next_pin) in used or (next_pin, current_pin) in used:
|
| 50 |
continue
|
| 51 |
+
h, w = img_work.shape
|
| 52 |
+
x1 = int((pins[current_pin][0] + 1) / 2 * (w - 1))
|
| 53 |
+
y1 = int((pins[current_pin][1] + 1) / 2 * (h - 1))
|
| 54 |
+
x2 = int((pins[next_pin][0] + 1) / 2 * (w - 1))
|
| 55 |
+
y2 = int((pins[next_pin][1] + 1) / 2 * (h - 1))
|
| 56 |
+
rr, cc = line(y1, x1, y2, x2)
|
| 57 |
+
rr = np.clip(rr, 0, h-1)
|
| 58 |
+
cc = np.clip(cc, 0, w-1)
|
| 59 |
+
line_pixels = img_work[rr, cc]
|
| 60 |
+
score = np.sum(1 - line_pixels)
|
| 61 |
if score > best_score:
|
| 62 |
best_score = score
|
| 63 |
best_pin = next_pin
|
| 64 |
+
best_rr, best_cc = rr, cc
|
| 65 |
if best_pin is None:
|
| 66 |
break
|
| 67 |
connections.append((current_pin, best_pin))
|
| 68 |
used.add((current_pin, best_pin))
|
| 69 |
+
# Lighten the pixels along this line (simulate string covering)
|
| 70 |
+
img_work[best_rr, best_cc] = 1.0
|
| 71 |
current_pin = best_pin
|
| 72 |
return connections
|
| 73 |
|
|
|
|
| 81 |
ax.axis("off")
|
| 82 |
for c in connections:
|
| 83 |
p1, p2 = pins[c[0]], pins[c[1]]
|
| 84 |
+
ax.plot([p1[0], p2[0]], [p1[1], p2[1]], 'k-', linewidth=0.7, alpha=0.2) # Black, thin, low opacity
|
| 85 |
ax.scatter(pins[:,0], pins[:,1], c='red', s=16) # Red pins, moderate size
|
| 86 |
plt.tight_layout(pad=0)
|
| 87 |
plt.close(fig)
|
| 88 |
# Prepare connections file (1-based indexing)
|
| 89 |
connections_1_based = [str(c[0]+1) for c in connections]
|
|
|
|
| 90 |
connections_str = ', '.join(connections_1_based)
|
| 91 |
# Save to temporary file
|
| 92 |
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode="w", encoding="utf-8")
|
|
|
|
| 110 |
gr.File(label="Connections File")
|
| 111 |
],
|
| 112 |
title="String Art Generator",
|
| 113 |
+
description="Upload an image, set the number of pins and connections, and generate circular string art with a downloadable connection file. Strings are drawn with reduced opacity."
|
| 114 |
)
|
| 115 |
|
| 116 |
if __name__ == "__main__":
|