facemesh / app.py
soiz1's picture
Update app.py
3cad4d8 verified
import cv2
import mediapipe as mp
import tempfile
import gradio as gr
import os
import subprocess
mp_face_mesh = mp.solutions.face_mesh
def process_video_with_landmarks(video_path):
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
return "❌ エラー: 動画ファイルを開けませんでした。形式を確認してください。"
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
if fps == 0:
fps = 25 # fallback
# 一時AVIファイルで書き出す
temp_avi = tempfile.NamedTemporaryFile(delete=False, suffix=".avi")
out = cv2.VideoWriter(temp_avi.name, cv2.VideoWriter_fourcc(*'XVID'), fps, (width, height))
face_mesh = mp_face_mesh.FaceMesh(
static_image_mode=False,
max_num_faces=1,
refine_landmarks=True,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = face_mesh.process(rgb)
if results.multi_face_landmarks:
for face_landmarks in results.multi_face_landmarks:
for lm in face_landmarks.landmark:
x = int(lm.x * width)
y = int(lm.y * height)
cv2.circle(frame, (x, y), 1, (255, 0, 0), -1)
out.write(frame)
cap.release()
out.release()
face_mesh.close()
# mp4へ変換
temp_mp4 = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
ffmpeg_cmd = [
"ffmpeg",
"-y",
"-i", temp_avi.name,
"-vcodec", "libx264",
"-crf", "23",
"-preset", "medium",
temp_mp4.name
]
try:
subprocess.run(ffmpeg_cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
return "❌ ffmpegによるmp4変換に失敗しました。"
return temp_mp4.name
def gradio_interface(video_file):
if isinstance(video_file, str) and os.path.isfile(video_file):
return process_video_with_landmarks(video_file)
else:
return "❌ 無効なファイルがアップロードされました。"
iface = gr.Interface(
fn=gradio_interface,
inputs=gr.Video(label="動画ファイルをアップロード"),
outputs=gr.File(label="再生可能なランドマーク付きmp4動画"),
title="Face Mesh ランドマーク付き動画出力(再生保証)",
description="動画に顔ランドマーク(青点)を描画し、再生互換性のあるmp4形式で出力します。"
)
iface.launch()