Upload 2 files
Browse files- app.py +33 -23
- requirements.txt +3 -2
app.py
CHANGED
|
@@ -21,9 +21,13 @@ from diffusers import FluxInpaintPipeline
|
|
| 21 |
from transformers import BlipProcessor, BlipForConditionalGeneration
|
| 22 |
from spandrel import ModelLoader, ImageModelDescriptor
|
| 23 |
from huggingface_hub import hf_hub_download
|
| 24 |
-
import
|
|
|
|
|
|
|
| 25 |
from skimage.metrics import peak_signal_noise_ratio as psnr
|
| 26 |
from skimage.metrics import structural_similarity as ssim
|
|
|
|
|
|
|
| 27 |
|
| 28 |
# ================================================================
|
| 29 |
# 5. LOAD ALL MODELS AT STARTUP (no lazy loading)
|
|
@@ -64,10 +68,14 @@ esrgan_model.to("cuda").eval()
|
|
| 64 |
ESRGAN_SCALE = int(esrgan_model.scale)
|
| 65 |
print("Enhancement model loaded. Scale factor:", ESRGAN_SCALE)
|
| 66 |
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
print("✅ DDColor loaded.")
|
| 72 |
|
| 73 |
print("✅ All models loaded. Starting Gradio interface...")
|
|
@@ -320,32 +328,32 @@ def enhance_image(image, scale_factor, benchmark_mode=False):
|
|
| 320 |
|
| 321 |
return output_image, info
|
| 322 |
|
| 323 |
-
# ================================================================
|
| 324 |
-
# 9. COLORIZATION (uses pre-loaded ddcolor_pipe)
|
| 325 |
-
# ================================================================
|
| 326 |
def colorize_ddcolor(image_rgb: np.ndarray) -> np.ndarray:
|
|
|
|
| 327 |
h, w = image_rgb.shape[:2]
|
| 328 |
img_float = image_rgb.astype(np.float32) / 255.0
|
| 329 |
l_orig = cv2.cvtColor(img_float, cv2.COLOR_RGB2Lab)[:, :, :1]
|
| 330 |
|
| 331 |
l_resized = cv2.resize(l_orig, (512, 512), interpolation=cv2.INTER_AREA)
|
| 332 |
-
l_resized = l_resized.reshape(512, 512, 1)
|
| 333 |
-
|
| 334 |
gray_lab = np.concatenate([l_resized, np.zeros_like(l_resized), np.zeros_like(l_resized)], axis=-1)
|
| 335 |
gray_rgb = cv2.cvtColor(gray_lab, cv2.COLOR_LAB2RGB)
|
| 336 |
-
input_tensor = gray_rgb.transpose(2, 0, 1)[np.newaxis, ...]
|
| 337 |
|
| 338 |
-
|
| 339 |
-
|
| 340 |
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
|
|
|
|
|
|
|
|
|
| 345 |
|
| 346 |
lab_out = np.concatenate([l_orig, a, b], axis=-1)
|
| 347 |
out_rgb = cv2.cvtColor(lab_out, cv2.COLOR_LAB2RGB)
|
| 348 |
-
return (out_rgb * 255).clip(0, 255).astype(np.uint8)
|
|
|
|
| 349 |
|
| 350 |
@spaces.GPU(duration=58)
|
| 351 |
def colour_image(image, strength):
|
|
@@ -356,11 +364,13 @@ def colour_image(image, strength):
|
|
| 356 |
small = rgb.copy()
|
| 357 |
small.thumbnail((768, 768), Image.LANCZOS)
|
| 358 |
|
| 359 |
-
#
|
| 360 |
-
|
| 361 |
-
|
|
|
|
| 362 |
|
| 363 |
-
#
|
|
|
|
| 364 |
lab_c = cv2.cvtColor(np.asarray(coloured_full), cv2.COLOR_RGB2LAB)
|
| 365 |
l_orig = cv2.cvtColor(np.asarray(rgb), cv2.COLOR_RGB2LAB)[:, :, 0]
|
| 366 |
a = lab_c[:, :, 1].astype(np.float32)
|
|
@@ -370,7 +380,7 @@ def colour_image(image, strength):
|
|
| 370 |
a = cv2.bilateralFilter(a, 9, 40, 9)
|
| 371 |
b = cv2.bilateralFilter(b, 9, 40, 9)
|
| 372 |
out = cv2.cvtColor(cv2.merge([l_orig, a, b]), cv2.COLOR_LAB2RGB)
|
| 373 |
-
return Image.fromarray(out)
|
| 374 |
|
| 375 |
# ================================================================
|
| 376 |
# 10. TAB HELPERS
|
|
|
|
| 21 |
from transformers import BlipProcessor, BlipForConditionalGeneration
|
| 22 |
from spandrel import ModelLoader, ImageModelDescriptor
|
| 23 |
from huggingface_hub import hf_hub_download
|
| 24 |
+
import torch
|
| 25 |
+
from ddcolor import DDColor
|
| 26 |
+
from huggingface_hub import PyTorchModelHubMixin
|
| 27 |
from skimage.metrics import peak_signal_noise_ratio as psnr
|
| 28 |
from skimage.metrics import structural_similarity as ssim
|
| 29 |
+
import sys
|
| 30 |
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "DDColor"))
|
| 31 |
|
| 32 |
# ================================================================
|
| 33 |
# 5. LOAD ALL MODELS AT STARTUP (no lazy loading)
|
|
|
|
| 68 |
ESRGAN_SCALE = int(esrgan_model.scale)
|
| 69 |
print("Enhancement model loaded. Scale factor:", ESRGAN_SCALE)
|
| 70 |
|
| 71 |
+
class DDColorHF(DDColor, PyTorchModelHubMixin):
|
| 72 |
+
def __init__(self, config=None, **kwargs):
|
| 73 |
+
if isinstance(config, dict):
|
| 74 |
+
kwargs = {**config, **kwargs}
|
| 75 |
+
super().__init__(**kwargs)
|
| 76 |
+
|
| 77 |
+
print("🚀 Loading DDColor (PyTorch tiny)...")
|
| 78 |
+
ddcolor_model = DDColorHF.from_pretrained("piddnad/ddcolor_paper_tiny").eval()
|
| 79 |
print("✅ DDColor loaded.")
|
| 80 |
|
| 81 |
print("✅ All models loaded. Starting Gradio interface...")
|
|
|
|
| 328 |
|
| 329 |
return output_image, info
|
| 330 |
|
|
|
|
|
|
|
|
|
|
| 331 |
def colorize_ddcolor(image_rgb: np.ndarray) -> np.ndarray:
|
| 332 |
+
"""Uses the PyTorch ddcolor_model (already on .cuda())."""
|
| 333 |
h, w = image_rgb.shape[:2]
|
| 334 |
img_float = image_rgb.astype(np.float32) / 255.0
|
| 335 |
l_orig = cv2.cvtColor(img_float, cv2.COLOR_RGB2Lab)[:, :, :1]
|
| 336 |
|
| 337 |
l_resized = cv2.resize(l_orig, (512, 512), interpolation=cv2.INTER_AREA)
|
| 338 |
+
l_resized = l_resized.reshape(512, 512, 1)
|
|
|
|
| 339 |
gray_lab = np.concatenate([l_resized, np.zeros_like(l_resized), np.zeros_like(l_resized)], axis=-1)
|
| 340 |
gray_rgb = cv2.cvtColor(gray_lab, cv2.COLOR_LAB2RGB)
|
|
|
|
| 341 |
|
| 342 |
+
# PyTorch tensor (not numpy for ONNX)
|
| 343 |
+
input_tensor = torch.from_numpy(gray_rgb.transpose(2, 0, 1)).float().unsqueeze(0).to("cuda")
|
| 344 |
|
| 345 |
+
with torch.no_grad():
|
| 346 |
+
output_ab = ddcolor_model(input_tensor) # (1, 2, 512, 512) in [0,1]
|
| 347 |
+
|
| 348 |
+
output_ab = output_ab.cpu().numpy()[0].transpose(1, 2, 0) # (512, 512, 2)
|
| 349 |
+
|
| 350 |
+
a = cv2.resize(output_ab[:, :, 0:1], (w, h), interpolation=cv2.INTER_AREA).reshape(h, w, 1)
|
| 351 |
+
b = cv2.resize(output_ab[:, :, 1:2], (w, h), interpolation=cv2.INTER_AREA).reshape(h, w, 1)
|
| 352 |
|
| 353 |
lab_out = np.concatenate([l_orig, a, b], axis=-1)
|
| 354 |
out_rgb = cv2.cvtColor(lab_out, cv2.COLOR_LAB2RGB)
|
| 355 |
+
return (out_rgb * 255).clip(0, 255).astype(np.uint8)
|
| 356 |
+
|
| 357 |
|
| 358 |
@spaces.GPU(duration=58)
|
| 359 |
def colour_image(image, strength):
|
|
|
|
| 364 |
small = rgb.copy()
|
| 365 |
small.thumbnail((768, 768), Image.LANCZOS)
|
| 366 |
|
| 367 |
+
# GPU: inference
|
| 368 |
+
ddcolor_model.cuda()
|
| 369 |
+
coloured = colorize_ddcolor(np.asarray(small))
|
| 370 |
+
ddcolor_model.cpu()
|
| 371 |
|
| 372 |
+
# CPU: LAB strength (no GPU needed)
|
| 373 |
+
coloured_full = Image.fromarray(coloured).resize((W, H), Image.LANCZOS)
|
| 374 |
lab_c = cv2.cvtColor(np.asarray(coloured_full), cv2.COLOR_RGB2LAB)
|
| 375 |
l_orig = cv2.cvtColor(np.asarray(rgb), cv2.COLOR_RGB2LAB)[:, :, 0]
|
| 376 |
a = lab_c[:, :, 1].astype(np.float32)
|
|
|
|
| 380 |
a = cv2.bilateralFilter(a, 9, 40, 9)
|
| 381 |
b = cv2.bilateralFilter(b, 9, 40, 9)
|
| 382 |
out = cv2.cvtColor(cv2.merge([l_orig, a, b]), cv2.COLOR_LAB2RGB)
|
| 383 |
+
return Image.fromarray(out)
|
| 384 |
|
| 385 |
# ================================================================
|
| 386 |
# 10. TAB HELPERS
|
requirements.txt
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
setuptools<82
|
| 2 |
-
onnxruntime
|
| 3 |
spandrel
|
| 4 |
safetensors
|
| 5 |
huggingface_hub
|
|
@@ -13,4 +12,6 @@ opencv-python-headless
|
|
| 13 |
addict
|
| 14 |
simplejson
|
| 15 |
sortedcontainers
|
| 16 |
-
scikit-image>=0.22
|
|
|
|
|
|
|
|
|
| 1 |
setuptools<82
|
|
|
|
| 2 |
spandrel
|
| 3 |
safetensors
|
| 4 |
huggingface_hub
|
|
|
|
| 12 |
addict
|
| 13 |
simplejson
|
| 14 |
sortedcontainers
|
| 15 |
+
scikit-image>=0.22
|
| 16 |
+
timm
|
| 17 |
+
einops
|