Spaces:
Runtime error
Runtime error
File size: 5,812 Bytes
f3d8556 2ec25b3 |
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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
import subprocess
subprocess.run("pip install opencv-python os gc torch torchaudio torchvision gfpgan basicsr realesrgan")
import os
import cv2
import time
import gc
import torch
from gfpgan import GFPGANer
from basicsr.archs.rrdbnet_arch import RRDBNet
from basicsr.utils.download_util import load_file_from_url
from realesrgan import RealESRGANer
# === GPU MEMORY MONITORING ===
def print_simple_gpu_memory():
allocated = torch.cuda.memory_allocated(0) / 1024**3
reserved = torch.cuda.memory_reserved(0) / 1024**3
print(f"[GPU Memory] Allocated: {allocated:.2f} GB | Reserved: {reserved:.2f} GB")
# === GFPGAN STEP ===
def run_gfpgan(image_path, output_path, model_path='GFPGAN\GFPGAN\experiments\pretrained_models\GFPGANv1.4.pth'):
gfpganer = GFPGANer(
model_path=model_path,
upscale=2,
arch='clean',
channel_multiplier=2,
bg_upsampler=None
)
img = cv2.imread(image_path)
if img is None:
raise FileNotFoundError(f"Input image not found: {image_path}")
_, _, restored_img = gfpganer.enhance(img, has_aligned=False, only_center_face=False, paste_back=True)
cv2.imwrite(output_path, restored_img)
print(f"[+] GFPGAN output saved: {output_path}")
return output_path
# === RealESRGAN STEP ===
def run_realesrgan(input_path, output_path, model_name='RealESRGAN_x4plus', outscale=4, gpu_id=None):
if model_name == 'RealESRGAN_x4plus':
model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
netscale = 4
file_url = ['https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth']
else:
raise NotImplementedError(f'Model {model_name} not implemented')
model_path = os.path.join('weights', model_name + '.pth')
if not os.path.isfile(model_path):
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
for url in file_url:
model_path = load_file_from_url(url=url, model_dir=os.path.join(ROOT_DIR, 'weights'), progress=True, file_name=None)
upsampler = RealESRGANer(
scale=netscale,
model_path=model_path,
dni_weight=None,
model=model,
tile=512, # <<< IMPORTANT for 4 GB VRAM!
tile_pad=10,
pre_pad=0,
half=False,
gpu_id=gpu_id
)
img = cv2.imread(input_path, cv2.IMREAD_UNCHANGED)
if img is None:
raise FileNotFoundError(f'Input image not found: {input_path}')
output, _ = upsampler.enhance(img, outscale=outscale)
output_dir = os.path.dirname(output_path)
if output_dir and not os.path.exists(output_dir):
os.makedirs(output_dir, exist_ok=True)
cv2.imwrite(output_path, output)
print(f"[+] RealESRGAN output saved: {output_path}")
return output_path
# === Combined Workflow ===
def combined_enhance(input_img_path, rescale_factor, output_dir):
start_time = time.perf_counter()
base_name = os.path.splitext(os.path.basename(input_img_path))[0]
# Step 1: GFPGAN enhancement
gfpgan_out = os.path.join(output_dir, f"{base_name}_GFPGAN.png")
run_gfpgan(input_img_path, gfpgan_out)
print("[GPU Memory after GFPGAN]")
print_simple_gpu_memory()
# Free memory before loading RealESRGAN
gc.collect()
torch.cuda.empty_cache()
print("[*] Cleared GPU cache before RealESRGAN")
# Step 2: RealESRGAN enhancement using GFPGAN result
realesrgan_out = os.path.join(output_dir, f"{base_name}_GFPGAN_RealESRGAN_combined.png")
run_realesrgan(gfpgan_out, realesrgan_out, outscale=rescale_factor)
print("[GPU Memory after RealESRGAN]")
print_simple_gpu_memory()
print(f"[***] Final combined image saved at: {realesrgan_out}")
# Get resolution and file size info
img = cv2.imread(realesrgan_out)
height, width = img.shape[:2]
file_size_bytes = os.path.getsize(realesrgan_out)
file_size_mb = file_size_bytes / (1024 * 1024)
end_time = time.perf_counter()
elapsed = end_time - start_time
mins, secs = divmod(elapsed, 60)
hours, mins = divmod(mins, 60)
print(f"[***] Image resolution: {width}x{height}, file size: {file_size_mb:.2f} MB")
print(f"[***] Total processing time: {int(hours):02d}h:{int(mins):02d}m:{secs:05.2f}s")
return realesrgan_out
import gradio as gr
import os
# Your core functions like combined_enhance must be defined/imported before this
def wrapped_combined_enhance(image, scale_factor):
temp_input_path = "temp_input.png"
temp_output_dir = "output"
os.makedirs(temp_output_dir, exist_ok=True)
image.save(temp_input_path)
try:
final_path = combined_enhance(temp_input_path, int(scale_factor), temp_output_dir)
return final_path, "Enhancement succeeded!"
except Exception as e:
return None, f"[ERROR]: {str(e)}"
with gr.Blocks(title="AI Face Enhancer (GFPGAN + RealESRGAN)") as demo:
gr.Markdown("# ✨ Face Enhancer Pro")
with gr.Row():
with gr.Column():
input_img = gr.Image(type="pil", label="Upload Image")
scale_slider= gr.Slider(1, 4, value=2, step=1, label="Upscale Factor")
enhance_btn = gr.Button("Enhance")
status_box = gr.Textbox(label="Status / Logs", lines=6, interactive=False)
with gr.Column():
output_img = gr.Image(label="Enhanced Output")
def ui_callback(image, scale):
if image is None:
return None, "⚠️ Please upload an image first."
out_path, status = wrapped_combined_enhance(image, scale)
# return filepath (or None) and status string
return out_path, status
enhance_btn.click(
fn=ui_callback,
inputs=[input_img, scale_slider],
outputs=[output_img, status_box]
)
demo.launch() |