File size: 2,763 Bytes
a718a55 a72e046 3cad4d8 a718a55 a72e046 a718a55 757e5d5 3cad4d8 757e5d5 a72e046 757e5d5 a72e046 3cad4d8 a72e046 a718a55 a72e046 a718a55 a72e046 757e5d5 a72e046 a718a55 a72e046 a718a55 3cad4d8 a718a55 757e5d5 a718a55 757e5d5 3cad4d8 a718a55 |
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 |
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()
|