Update app.py
Browse files
app.py
CHANGED
|
@@ -114,6 +114,9 @@ def load_generator(model_name):
|
|
| 114 |
def inference_image(img_path, model_name):
|
| 115 |
"""Process a single image"""
|
| 116 |
try:
|
|
|
|
|
|
|
|
|
|
| 117 |
generator = load_generator(model_name)
|
| 118 |
|
| 119 |
print("Processing image:", img_path)
|
|
@@ -141,7 +144,7 @@ def inference_image(img_path, model_name):
|
|
| 141 |
return outputs, f"β
Saved to: {output_path}"
|
| 142 |
|
| 143 |
except Exception as error:
|
| 144 |
-
|
| 145 |
|
| 146 |
|
| 147 |
def process_video_frame_by_frame(video_path, model_name, task_id):
|
|
@@ -292,7 +295,7 @@ def clear_history():
|
|
| 292 |
"""Clear all history"""
|
| 293 |
if os.path.exists(HISTORY_FILE):
|
| 294 |
os.remove(HISTORY_FILE)
|
| 295 |
-
return "β
History cleared!"
|
| 296 |
|
| 297 |
|
| 298 |
if __name__ == '__main__':
|
|
@@ -301,20 +304,20 @@ if __name__ == '__main__':
|
|
| 301 |
worker_thread = threading.Thread(target=video_queue_worker, daemon=True)
|
| 302 |
worker_thread.start()
|
| 303 |
|
| 304 |
-
MARKDOWN =
|
| 305 |
-
|
| 306 |
-
## <p style='text-align: center'> APISR: Anime Production Inspired Real-World Anime Super-Resolution (CVPR 2024) </p>
|
| 307 |
-
|
| 308 |
-
[GitHub](https://github.com/Kiteretsu77/APISR) | [Paper](https://arxiv.org/abs/2403.01598)
|
| 309 |
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
### πΉ New: Video processing runs in background queue - you can close the browser and it continues!
|
| 314 |
-
"""
|
| 315 |
|
| 316 |
-
|
| 317 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 318 |
gr.Markdown(MARKDOWN)
|
| 319 |
|
| 320 |
with gr.Tabs():
|
|
@@ -324,7 +327,7 @@ if __name__ == '__main__':
|
|
| 324 |
with gr.Column(scale=2):
|
| 325 |
input_image = gr.Image(type="filepath", label="Input Image")
|
| 326 |
image_model = gr.Dropdown(
|
| 327 |
-
["2xRRDB", "4xRRDB", "4xGRL", "4xDAT"],
|
| 328 |
value="4xGRL",
|
| 329 |
label="Model"
|
| 330 |
)
|
|
@@ -336,17 +339,17 @@ if __name__ == '__main__':
|
|
| 336 |
|
| 337 |
with gr.Row():
|
| 338 |
gr.Examples(
|
| 339 |
-
[
|
| 340 |
["__assets__/lr_inputs/image-00277.png"],
|
| 341 |
["__assets__/lr_inputs/image-00542.png"],
|
| 342 |
["__assets__/lr_inputs/41.png"],
|
| 343 |
["__assets__/lr_inputs/f91.jpg"],
|
| 344 |
],
|
| 345 |
-
[input_image],
|
| 346 |
)
|
| 347 |
|
| 348 |
image_btn.click(
|
| 349 |
-
inference_image,
|
| 350 |
inputs=[input_image, image_model],
|
| 351 |
outputs=[output_image, image_status]
|
| 352 |
)
|
|
@@ -362,7 +365,7 @@ if __name__ == '__main__':
|
|
| 362 |
with gr.Column():
|
| 363 |
input_video = gr.Video(label="Input Video")
|
| 364 |
video_model = gr.Dropdown(
|
| 365 |
-
["2xRRDB", "4xRRDB", "4xGRL", "4xDAT"],
|
| 366 |
value="4xGRL",
|
| 367 |
label="Model"
|
| 368 |
)
|
|
@@ -371,19 +374,22 @@ if __name__ == '__main__':
|
|
| 371 |
|
| 372 |
with gr.Column():
|
| 373 |
gr.Markdown("### π Queue Monitor")
|
| 374 |
-
queue_status = gr.Textbox(label="Queue Status", lines=15)
|
| 375 |
refresh_btn = gr.Button("π Refresh Status")
|
| 376 |
|
| 377 |
video_btn.click(
|
| 378 |
-
submit_video,
|
| 379 |
inputs=[input_video, video_model],
|
| 380 |
outputs=[input_video, video_status]
|
| 381 |
)
|
| 382 |
|
| 383 |
refresh_btn.click(
|
| 384 |
-
get_queue_status,
|
| 385 |
outputs=[queue_status]
|
| 386 |
)
|
|
|
|
|
|
|
|
|
|
| 387 |
|
| 388 |
# Tab 3: History
|
| 389 |
with gr.Tab("π History"):
|
|
@@ -393,20 +399,26 @@ if __name__ == '__main__':
|
|
| 393 |
refresh_history_btn = gr.Button("π Refresh History")
|
| 394 |
clear_history_btn = gr.Button("ποΈ Clear History", variant="stop")
|
| 395 |
|
| 396 |
-
history_display = gr.Textbox(label="History", lines=20)
|
| 397 |
-
clear_status = gr.Textbox(label="Status", lines=1)
|
| 398 |
|
| 399 |
refresh_history_btn.click(
|
| 400 |
-
get_history_display,
|
| 401 |
outputs=[history_display]
|
| 402 |
)
|
| 403 |
|
| 404 |
clear_history_btn.click(
|
| 405 |
-
clear_history,
|
| 406 |
-
outputs=[clear_status]
|
| 407 |
)
|
| 408 |
|
| 409 |
-
# Auto-load history on
|
| 410 |
-
|
| 411 |
-
|
| 412 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
def inference_image(img_path, model_name):
|
| 115 |
"""Process a single image"""
|
| 116 |
try:
|
| 117 |
+
if img_path is None:
|
| 118 |
+
return None, "β Please upload an image first"
|
| 119 |
+
|
| 120 |
generator = load_generator(model_name)
|
| 121 |
|
| 122 |
print("Processing image:", img_path)
|
|
|
|
| 144 |
return outputs, f"β
Saved to: {output_path}"
|
| 145 |
|
| 146 |
except Exception as error:
|
| 147 |
+
return None, f"β Error: {str(error)}"
|
| 148 |
|
| 149 |
|
| 150 |
def process_video_frame_by_frame(video_path, model_name, task_id):
|
|
|
|
| 295 |
"""Clear all history"""
|
| 296 |
if os.path.exists(HISTORY_FILE):
|
| 297 |
os.remove(HISTORY_FILE)
|
| 298 |
+
return "β
History cleared!", get_history_display()
|
| 299 |
|
| 300 |
|
| 301 |
if __name__ == '__main__':
|
|
|
|
| 304 |
worker_thread = threading.Thread(target=video_queue_worker, daemon=True)
|
| 305 |
worker_thread.start()
|
| 306 |
|
| 307 |
+
MARKDOWN = """
|
| 308 |
+
# APISR: Anime Production Inspired Real-World Anime Super-Resolution (CVPR 2024)
|
|
|
|
|
|
|
|
|
|
| 309 |
|
| 310 |
+
[GitHub](https://github.com/Kiteretsu77/APISR) | [Paper](https://arxiv.org/abs/2403.01598)
|
| 311 |
+
|
| 312 |
+
APISR aims at restoring and enhancing low-quality low-resolution **anime** images and video sources with various degradations from real-world scenarios.
|
|
|
|
|
|
|
| 313 |
|
| 314 |
+
### β οΈ Note: Images with short side > 720px will be downsampled to 720px (e.g., 1920x1080 β 1280x720)
|
| 315 |
+
### πΉ New: Video processing runs in background queue - you can close the browser and it continues!
|
| 316 |
+
"""
|
| 317 |
+
|
| 318 |
+
# Create Gradio interface with Gradio 5.x/6.x syntax
|
| 319 |
+
with gr.Blocks(title="APISR - Anime Super Resolution", theme=gr.themes.Soft()) as demo:
|
| 320 |
+
|
| 321 |
gr.Markdown(MARKDOWN)
|
| 322 |
|
| 323 |
with gr.Tabs():
|
|
|
|
| 327 |
with gr.Column(scale=2):
|
| 328 |
input_image = gr.Image(type="filepath", label="Input Image")
|
| 329 |
image_model = gr.Dropdown(
|
| 330 |
+
choices=["2xRRDB", "4xRRDB", "4xGRL", "4xDAT"],
|
| 331 |
value="4xGRL",
|
| 332 |
label="Model"
|
| 333 |
)
|
|
|
|
| 339 |
|
| 340 |
with gr.Row():
|
| 341 |
gr.Examples(
|
| 342 |
+
examples=[
|
| 343 |
["__assets__/lr_inputs/image-00277.png"],
|
| 344 |
["__assets__/lr_inputs/image-00542.png"],
|
| 345 |
["__assets__/lr_inputs/41.png"],
|
| 346 |
["__assets__/lr_inputs/f91.jpg"],
|
| 347 |
],
|
| 348 |
+
inputs=[input_image],
|
| 349 |
)
|
| 350 |
|
| 351 |
image_btn.click(
|
| 352 |
+
fn=inference_image,
|
| 353 |
inputs=[input_image, image_model],
|
| 354 |
outputs=[output_image, image_status]
|
| 355 |
)
|
|
|
|
| 365 |
with gr.Column():
|
| 366 |
input_video = gr.Video(label="Input Video")
|
| 367 |
video_model = gr.Dropdown(
|
| 368 |
+
choices=["2xRRDB", "4xRRDB", "4xGRL", "4xDAT"],
|
| 369 |
value="4xGRL",
|
| 370 |
label="Model"
|
| 371 |
)
|
|
|
|
| 374 |
|
| 375 |
with gr.Column():
|
| 376 |
gr.Markdown("### π Queue Monitor")
|
| 377 |
+
queue_status = gr.Textbox(label="Queue Status", lines=15, interactive=False)
|
| 378 |
refresh_btn = gr.Button("π Refresh Status")
|
| 379 |
|
| 380 |
video_btn.click(
|
| 381 |
+
fn=submit_video,
|
| 382 |
inputs=[input_video, video_model],
|
| 383 |
outputs=[input_video, video_status]
|
| 384 |
)
|
| 385 |
|
| 386 |
refresh_btn.click(
|
| 387 |
+
fn=get_queue_status,
|
| 388 |
outputs=[queue_status]
|
| 389 |
)
|
| 390 |
+
|
| 391 |
+
# Auto-refresh every 5 seconds
|
| 392 |
+
demo.load(fn=get_queue_status, outputs=[queue_status], every=5)
|
| 393 |
|
| 394 |
# Tab 3: History
|
| 395 |
with gr.Tab("π History"):
|
|
|
|
| 399 |
refresh_history_btn = gr.Button("π Refresh History")
|
| 400 |
clear_history_btn = gr.Button("ποΈ Clear History", variant="stop")
|
| 401 |
|
| 402 |
+
history_display = gr.Textbox(label="History", lines=20, interactive=False)
|
| 403 |
+
clear_status = gr.Textbox(label="Status", lines=1, visible=True)
|
| 404 |
|
| 405 |
refresh_history_btn.click(
|
| 406 |
+
fn=get_history_display,
|
| 407 |
outputs=[history_display]
|
| 408 |
)
|
| 409 |
|
| 410 |
clear_history_btn.click(
|
| 411 |
+
fn=clear_history,
|
| 412 |
+
outputs=[clear_status, history_display]
|
| 413 |
)
|
| 414 |
|
| 415 |
+
# Auto-load history on page load
|
| 416 |
+
demo.load(fn=get_history_display, outputs=[history_display])
|
| 417 |
+
|
| 418 |
+
# Launch the app
|
| 419 |
+
demo.queue(max_size=20)
|
| 420 |
+
demo.launch(
|
| 421 |
+
server_name="0.0.0.0",
|
| 422 |
+
server_port=7860,
|
| 423 |
+
share=False
|
| 424 |
+
)
|