mikonvergence commited on
Commit
620f5cb
1 Parent(s): 98bea29

Added error messages, changed input to pil-type, small visual tweaks

Browse files
Files changed (1) hide show
  1. app.py +96 -74
app.py CHANGED
@@ -76,81 +76,85 @@ def get_guide(image):
76
  return hed(image,scribble=True)
77
 
78
  def create_demo(max_images=12, default_num_images=3):
79
- with gr.Blocks(theme=gr.themes.Default(font=[gr.themes.GoogleFont("IBM Plex Mono"), "ui-monospace","monospace"]), css=css) as demo:
 
 
 
 
80
 
81
- gr.Markdown('# Mask and Sketch ✂️▶️✏️')
82
  with gr.Accordion('Instructions', open=False):
83
- gr.Markdown('## Mask ✂️')
84
  gr.Markdown('1. Upload your image below')
85
- gr.Markdown('2. **Draw the mask** for the region you want changed (Mask ✂️)')
86
  gr.Markdown('3. Click `Set Mask` when it is ready!')
87
  gr.Markdown('## Sketch ✏️')
88
  gr.Markdown('4. Now, you can **sketch a replacement** object! (Sketch ✏️)')
89
  gr.Markdown('5. (You can also provide a **text prompt** if you want)')
90
- gr.Markdown('6. 🔮 Click `Generate` when ready! ')
91
  example_button=gr.Button(label='example',value='Try example image!').style(full_width=False, size='sm')
92
 
93
  with gr.Group():
94
- with gr.Box():
95
- with gr.Column():
96
- with gr.Row() as main_blocks:
97
- with gr.Column() as step_1:
98
- gr.Markdown('### Mask Input')
99
- image = gr.Image(source='upload',
100
- shape=[HEIGHT,WIDTH],
101
- type='numpy',
102
- elem_classes="image_upload",
103
- label='Mask Draw (Mask!)',
104
- tool='sketch',
105
- brush_radius=60).style(height=500)
106
- input_image=image
107
- mask_button = gr.Button(label='Set Mask', value='Set Mask')
108
- with gr.Column(visible=False) as step_2:
109
- gr.Markdown('### Sketch Input')
110
- sketch = gr.Image(source='upload',
111
- shape=[HEIGHT,WIDTH],
112
- type='numpy',
113
  elem_classes="image_upload",
114
- label='Fill Draw (Sketch!)',
115
- tool='sketch',
116
- brush_radius=10).style(height=500)
117
- sketch_image=sketch
118
- run_button = gr.Button(label='Generate', value='Generate')
119
- prompt = gr.Textbox(label='Prompt')
120
-
121
- with gr.Column() as output_step:
122
- gr.Markdown('### Output')
123
- output_image = gr.Gallery(
124
- label="Generated images",
125
- show_label=False,
126
- elem_id="output_image",
127
- ).style(height=500,containter=True)
128
- with gr.Accordion('Advanced options', open=False):
129
- num_steps = gr.Slider(label='Steps',
130
- minimum=1,
131
- maximum=100,
132
- value=20,
133
- step=1)
134
- text_scale = gr.Slider(label='Text Guidance Scale',
135
- minimum=0.1,
136
- maximum=30.0,
137
- value=7.5,
138
- step=0.1)
139
- seed = gr.Slider(label='Seed',
140
- minimum=-1,
141
- maximum=2147483647,
142
- step=1,
143
- randomize=True)
144
-
145
- sketch_scale = gr.Slider(label='Sketch Guidance Scale',
146
- minimum=0.0,
147
- maximum=1.0,
148
- value=1.0,
149
- step=0.05)
 
 
 
 
 
 
 
 
 
 
 
150
 
151
  with gr.Accordion('More Info', open=False):
152
  gr.Markdown('This demo was created by Mikolaj Czerkawski [@mikonvergence](https://twitter.com/mikonvergence) based on the 🌱 open-source implementation of [ControlNetInpaint](https://github.com/mikonvergence/ControlNetInpaint) (diffusers-friendly!).')
153
- gr.Markdown('**Limitation** The tool currently only works with image resolution of 512px. You need to click reload button to draw a new mask after the previous generation since gradio does not allow to control it from software.')
154
  gr.Markdown('💡 To learn more about diffusion with interactive code, check out my open-source ⏩[DiffusionFastForward](https://github.com/mikonvergence/DiffusionFastForward) course. It contains example code, executable notebooks, videos, notes, and a few use cases for training from scratch!')
155
 
156
  inputs = [
@@ -163,37 +167,55 @@ def create_demo(max_images=12, default_num_images=3):
163
  ]
164
 
165
  # STEP 1: Set Mask
166
- def set_mask(image):
167
- img=image['image'][...,:3]
168
- mask=1*(image['mask'][...,:3]>0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  # save vars
170
- CURRENT_IMAGE['image']=img
171
  CURRENT_IMAGE['mask']=mask
172
 
173
- guide=get_guide(img)
174
  CURRENT_IMAGE['guide']=np.array(guide)
175
  guide=255-np.asarray(guide)
176
 
177
  seg_img = guide*(1-mask) + mask*192
178
- preview = img * (seg_img==255)
179
 
180
  vis_image=(preview/2).astype(seg_img.dtype) + seg_img * (seg_img!=255)
181
 
182
- return {input_image : image['image'],
183
- sketch_image : vis_image,
184
- step_1: gr.update(visible=False),
185
- step_2: gr.update(visible=True)
186
  }
187
 
188
  # STEP 2: Generate
189
- def generate(image,
190
  prompt,
191
  num_steps,
192
  text_scale,
193
  sketch_scale,
194
  seed):
195
-
196
- sketch=(255*(image['mask'][...,:3]>0)).astype(CURRENT_IMAGE['image'].dtype)
197
  mask=CURRENT_IMAGE['mask']
198
 
199
  CURRENT_IMAGE['guide']=(CURRENT_IMAGE['guide']*(mask==0) + sketch*(mask!=0)).astype(CURRENT_IMAGE['image'].dtype)
 
76
  return hed(image,scribble=True)
77
 
78
  def create_demo(max_images=12, default_num_images=3):
79
+ with gr.Blocks(theme=gr.themes.Default(font=[gr.themes.GoogleFont("IBM Plex Mono"), "ui-monospace","monospace"],
80
+ primary_hue="lime",
81
+ secondary_hue="emerald",
82
+ neutral_hue="slate",
83
+ ), css=css) as demo:
84
 
85
+ gr.Markdown('# Cut and Sketch ✂️▶️✏️')
86
  with gr.Accordion('Instructions', open=False):
87
+ gr.Markdown('## Cut ✂️')
88
  gr.Markdown('1. Upload your image below')
89
+ gr.Markdown('2. **Draw the mask** for the region you want changed (Cut ✂️)')
90
  gr.Markdown('3. Click `Set Mask` when it is ready!')
91
  gr.Markdown('## Sketch ✏️')
92
  gr.Markdown('4. Now, you can **sketch a replacement** object! (Sketch ✏️)')
93
  gr.Markdown('5. (You can also provide a **text prompt** if you want)')
94
+ gr.Markdown('6. 🔮 Click `Generate` when ready! ')
95
  example_button=gr.Button(label='example',value='Try example image!').style(full_width=False, size='sm')
96
 
97
  with gr.Group():
98
+ with gr.Box():
99
+ with gr.Column():
100
+ with gr.Row() as main_blocks:
101
+ with gr.Column() as step_1:
102
+ gr.Markdown('### Mask Input')
103
+ image = gr.Image(source='upload',
104
+ shape=[HEIGHT,WIDTH],
105
+ type='pil',#numpy',
 
 
 
 
 
 
 
 
 
 
 
106
  elem_classes="image_upload",
107
+ label='Mask Draw (Cut!)',
108
+ tool='sketch',
109
+ brush_radius=60).style(height=500)
110
+ input_image=image
111
+ mask_button = gr.Button(label='Set Mask', value='Set Mask')
112
+ with gr.Column(visible=False) as step_2:
113
+ gr.Markdown('### Sketch Input')
114
+ sketch = gr.Image(source='upload',
115
+ shape=[HEIGHT,WIDTH],
116
+ type='pil',#'numpy',
117
+ elem_classes="image_upload",
118
+ label='Fill Draw (Sketch!)',
119
+ tool='sketch',
120
+ brush_radius=10).style(height=500)
121
+ sketch_image=sketch
122
+ run_button = gr.Button(label='Generate', value='Generate', variant="primary")
123
+ prompt = gr.Textbox(label='Prompt')
124
+
125
+ with gr.Column() as output_step:
126
+ gr.Markdown('### Output')
127
+ output_image = gr.Gallery(
128
+ label="Generated images",
129
+ show_label=False,
130
+ elem_id="output_image",
131
+ ).style(height=500,containter=True)
132
+ with gr.Accordion('Advanced options', open=False):
133
+ num_steps = gr.Slider(label='Steps',
134
+ minimum=1,
135
+ maximum=100,
136
+ value=20,
137
+ step=1)
138
+ text_scale = gr.Slider(label='Text Guidance Scale',
139
+ minimum=0.1,
140
+ maximum=30.0,
141
+ value=7.5,
142
+ step=0.1)
143
+ seed = gr.Slider(label='Seed',
144
+ minimum=-1,
145
+ maximum=2147483647,
146
+ step=1,
147
+ randomize=True)
148
+
149
+ sketch_scale = gr.Slider(label='Sketch Guidance Scale',
150
+ minimum=0.0,
151
+ maximum=1.0,
152
+ value=1.0,
153
+ step=0.05)
154
 
155
  with gr.Accordion('More Info', open=False):
156
  gr.Markdown('This demo was created by Mikolaj Czerkawski [@mikonvergence](https://twitter.com/mikonvergence) based on the 🌱 open-source implementation of [ControlNetInpaint](https://github.com/mikonvergence/ControlNetInpaint) (diffusers-friendly!).')
157
+ gr.Markdown('The tool currently only works with image resolution of 512px.')
158
  gr.Markdown('💡 To learn more about diffusion with interactive code, check out my open-source ⏩[DiffusionFastForward](https://github.com/mikonvergence/DiffusionFastForward) course. It contains example code, executable notebooks, videos, notes, and a few use cases for training from scratch!')
159
 
160
  inputs = [
 
167
  ]
168
 
169
  # STEP 1: Set Mask
170
+ def set_mask(content):
171
+ if content is None:
172
+ gr.Error("You must upload an image first.")
173
+ return {input_image : None,
174
+ sketch_image : None,
175
+ step_1: gr.update(visible=True),
176
+ step_2: gr.update(visible=False)
177
+ }
178
+
179
+ background=np.array(content["image"].convert("RGB").resize((512, 512))) # note: direct numpy seemed buggy
180
+ mask=np.array(content["mask"].convert("RGB").resize((512, 512)))
181
+
182
+ if (mask==0).all():
183
+ gr.Error("You must draw a mask for the cut out first.")
184
+ return {input_image : content['image'],
185
+ sketch_image : None,
186
+ step_1: gr.update(visible=True),
187
+ step_2: gr.update(visible=False)
188
+ }
189
+
190
+ mask=1*(mask>0)
191
  # save vars
192
+ CURRENT_IMAGE['image']=background
193
  CURRENT_IMAGE['mask']=mask
194
 
195
+ guide=get_guide(background)
196
  CURRENT_IMAGE['guide']=np.array(guide)
197
  guide=255-np.asarray(guide)
198
 
199
  seg_img = guide*(1-mask) + mask*192
200
+ preview = background * (seg_img==255)
201
 
202
  vis_image=(preview/2).astype(seg_img.dtype) + seg_img * (seg_img!=255)
203
 
204
+ return {input_image : content["image"],
205
+ sketch_image : vis_image,
206
+ step_1: gr.update(visible=False),
207
+ step_2: gr.update(visible=True)
208
  }
209
 
210
  # STEP 2: Generate
211
+ def generate(content,
212
  prompt,
213
  num_steps,
214
  text_scale,
215
  sketch_scale,
216
  seed):
217
+ sketch=np.array(content["mask"].convert("RGB").resize((512, 512)))
218
+ sketch=(255*(sketch>0)).astype(CURRENT_IMAGE['image'].dtype)
219
  mask=CURRENT_IMAGE['mask']
220
 
221
  CURRENT_IMAGE['guide']=(CURRENT_IMAGE['guide']*(mask==0) + sketch*(mask!=0)).astype(CURRENT_IMAGE['image'].dtype)