soiz1 commited on
Commit
3cad4d8
·
verified ·
1 Parent(s): 757e5d5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -12
app.py CHANGED
@@ -2,16 +2,15 @@ import cv2
2
  import mediapipe as mp
3
  import tempfile
4
  import gradio as gr
5
- import shutil
6
  import os
 
7
 
8
  mp_face_mesh = mp.solutions.face_mesh
9
 
10
  def process_video_with_landmarks(video_path):
11
- # OpenCVで読み込み確認
12
  cap = cv2.VideoCapture(video_path)
13
  if not cap.isOpened():
14
- return "❌ エラー: 動画ファイルを開けませんでした。形式が正しいか確認してください。"
15
 
16
  width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
17
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
@@ -19,9 +18,9 @@ def process_video_with_landmarks(video_path):
19
  if fps == 0:
20
  fps = 25 # fallback
21
 
22
- # 一時ファイル力動画)
23
- temp_output = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
24
- out = cv2.VideoWriter(temp_output.name, cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height))
25
 
26
  face_mesh = mp_face_mesh.FaceMesh(
27
  static_image_mode=False,
@@ -39,7 +38,6 @@ def process_video_with_landmarks(video_path):
39
  rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
40
  results = face_mesh.process(rgb)
41
 
42
- # 青いランドマーク点を描画
43
  if results.multi_face_landmarks:
44
  for face_landmarks in results.multi_face_landmarks:
45
  for lm in face_landmarks.landmark:
@@ -53,10 +51,26 @@ def process_video_with_landmarks(video_path):
53
  out.release()
54
  face_mesh.close()
55
 
56
- return temp_output.name
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  def gradio_interface(video_file):
59
- # video_file: パス (str) または File オブジェクト (gradioの仕様により)
60
  if isinstance(video_file, str) and os.path.isfile(video_file):
61
  return process_video_with_landmarks(video_file)
62
  else:
@@ -65,9 +79,9 @@ def gradio_interface(video_file):
65
  iface = gr.Interface(
66
  fn=gradio_interface,
67
  inputs=gr.Video(label="動画ファイルをアップロード"),
68
- outputs=gr.File(label="ランドマーク描画済み動画 (.mp4)"),
69
- title="Face Mesh ランドマーク付き動画出力",
70
- description="動画からランドマークを検出し、各点を青く描画した動画を出力します。対応形式: .mp4(推奨)"
71
  )
72
 
73
  iface.launch()
 
2
  import mediapipe as mp
3
  import tempfile
4
  import gradio as gr
 
5
  import os
6
+ import subprocess
7
 
8
  mp_face_mesh = mp.solutions.face_mesh
9
 
10
  def process_video_with_landmarks(video_path):
 
11
  cap = cv2.VideoCapture(video_path)
12
  if not cap.isOpened():
13
+ return "❌ エラー: 動画ファイルを開けませんでした。形式確認してください。"
14
 
15
  width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
16
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
 
18
  if fps == 0:
19
  fps = 25 # fallback
20
 
21
+ # 一時AVIファイルで書き
22
+ temp_avi = tempfile.NamedTemporaryFile(delete=False, suffix=".avi")
23
+ out = cv2.VideoWriter(temp_avi.name, cv2.VideoWriter_fourcc(*'XVID'), fps, (width, height))
24
 
25
  face_mesh = mp_face_mesh.FaceMesh(
26
  static_image_mode=False,
 
38
  rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
39
  results = face_mesh.process(rgb)
40
 
 
41
  if results.multi_face_landmarks:
42
  for face_landmarks in results.multi_face_landmarks:
43
  for lm in face_landmarks.landmark:
 
51
  out.release()
52
  face_mesh.close()
53
 
54
+ # mp4へ変換
55
+ temp_mp4 = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
56
+ ffmpeg_cmd = [
57
+ "ffmpeg",
58
+ "-y",
59
+ "-i", temp_avi.name,
60
+ "-vcodec", "libx264",
61
+ "-crf", "23",
62
+ "-preset", "medium",
63
+ temp_mp4.name
64
+ ]
65
+
66
+ try:
67
+ subprocess.run(ffmpeg_cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
68
+ except subprocess.CalledProcessError:
69
+ return "❌ ffmpegによるmp4変換に失敗しました。"
70
+
71
+ return temp_mp4.name
72
 
73
  def gradio_interface(video_file):
 
74
  if isinstance(video_file, str) and os.path.isfile(video_file):
75
  return process_video_with_landmarks(video_file)
76
  else:
 
79
  iface = gr.Interface(
80
  fn=gradio_interface,
81
  inputs=gr.Video(label="動画ファイルをアップロード"),
82
+ outputs=gr.File(label="再生可能なランドマーク付きmp4動画"),
83
+ title="Face Mesh ランドマーク付き動画出力(再生保証)",
84
+ description="動画顔ランドマーク(青を描画し、再生互換性のあるmp4形式で出力します。"
85
  )
86
 
87
  iface.launch()