Sagar Bharadwaj commited on
Commit
ba60f57
·
1 Parent(s): a4ba88e

Added gradio app

Browse files
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
+