Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -180,10 +180,19 @@ def prepare_image(image, max_size=MAX_INPUT_SIZE):
|
|
180 |
return image
|
181 |
|
182 |
|
183 |
-
def esrgan_upscale(image, model, device='cuda'):
|
184 |
-
"""Upscale image
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
# Prepare image
|
186 |
-
img_np = np.array(
|
187 |
img_np = np.transpose(img_np, (2, 0, 1)) # HWC to CHW
|
188 |
img_tensor = torch.from_numpy(img_np).unsqueeze(0).to(device)
|
189 |
|
@@ -195,10 +204,18 @@ def esrgan_upscale(image, model, device='cuda'):
|
|
195 |
output_np = np.transpose(output_np, (1, 2, 0)) # CHW to HWC
|
196 |
output_np = (output_np * 255).astype(np.uint8)
|
197 |
|
198 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
|
200 |
|
201 |
-
@spaces.GPU(duration=
|
202 |
def enhance_image(
|
203 |
input_image,
|
204 |
prompt,
|
@@ -206,6 +223,7 @@ def enhance_image(
|
|
206 |
randomize_seed,
|
207 |
num_inference_steps,
|
208 |
denoising_strength,
|
|
|
209 |
progress=gr.Progress(track_tqdm=True),
|
210 |
):
|
211 |
"""Main enhancement function"""
|
@@ -228,12 +246,12 @@ def enhance_image(
|
|
228 |
input_image = prepare_image(input_image)
|
229 |
original_size = input_image.size
|
230 |
|
231 |
-
# Step 1: ESRGAN upscale
|
232 |
-
gr.Info("π Upscaling with ESRGAN
|
233 |
|
234 |
# Move ESRGAN to GPU for faster processing
|
235 |
esrgan_model.to("cuda")
|
236 |
-
upscaled_image = esrgan_upscale(input_image, esrgan_model, device="cuda")
|
237 |
|
238 |
# Move ESRGAN back to CPU to free memory
|
239 |
esrgan_model.to("cpu")
|
@@ -299,9 +317,9 @@ def enhance_image(
|
|
299 |
with gr.Blocks(css=css) as demo:
|
300 |
gr.HTML("""
|
301 |
<div class="main-header">
|
302 |
-
<h1>π
|
303 |
-
<p>Upload an image to upscale 4x with ESRGAN and enhance with FLUX</p>
|
304 |
-
<p>Optimized for <strong>ZeroGPU</strong> | Max input: 512x512 β Output: 2048x2048</p>
|
305 |
</div>
|
306 |
""")
|
307 |
|
@@ -315,46 +333,52 @@ with gr.Blocks(css=css) as demo:
|
|
315 |
)
|
316 |
|
317 |
prompt = gr.Textbox(
|
318 |
-
label="
|
319 |
placeholder="Describe the desired enhancement (e.g., 'high quality, sharp details, vibrant colors')",
|
320 |
value="high quality, ultra detailed, sharp",
|
321 |
lines=2
|
322 |
)
|
323 |
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
332 |
)
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
minimum=0.1,
|
337 |
-
maximum=0.6,
|
338 |
-
step=0.05,
|
339 |
-
value=0.35,
|
340 |
-
info="Higher = more changes to the image"
|
341 |
)
|
342 |
-
|
343 |
-
with gr.Row():
|
344 |
-
randomize_seed = gr.Checkbox(
|
345 |
-
label="Randomize seed",
|
346 |
-
value=True
|
347 |
-
)
|
348 |
-
seed = gr.Slider(
|
349 |
-
label="Seed",
|
350 |
-
minimum=0,
|
351 |
-
maximum=MAX_SEED,
|
352 |
-
step=1,
|
353 |
-
value=42
|
354 |
-
)
|
355 |
|
356 |
enhance_btn = gr.Button(
|
357 |
-
"
|
358 |
variant="primary",
|
359 |
size="lg"
|
360 |
)
|
@@ -374,18 +398,6 @@ with gr.Blocks(css=css) as demo:
|
|
374 |
visible=False
|
375 |
)
|
376 |
|
377 |
-
# Examples
|
378 |
-
gr.Examples(
|
379 |
-
examples=[
|
380 |
-
["high quality, ultra detailed, sharp"],
|
381 |
-
["cinematic, professional photography, enhanced details"],
|
382 |
-
["vibrant colors, high contrast, sharp focus"],
|
383 |
-
["photorealistic, 8k quality, fine details"],
|
384 |
-
],
|
385 |
-
inputs=[prompt],
|
386 |
-
label="Example Prompts"
|
387 |
-
)
|
388 |
-
|
389 |
# Event handler
|
390 |
enhance_btn.click(
|
391 |
fn=enhance_image,
|
@@ -396,14 +408,16 @@ with gr.Blocks(css=css) as demo:
|
|
396 |
randomize_seed,
|
397 |
num_inference_steps,
|
398 |
denoising_strength,
|
|
|
399 |
],
|
400 |
outputs=[result_slider, used_seed]
|
401 |
)
|
402 |
|
403 |
gr.HTML("""
|
404 |
<div style="margin-top: 2rem; text-align: center; color: #666;">
|
405 |
-
<p>π Pipeline: ESRGAN 4x-UltraSharp β FLUX Dev Enhancement</p>
|
406 |
<p>β‘ Optimized for ZeroGPU with automatic memory management</p>
|
|
|
407 |
</div>
|
408 |
""")
|
409 |
|
|
|
180 |
return image
|
181 |
|
182 |
|
183 |
+
def esrgan_upscale(image, model, device='cuda', upscale_factor=4):
|
184 |
+
"""Upscale image using ESRGAN with variable factor support"""
|
185 |
+
orig_w, orig_h = image.size
|
186 |
+
pre_resize_factor = upscale_factor / 4.0
|
187 |
+
low_res_w = int(orig_w * pre_resize_factor)
|
188 |
+
low_res_h = int(orig_h * pre_resize_factor)
|
189 |
+
if low_res_w < 1 or low_res_h < 1:
|
190 |
+
raise ValueError("Upscale factor too small for image size")
|
191 |
+
|
192 |
+
low_res_image = image.resize((low_res_w, low_res_h), Image.LANCZOS)
|
193 |
+
|
194 |
# Prepare image
|
195 |
+
img_np = np.array(low_res_image).astype(np.float32) / 255.
|
196 |
img_np = np.transpose(img_np, (2, 0, 1)) # HWC to CHW
|
197 |
img_tensor = torch.from_numpy(img_np).unsqueeze(0).to(device)
|
198 |
|
|
|
204 |
output_np = np.transpose(output_np, (1, 2, 0)) # CHW to HWC
|
205 |
output_np = (output_np * 255).astype(np.uint8)
|
206 |
|
207 |
+
upscaled = Image.fromarray(output_np)
|
208 |
+
|
209 |
+
# Resize back to exact target size if needed (due to rounding)
|
210 |
+
target_w = int(orig_w * upscale_factor)
|
211 |
+
target_h = int(orig_h * upscale_factor)
|
212 |
+
if upscaled.size != (target_w, target_h):
|
213 |
+
upscaled = upscaled.resize((target_w, target_h), Image.LANCZOS)
|
214 |
+
|
215 |
+
return upscaled
|
216 |
|
217 |
|
218 |
+
@spaces.GPU(duration=120) # Increased to 120 seconds
|
219 |
def enhance_image(
|
220 |
input_image,
|
221 |
prompt,
|
|
|
223 |
randomize_seed,
|
224 |
num_inference_steps,
|
225 |
denoising_strength,
|
226 |
+
upscale_factor,
|
227 |
progress=gr.Progress(track_tqdm=True),
|
228 |
):
|
229 |
"""Main enhancement function"""
|
|
|
246 |
input_image = prepare_image(input_image)
|
247 |
original_size = input_image.size
|
248 |
|
249 |
+
# Step 1: ESRGAN upscale on GPU
|
250 |
+
gr.Info(f"π Upscaling with ESRGAN x{upscale_factor}...")
|
251 |
|
252 |
# Move ESRGAN to GPU for faster processing
|
253 |
esrgan_model.to("cuda")
|
254 |
+
upscaled_image = esrgan_upscale(input_image, esrgan_model, device="cuda", upscale_factor=upscale_factor)
|
255 |
|
256 |
# Move ESRGAN back to CPU to free memory
|
257 |
esrgan_model.to("cpu")
|
|
|
317 |
with gr.Blocks(css=css) as demo:
|
318 |
gr.HTML("""
|
319 |
<div class="main-header">
|
320 |
+
<h1>π Flux Dev Ultimate Upscaler</h1>
|
321 |
+
<p>Upload an image to upscale 2-4x with ESRGAN and enhance with FLUX</p>
|
322 |
+
<p>Optimized for <strong>ZeroGPU</strong> | Max input: 512x512 β Output: up to 2048x2048</p>
|
323 |
</div>
|
324 |
""")
|
325 |
|
|
|
333 |
)
|
334 |
|
335 |
prompt = gr.Textbox(
|
336 |
+
label="Describe image with prompt",
|
337 |
placeholder="Describe the desired enhancement (e.g., 'high quality, sharp details, vibrant colors')",
|
338 |
value="high quality, ultra detailed, sharp",
|
339 |
lines=2
|
340 |
)
|
341 |
|
342 |
+
# Advanced Settings (always open)
|
343 |
+
upscale_factor = gr.Slider(
|
344 |
+
label="Upscale Ratio",
|
345 |
+
minimum=2,
|
346 |
+
maximum=4,
|
347 |
+
step=1,
|
348 |
+
value=4,
|
349 |
+
info="Choose upscale factor (2x, 3x, 4x)"
|
350 |
+
)
|
351 |
+
|
352 |
+
num_inference_steps = gr.Slider(
|
353 |
+
label="Enhancement Steps",
|
354 |
+
minimum=10,
|
355 |
+
maximum=25,
|
356 |
+
step=1,
|
357 |
+
value=18,
|
358 |
+
info="More steps = better quality but slower"
|
359 |
+
)
|
360 |
+
|
361 |
+
denoising_strength = gr.Slider(
|
362 |
+
label="Creativity (Denoising)",
|
363 |
+
minimum=0.1,
|
364 |
+
maximum=0.6,
|
365 |
+
step=0.05,
|
366 |
+
value=0.35,
|
367 |
+
info="Higher = more changes to the image"
|
368 |
+
)
|
369 |
+
|
370 |
+
with gr.Row():
|
371 |
+
randomize_seed = gr.Checkbox(
|
372 |
+
label="Randomize seed",
|
373 |
+
value=True
|
374 |
)
|
375 |
+
seed = gr.Number(
|
376 |
+
label="Seed",
|
377 |
+
value=42
|
|
|
|
|
|
|
|
|
|
|
378 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
|
380 |
enhance_btn = gr.Button(
|
381 |
+
"Upscale",
|
382 |
variant="primary",
|
383 |
size="lg"
|
384 |
)
|
|
|
398 |
visible=False
|
399 |
)
|
400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
# Event handler
|
402 |
enhance_btn.click(
|
403 |
fn=enhance_image,
|
|
|
408 |
randomize_seed,
|
409 |
num_inference_steps,
|
410 |
denoising_strength,
|
411 |
+
upscale_factor,
|
412 |
],
|
413 |
outputs=[result_slider, used_seed]
|
414 |
)
|
415 |
|
416 |
gr.HTML("""
|
417 |
<div style="margin-top: 2rem; text-align: center; color: #666;">
|
418 |
+
<p>π Pipeline: ESRGAN 2-4x-UltraSharp β FLUX Dev Enhancement</p>
|
419 |
<p>β‘ Optimized for ZeroGPU with automatic memory management</p>
|
420 |
+
<p>π Note: User is responsible for obtaining commercial license from Flux Dev if using image commercially under their license.</p>
|
421 |
</div>
|
422 |
""")
|
423 |
|