Spaces:
Running
Running
gdTharusha
commited on
Commit
•
1b684f1
1
Parent(s):
d24131d
Update app.py
Browse files
app.py
CHANGED
@@ -4,83 +4,62 @@ import numpy as np
|
|
4 |
import io
|
5 |
import tempfile
|
6 |
import vtracer
|
7 |
-
from skimage import color, filters
|
8 |
-
|
9 |
-
from skimage.measure import shannon_entropy
|
10 |
|
11 |
-
def
|
12 |
-
"""
|
13 |
-
|
|
|
|
|
|
|
|
|
14 |
gray_image = np.array(image.convert('L'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
-
|
17 |
-
entropy = shannon_entropy(gray_image)
|
18 |
-
edges = canny(gray_image, sigma=1.0).mean() # Mean edge intensity
|
19 |
-
|
20 |
-
# Adjust parameters based on metrics
|
21 |
-
if entropy > 5.0:
|
22 |
-
color_mode = "Color"
|
23 |
-
blur_radius = 0
|
24 |
-
edge_enhance = True
|
25 |
-
edge_threshold = 2.0
|
26 |
-
else:
|
27 |
-
color_mode = "Binary"
|
28 |
-
blur_radius = 2
|
29 |
-
edge_enhance = False
|
30 |
-
edge_threshold = 1.0
|
31 |
-
|
32 |
-
hierarchical = "Stacked" if edges > 0.1 else "Cutout"
|
33 |
-
mode = "Spline" if edges > 0.15 else "Polygon"
|
34 |
-
|
35 |
-
filter_speckle = int(5 if edges > 0.12 else 15)
|
36 |
-
color_precision = int(8 if entropy > 4.5 else 10)
|
37 |
-
layer_difference = int(12 if edges > 0.2 else 20)
|
38 |
-
corner_threshold = int(60 if edges > 0.12 else 75)
|
39 |
-
length_threshold = float(5.0 if edges > 0.15 else 10.0)
|
40 |
-
max_iterations = int(15 if entropy > 4.5 else 10)
|
41 |
-
splice_threshold = int(50 if entropy > 4.0 else 70)
|
42 |
-
path_precision = int(10 if edges > 0.15 else 5)
|
43 |
-
|
44 |
-
return {
|
45 |
-
"blur_radius": blur_radius,
|
46 |
-
"edge_enhance": edge_enhance,
|
47 |
-
"edge_threshold": edge_threshold,
|
48 |
-
"color_mode": color_mode,
|
49 |
-
"hierarchical": hierarchical,
|
50 |
-
"mode": mode,
|
51 |
-
"filter_speckle": filter_speckle,
|
52 |
-
"color_precision": color_precision,
|
53 |
-
"layer_difference": layer_difference,
|
54 |
-
"corner_threshold": corner_threshold,
|
55 |
-
"length_threshold": length_threshold,
|
56 |
-
"max_iterations": max_iterations,
|
57 |
-
"splice_threshold": splice_threshold,
|
58 |
-
"path_precision": path_precision
|
59 |
-
}
|
60 |
-
|
61 |
-
def update_settings_live(image):
|
62 |
-
"""Update settings live based on image analysis."""
|
63 |
-
settings = analyze_image_and_update_settings(image)
|
64 |
-
return (settings["blur_radius"], settings["edge_enhance"], settings["edge_threshold"],
|
65 |
-
settings["color_mode"], settings["hierarchical"], settings["mode"],
|
66 |
-
settings["filter_speckle"], settings["color_precision"], settings["layer_difference"],
|
67 |
-
settings["corner_threshold"], settings["length_threshold"], settings["max_iterations"],
|
68 |
-
settings["splice_threshold"], settings["path_precision"])
|
69 |
-
|
70 |
-
def convert_image(image, blur_radius, edge_enhance, edge_threshold, color_mode, hierarchical, mode,
|
71 |
-
filter_speckle, color_precision, layer_difference, corner_threshold, length_threshold,
|
72 |
-
max_iterations, splice_threshold, path_precision):
|
73 |
-
"""Converts an image to SVG using vtracer with customizable parameters."""
|
74 |
-
|
75 |
-
# Preprocess the image
|
76 |
-
image = preprocess_image(image, blur_radius, edge_enhance, edge_threshold)
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
# Convert Gradio image to bytes for vtracer compatibility
|
79 |
img_byte_array = io.BytesIO()
|
80 |
image.save(img_byte_array, format='PNG')
|
81 |
img_bytes = img_byte_array.getvalue()
|
82 |
-
|
83 |
-
# Perform the conversion
|
84 |
svg_str = vtracer.convert_raw_image_to_svg(
|
85 |
img_bytes,
|
86 |
img_format='png',
|
@@ -96,86 +75,60 @@ def convert_image(image, blur_radius, edge_enhance, edge_threshold, color_mode,
|
|
96 |
splice_threshold=int(splice_threshold),
|
97 |
path_precision=int(path_precision)
|
98 |
)
|
99 |
-
|
100 |
# Save the SVG string to a temporary file
|
101 |
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.svg')
|
102 |
temp_file.write(svg_str.encode('utf-8'))
|
103 |
temp_file.close()
|
104 |
-
|
105 |
# Display the SVG in the Gradio interface and provide the download link
|
106 |
svg_html = f'<svg viewBox="0 0 {image.width} {image.height}">{svg_str}</svg>'
|
107 |
return gr.HTML(svg_html), temp_file.name
|
108 |
|
109 |
-
def preprocess_image(image, blur_radius, edge_enhance, edge_threshold):
|
110 |
-
"""Applies advanced preprocessing steps to the image before tracing."""
|
111 |
-
if blur_radius > 0:
|
112 |
-
image = image.filter(ImageFilter.GaussianBlur(blur_radius))
|
113 |
-
|
114 |
-
if edge_enhance:
|
115 |
-
# Convert image to grayscale and apply edge detection
|
116 |
-
gray_image = np.array(image.convert('L'))
|
117 |
-
edges = canny(gray_image, sigma=edge_threshold)
|
118 |
-
edges_img = Image.fromarray((edges * 255).astype(np.uint8))
|
119 |
-
image = Image.blend(image.convert('RGB'), edges_img.convert('RGB'), alpha=0.5)
|
120 |
-
|
121 |
-
return image
|
122 |
-
|
123 |
# Gradio interface
|
124 |
iface = gr.Blocks()
|
125 |
|
126 |
with iface:
|
127 |
-
gr.Markdown("# Advanced Image to SVG
|
128 |
-
gr.Markdown("Upload an image and
|
129 |
-
|
130 |
with gr.Row():
|
131 |
image_input = gr.Image(type="pil", label="Upload Image")
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
gr.Slider.update(), gr.Slider.update())
|
157 |
-
|
158 |
-
auto_settings_input.change(
|
159 |
-
fn=auto_update,
|
160 |
-
inputs=[image_input, auto_settings_input],
|
161 |
-
outputs=[
|
162 |
-
blur_radius_input, edge_enhance_input, edge_threshold_input, color_mode_input, hierarchical_input,
|
163 |
-
mode_input, filter_speckle_input, color_precision_input, layer_difference_input, corner_threshold_input,
|
164 |
-
length_threshold_input, max_iterations_input, splice_threshold_input, path_precision_input
|
165 |
-
]
|
166 |
-
)
|
167 |
-
|
168 |
convert_button = gr.Button("Convert Image to SVG")
|
169 |
svg_output = gr.HTML(label="SVG Output")
|
170 |
download_output = gr.File(label="Download SVG")
|
171 |
-
|
172 |
convert_button.click(
|
173 |
fn=convert_image,
|
174 |
inputs=[
|
175 |
-
image_input, blur_radius_input, edge_enhance_input, edge_threshold_input,
|
176 |
-
hierarchical_input, mode_input, filter_speckle_input, color_precision_input,
|
177 |
-
corner_threshold_input, length_threshold_input, max_iterations_input,
|
178 |
-
path_precision_input
|
179 |
],
|
180 |
outputs=[svg_output, download_output]
|
181 |
)
|
|
|
4 |
import io
|
5 |
import tempfile
|
6 |
import vtracer
|
7 |
+
from skimage import color, filters, feature, morphology
|
8 |
+
import cv2
|
|
|
9 |
|
10 |
+
def preprocess_image(image, blur_radius, edge_enhance, edge_threshold, detail_level):
|
11 |
+
"""Preprocess the image with advanced options before vectorization."""
|
12 |
+
|
13 |
+
if blur_radius > 0:
|
14 |
+
image = image.filter(ImageFilter.GaussianBlur(blur_radius))
|
15 |
+
|
16 |
+
# Convert to grayscale for edge detection
|
17 |
gray_image = np.array(image.convert('L'))
|
18 |
+
|
19 |
+
# Detail level settings
|
20 |
+
if detail_level == 'Very Low':
|
21 |
+
sigma = 3.0
|
22 |
+
morphology_size = 5
|
23 |
+
elif detail_level == 'Low':
|
24 |
+
sigma = 2.0
|
25 |
+
morphology_size = 4
|
26 |
+
elif detail_level == 'Medium':
|
27 |
+
sigma = 1.5
|
28 |
+
morphology_size = 3
|
29 |
+
elif detail_level == 'High':
|
30 |
+
sigma = 1.0
|
31 |
+
morphology_size = 2
|
32 |
+
else: # Ultra
|
33 |
+
sigma = 0.5
|
34 |
+
morphology_size = 1
|
35 |
+
|
36 |
+
if edge_enhance:
|
37 |
+
# Canny edge detection
|
38 |
+
edges = feature.canny(gray_image, sigma=sigma, low_threshold=edge_threshold)
|
39 |
+
|
40 |
+
# Morphological operations to refine edges
|
41 |
+
edges = morphology.dilation(edges, morphology.square(morphology_size))
|
42 |
+
edges_img = Image.fromarray((edges * 255).astype(np.uint8))
|
43 |
+
|
44 |
+
# Blend the edges with the original image
|
45 |
+
image = Image.blend(image.convert('RGB'), edges_img.convert('RGB'), alpha=0.5)
|
46 |
|
47 |
+
return image
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
+
def convert_image(image, blur_radius, edge_enhance, edge_threshold, detail_level, color_mode,
|
50 |
+
hierarchical, mode, filter_speckle, color_precision, layer_difference,
|
51 |
+
corner_threshold, length_threshold, max_iterations, splice_threshold, path_precision):
|
52 |
+
"""Convert an image to SVG using vtracer with customizable and advanced parameters."""
|
53 |
+
|
54 |
+
# Preprocess the image with additional detail level settings
|
55 |
+
image = preprocess_image(image, blur_radius, edge_enhance, edge_threshold, detail_level)
|
56 |
+
|
57 |
# Convert Gradio image to bytes for vtracer compatibility
|
58 |
img_byte_array = io.BytesIO()
|
59 |
image.save(img_byte_array, format='PNG')
|
60 |
img_bytes = img_byte_array.getvalue()
|
61 |
+
|
62 |
+
# Perform the conversion
|
63 |
svg_str = vtracer.convert_raw_image_to_svg(
|
64 |
img_bytes,
|
65 |
img_format='png',
|
|
|
75 |
splice_threshold=int(splice_threshold),
|
76 |
path_precision=int(path_precision)
|
77 |
)
|
78 |
+
|
79 |
# Save the SVG string to a temporary file
|
80 |
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.svg')
|
81 |
temp_file.write(svg_str.encode('utf-8'))
|
82 |
temp_file.close()
|
83 |
+
|
84 |
# Display the SVG in the Gradio interface and provide the download link
|
85 |
svg_html = f'<svg viewBox="0 0 {image.width} {image.height}">{svg_str}</svg>'
|
86 |
return gr.HTML(svg_html), temp_file.name
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
# Gradio interface
|
89 |
iface = gr.Blocks()
|
90 |
|
91 |
with iface:
|
92 |
+
gr.Markdown("# Advanced Image to SVG Converter")
|
93 |
+
gr.Markdown("Upload an image and customize the conversion parameters for high-quality vector results. This tool provides advanced options to analyze and vectorize images at a pixel level with various detail settings.")
|
94 |
+
|
95 |
with gr.Row():
|
96 |
image_input = gr.Image(type="pil", label="Upload Image")
|
97 |
+
blur_radius_input = gr.Slider(minimum=0, maximum=10, value=0, step=0.5, label="Blur Radius (for smoothing)")
|
98 |
+
edge_enhance_input = gr.Checkbox(value=False, label="AI Edge Enhance")
|
99 |
+
edge_threshold_input = gr.Slider(minimum=0.1, maximum=3.0, value=1.0, step=0.1, label="Edge Detection Threshold")
|
100 |
+
detail_level_input = gr.Radio(choices=["Very Low", "Low", "Medium", "High", "Ultra"], value="Medium", label="Detail Level")
|
101 |
+
|
102 |
+
with gr.Row():
|
103 |
+
color_mode_input = gr.Radio(choices=["Color", "Binary"], value="Color", label="Color Mode")
|
104 |
+
hierarchical_input = gr.Radio(choices=["Stacked", "Cutout"], value="Stacked", label="Hierarchical")
|
105 |
+
mode_input = gr.Radio(choices=["Spline", "Polygon", "None"], value="Spline", label="Mode")
|
106 |
+
|
107 |
+
with gr.Row():
|
108 |
+
filter_speckle_input = gr.Slider(minimum=1, maximum=100, value=4, step=1, label="Filter Speckle")
|
109 |
+
color_precision_input = gr.Slider(minimum=1, maximum=100, value=6, step=1, label="Color Precision")
|
110 |
+
layer_difference_input = gr.Slider(minimum=1, maximum=100, value=16, step=1, label="Layer Difference")
|
111 |
+
|
112 |
+
with gr.Row():
|
113 |
+
corner_threshold_input = gr.Slider(minimum=1, maximum=100, value=60, step=1, label="Corner Threshold")
|
114 |
+
length_threshold_input = gr.Slider(minimum=1, maximum=100, value=4.0, step=0.5, label="Length Threshold")
|
115 |
+
max_iterations_input = gr.Slider(minimum=1, maximum=100, value=10, step=1, label="Max Iterations")
|
116 |
+
|
117 |
+
with gr.Row():
|
118 |
+
splice_threshold_input = gr.Slider(minimum=1, maximum=100, value=45, step=1, label="Splice Threshold")
|
119 |
+
path_precision_input = gr.Slider(minimum=1, maximum=100, value=8, step=1, label="Path Precision")
|
120 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
convert_button = gr.Button("Convert Image to SVG")
|
122 |
svg_output = gr.HTML(label="SVG Output")
|
123 |
download_output = gr.File(label="Download SVG")
|
124 |
+
|
125 |
convert_button.click(
|
126 |
fn=convert_image,
|
127 |
inputs=[
|
128 |
+
image_input, blur_radius_input, edge_enhance_input, edge_threshold_input, detail_level_input,
|
129 |
+
color_mode_input, hierarchical_input, mode_input, filter_speckle_input, color_precision_input,
|
130 |
+
layer_difference_input, corner_threshold_input, length_threshold_input, max_iterations_input,
|
131 |
+
splice_threshold_input, path_precision_input
|
132 |
],
|
133 |
outputs=[svg_output, download_output]
|
134 |
)
|