토론

로컬 깊이 비디오 변환기를 Gradio로 구축하기

Wikiprompt, 무료 프롬프트 백과사전에서

Larus Canus

2026년 7월 20일

로컬 깊이 비디오 변환기를 Gradio로 구축하기 Gradio와 Depth Anything V2를 사용하여 로컬 Depth 비디오 변환기 애플리케이션을 만드는 상세한 프롬프트이며, 크로스 플랫폼 가속 지원과 다양한 사용자 지정 옵션을 포함합니다.

프롬프트 내용저장

🌐
import os import tempfile import subprocess import numpy as np import cv2 import torch import gradio as gr from PIL import Image from transformers import pipeline from scipy.ndimage import gaussian_filter1d import shutil import platform import json from pathlib import Path import warnings warnings.filterwarnings('ignore') # ============================================ # Configuration and Constants # ============================================ MODEL_SIZES = { "vits": "depth-anything/Depth-Anything-V2-Small", "vitb": "depth-anything/Depth-Anything-V2-Base", "vitl": "depth-anything/Depth-Anything-V2-Large", "vitg": "depth-anything/Depth-Anything-V2-Giant" } DEFAULT_OUTPUT_RES = 768 SUPPORTED_EXTENSIONS = ['.mp4', '.mov', '.avi', '.mkv'] # ============================================ # Device Detection # ============================================ def detect_device(): """Detect best available device for inference""" if platform.system() == 'Darwin': # macOS if torch.backends.mps.is_available(): return torch.device('mps') return torch.device('cpu') elif platform.system() == 'Windows': if torch.cuda.is_available(): return torch.device('cuda') return torch.device('cpu') else: if torch.cuda.is_available(): return torch.device('cuda') return torch.device('cpu') DEVICE = detect_device() # ============================================ # Depth Estimation Pipeline # ============================================ class DepthEstimator: def __init__(self, model_size='vitb'): self.model_id = MODEL_SIZES[model_size] self.device = DEVICE self.pipe = None self.load_model() def load_model(self): """Load the depth estimation pipeline""" try: self.pipe = pipeline( "depth-estimation", model=self.model_id, device=self.device ) except Exception as e: print(f"Error loading model: {e}") # Fallback to CPU if GPU loading fails self.device = torch.device('cpu') self.pipe = pipeline( "depth-estimation", model=self.model_id, device=self.device ) def estimate_depth(self, image): """Estimate depth map from image""" if self.pipe is None: raise RuntimeError("Model not loaded") # Convert to PIL if needed if isinstance(image, np.ndarray): image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) # Get depth prediction with torch.no_grad(): depth = self.pipe(image)["depth"] # Convert to numpy array depth_np = np.array(depth) # Normalize to 0-255 range depth_np = cv2.normalize(depth_np, None, 0, 255, cv2.NORM_MINMAX) depth_np = depth_np.astype(np.uint8) return depth_np # ============================================ # Video Processing Functions # ============================================ def apply_temporal_smoothing(depth_frames, sigma=2.0): """Apply temporal smoothing to reduce flicker""" if len(depth_frames) < 3: return depth_frames # Stack frames into 3D array stack = np.stack(depth_frames) # Apply Gaussian filter along temporal axis smoothed = gaussian_filter1d(stack, sigma=sigma, axis=0) # Convert back to list return [smoothed[i] for i in range(len(depth_frames))] def process_video(input_path, output_path, model_size='vitb', output_res=DEFAULT_OUTPUT_RES, invert=False, temporal_smoothing=True, preserve_audio=True): """Main video processing function""" # Initialize depth estimator estimator = DepthEstimator(model_size) # Open video cap = cv2.VideoCapture(input_path) if not cap.isOpened(): raise ValueError(f"Could not open video: {input_path}") # Get video properties fps = cap.get(cv2.CAP_PROP_FPS) total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # Calculate output dimensions aspect_ratio = width / height if output_res: if aspect_ratio > 1: out_width = output_res out_height = int(output_res / aspect_ratio) else: out_height = output_res out_width = int(output_res * aspect_ratio) # Ensure even dimensions out_width = out_width - (out_width % 2) out_height = out_height - (out_height % 2) else: out_width, out_height = width, height # Create temporary directory for frames temp_dir = tempfile.mkdtemp() depth_frames = [] print(f"Processing {total_frames} frames...") try: # Process each frame frame_count = 0 while True: ret, frame = cap.read() if not ret: break # Resize frame for processing if frame.shape[1] != out_width or frame.shape[0] != out_height: frame = cv2.resize(frame, (out_width, out_height)) # Estimate depth depth = estimator.estimate_depth(frame) # Invert if requested if invert: depth = 255 - depth depth_frames.append(depth) frame_count += 1 if frame_count % 10 == 0: print(f"Processed {frame_count}/{total_frames} frames") # Apply temporal smoothing if requested if temporal_smoothing and len(depth_frames) > 1: print("Applying temporal smoothing...") depth_frames = apply_temporal_smoothing(depth_frames) # Write output video print("Writing output video...") fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, fps, (out_width, out_height), False) for frame in depth_frames: out.write(frame) out.release() # Preserve audio if requested if preserve_audio: print("Preserving original audio...") temp_video = output_path + '.temp.mp4' os.rename(output_path, temp_video) cmd = [ 'ffmpeg', '-y', '-i', temp_video, '-i', input_path, '-map', '0:v:0', '-map', '1:a:0', '-c:v', 'copy', '-c:a', 'aac', '-shortest', output_path ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: print(f"Audio preservation failed: {result.stderr}") os.rename(temp_video, output_path) else: os.remove(temp_video) print(f"Processing complete! Output saved to: {output_path}") return output_path finally: cap.release() # Clean up temp directory shutil.rmtree(temp_dir, ignore_errors=True) # ============================================ # Gradio Interface # ============================================ def create_interface(): """Create the Gradio web interface""" def process_video_wrapper(video_file, model_size, output_res, invert, temporal_smoothing, preserve_audio): """Wrapper function for Gradio""" if video_file is None: return None, "Please upload a video file." # Get file extension ext = os.path.splitext(video_file.name)[1].lower() if ext not in SUPPORTED_EXTENSIONS: return None, f"Unsupported file format: {ext}. Please use {', '.join(SUPPORTED_EXTENSIONS)}" # Create output filename output_path = os.path.join( os.path.dirname(video_file.name), f"depth_{os.path.basename(video_file.name)}" ) try: # Process video result_path = process_video( video_file.name, output_path, model_size=model_size, output_res=output_res, invert=invert, temporal_smoothing=temporal_smoothing, preserve_audio=preserve_audio ) return result_path, f"Processing complete! Output saved to: {result_path}" except Exception as e: return None, f"Error processing video: {str(e)}" # Create Gradio interface with gr.Blocks(title="Depth Video Converter") as demo: gr.Markdown(""" # Depth Video Converter Convert regular videos into depth videos using Depth Anything V2. **Features:** - Converts each frame to grayscale depth map - Supports MP4/MOV uploads - Automatic hardware acceleration (CUDA/MPS/CPU) - Temporal smoothing to reduce flicker - Optional audio preservation """) with gr.Row(): with gr.Column(): video_input = gr.Video( label="Input Video", sources=["upload"], format="mp4" ) model_size = gr.Dropdown( choices=list(MODEL_SIZES.keys()), value="vitb", label="Model Size", info="Larger models are more accurate but slower" ) output_res = gr.Slider( minimum=256, maximum=2048, value=DEFAULT_OUTPUT_RES, step=64, label="Output Resolution", info="Maximum dimension of output video" ) invert = gr.Checkbox( label="Invert Depth Map", value=False, info="Invert black/white colors" ) temporal_smoothing = gr.Checkbox( label="Temporal Smoothing", value=True, info="Reduce flicker between frames" ) preserve_audio = gr.Checkbox( label="Preserve Original Audio", value=True, info="Keep original audio track" ) process_button = gr.Button("Convert Video", variant="primary") with gr.Column(): video_output = gr.Video( label="Output Video", interactive=False ) status_text = gr.Textbox( label="Status", interactive=False ) process_button.click( fn=process_video_wrapper, inputs=[ video_input, model_size, output_res, invert, temporal_smoothing, preserve_audio ], outputs=[video_output, status_text] ) return demo # ============================================ # Main Entry Point # ============================================ def main(): """Main function to launch the application""" print("=" * 60) print("Depth Video Converter") print("=" * 60) print(f"Platform: {platform.system()}") print(f"Device: {DEVICE}") print(f"PyTorch: {torch.__version__}") print(f"CUDA Available: {torch.cuda.is_available()}") if torch.cuda.is_available(): print(f"CUDA Device: {torch.cuda.get_device_name(0)}") print("=" * 60) # Create and launch interface demo = create_interface() demo.launch( server_name="127.0.0.1", server_port=7860, share=False ) if __name__ == "__main__": main()

전체 프롬프트를 보려면 로그인하세요

Continue with:

By logging in, you agree to our Terms of Use and Privacy Policy

사용법

이 프롬프트는 coding와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.

최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.

참고 자료

분류:coding| twitter| python| gradio

토론