okpy

Pythonエンジニア兼テックリーダーが、多くのプロジェクトとチーム運営から得た実践的な知識を共有するブログです。

Python mediapipe入門: あなたのWebカメラが「魔法の鏡」に変わる方法、知りたくないですか?

Python mediapipe入門: あなたのWebカメラが「魔法の鏡」に変わる方法、知りたくないですか?

📝 TL;DR (3行要約)

mediapipeは、Googleが開発した機械学習ベースのコンピュータビジョンライブラリです。 顔認識や姿勢推定といった複雑なタスクを、まるで魔法のように数行のコードで実現したい時に使います。 最大の利点は、自分でAIモデルを学習させる手間が一切不要で、すぐに高精度な認識機能を使えることです。


1. 🤔 一体mediapipeとは何?(核心的な役割と主な使用例)

Pythonを学び始めると、「AIで何かすごいことをしてみたい!」と思いますよね。でも、機械学習の理論を学んだり、大量のデータを集めてモデルを訓練したりするのは、正直なところ、初心者にはハードルが高い道のりです。

そんな「やりたいこと」と「できること」のギャップを、一気に埋めてくれるのがmediapipeです。

核心的な役割: AIアシスタント搭載の「魔法のメガネ」👓

mediapipeをひと言で例えるなら、「超高性能なAIアシスタントが搭載された魔法のメガネ」です。

想像してみてください。あなたがこのメガネをかけてパソコンのWebカメラを覗くと、AIアシスタントが映像に映るものを瞬時に理解し、その情報を整理してあなたに教えてくれるのです。

  • 「あ、ここに人の顔がありますね。目、鼻、口の位置はここですよ」
  • 「この人は今、右手を挙げていますね。肘や手首の関節は、この座標にあります」
  • 「画面内に手が映りました。指の関節は全部で21箇所、それぞれの位置はこちらです」

普通なら、このような情報を画像や動画から読み解くには、複雑な画像処理の知識と、膨大な計算をこなすための高度なAIモデルが必要になります。しかしmediapipeは、この「魔法のメガネ」を私たちに提供してくれます。私たちは難しいことを考える必要はありません。ただメガネ(ライブラリ)をかけて、AIアシスタント(事前学習済みモデル)が教えてくれる情報を活用するだけで良いのです。

つまりmediapipeは、複雑なコンピュータビジョンの「下ごしらえ」や「調理」の部分をすべて肩代わりしてくれる、非常に親切なライブラリなのです。

主な使用例: あなたのアイデアが形になる瞬間 ✨

この「魔法のメガネ」を使えば、一体どんなことができるのでしょうか?代表的な例を3つ見てみましょう。

  1. リアルタイム姿勢推定 (Pose Estimation) mediapipeが最も得意とする分野の一つです。カメラに映った人の全身の骨格(関節の位置)をリアルタイムで検出できます。

    • 応用例:
      • フィットネスアプリ: ユーザーのスクワットやヨガのポーズが正しいか、骨格情報から判定する。
      • バーチャルアバター操作: 自分の動きをリアルタイムで3Dアバターに反映させる(VTuberのような技術)。
      • ジェスチャーコントロール: 体の動きでドローンを操縦したり、プレゼンテーションのスライドをめくったりする。
  2. 顔ランドマーク検出 (Face Mesh) 顔の輪郭、目、眉、鼻、口など、最大468個もの特徴点を精密に検出します。

    • 応用例:
      • ARエフェクトアプリ: InstagramやSnapchatのフィルターのように、顔にメガネや動物の耳を合成する。
      • バーチャルメイク: ユーザーの顔に口紅やアイシャドウを仮想的に試せるアプリ。
      • 表情分析: 笑顔や驚きといった表情を読み取り、感情を推定するシステム。
  3. ハンドトラッキング (Hand Tracking) 手の形や指の関節(21点)を正確に追跡します。

    • 応用例:
      • ジェスチャー認識: 指の形で「OK」や「ピース」サインを認識し、PCを操作する。
      • VR/AR空間でのインタラクション: 仮想空間内のオブジェクトを、自分の手で直接掴んだり、動かしたりする。

このように、mediapipeは単なるツールではなく、あなたのアイデアを形にするための強力なパートナーとなってくれるのです。


2. 💻 インストール方法

mediapipeのインストールはとても簡単です。また、カメラ映像を扱うためにopencv-pythonも一緒にインストールするのが定番です。ターミナル(またはコマンドプロンプト)を開いて、以下のコマンドを実行しましょう。

pip install mediapipe opencv-python

たったこれだけで、あなたの開発環境に「魔法のメガネ」をかける準備が整いました!


3. 🛠️ 実際に動作するサンプルコード

百聞は一見に如かず。実際にmediapipeがどれほど強力か、Webカメラを使ってリアルタイムであなたの姿勢を検出するコードを動かしてみましょう。

以下のコードをコピーして、pose_detection.pyのような名前で保存し、実行してみてください。Webカメラが起動し、あなたの体の動きに合わせて骨格が線で描画されるはずです。(終了する時は、表示されたウィンドウを選択した状態でqキーを押してください)

import cv2
import mediapipe as mp

# mediapipeの描画ユーティリティと姿勢推定モデルを初期化
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose

# Webカメラからの入力を開始
# 0は通常、内蔵カメラを指します。外部カメラの場合は1, 2, ...と試してください。
cap = cv2.VideoCapture(0)

# 姿勢推定モデルを読み込み
# withブロックを使うことで、リソースのクリーンアップを確実に行います。
with mp_pose.Pose(
    min_detection_confidence=0.5,  # 検出の信頼度の最小値
    min_tracking_confidence=0.5) as pose: # トラッキングの信頼度の最小値

    # カメラが起動している間、ループを続ける
    while cap.isOpened():
        # カメラからフレームを1枚読み込む
        success, image = cap.read()
        if not success:
            print("カメラフレームの読み込みに失敗しました。")
            continue

        # パフォーマンス向上のため、画像を書き込み不可にして参照渡しする
        image.flags.setflags(write=False)
        # OpenCVのBGR形式からmediapipeのRGB形式に変換
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

        # 姿勢推定を実行
        results = pose.process(image)

        # 処理のために画像を書き込み可能に戻す
        image.flags.setflags(write=True)
        # mediapipeのRGB形式からOpenCVのBGR形式に戻す
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

        # 検出された姿勢のランドマークを画像に描画
        if results.pose_landmarks:
            mp_drawing.draw_landmarks(
                image,
                results.pose_landmarks,
                mp_pose.POSE_CONNECTIONS)

        # 結果を画面に表示
        cv2.imshow('MediaPipe Pose', image)

        # 'q'キーが押されたらループを抜ける
        if cv2.waitKey(5) & 0xFF == ord('q'):
            break

# 使い終わったらリソースを解放
cap.release()
cv2.destroyAllWindows()

4. 🔍 コードの詳細説明

上記のコードが魔法のように動く様子に驚いたかもしれませんね。でも、心配はいりません。一つ一つの処理は非常にシンプルです。コードを意味のある塊(チャンク)に分けて、何が行われているのかを解説します。

① 準備運動: ライブラリのインポートと初期化 🏃‍♀️

import cv2
import mediapipe as mp

mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose

ここでは、このプログラムで使う道具を準備しています。 - cv2: OpenCVライブラリです。Webカメラの映像を読み込んだり、画面に表示したりする「目」と「手」の役割を担います。 - mediapipe as mp: 主役のmediapipeライブラリです。mpという短い名前で使えるようにしています。 - mp_drawing: 検出した骨格(ランドマーク)を線で結んで、見やすく描画するためのヘルパーツールです。 - mp_pose: mediapipeが提供する様々な機能の中から、「姿勢推定」の機能を使うことを宣言しています。

② メインエンジン: カメラの起動と姿勢推定モデルのセットアップ 🚀

cap = cv2.VideoCapture(0)
with mp_pose.Pose(...) as pose:
    while cap.isOpened():
        # ... (ループ内の処理) ...

ここからがプログラムの本体です。 - cap = cv2.VideoCapture(0): PCに接続されたWebカメラを起動し、映像を取り込む準備をします。0は通常、PC内蔵のカメラを指します。 - with mp_pose.Pose(...) as pose:: これが「魔法のメガネ」をかける瞬間にあたります。姿勢推定のAIモデル(pose)をここで準備します。min_detection_confidenceは「このくらい自信があったら、人を検出したと判断する」という閾値(しきいち)です。0.0から1.0の値で設定します。 - while cap.isOpened():: カメラが動いている間、ずっと中の処理を繰り返すためのループです。動画は静止画の連続なので、1フレーム(1枚の画像)ずつ処理していきます。

③ 核心部分: AIによる画像分析 🧠

success, image = cap.read()
# ...
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = pose.process(image)

ループの中で、最も重要な処理を行っているのがこの部分です。 - success, image = cap.read(): カメラから現在のフレーム(静止画)を1枚取得します。imageにその画像データが入ります。 - image = cv2.cvtColor(...): 小さな、しかし重要なステップです。OpenCVは画像を「青・緑・赤 (BGR)」の順で扱いますが、mediapipeは「赤・緑・青 (RGB)」の順で扱います。そのため、mediapipeに画像を渡す前に、色の順番を変換してあげています。 - results = pose.process(image): ここがAIの魔法が使われる瞬間です! 準備したposeモデルに、カメラから取得した画像imageを渡して分析を依頼しています。戻り値のresultsオブジェクトの中に、検出された関節の位置情報などがすべて格納されます。

④ 結果の可視化: 検出結果を描画して表示 🎨

image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
if results.pose_landmarks:
    mp_drawing.draw_landmarks(...)
cv2.imshow('MediaPipe Pose', image)

AIが分析した結果は、ただの数値データです。それを人間が見て分かるように、画像に描き加えていきます。 - image = cv2.cvtColor(...): 分析が終わったので、今度は画面に表示するために、色の順番をOpenCVが扱うBGR形式に戻します。 - if results.pose_landmarks:: 「もし、画像の中から人の関節が見つかっていたら…」という条件分岐です。人が映っていないフレームでは何も描画しません。 - mp_drawing.draw_landmarks(...): 準備しておいた描画ツールを使い、results.pose_landmarks(検出された関節の位置情報)を元に、画像imageの上に関節の点と、それらをつなぐ線を描き込んでいます。 - cv2.imshow(...): 骨格が描画された最終的な画像を、ウィンドウに表示します。

この①〜④の処理を高速で繰り返すことで、まるで動画のようにリアルタイムで姿勢が検出されているように見えるのです。


5. ⚠️ 注意点またはヒント

mediapipeは非常に強力ですが、初心者が少し戸惑うかもしれないポイントが1つあります。これを知っておくだけで、応用する際のデバッグ時間が大幅に短縮されるはずです。

📌 ヒント: 座標は「正規化」されていることを忘れずに!

サンプルコードではdraw_landmarksが自動で描画してくれましたが、自分で「右手首の位置に円を描く」といった処理をしたい場合、注意が必要です。

mediapipeが返すランドマークの座標(results.pose_landmarks.landmarkの中にあるx, y)は、画像のピクセル座標(例: x=320, y=240)ではありません

これらの座標は正規化 (Normalization) されており、画像の幅と高さをそれぞれ1.0とした時の相対的な位置を0.01.0の範囲で示します。

  • x = 0.0 は画像の左端
  • x = 1.0 は画像の右端
  • y = 0.0 は画像の上端
  • y = 1.0 は画像の下端

(簡易的なイメージです)

もし、実際のピクセル座標が知りたい場合は、以下のように画像の幅と高さを掛けてあげる必要があります。

# 例: 右手首(インデックス16)のピクセル座標を取得する

# まず、画像の高さと幅を取得
image_height, image_width, _ = image.shape

# ランドマークが存在するか確認
if results.pose_landmarks:
    # 右手首のランドマークを取得
    right_wrist_landmark = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST]
    
    # 正規化座標をピクセル座標に変換
    pixel_x = int(right_wrist_landmark.x * image_width)
    pixel_y = int(right_wrist_landmark.y * image_height)
    
    print(f"右手首のピクセル座標: ({pixel_x}, {pixel_y})")
    
    # その位置に円を描画してみる
    cv2.circle(image, (pixel_x, pixel_y), 10, (0, 255, 0), -1)

この「正規化座標」の仕組みを理解しておけば、特定の関節が画像のどのエリアにあるかを判定したり、他のオブジェクトと連携させたりする応用がスムーズに実装できます。


6. 🔗 一緒に見ておくと良いライブラリ

mediapipeを学ぶ上で、切っても切れない関係にあるのが OpenCV (opencv-python) です。

  • 役割分担:
    • OpenCV: カメラからの映像入力、画像のリサイズやクロップ、図形の描画、画面への表示など、画像・動画の「入出力」や「加工」を担当します。いわば、システムの「目」と「手」です。
    • mediapipe: OpenCVから受け取った画像の中身を「理解」し、人の骨格や顔のパーツといった意味のある情報を取り出します。いわば、システムの「頭脳」です。

サンプルコードでも、カメラの起動(cv2.VideoCapture)や画面表示(cv2.imshow)でOpenCVを使いましたね。mediapipeで得た情報を元に、さらに複雑な画像処理(例えば、顔の部分だけ切り抜く、特定の色を検出するなど)を行いたい場合、OpenCVの知識が直接役立ちます。

mediapipeを使いこなすことは、同時にOpenCVとの連携を学ぶことでもあります。ぜひ、OpenCVの基本的な使い方も合わせて学習してみてください。


7. 🎉 まとめ

今回は、Pythonで高度なコンピュータビジョンを驚くほど簡単に実現できるライブラリmediapipeについて学びました。

  • mediapipeは、AI搭載の「魔法のメガネ」であり、複雑なモデル構築なしに姿勢推定や顔検出ができます。
  • pip install mediapipe opencv-pythonで簡単に始められます。
  • Webカメラを使ったリアルタイム姿勢推定は、数行のコードで実装可能です。
  • 座標は「正規化」されているという点だけ、応用する際には覚えておきましょう。

mediapipeの登場によって、これまで専門家しか作れなかったようなインタラクティブなアプリケーションを、私たち初学者でも開発できる道が開かれました。

最後に、今日学んだことを定着させるための「挑戦課題」です。

【挑戦課題】 サンプルコードを改造して、両手を挙げた「バンザイ」のポーズを検出してみましょう!

ヒント: 1. mediapipeは、両手首のランドマーク(LEFT_WRIST, RIGHT_WRIST)と、鼻のランドマーク(NOSE)の位置を教えてくれます。 2. 「バンザイ」のポーズは、「両手首のy座標が、鼻のy座標よりも小さい(画面の上にある)」状態だと定義できます。 3. if文を使って、この条件が満たされた時に、コンソールに"バンザイ!"と表示したり、画面にテキストを描画(cv2.putText)したりしてみてください。

この課題をクリアできれば、あなたはもうmediapipeを使いこなす第一歩を踏み出したも同然です。ぜひ、あなたのアイデアmediapipeで形にしてみてください!