Spaces:
Running
Running
Sagar Bharadwaj
commited on
Commit
·
ba60f57
1
Parent(s):
a4ba88e
Added gradio app
Browse files- colorbynumber/__init__.py +0 -0
- environment.yml +2 -1
- gradio_server/__init__.py +0 -0
- gradio_server/app.py +232 -0
- gradio_server/doc.py +35 -0
colorbynumber/__init__.py
ADDED
File without changes
|
environment.yml
CHANGED
@@ -10,4 +10,5 @@ dependencies:
|
|
10 |
- matplotlib
|
11 |
- scipy
|
12 |
- pip:
|
13 |
-
- python-polylabel
|
|
|
|
10 |
- matplotlib
|
11 |
- scipy
|
12 |
- pip:
|
13 |
+
- python-polylabel
|
14 |
+
- gradio
|
gradio_server/__init__.py
ADDED
File without changes
|
gradio_server/app.py
ADDED
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
|
3 |
+
from colorbynumber.main import ColorByNumber
|
4 |
+
from colorbynumber.config import default_config
|
5 |
+
from . import doc
|
6 |
+
|
7 |
+
MAX_NUM_COLORS = 50 # Mostly for UI purposes
|
8 |
+
|
9 |
+
def get_color_by_number(image_path, number_of_colors,
|
10 |
+
is_automatic_colors, num_colors,
|
11 |
+
denoise_flag, denoise_order, denoise_type,
|
12 |
+
blur_size, denoise_h,
|
13 |
+
open_kernel_size, area_perc_threshold,
|
14 |
+
check_shape_validity, arc_length_area_ratio_threshold,
|
15 |
+
*color_list):
|
16 |
+
# Convert each color to r,g,b tuple
|
17 |
+
color_list = color_list[:num_colors]
|
18 |
+
def _hex_to_rgb(hex_color):
|
19 |
+
hex_color = hex_color.lstrip("#")
|
20 |
+
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
|
21 |
+
color_list = [_hex_to_rgb(h) for h in color_list]
|
22 |
+
|
23 |
+
# Update config
|
24 |
+
config = default_config.copy()
|
25 |
+
config["denoise"] = denoise_flag
|
26 |
+
config["denoise_order"] = denoise_order
|
27 |
+
config["denoise_type"] = denoise_type
|
28 |
+
config["blur_size"] = blur_size
|
29 |
+
config["denoise_h"] = denoise_h
|
30 |
+
config["open_kernel_size"] = open_kernel_size
|
31 |
+
config["area_perc_threshold"] = area_perc_threshold
|
32 |
+
config["check_shape_validity"] = check_shape_validity
|
33 |
+
config["arc_length_area_ratio_threshold"] = arc_length_area_ratio_threshold
|
34 |
+
|
35 |
+
if is_automatic_colors:
|
36 |
+
colorbynumber_obj = ColorByNumber(
|
37 |
+
image_path = image_path,
|
38 |
+
num_colors = number_of_colors,
|
39 |
+
config = config,
|
40 |
+
)
|
41 |
+
else:
|
42 |
+
colorbynumber_obj = ColorByNumber(
|
43 |
+
image_path = image_path,
|
44 |
+
color_list = color_list,
|
45 |
+
config = config,
|
46 |
+
)
|
47 |
+
|
48 |
+
numbered_islands = colorbynumber_obj.create_color_by_number()
|
49 |
+
return numbered_islands, \
|
50 |
+
colorbynumber_obj.generate_color_legend(), \
|
51 |
+
colorbynumber_obj.simplified_image
|
52 |
+
|
53 |
+
with gr.Blocks(title = "Color by number") as demo:
|
54 |
+
with gr.Row():
|
55 |
+
# Inputs
|
56 |
+
with gr.Column():
|
57 |
+
image_path = gr.Image(type="filepath")
|
58 |
+
image_examples = gr.Examples(
|
59 |
+
examples=[
|
60 |
+
["ExampleImages/Macaw.jpeg"],
|
61 |
+
["ExampleImages/Grids.png"],
|
62 |
+
],
|
63 |
+
inputs=[image_path]
|
64 |
+
)
|
65 |
+
|
66 |
+
# Color selection
|
67 |
+
gr.Markdown(doc.color_selection_block())
|
68 |
+
is_automatic_colors = gr.Checkbox(label = "Automatic colors", value = True)
|
69 |
+
number_of_colors = gr.Number(precision=0, label = "Number of colors", value=10)
|
70 |
+
|
71 |
+
# Color pickers
|
72 |
+
color_pickers = []
|
73 |
+
with gr.Row(visible=False) as color_picker_row:
|
74 |
+
for i in range(MAX_NUM_COLORS):
|
75 |
+
color_pickers.append(gr.ColorPicker(label = str(i + 1)))
|
76 |
+
|
77 |
+
# Toggle visibility of color pickers
|
78 |
+
def _change_number_of_colors(number_of_colors):
|
79 |
+
return [gr.update(visible=True)]*number_of_colors + \
|
80 |
+
[gr.update(visible=False)]*(MAX_NUM_COLORS - number_of_colors)
|
81 |
+
def _get_color_selection_ui(is_automatic_colors_checked, number_of_colors):
|
82 |
+
if is_automatic_colors_checked:
|
83 |
+
return [gr.update(visible=False)] + _change_number_of_colors(0)
|
84 |
+
else:
|
85 |
+
return [gr.update(visible=True)] + _change_number_of_colors(number_of_colors)
|
86 |
+
|
87 |
+
is_automatic_colors.change(
|
88 |
+
_get_color_selection_ui,
|
89 |
+
inputs = [is_automatic_colors, number_of_colors],
|
90 |
+
outputs=[color_picker_row] + color_pickers,
|
91 |
+
)
|
92 |
+
number_of_colors.change(
|
93 |
+
fn=_change_number_of_colors,
|
94 |
+
inputs=[number_of_colors],
|
95 |
+
outputs=color_pickers,
|
96 |
+
)
|
97 |
+
|
98 |
+
# Config UI
|
99 |
+
gr.Markdown(doc.parameters_block_header())
|
100 |
+
with gr.Accordion(label="Configuration") as config_accordion:
|
101 |
+
with gr.Tab(label="Denoise") as denoise_tab:
|
102 |
+
# Denoise parameters
|
103 |
+
gr.Markdown(doc.denoise_block_header())
|
104 |
+
denoise_flag = gr.Checkbox(
|
105 |
+
label = "Denoise",
|
106 |
+
value = default_config["denoise"]
|
107 |
+
)
|
108 |
+
with gr.Group() as denoise_params:
|
109 |
+
with gr.Row():
|
110 |
+
denoise_order = gr.Dropdown(
|
111 |
+
label = "Denoise order",
|
112 |
+
choices = ["before_simplify", "after_simplify"],
|
113 |
+
value = default_config["denoise_order"],
|
114 |
+
)
|
115 |
+
denoise_type = gr.Dropdown(
|
116 |
+
label = "Denoise type",
|
117 |
+
choices = ["fastNlMeansDenoisingColored", "gaussianBlur", "blur"],
|
118 |
+
value = default_config["denoise_type"],
|
119 |
+
info="Algorithm to be used for denoising"
|
120 |
+
)
|
121 |
+
show_denoise_h = False
|
122 |
+
if default_config["denoise_type"] == "fastNlMeansDenoisingColored":
|
123 |
+
show_denoise_h = True
|
124 |
+
|
125 |
+
with gr.Row():
|
126 |
+
blur_size = gr.Slider(
|
127 |
+
label = "Blur size",
|
128 |
+
minimum = 3,
|
129 |
+
maximum = 101,
|
130 |
+
step=2,
|
131 |
+
value = default_config["blur_size"],
|
132 |
+
info="Larger values will denoise more",
|
133 |
+
visible=(not show_denoise_h)
|
134 |
+
)
|
135 |
+
denoise_h = gr.Slider(
|
136 |
+
label = "h",
|
137 |
+
value = default_config["denoise_h"],
|
138 |
+
info="Larger values will denoise more",
|
139 |
+
visible=show_denoise_h
|
140 |
+
)
|
141 |
+
|
142 |
+
def _toggle_h_blur_size_visibility(event: gr.SelectData):
|
143 |
+
if event.value == "fastNlMeansDenoisingColored":
|
144 |
+
# Show denoise_h, hide blur_size
|
145 |
+
return [gr.update(visible=False), gr.update(visible=True)]
|
146 |
+
else:
|
147 |
+
# Show blur_size, hide denoise_h
|
148 |
+
return [gr.update(visible=True), gr.update(visible=False)]
|
149 |
+
denoise_type.select(
|
150 |
+
fn = _toggle_h_blur_size_visibility,
|
151 |
+
inputs = None,
|
152 |
+
outputs = [blur_size, denoise_h]
|
153 |
+
)
|
154 |
+
|
155 |
+
denoise_flag.change(
|
156 |
+
fn = lambda x: gr.update(visible=x),
|
157 |
+
inputs = [denoise_flag],
|
158 |
+
outputs = denoise_params
|
159 |
+
)
|
160 |
+
|
161 |
+
with gr.Tab(label = "Simplify") as simplify_tab:
|
162 |
+
|
163 |
+
# Simplification parameters
|
164 |
+
gr.Markdown(doc.simplify_islands_parameters())
|
165 |
+
open_kernel_size = gr.Slider(
|
166 |
+
label = "Open kernel size",
|
167 |
+
minimum = 3,
|
168 |
+
maximum = 51,
|
169 |
+
step=2,
|
170 |
+
value = default_config["open_kernel_size"],
|
171 |
+
info="Larger the value, cleaner the image. But too large values can remove important details."
|
172 |
+
)
|
173 |
+
area_perc_threshold = gr.Slider(
|
174 |
+
label = "Area Percentage threshold",
|
175 |
+
minimum = 0,
|
176 |
+
maximum = 10,
|
177 |
+
step=0.01,
|
178 |
+
value = default_config["area_perc_threshold"],
|
179 |
+
info="Islands which cover a percentage area less than this threshold will be removed."
|
180 |
+
)
|
181 |
+
|
182 |
+
check_shape_validity = gr.Checkbox(
|
183 |
+
label = "Remove thin islands",
|
184 |
+
value = default_config["check_shape_validity"],
|
185 |
+
)
|
186 |
+
arc_length_area_ratio_threshold = gr.Slider(
|
187 |
+
label = "Arc length to Area ratio",
|
188 |
+
minimum = 0,
|
189 |
+
maximum = 10,
|
190 |
+
step=0.01,
|
191 |
+
value = default_config["arc_length_area_ratio_threshold"],
|
192 |
+
info="Smaller value removes more islands.",
|
193 |
+
visible=default_config["check_shape_validity"]
|
194 |
+
)
|
195 |
+
check_shape_validity.change(
|
196 |
+
fn = lambda x: gr.update(visible=x),
|
197 |
+
inputs = [check_shape_validity],
|
198 |
+
outputs = [arc_length_area_ratio_threshold]
|
199 |
+
)
|
200 |
+
|
201 |
+
# Submit button
|
202 |
+
submit_button = gr.Button("Submit")
|
203 |
+
|
204 |
+
# Outputs
|
205 |
+
with gr.Column():
|
206 |
+
color_by_number_image = gr.Image(label = "Color by number")
|
207 |
+
legend_image = gr.Image(label = "Legend")
|
208 |
+
simplified_image = gr.Image(label = "Simplified image")
|
209 |
+
|
210 |
+
# Submit button callback
|
211 |
+
submit_button.click(
|
212 |
+
fn = get_color_by_number,
|
213 |
+
inputs = [
|
214 |
+
image_path,
|
215 |
+
number_of_colors,
|
216 |
+
is_automatic_colors,
|
217 |
+
number_of_colors,
|
218 |
+
denoise_flag,
|
219 |
+
denoise_order,
|
220 |
+
denoise_type,
|
221 |
+
blur_size,
|
222 |
+
denoise_h,
|
223 |
+
open_kernel_size,
|
224 |
+
area_perc_threshold,
|
225 |
+
check_shape_validity,
|
226 |
+
arc_length_area_ratio_threshold,
|
227 |
+
*color_pickers
|
228 |
+
],
|
229 |
+
outputs = [color_by_number_image, legend_image, simplified_image]
|
230 |
+
)
|
231 |
+
|
232 |
+
demo.launch()
|
gradio_server/doc.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def color_selection_block():
|
2 |
+
return """
|
3 |
+
---
|
4 |
+
## Color selection
|
5 |
+
Limit the colors to the ones you already have in your paint palette,
|
6 |
+
or let the algorithm choose the best colors for you.
|
7 |
+
"""
|
8 |
+
|
9 |
+
def parameters_block_header():
|
10 |
+
return """
|
11 |
+
---
|
12 |
+
Configuration influences how the image is processed and thereby
|
13 |
+
affects the complexity of the coloring page. You can use the default values
|
14 |
+
to get started. Tweak them if nexessary to get the desired results.
|
15 |
+
"""
|
16 |
+
|
17 |
+
# Denoise parameters
|
18 |
+
def denoise_block_header():
|
19 |
+
return """
|
20 |
+
## Denoise
|
21 |
+
Removing noise from the image can help in simplifying the image.
|
22 |
+
Not recommended for some images where sharp edges are to be preserved
|
23 |
+
(e.g. Grid image in above example).
|
24 |
+
"""
|
25 |
+
|
26 |
+
def simplify_islands_parameters():
|
27 |
+
return """
|
28 |
+
## Simplify Islands
|
29 |
+
The individual blocks of colors are _Islands_.
|
30 |
+
The parameters below influence the simplification of these islands
|
31 |
+
and determine the complexity of the coloring page.
|
32 |
+
"""
|
33 |
+
|
34 |
+
|
35 |
+
|