今回は、MediaPipe と Streamlit を使って、動画内の「中心にいる人物だけをマスク表示する」アプリを作ってみました。mediapipeを利用したい動画があったとしても、複数人が映っていたり、背景がごちゃごちゃしている場合には、編集したくなる場合が多くなると思います。
今回作成したアプリは、ブラウザ上で動作する軽量アプリで、30秒以内の動画には限定されますが、アップロードすると、中心人物だけが表示された動画を自動生成します。
✅ 使用ツール&ライブラリ
- フレームワーク:Streamlit
- 人物検出AI:Google MediaPipe Pose
- 処理フロー:動画 → フレームごとに人物検出 → マスク処理 → 動画生成
ライブラリ一覧
- streamlit
- mediapipe
- opencv-python-headless
- numpy
- Pillow
✅ 環境構築
pip install streamlit mediapipe opencv-python-headless numpy pillow
ご自身のpython環境で実施する場合には、上記のパッケージのインストールが必要になります。
※ Streamlit Cloud 上でも動作確認済みです!
インターネット環境があれば、こちらのリンクからアプリを利用かのうです。その場合には環境構築などは不要です。
アプリリンク:https://centervideomask-582zpg8i3yeeb3rphyuswj.streamlit.app/
✅ アプリ概要
- 動画(30秒以内)をアップロード
- MediaPipeで人物検出
- 中心に最も近い人物の領域を一回り大きくマスク
- 処理後、即ダウンロード可能!
基本的に、中心の人物以外を消したい動画を30秒以内に編集してアップロードするだけなので、非常に簡単です。
✅ コード全文(Streamlitアプリ)
こちらがコードの中身です。ご自身のローカル環境で実施する場合には、こちらのpythonコードをコピペすれば利用可能です。
import streamlit as st
import cv2
import numpy as np
import tempfile
import os
import mediapipe as mp
st.title("Center Person Extractor using MediaPipe (Videos up to 30 seconds)")
@st.cache_resource
def load_pose_model():
mp_pose = mp.solutions.pose
return mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5)
pose = load_pose_model()
video_file = st.file_uploader("Upload a video file", type=["mp4", "mov", "avi"])
if video_file:
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_video:
temp_video.write(video_file.read())
video_path = temp_video.name
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
duration_sec = total_frames / fps
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
if duration_sec > 30:
st.error(f"❌ This video is {duration_sec:.1f} seconds long. Please upload a video shorter than 30 seconds.")
cap.release()
else:
st.success(f"Video accepted! Duration: {duration_sec:.1f} seconds")
output_path = os.path.join(tempfile.gettempdir(), "output_masked.mp4")
out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
progress_bar = st.progress(0)
frame_idx = 0
while True:
ret, frame = cap.read()
if not ret:
break
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = pose.process(rgb_frame)
mask = np.zeros(frame.shape[:2], dtype=np.uint8)
if results.pose_landmarks:
landmarks = results.pose_landmarks.landmark
xs = [lm.x for lm in landmarks]
ys = [lm.y for lm in landmarks]
x_min = int(min(xs) * w)
x_max = int(max(xs) * w)
y_min = int(min(ys) * h)
y_max = int(max(ys) * h)
padding_x = int((x_max - x_min) * 0.1)
padding_y = int((y_max - y_min) * 0.1)
x_min_exp = max(0, x_min - padding_x)
x_max_exp = min(w, x_max + padding_x)
y_min_exp = max(0, y_min - padding_y)
y_max_exp = min(h, y_max + padding_y)
mask[y_min_exp:y_max_exp, x_min_exp:x_max_exp] = 255
masked = cv2.bitwise_and(frame, frame, mask=mask)
out.write(masked)
frame_idx += 1
progress_bar.progress(frame_idx / total_frames)
cap.release()
out.release()
st.success("✅ Processing complete!")
with open(output_path, "rb") as f:
st.download_button("Download processed video", f, file_name="center_person_masked.mp4")
✅ 実行結果
- アップロードした動画から、中心人物だけが表示された動画が自動生成されます。
- 処理完了後は即ダウンロード可能。
✅ 注意点
- MediaPipeは軽量ですが、フレーム数が多いと処理時間は長くなります(30秒以内推奨)。
- 複数人が映る場合、最も中心に近い人物のみが対象です。
- 検出精度は背景や姿勢によって変動する場合があります。
ご質問があればX(https://x.com/shimitaro_108)まで
コメント