aboalaa147 commited on
Commit
a14216e
·
verified ·
1 Parent(s): c848f48

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -0
app.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import tempfile
4
+ import os
5
+ from PIL import Image
6
+ import sys
7
+
8
+ # Import your modules (you'll need to include them in the space)
9
+ from strings import *
10
+
11
+ def process_string_art(image, n_hooks=180, radius=250, quantization=30):
12
+ """Process uploaded image and return string art result"""
13
+
14
+ # Save uploaded image temporarily
15
+ with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp_input:
16
+ image.save(tmp_input.name)
17
+ input_path = tmp_input.name
18
+
19
+ # Create temporary output prefix
20
+ output_prefix = tempfile.mktemp()
21
+
22
+ try:
23
+ # Build adjacency matrix
24
+ sparse, hooks, edge_codes = build_arc_adjecency_matrix(n_hooks, radius)
25
+
26
+ # Process image
27
+ shrinkage = 0.75
28
+ img = image_from_pil(image, int(radius * 2 * shrinkage))
29
+ sparse_b = build_image_vector(img, radius)
30
+
31
+ # Solve linear system
32
+ result = scipy.sparse.linalg.lsqr(sparse, np.array(sparse_b.todense()).flatten())
33
+ x = result[0]
34
+
35
+ # Apply quantization
36
+ x = np.clip(x, 0, 1e6)
37
+ max_edge_weight_orig = np.max(x)
38
+ x_quantized = (x / np.max(x) * quantization).round()
39
+ clip_factor = 0.3
40
+ x_quantized = np.clip(x_quantized, 0, int(np.max(x_quantized) * clip_factor))
41
+ x = x_quantized / quantization * max_edge_weight_orig
42
+
43
+ # Reconstruct final image
44
+ brightness_correction = 1.2
45
+ final_image = reconstruct(x * brightness_correction, sparse, radius)
46
+
47
+ # Calculate statistics
48
+ arc_count = int(np.sum(x_quantized))
49
+ unique_arcs = len(x_quantized[x_quantized > 0])
50
+
51
+ # Convert to PIL Image for return
52
+ final_pil = Image.fromarray(np.clip(final_image, 0, 255).astype(np.uint8))
53
+
54
+ stats = f"Total arcs: {arc_count}\nUnique arc types: {unique_arcs}"
55
+
56
+ return final_pil, stats
57
+
58
+ finally:
59
+ # Cleanup
60
+ if os.path.exists(input_path):
61
+ os.unlink(input_path)
62
+
63
+ def image_from_pil(pil_image, size):
64
+ """Convert PIL image to grayscale numpy array"""
65
+ img = pil_image.convert('L') # Convert to grayscale
66
+ img = img.resize((size, size), Image.Resampling.LANCZOS)
67
+ return np.array(img)
68
+
69
+ # Create Gradio interface
70
+ iface = gr.Interface(
71
+ fn=process_string_art,
72
+ inputs=[
73
+ gr.Image(type="pil", label="Upload Image"),
74
+ gr.Slider(50, 360, value=180, step=10, label="Number of Hooks"),
75
+ gr.Slider(100, 500, value=250, step=50, label="Circle Radius"),
76
+ gr.Slider(10, 100, value=30, step=5, label="Quantization Level")
77
+ ],
78
+ outputs=[
79
+ gr.Image(type="pil", label="String Art Result"),
80
+ gr.Textbox(label="Statistics")
81
+ ],
82
+ title="String Art Generator",
83
+ description="Convert any image into string art patterns! Upload a square image and adjust parameters.",
84
+ examples=[
85
+ # You can add example images here
86
+ ]
87
+ )
88
+
89
+ if __name__ == "__main__":
90
+ iface.launch()