mikonvergence commited on
Commit
159c049
1 Parent(s): b559a46

initial commit

Browse files
Files changed (5) hide show
  1. .gitignore +1 -0
  2. .gitmodules +3 -0
  3. app.py +183 -0
  4. requirements.txt +7 -0
  5. src/ControlNetInpaint +1 -0
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ __pycache__
.gitmodules ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [submodule "src/ControlNetInpaint"]
2
+ path = src/ControlNetInpaint
3
+ url = https://github.com/mikonvergence/ControlNetInpaint.git
app.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # this code is largely inspired by https://huggingface.co/spaces/hysts/ControlNet-with-Anything-v4/blob/main/app_scribble_interactive.py
2
+ # Thank you, hysts!
3
+
4
+ import sys
5
+ sys.path.append('./src/ControlNetInpaint/')
6
+ # functionality based on https://github.com/mikonvergence/ControlNetInpaint
7
+
8
+ import gradio as gr
9
+ #import torch
10
+ #from torch import autocast // only for GPU
11
+
12
+ from PIL import Image
13
+ import numpy as np
14
+ from io import BytesIO
15
+ import os
16
+
17
+ # Usage
18
+ # 1. Upload image or fill with white
19
+ # 2. Sketch the mask (image->[image,mask]
20
+ # 3. Sketch the content of the mask
21
+
22
+ # Global Storage
23
+ CURRENT_IMAGE={'image' : None,
24
+ 'mask' : None,
25
+ 'guide' : None
26
+ }
27
+
28
+ HEIGHT,WIDTH=512,512
29
+
30
+ ## SETUP PIPE
31
+
32
+ from diffusers import StableDiffusionInpaintPipeline, ControlNetModel, UniPCMultistepScheduler
33
+ from src.pipeline_stable_diffusion_controlnet_inpaint import *
34
+ from diffusers.utils import load_image
35
+ from controlnet_aux import HEDdetector
36
+
37
+ hed = HEDdetector.from_pretrained('lllyasviel/ControlNet')
38
+
39
+ controlnet = ControlNetModel.from_pretrained(
40
+ "fusing/stable-diffusion-v1-5-controlnet-scribble", torch_dtype=torch.float16
41
+ )
42
+ pipe = StableDiffusionControlNetInpaintPipeline.from_pretrained(
43
+ "runwayml/stable-diffusion-inpainting", controlnet=controlnet, torch_dtype=torch.float16
44
+ )
45
+
46
+ pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)
47
+
48
+ if torch.cuda.is_available():
49
+ # Remove if you do not have xformers installed
50
+ # see https://huggingface.co/docs/diffusers/v0.13.0/en/optimization/xformers#installing-xformers
51
+ # for installation instructions
52
+ pipe.enable_xformers_memory_efficient_attention()
53
+
54
+ pipe.to('cuda')
55
+
56
+ # Functions
57
+
58
+ def get_guide(image):
59
+ return hed(image,scribble=True)
60
+
61
+ def set_mask(image):
62
+ img=image['image'][...,:3]
63
+ mask=1*(image['mask'][...,:3]>0)
64
+ # save vars
65
+ CURRENT_IMAGE['image']=img
66
+ CURRENT_IMAGE['mask']=mask
67
+
68
+ guide=get_guide(img)
69
+ CURRENT_IMAGE['guide']=np.array(guide)
70
+ guide=255-np.asarray(guide)
71
+
72
+ seg_img = guide*(1-mask) + mask*192
73
+ preview = img * (seg_img==255)
74
+
75
+ vis_image=(preview/2).astype(seg_img.dtype) + seg_img * (seg_img!=255)
76
+
77
+ return vis_image
78
+
79
+ def generate(image,
80
+ prompt,
81
+ num_steps,
82
+ text_scale,
83
+ sketch_scale,
84
+ seed):
85
+
86
+ sketch=(255*(image['mask'][...,:3]>0)).astype(CURRENT_IMAGE['image'].dtype)
87
+ mask=CURRENT_IMAGE['mask']
88
+
89
+ CURRENT_IMAGE['guide']=(CURRENT_IMAGE['guide']*(mask==0) + sketch*(mask!=0)).astype(CURRENT_IMAGE['image'].dtype)
90
+
91
+ mask_img=255*CURRENT_IMAGE['mask'].astype(CURRENT_IMAGE['image'].dtype)
92
+
93
+ new_image = pipe(
94
+ prompt,
95
+ num_inference_steps=num_steps,
96
+ guidance_scale=text_scale,
97
+ generator=torch.manual_seed(seed),
98
+ image=Image.fromarray(CURRENT_IMAGE['image']),
99
+ control_image=Image.fromarray(CURRENT_IMAGE['guide']),
100
+ controlnet_conditioning_scale=sketch_scale,
101
+ mask_image=Image.fromarray(mask_img)
102
+ ).images
103
+
104
+ return new_image
105
+
106
+ def create_demo(max_images=12, default_num_images=3):
107
+
108
+ with gr.Blocks(theme=gr.themes.Default(font=[gr.themes.GoogleFont("IBM Plex Mono"), "ui-monospace","monospace"])
109
+ ) as demo:
110
+ gr.Markdown('## Cut and Sketch ✂️▶️✏️')
111
+ gr.Markdown('**Usage**')
112
+ gr.Markdown('1. Upload your image to the left window')
113
+ gr.Markdown('2. Draw the mask in the left window (Cut ✂️)')
114
+ gr.Markdown('3. Click `Set Mask`')
115
+ gr.Markdown('4. In the right window, sketch a replacement object! (Sketch ✏️)')
116
+ gr.Markdown('5. (You can also provide a text prompt if you want)')
117
+ gr.Markdown('6. 🔮 Click Generate! ')
118
+
119
+ prompt = gr.Textbox(label='Prompt')
120
+
121
+ with gr.Row():
122
+ with gr.Column():
123
+ with gr.Row():
124
+ input_image = gr.Image(source='upload',
125
+ shape=[HEIGHT,WIDTH],
126
+ type='numpy',
127
+ label='Mask Draw',
128
+ tool='sketch',
129
+ brush_radius=70)
130
+ sketch_image = gr.Image(source='upload',
131
+ shape=[HEIGHT,WIDTH],
132
+ type='numpy',
133
+ label='Fill Draw',
134
+ tool='sketch',
135
+ brush_radius=15)
136
+ with gr.Row():
137
+ mask_button = gr.Button(label='Set Mask', value='Set Mask')
138
+ run_button = gr.Button(label='Generate', value='Generate')
139
+ output_image = gr.Gallery(
140
+ label="Generated images",
141
+ show_label=False,
142
+ elem_id="gallery",
143
+ )
144
+
145
+ with gr.Accordion('Advanced options', open=False):
146
+ num_steps = gr.Slider(label='Steps',
147
+ minimum=1,
148
+ maximum=100,
149
+ value=20,
150
+ step=1)
151
+ text_scale = gr.Slider(label='Text Guidance Scale',
152
+ minimum=0.1,
153
+ maximum=30.0,
154
+ value=7.5,
155
+ step=0.1)
156
+ seed = gr.Slider(label='Seed',
157
+ minimum=-1,
158
+ maximum=2147483647,
159
+ step=1,
160
+ randomize=True)
161
+
162
+ sketch_scale = gr.Slider(label='Sketch Guidance Scale',
163
+ minimum=0.0,
164
+ maximum=1.0,
165
+ value=1.0,
166
+ step=0.05)
167
+
168
+ inputs = [
169
+ sketch_image,
170
+ prompt,
171
+ num_steps,
172
+ text_scale,
173
+ sketch_scale,
174
+ seed
175
+ ]
176
+
177
+ mask_button.click(fn=set_mask, inputs=input_image, outputs=sketch_image)
178
+ run_button.click(fn=generate, inputs=inputs, outputs=output_image)
179
+ return demo
180
+
181
+ if __name__ == '__main__':
182
+ demo = create_demo()
183
+ demo.queue().launch()
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ diffusers
2
+ xformers
3
+ transformers
4
+ scipy
5
+ ftfy
6
+ accelerate
7
+ controlnet_aux
src/ControlNetInpaint ADDED
@@ -0,0 +1 @@
 
 
1
+ Subproject commit f33c386fe81d226dc50d4344c509288a1bcca7a2