Spaces:
Running
on
Zero
Running
on
Zero
File size: 5,868 Bytes
7b0a8f1 219cab0 ea799b5 219cab0 ea799b5 a7703a7 219cab0 ea799b5 219cab0 ea799b5 219cab0 ea799b5 219cab0 ea799b5 219cab0 ea799b5 219cab0 9b77af9 ea799b5 219cab0 e0180e9 219cab0 ea799b5 219cab0 9b77af9 ea799b5 219cab0 ea799b5 219cab0 ea799b5 219cab0 ea799b5 219cab0 ea799b5 8b634d8 219cab0 ea799b5 219cab0 8b634d8 ea799b5 8b634d8 ea799b5 8b634d8 219cab0 8b634d8 219cab0 8b634d8 219cab0 ea799b5 3f6eb3e 219cab0 ea799b5 219cab0 ea799b5 219cab0 8194697 |
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 |
import spaces
import torch
import os
import time
import datetime
from moviepy.editor import VideoFileClip
import gradio as gr
# Download Weights
from huggingface_hub import snapshot_download
# List of subdirectories to create inside "weights"
subfolders = [
"diffuEraser",
"stable-diffusion-v1-5",
"PCM_Weights",
"propainter",
"sd-vae-ft-mse"
]
# Create directories
for subfolder in subfolders:
os.makedirs(os.path.join("weights", subfolder), exist_ok=True)
snapshot_download(repo_id="lixiaowen/diffuEraser", local_dir="./weights/diffuEraser")
snapshot_download(repo_id="stable-diffusion-v1-5/stable-diffusion-v1-5", local_dir="./weights/stable-diffusion-v1-5")
snapshot_download(repo_id="wangfuyun/PCM_Weights", local_dir="./weights/PCM_Weights")
snapshot_download(repo_id="camenduru/ProPainter", local_dir="./weights/propainter")
snapshot_download(repo_id="stabilityai/sd-vae-ft-mse", local_dir="./weights/sd-vae-ft-mse")
# Import model classes
from diffueraser.diffueraser import DiffuEraser
from propainter.inference import Propainter, get_device
base_model_path = "weights/stable-diffusion-v1-5"
vae_path = "weights/sd-vae-ft-mse"
diffueraser_path = "weights/diffuEraser"
propainter_model_dir = "weights/propainter"
# Model setup
device = get_device()
ckpt = "2-Step"
video_inpainting_sd = DiffuEraser(device, base_model_path, vae_path, diffueraser_path, ckpt=ckpt)
propainter = Propainter(propainter_model_dir, device=device)
# Helper function to trim videos
def trim_video(input_path, output_path, max_duration=5):
clip = VideoFileClip(input_path)
trimmed_clip = clip.subclip(0, min(max_duration, clip.duration))
trimmed_clip.write_videofile(output_path, codec="libx264", audio_codec="aac")
clip.close()
trimmed_clip.close()
@spaces.GPU(duration=100)
def infer(input_video, input_mask):
# Setup paths and parameters
save_path = "results"
mask_dilation_iter = 8
max_img_size = 960
ref_stride = 10
neighbor_length = 10
subvideo_length = 50
if not os.path.exists(save_path):
os.makedirs(save_path)
# Timestamp for unique filenames
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
trimmed_video_path = os.path.join(save_path, f"trimmed_video_{timestamp}.mp4")
trimmed_mask_path = os.path.join(save_path, f"trimmed_mask_{timestamp}.mp4")
priori_path = os.path.join(save_path, f"priori_{timestamp}.mp4")
output_path = os.path.join(save_path, f"diffueraser_result_{timestamp}.mp4")
# Trim input videos
trim_video(input_video, trimmed_video_path)
trim_video(input_mask, trimmed_mask_path)
# Dynamically compute video_length (in frames) assuming 30 fps
clip = VideoFileClip(trimmed_video_path)
video_duration = clip.duration
clip.close()
video_length = int(video_duration * 30)
# Run models
start_time = time.time()
# ProPainter (priori)
propainter.forward(trimmed_video_path, trimmed_mask_path, priori_path,
video_length=video_length, ref_stride=ref_stride,
neighbor_length=neighbor_length, subvideo_length=subvideo_length,
mask_dilation=mask_dilation_iter)
# DiffuEraser
guidance_scale = None
video_inpainting_sd.forward(trimmed_video_path, trimmed_mask_path, priori_path, output_path,
max_img_size=max_img_size, video_length=video_length,
mask_dilation_iter=mask_dilation_iter,
guidance_scale=guidance_scale)
end_time = time.time()
print(f"DiffuEraser inference time: {end_time - start_time:.2f} seconds")
torch.cuda.empty_cache()
return output_path
# Gradio interface
with gr.Blocks() as demo:
with gr.Column():
gr.Markdown("# DiffuEraser: A Diffusion Model for Video Inpainting")
gr.Markdown("DiffuEraser is a diffusion model for video inpainting, which outperforms state-of-the-art model ProPainter in both content completeness and temporal consistency while maintaining acceptable efficiency.")
gr.HTML("""
<div style="display:flex;column-gap:4px;">
<a href="https://github.com/lixiaowen-xw/DiffuEraser">
<img src='https://img.shields.io/badge/GitHub-Repo-blue'>
</a>
<a href="https://lixiaowen-xw.github.io/DiffuEraser-page">
<img src='https://img.shields.io/badge/Project-Page-green'>
</a>
<a href="https://lixiaowen-xw.github.io/DiffuEraser-page">
<img src='https://img.shields.io/badge/ArXiv-Paper-red'>
</a>
<a href="https://huggingface.co/spaces/fffiloni/DiffuEraser-demo?duplicate=true">
<img src="https://huggingface.co/datasets/huggingface/badges/resolve/main/duplicate-this-space-sm.svg" alt="Duplicate this Space">
</a>
</div>
""")
with gr.Row():
with gr.Column():
input_video = gr.Video(label="Input Video (MP4 ONLY)")
input_mask = gr.Video(label="Input Mask Video (MP4 ONLY)")
submit_btn = gr.Button("Submit")
with gr.Column():
video_result = gr.Video(label="Result")
gr.Examples(
examples=[
["./examples/example1/video.mp4", "./examples/example1/mask.mp4"],
["./examples/example2/video.mp4", "./examples/example2/mask.mp4"],
["./examples/example3/video.mp4", "./examples/example3/mask.mp4"],
],
inputs=[input_video, input_mask]
)
submit_btn.click(fn=infer, inputs=[input_video, input_mask], outputs=[video_result])
demo.queue().launch(show_api=True, show_error=True, ssr_mode=False)
|