kevinantony commited on
Commit
f275585
·
verified ·
1 Parent(s): c7ea5d6

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +240 -0
app.py ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Tuple
2
+
3
+ import requests
4
+ import random
5
+ import numpy as np
6
+ import gradio as gr
7
+ import spaces
8
+ import torch
9
+ from PIL import Image
10
+ from diffusers import FluxInpaintPipeline
11
+
12
+ torch.cuda.empty_cache()
13
+
14
+ MARKDOWN = """
15
+ # FLUX Inpainting
16
+ Model used FLUX.1-schnell.
17
+ """
18
+
19
+ MAX_SEED = np.iinfo(np.int32).max
20
+ IMAGE_SIZE = 512
21
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
22
+
23
+
24
+ def remove_background(image: Image.Image, threshold: int = 50) -> Image.Image:
25
+ image = image.convert("RGBA")
26
+ data = image.getdata()
27
+ new_data = []
28
+ for item in data:
29
+ avg = sum(item[:3]) / 3
30
+ if avg < threshold:
31
+ new_data.append((0, 0, 0, 0))
32
+ else:
33
+ new_data.append(item)
34
+
35
+ image.putdata(new_data)
36
+ return image
37
+
38
+
39
+ # EXAMPLES = [
40
+ # [
41
+ # {
42
+ # "background": Image.open(requests.get("https://media.roboflow.com/spaces/doge-2-image.png", stream=True).raw),
43
+ # "layers": [remove_background(Image.open(requests.get("https://media.roboflow.com/spaces/doge-2-mask-2.png", stream=True).raw))],
44
+ # "composite": Image.open(requests.get("https://media.roboflow.com/spaces/doge-2-composite-2.png", stream=True).raw),
45
+ # },
46
+ # "little lion",
47
+ # 42,
48
+ # False,
49
+ # 0.85,
50
+ # 30
51
+ # ],
52
+ # [
53
+ # {
54
+ # "background": Image.open(requests.get("https://media.roboflow.com/spaces/doge-2-image.png", stream=True).raw),
55
+ # "layers": [remove_background(Image.open(requests.get("https://media.roboflow.com/spaces/doge-2-mask-3.png", stream=True).raw))],
56
+ # "composite": Image.open(requests.get("https://media.roboflow.com/spaces/doge-2-composite-3.png", stream=True).raw),
57
+ # },
58
+ # "tribal tattoos",
59
+ # 42,
60
+ # False,
61
+ # 0.85,
62
+ # 30
63
+ # ]
64
+ # ]
65
+
66
+ pipe = FluxInpaintPipeline.from_pretrained(
67
+ "black-forest-labs/FLUX.1-schnell", torch_dtype=torch.bfloat16).to(DEVICE)
68
+
69
+
70
+ def resize_image_dimensions(
71
+ original_resolution_wh: Tuple[int, int],
72
+ maximum_dimension: int = IMAGE_SIZE
73
+ ) -> Tuple[int, int]:
74
+ width, height = original_resolution_wh
75
+
76
+ # if width <= maximum_dimension and height <= maximum_dimension:
77
+ # width = width - (width % 32)
78
+ # height = height - (height % 32)
79
+ # return width, height
80
+
81
+ if width > height:
82
+ scaling_factor = maximum_dimension / width
83
+ else:
84
+ scaling_factor = maximum_dimension / height
85
+
86
+ new_width = int(width * scaling_factor)
87
+ new_height = int(height * scaling_factor)
88
+
89
+ new_width = new_width - (new_width % 32)
90
+ new_height = new_height - (new_height % 32)
91
+
92
+ return new_width, new_height
93
+
94
+
95
+ @spaces.GPU(duration=100)
96
+ def process(
97
+ input_image_editor: dict,
98
+ input_text: str,
99
+ seed_slicer: int,
100
+ randomize_seed_checkbox: bool,
101
+ strength_slider: float,
102
+ num_inference_steps_slider: int,
103
+ progress=gr.Progress(track_tqdm=True)
104
+ ):
105
+ if not input_text:
106
+ gr.Info("Please enter a text prompt.")
107
+ return None, None
108
+
109
+ image = input_image_editor['background']
110
+ mask = input_image_editor['layers'][0]
111
+
112
+ if not image:
113
+ gr.Info("Please upload an image.")
114
+ return None, None
115
+
116
+ if not mask:
117
+ gr.Info("Please draw a mask on the image.")
118
+ return None, None
119
+
120
+ width, height = resize_image_dimensions(original_resolution_wh=image.size)
121
+ resized_image = image.resize((width, height), Image.LANCZOS)
122
+ resized_mask = mask.resize((width, height), Image.LANCZOS)
123
+
124
+ if randomize_seed_checkbox:
125
+ seed_slicer = random.randint(0, MAX_SEED)
126
+ generator = torch.Generator().manual_seed(seed_slicer)
127
+ with torch.no_grad(), torch.autocast("cuda"):
128
+ result = pipe(
129
+ prompt=input_text,
130
+ image=resized_image,
131
+ mask_image=resized_mask,
132
+ width=width,
133
+ height=height,
134
+ strength=strength_slider,
135
+ generator=generator,
136
+ num_inference_steps=num_inference_steps_slider
137
+ ).images[0]
138
+ torch.cuda.empty_cache()
139
+ return result, resized_mask
140
+
141
+
142
+ with gr.Blocks() as demo:
143
+ gr.Markdown(MARKDOWN)
144
+ with gr.Row():
145
+ with gr.Column():
146
+ input_image_editor_component = gr.ImageEditor(
147
+ label='Image',
148
+ type='pil',
149
+ sources=["upload", "webcam"],
150
+ image_mode='RGB',
151
+ layers=False,
152
+ brush=gr.Brush(colors=["#FFFFFF"], color_mode="fixed"))
153
+
154
+ with gr.Row():
155
+ input_text_component = gr.Text(
156
+ label="Prompt",
157
+ show_label=False,
158
+ max_lines=1,
159
+ placeholder="Enter your prompt",
160
+ container=False,
161
+ )
162
+ submit_button_component = gr.Button(
163
+ value='Submit', variant='primary', scale=0)
164
+
165
+ with gr.Accordion("Advanced Settings", open=False):
166
+ seed_slicer_component = gr.Slider(
167
+ label="Seed",
168
+ minimum=0,
169
+ maximum=MAX_SEED,
170
+ step=1,
171
+ value=42,
172
+ )
173
+
174
+ randomize_seed_checkbox_component = gr.Checkbox(
175
+ label="Randomize seed", value=True)
176
+
177
+ with gr.Row():
178
+ strength_slider_component = gr.Slider(
179
+ label="Strength",
180
+ # info="Indicates extent to transform the reference `image`. "
181
+ # "Must be between 0 and 1. `image` is used as a starting "
182
+ # "point and more noise is added the higher the `strength`.",
183
+ minimum=0,
184
+ maximum=1,
185
+ step=0.01,
186
+ value=0.85,
187
+ )
188
+
189
+ num_inference_steps_slider_component = gr.Slider(
190
+ label="Number of inference steps",
191
+ # info="The number of denoising steps. More denoising steps "
192
+ # "usually lead to a higher quality image at the",
193
+ minimum=1,
194
+ maximum=20,
195
+ step=1,
196
+ value=20,
197
+ )
198
+ with gr.Column():
199
+ output_image_component = gr.Image(
200
+ type='pil', image_mode='RGB', label='Generated image', format="png")
201
+ with gr.Accordion("Debug", open=False):
202
+ output_mask_component = gr.Image(
203
+ type='pil', image_mode='RGB', label='Input mask', format="png")
204
+ # with gr.Row():
205
+ # gr.Examples(
206
+ # fn=process,
207
+ # examples=EXAMPLES,
208
+ # inputs=[
209
+ # input_image_editor_component,
210
+ # input_text_component,
211
+ # seed_slicer_component,
212
+ # randomize_seed_checkbox_component,
213
+ # strength_slider_component,
214
+ # num_inference_steps_slider_component
215
+ # ],
216
+ # outputs=[
217
+ # output_image_component,
218
+ # output_mask_component
219
+ # ],
220
+ # run_on_click=True,
221
+ # cache_examples=True
222
+ # )
223
+
224
+ submit_button_component.click(
225
+ fn=process,
226
+ inputs=[
227
+ input_image_editor_component,
228
+ input_text_component,
229
+ seed_slicer_component,
230
+ randomize_seed_checkbox_component,
231
+ strength_slider_component,
232
+ num_inference_steps_slider_component
233
+ ],
234
+ outputs=[
235
+ output_image_component,
236
+ output_mask_component
237
+ ]
238
+ )
239
+
240
+ demo.launch(debug=False, show_error=True)