File size: 4,335 Bytes
01c0c12 92e5cf2 ce188b1 92e5cf2 01c0c12 ae92154 92e5cf2 01c0c12 92e5cf2 01c0c12 92e5cf2 01c0c12 92e5cf2 01c0c12 92e5cf2 01c0c12 92e5cf2 01c0c12 92e5cf2 01c0c12 92e5cf2 01c0c12 92e5cf2 87680ff 01c0c12 ce188b1 01c0c12 ce188b1 01c0c12 ce188b1 87680ff 01c0c12 b761b10 92e5cf2 01c0c12 92e5cf2 01c0c12 92e5cf2 |
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 |
# app.py
import sys
import os
import tempfile
from pathlib import Path
import streamlit as st
from PIL import Image
# Force app root and pipeline to be importable (for HF docker)
sys.path.append(str(Path(__file__).parent.resolve()))
sys.path.append(str(Path(__file__).parent.resolve() / "pipeline"))
# === CUDA DIAGNOSTICS (LOGS) ===
try:
import torch
print("=== CUDA Info ===")
print("CUDA available:", torch.cuda.is_available())
print("CUDA device count:", torch.cuda.device_count())
print("torch version:", torch.__version__)
print("=================")
except Exception as e:
print(f"[WARN] Could not print CUDA info: {e}")
# === Import the two-stage pipeline ===
try:
from pipeline.two_stage_pipeline import process_two_stage
except ImportError as e:
st.error(f"Pipeline not found or misconfigured: {e}")
st.stop()
st.set_page_config(
page_title="BackgroundFX Pro",
layout="wide",
page_icon="π¬"
)
st.title("π¬ BackgroundFX Pro β AI Video Background Replacer")
st.write(
"Upload a video and a background image (optional). The system will remove the original background "
"using **SAM2** & **MatAnyone**, and composite the subject over your new background image."
)
def progress_callback(msg, prog):
"""Streamlit-friendly progress reporting (persistent)."""
if "progress_bar" not in st.session_state:
st.session_state.progress_bar = st.progress(0)
st.session_state.progress_text = st.empty()
st.session_state.progress_bar.progress(min(max(prog,0.0),1.0))
st.session_state.progress_text.text(msg)
# --- Uploaders ---
video_file = st.file_uploader(
"1οΈβ£ Upload video file (mp4, mov, avi, mkv)",
type=["mp4", "mov", "avi", "mkv"]
)
bg_file = st.file_uploader(
"2οΈβ£ Upload new background (jpg/png, optional)",
type=["jpg", "jpeg", "png"]
)
video_path, bg_path = None, None
if video_file:
# Save video to temp file
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as vf:
vf.write(video_file.read())
video_path = vf.name
st.video(video_path)
if bg_file:
# Save background to temp file
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as bf:
bf.write(bg_file.read())
bg_path = bf.name
background_img = Image.open(bg_path).convert("RGB")
st.image(background_img, caption="Background Image")
elif video_file:
# Fallback: green background sized to video or 1280x720
try:
import cv2
cap = cv2.VideoCapture(video_path)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) or 1280
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) or 720
cap.release()
except Exception:
width, height = 1280, 720
background_img = Image.new("RGB", (width, height), (0,255,0))
st.info("No background image uploaded. Using default green background.")
# --- Processing ---
if video_path and background_img:
if st.button("π Run Background Replacement"):
st.session_state.progress_bar = st.progress(0)
st.session_state.progress_text = st.empty()
with st.spinner("Processing video... (May take several minutes for long videos)"):
try:
out_path = process_two_stage(
video_path,
background_img,
progress=progress_callback
)
st.success("β
Done! Here is your composited video:")
st.video(str(out_path))
with open(out_path, "rb") as f:
st.download_button(
label="πΎ Download Result",
data=f,
file_name="backgroundfx_result.mp4",
mime="video/mp4"
)
except Exception as e:
st.error(f"β Processing failed: {e}")
# Clean up temp files (best effort)
try:
if video_path and os.path.exists(video_path):
os.unlink(video_path)
except Exception: pass
try:
if bg_path and os.path.exists(bg_path):
os.unlink(bg_path)
except Exception: pass
# HF Spaces tip
st.caption("Built for Hugging Face T4 Spaces β’ CUDA & GPU acceleration required β’ v2025.10")
|