サイトアイコン アマチュア無線局JS2IIU

【Streamlit】MediaPipeで顔認識アプリを作ろう!

こんにちは、JS2IIUです。

この記事では、StreamlitとMediaPipeを使って、Webカメラの映像から顔を認識し、表情を分析するアプリケーションを作成する方法を紹介します。Streamlitは、Pythonで記述したコードからインタラクティブなWebアプリケーションを簡単に構築できるフレームワークです。MediaPipeは、Googleが開発したオープンソースの機械学習ソリューションで、顔認識、手検出、姿勢推定など、様々なタスクを高速かつ効率的に実行できます。

MediaPipe

MediaPipeは、様々な機械学習タスクをパイプラインとして構築するためのフレームワークです。パイプラインは、複数のモジュールを連結することで構成され、各モジュールは特定の処理を実行します。顔認識の場合、顔検出、ランドマーク検出、表情認識などのモジュールが使用されます。

MediaPipeはPython APIを提供しており、Pythonから簡単に利用できます。顔認識には、mediapipe.solutions.face_meshモジュールを使用します。このモジュールは、顔のランドマークを検出し、それらに基づいて表情を分析することができます。

MediaPipe ソリューション ガイド  |  Google AI Edge  |  Google AI for Developers

インストール

MediaPipeはpipを使って簡単にインストールできます。以下のコマンドをターミナルで実行してください。

Bash
pip install mediapipe

MediaPipeを使うには、OpenCVも必要です。OpenCVがインストールされていない場合は、以下のコマンドでインストールしてください。

Bash
pip install opencv-python

MediaPipeを使った簡単なプログラム:手の検出

MediaPipeを使って手の検出を行う簡単なプログラムを紹介します。10行目のcv2.VideoCapture(0)の引数をお使いの環境に合わせて変更して下さい。私の環境では引数を0にするとiPhoneのカメラ、1にするとMacBookのカメラが起動しました。VideoCapture()についてはこちらのリンク先を参照して下さい。

OpenCV: cv::VideoCapture Class Reference
Python
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()で検出された手のランドマークを描画しています。

解説

  1. モジュールのインポート: cv2 (OpenCV) と mediapipe をインポートします。
  2. Handsモジュールの初期化: mp.solutions.hands.Hands() で手の検出器を初期化します。
  3. カメラの初期化: cv2.VideoCapture(0) でWebカメラを初期化します。
  4. ループ処理: カメラからフレームを読み込み、手の検出と描画を繰り返します。
    • cv2.cvtColor でBGR (OpenCVのデフォルト) からRGB (MediaPipeの入力形式) に変換します。
    • hands.process で手の検出を実行します。
    • mp_drawing.draw_landmarks で検出された手のランドマークを描画します。
    • cv2.imshow で画像を表示します。
    • cv2.waitKey でキー入力待ちをし、’q’ キーが押されたらループを終了します。
  5. 後処理: cap.release() でカメラを解放し、cv2.destroyAllWindows() でウィンドウを閉じます。

サンプルプログラム

以下のコードは、StreamlitとMediaPipeを使って、Webカメラの映像から顔を認識し、表情を分析するアプリケーションのサンプルプログラムです。

Python
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()

コード解説

  1. MediaPipeの初期化: mp_face_mesh.FaceMesh()で顔メッシュ検出器を初期化します。
  2. カメラ映像の取得: cv2.VideoCapture(0)でWebカメラの映像を取得します。
  3. 顔認識: face_mesh.process(image)で画像から顔を認識します。
  4. ランドマークの描画: mp_drawing.draw_landmarks()で顔のランドマークを描画します。
  5. Streamlitへの表示: st.image()で画像をStreamlitアプリケーションに表示します。

参考になるWebサイト

最後に、書籍のPRです。

最新のOpenAIのチャットAPIの使い方もしっかりと解説されている良書です。2024年11月初版発行、「LangChainとLangGraphによるRAG・AIエージェント[実践]入門」西見、吉田、大嶋著。

最後まで読んでいただきありがとうございます。73

モバイルバージョンを終了