File size: 9,913 Bytes
ba60f57
 
 
314b8be
 
ba60f57
 
 
 
 
 
b3d91b5
ba60f57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b3d91b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ba60f57
 
b3d91b5
 
ba60f57
 
 
b3d91b5
ba60f57
 
 
 
 
 
 
 
 
 
 
 
 
 
b3d91b5
 
 
ba60f57
 
b3d91b5
ba60f57
 
b3d91b5
 
 
 
 
 
 
 
 
 
 
 
 
 
ba60f57
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
import gradio as gr

from colorbynumber.config import default_config
from gradio_server import callbacks
from gradio_server import doc

MAX_NUM_COLORS = 50 # Mostly for UI purposes

with gr.Blocks(title = "Color by number") as demo:
    with gr.Row():
        # Inputs
        with gr.Column(elem_id="inputColumn"):
            image_path = gr.Image(type="filepath")
            image_examples = gr.Examples(
                examples=[
                    ["ExampleImages/Macaw.jpeg"],
                    ["ExampleImages/Grids.png"],
                ],
                inputs=[image_path]
            )

            # Color selection
            gr.Markdown(doc.color_selection_block())
            is_automatic_colors = gr.Checkbox(label = "Automatic colors", value = True)
            number_of_colors = gr.Number(precision=0, label = "Number of colors", value=10)
            
            # Color pickers
            color_pickers = []
            with gr.Row(visible=False) as color_picker_row:
                for i in range(MAX_NUM_COLORS):
                    color_pickers.append(gr.ColorPicker(label = str(i + 1)))

            # Toggle visibility of color pickers
            def _change_number_of_colors(number_of_colors):
                return [gr.update(visible=True)]*number_of_colors + \
                    [gr.update(visible=False)]*(MAX_NUM_COLORS - number_of_colors)
            def _get_color_selection_ui(is_automatic_colors_checked, number_of_colors):
                if is_automatic_colors_checked:
                    return [gr.update(visible=False)] + _change_number_of_colors(0)
                else:
                    return [gr.update(visible=True)] + _change_number_of_colors(number_of_colors)

            is_automatic_colors.change(
                _get_color_selection_ui,
                inputs = [is_automatic_colors, number_of_colors],
                outputs=[color_picker_row] + color_pickers,
            )     
            number_of_colors.change(
                fn=_change_number_of_colors,
                inputs=[number_of_colors],
                outputs=color_pickers,
            )

            # Config UI
            gr.Markdown(doc.parameters_block_header())
            with gr.Accordion(label="Configuration") as config_accordion:
                with gr.Tab(label="Denoise") as denoise_tab:
                    # Denoise parameters
                    gr.Markdown(doc.denoise_block_header())
                    denoise_flag = gr.Checkbox(
                            label = "Denoise", 
                            value = default_config["denoise"]
                            )
                    with gr.Group() as denoise_params:
                        with gr.Row():
                            denoise_order = gr.Dropdown(
                                label = "Denoise order", 
                                choices = ["before_simplify", "after_simplify"], 
                                value = default_config["denoise_order"],
                                )
                            denoise_type = gr.Dropdown(
                                label = "Denoise type", 
                                choices = ["fastNlMeansDenoisingColored", "gaussianBlur", "blur"], 
                                value = default_config["denoise_type"],
                                info="Algorithm to be used for denoising"
                                )
                        show_denoise_h = False
                        if default_config["denoise_type"] == "fastNlMeansDenoisingColored":
                            show_denoise_h = True

                        with gr.Row():
                            blur_size = gr.Slider(
                                label = "Blur size",
                                minimum = 3,
                                maximum = 101,
                                step=2, 
                                value = default_config["blur_size"],
                                info="Larger values will denoise more",
                                visible=(not show_denoise_h)
                                )
                            denoise_h = gr.Slider(
                                label = "h", 
                                value = default_config["denoise_h"],
                                info="Larger values will denoise more",
                                visible=show_denoise_h
                                )
                    
                    def _toggle_h_blur_size_visibility(event: gr.SelectData):
                        if event.value == "fastNlMeansDenoisingColored":
                            # Show denoise_h, hide blur_size
                            return [gr.update(visible=False), gr.update(visible=True)]
                        else:
                            # Show blur_size, hide denoise_h
                            return [gr.update(visible=True), gr.update(visible=False)]
                    denoise_type.select(
                        fn = _toggle_h_blur_size_visibility,
                        inputs = None,
                        outputs = [blur_size, denoise_h]
                        )
                        
                    denoise_flag.change(
                        fn = lambda x: gr.update(visible=x),
                        inputs = [denoise_flag],
                        outputs = denoise_params
                    )

                with gr.Tab(label = "Simplify") as simplify_tab:    
                
                    # Simplification parameters
                    gr.Markdown(doc.simplify_islands_parameters())
                    open_kernel_size = gr.Slider(
                        label = "Open kernel size",
                        minimum = 3,
                        maximum = 51,
                        step=2, 
                        value = default_config["open_kernel_size"],
                        info="Larger the value, cleaner the image. But too large values can remove important details."
                    )
                    area_perc_threshold = gr.Slider(
                        label = "Area Percentage threshold",
                        minimum = 0,
                        maximum = 10,
                        step=0.01, 
                        value = default_config["area_perc_threshold"],
                        info="Islands which cover a percentage area less than this threshold will be removed."
                    )

                    check_shape_validity = gr.Checkbox(
                        label = "Remove thin islands", 
                        value = default_config["check_shape_validity"],
                    )
                    arc_length_area_ratio_threshold = gr.Slider(
                        label = "Arc length to Area ratio",
                        minimum = 0,
                        maximum = 10,
                        step=0.01, 
                        value = default_config["arc_length_area_ratio_threshold"],
                        info="Smaller value removes more islands.",
                        visible=default_config["check_shape_validity"]
                    )
                    check_shape_validity.change(
                        fn = lambda x: gr.update(visible=x),
                        inputs = [check_shape_validity],
                        outputs = [arc_length_area_ratio_threshold]
                    )

            # Submit button
            submit_button = gr.Button("Submit")

        # Outputs
        with gr.Column():
            color_by_number_image = gr.Image(label = "Color by number")

            # Edit coloring page
            with gr.Row():
                font_size = gr.Slider(
                    label = "Font size", 
                    minimum = 0.1, 
                    maximum = 10, 
                    value = default_config["font_size"],
                )
                font_thickness = gr.Slider(
                    label = "Font thickness", 
                    minimum = 1, 
                    maximum = 10,
                    step=1, 
                    value = default_config["font_thickness"],
                )
                font_color = gr.ColorPicker(
                    label = "Font color", 
                    value = "#8c8c8c",
                    visible=False,
                    )
            legend_image = gr.Image(label = "Legend")
            simplified_image = gr.Image(label = "Simplified image")
            islands_image = gr.Image(label = "Islands (no numbers)", visible=False)
            data = gr.State() # To store the data for font change

        # Submit button callback
        submit_button.click(
            fn = callbacks.get_color_by_number,
            inputs = [
                image_path, 
                number_of_colors,
                is_automatic_colors,
                number_of_colors,
                denoise_flag,
                denoise_order,
                denoise_type,
                blur_size,
                denoise_h,
                open_kernel_size,
                area_perc_threshold,
                check_shape_validity,
                arc_length_area_ratio_threshold,
                font_size,
                font_color,
                font_thickness,
                *color_pickers
                ],
            outputs = [color_by_number_image, legend_image, simplified_image, islands_image, data]
        )

        # Callback to change font on image
        gr.on(
                triggers=[font_size.change, font_thickness.change],
                fn = callbacks.change_font_on_image,
                inputs = [
                    islands_image, 
                    data, 
                    font_size, 
                    font_color, 
                    font_thickness
                    ],
                outputs = color_by_number_image
            )

demo.launch()