こんにちは、JS2IIUです。
この記事では、StreamlitとMediaPipeを使って、Webカメラの映像から顔を認識し、表情を分析するアプリケーションを作成する方法を紹介します。Streamlitは、Pythonで記述したコードからインタラクティブなWebアプリケーションを簡単に構築できるフレームワークです。MediaPipeは、Googleが開発したオープンソースの機械学習ソリューションで、顔認識、手検出、姿勢推定など、様々なタスクを高速かつ効率的に実行できます。
MediaPipe
MediaPipeは、様々な機械学習タスクをパイプラインとして構築するためのフレームワークです。パイプラインは、複数のモジュールを連結することで構成され、各モジュールは特定の処理を実行します。顔認識の場合、顔検出、ランドマーク検出、表情認識などのモジュールが使用されます。
MediaPipeはPython APIを提供しており、Pythonから簡単に利用できます。顔認識には、mediapipe.solutions.face_meshモジュールを使用します。このモジュールは、顔のランドマークを検出し、それらに基づいて表情を分析することができます。
インストール
MediaPipeはpipを使って簡単にインストールできます。以下のコマンドをターミナルで実行してください。
pip install mediapipeMediaPipeを使うには、OpenCVも必要です。OpenCVがインストールされていない場合は、以下のコマンドでインストールしてください。
pip install opencv-pythonMediaPipeを使った簡単なプログラム:手の検出
MediaPipeを使って手の検出を行う簡単なプログラムを紹介します。10行目のcv2.VideoCapture(0)の引数をお使いの環境に合わせて変更して下さい。私の環境では引数を0にするとiPhoneのカメラ、1にするとMacBookのカメラが起動しました。VideoCapture()についてはこちらのリンク先を参照して下さい。
import cv2
import mediapipe as mp
# Handsモジュールの初期化
mp_hands = mp.solutions.hands
hands = mp_hands.Hands()
mp_drawing = mp.solutions.drawing_utils
# カメラの初期化
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# BGRをRGBに変換
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 手の検出
results = hands.process(image)
# 検出された手のランドマークを描画
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp_drawing.draw_landmarks(
image,
hand_landmarks,
mp_hands.HAND_CONNECTIONS)
# RGBをBGRに変換
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# 画像を表示
cv2.imshow('Hand Detection', image)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()このプログラムでは、まずmp.solutions.handsモジュールを初期化し、hands.process(image)で画像から手を検出しています。そして、mp_drawing.draw_landmarks()で検出された手のランドマークを描画しています。
解説
- モジュールのインポート:
cv2(OpenCV) とmediapipeをインポートします。 - Handsモジュールの初期化:
mp.solutions.hands.Hands()で手の検出器を初期化します。 - カメラの初期化:
cv2.VideoCapture(0)でWebカメラを初期化します。 - ループ処理: カメラからフレームを読み込み、手の検出と描画を繰り返します。
cv2.cvtColorでBGR (OpenCVのデフォルト) からRGB (MediaPipeの入力形式) に変換します。hands.processで手の検出を実行します。mp_drawing.draw_landmarksで検出された手のランドマークを描画します。cv2.imshowで画像を表示します。cv2.waitKeyでキー入力待ちをし、’q’ キーが押されたらループを終了します。
- 後処理:
cap.release()でカメラを解放し、cv2.destroyAllWindows()でウィンドウを閉じます。
サンプルプログラム
以下のコードは、StreamlitとMediaPipeを使って、Webカメラの映像から顔を認識し、表情を分析するアプリケーションのサンプルプログラムです。
import cv2
import streamlit as st
import mediapipe as mp
st.title('Face Detection with MediaPipe')
# MediaPipeの初期化
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(
max_num_faces=1,
refine_landmarks=True,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
mp_drawing = mp.solutions.drawing_utils
drawing_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1)
# カメラ映像を配置するプレースホルダーを作成
placeholder = st.empty()
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
# BGRをRGBに変換
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# MediaPipeで顔認識
results = face_mesh.process(image)
# 顔のランドマークを描画
if results.multi_face_landmarks:
for face_landmarks in results.multi_face_landmarks:
mp_drawing.draw_landmarks(
image=image,
landmark_list=face_landmarks,
connections=mp_face_mesh.FACEMESH_TESSELATION,
landmark_drawing_spec=drawing_spec,
connection_drawing_spec=drawing_spec
)
# `st.image()`でプレースホルダーに画像を表示
placeholder.image(image, channels="RGB")
cap.release()コード解説
- MediaPipeの初期化:
mp_face_mesh.FaceMesh()で顔メッシュ検出器を初期化します。 - カメラ映像の取得:
cv2.VideoCapture(0)でWebカメラの映像を取得します。 - 顔認識:
face_mesh.process(image)で画像から顔を認識します。 - ランドマークの描画:
mp_drawing.draw_landmarks()で顔のランドマークを描画します。 - Streamlitへの表示:
st.image()で画像をStreamlitアプリケーションに表示します。
参考になるWebサイト
- MediaPipe ソリューション ガイド | Google AI Edge | Google AI for Developers
- Streamlit • A faster way to build and share data apps
最後に、書籍のPRです。
最新のOpenAIのチャットAPIの使い方もしっかりと解説されている良書です。2024年11月初版発行、「LangChainとLangGraphによるRAG・AIエージェント[実践]入門」西見、吉田、大嶋著。
最後まで読んでいただきありがとうございます。73

