File size: 3,152 Bytes
9aa2121 3c3c722 1479050 3c3c722 9aa2121 3c3c722 d0d2317 194e5a4 d0d2317 504d606 d0d2317 1479050 504d606 d0d2317 9aa2121 6012655 6a62aa8 3c3c722 8549916 3c3c722 6a62aa8 3c3c722 206ac15 3c3c722 8549916 3c3c722 6a62aa8 8549916 3c3c722 8549916 3c3c722 9aa2121 d0d2317 3c3c722 d0d2317 6a62aa8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | import os
import gradio as gr
from zeroscratches import EraseScratches
import cv2
import numpy as np
from concurrent.futures import ThreadPoolExecutor
from PIL import Image
# ✅ Custom CSS for clean UI
custom_css = """
/* Dark theme styling */
body, .gradio-container {
background-color: #000000 !important;
color: white !important;
/* Hide fullscreen and share buttons */
button[title="Fullscreen"], button[title="Share"] {
display: none !important;
}
}
/* Styling for buttons */
.gr-button {
background: #1e90ff !important;
color: white !important;
border: none !important;
padding: 10px 20px !important;
font-size: 14px !important;
width: 100% !important;
cursor: pointer;
}
.gr-button:hover {
background: #0056b3 !important;
}
/* Styling for output boxes */
.gr-box, .gr-input, .gr-output {
background-color: #1c1c1c !important;
color: white !important;
border: 1px solid #333333 !important;
}
/* Hide Gradio footer, branding, and header folders */
footer, header, .gradio-footer, .gradio-header,
#footer, #header, #description,
.svelte-1i4i8j8, .svelte-1lcdy9p, .svelte-18k01vx,
.svelte-1qtpyo7, .svelte-1xjlq5, .svelte-1g01jrn,
.svelte-1rs4uyx, .gradio-branding,
#share-btn, #share, #download-btn, #download,
.gradio-flag, .gradio-screenshot,
.gradio-tab, .gradio-tabs,
.gradio-tabs-wrapper,
.gradio-header__space {
display: none !important;
}
/* Remove share button in output box */
.gradio-container .gr-image .share-btn,
.gradio-container .gr-image .share-button,
.gradio-container .gr-image .share {
display: none !important;
}
/* Make images non-draggable */
img {
pointer-events: none !important;
-webkit-user-drag: none !important;
user-select: none !important;
}
"""
# ✅ Optimized image processing function
def predict(img_file):
"""Apply scratch removal with multi-threading"""
with ThreadPoolExecutor(max_workers=4) as executor:
future = executor.submit(process_image, img_file)
restored_img = future.result()
return restored_img
# ✅ Faster image loading and processing
def process_image(img_file):
"""Efficient image loading and restoration"""
# Load image from file path using OpenCV
img_path = img_file.name
img = cv2.imread(img_path)
# Check if image was properly loaded
if img is None:
raise ValueError("Failed to load image")
# Convert to RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Resize large images for faster processing
max_size = (1024, 1024)
img = cv2.resize(img, max_size, interpolation=cv2.INTER_AREA)
# Convert to PIL format for compatibility with zeroscratches
img_pil = Image.fromarray(img)
# Perform scratch removal
restorer = EraseScratches()
restored_img = restorer.erase(img_pil)
return restored_img
# ✅ Gradio Interface
demo = gr.Interface(
fn=predict,
inputs=[gr.File(label="Upload Image")],
outputs=[gr.Image(type="pil", label="Restored Image")],
title="Restore",
css=custom_css
)
# ✅ Launch Gradio app
demo.queue().launch(debug=True)
|