NVIDIA Jetson

Jetson Nano × Webカメラで手を検出!リアルタイムで動きをキャッチ

Jetson NanoとWebカメラで手を検出!リアルタイムで動きをキャッチしよう

Jetson NanoのPython開発環境設定、編集ツール VS Code、必須ツールの

インストール方法を行ってきました。

今回は、Jetson NanoとWebカメラを使って、手をリアルタイムで検出する方法

を紹介します。

AIを活用した画像認識の基本として、手の特定の部分(指先や手のひら)を検出し、

簡単なプログラムを作成して遊んでみましょう。

※一部アフィリエイトリンクが含まれています。

 

手のどの部分を検出するか決めよう

Webカメラを使って手を検出する際、どの部分を認識するかを決めることが重要です。

手の主要な部位には、「親指、人差し指、中指、薬指、小指、手首」などがあり、

それぞれ異なる特性を持っています。

手の部位は「ランドマーク」として数値化され、指ごとに特徴が異なります。

これらのランドマークを活用し、どのような検出方法が適しているのかを

見ていきましょう。

 

ランドマークの主な位置

手の主要な部位には、「親指、人差し指、中指、薬指、小指、手首」があり

関節により、ランドマークによる数値化されています。

【手首 (Wrist) – 手の基準点となる位置】

親指 (Thumb) – 基部 (1)、関節 (2, 3)、先端 (4)

人差し指 (Index Finger) – 基部 (5)、関節 (6, 7)、先端 (8)

中指 (Middle Finger) – 基部 (9)、関節 (10, 11)、先端 (12)

薬指 (Ring Finger) – 基部 (13)、関節 (14, 15)、先端 (16)

小指 (Pinky Finger) – 基部 (17)、関節 (18, 19)、先端 (20)

 

検出方法の特性

 

1.親指の検出

メディアパイプ (MediaPipe) の Hand Landmark Model を使い、21か所の手のランドマークを取得して、親指の付け根 (Landmark 1) と先端 (Landmark 4) の位置関係を解析。

他の指と一定の距離がある場合、「親指が立っている」と判定できます。

親指は他の指と異なり、独立して大きく動くため、特徴的な動きを持ちます。

特定のジェスチャー(例:サムズアップ)を検出するのに適しています。

 

2.人差し指の検出

MediaPipeの Hand Landmark Model を使い、人差し指の先端 (Landmark 8) の位置を取得て、手のひらの中心 (Landmark 0) との距離を計算し、指が伸びているか曲がっているかを判定。

他の指の状態と組み合わせることで、ピンチ(つまむ)動作も認識可能。

人差し指は指の中でも特に細かい動きが可能で、マウスカーソルのようなポインティング動作に向いています。

 

3.中指の検出

MediaPipeのHand Landmark Modelの Landmark 12(中指の先端)を取得して、手のひらの中心 (Landmark 0) との距離や角度を計算して、中指のみが伸びている場合、特定のサイン(例:「ストップ」ジェスチャー)を認識できます。

中指は手の中央に位置し、安定した動作をするため、ハンドジェスチャー認識や特定のタップ動作に活用できます。

 

4.薬指の検出

MediaPipeのHand Landmark Modelの Landmark 16(薬指の先端)を取得して、他の指(特に小指や中指)と比較して動きが制限されるため、組み合わせ動作の認識に利用可能。

指輪検出などの応用にも使えます。

薬指は比較的動きが少なく、安定したジェスチャーを認識するのに適しています。

 

5. 小指の検出

MediaPipeのHand Landmark Modelの Landmark 20(小指の先端)を取得して、親指との距離や角度を解析し、特定のジェスチャーを判定。
指の開閉を利用して、ハンドサインをより詳細に識別可能。

小指は手の端に位置し、特定のハンドサイン適しています。

(例:「ピース」サインや「ロック」ジェスチャー)を検出するのに役立ちます。

 

6. 手首の検出

MediaPipeのHand Landmark Modelの Landmark 0 を手首として取得して、画面内の座標を基準に、手の全体的な位置を特定します。

角度の変化を計算し、手を回転させる動作を検出可能。

手首の位置は手全体の動きをトラッキングするのに重要です。手の向きや回転の判定に使用できます。

 

人差し指の先端を検知するプログラム

人差し指を検出するプログラムを作成してみます。

人差し指を検出は、ポインティング動作をいろいろな場面で使うことができます、

Pythonコードを用いて 人差し指の先端を検出するプログラム を作成します。

 

【使用環境】

Jetson Nano Orin 8GB

Webカメラ(ロジクール C920n)

Python3 環境

OpenCV、MediaPipe(手の検出ライブラリ)

<PR>今回使用している機器はこちら

 

 

<PR>Jetson Nanoを試してみたい方は方はこちら

 

サンプルプログラム

プログラムのポイントは、4つあります。

①人差し指の先端(INDEX_FINGER_TIP)の座標を取得し、画面に表示

②人差し指の位置に円(緑色)を描画し、ラベル表示

③Mediapipeの骨格検出を有効化し、手全体のランドマークを表示

④Webカメラ映像をリアルタイムで処理し、’q’キーで終了処理

 

【サンプルプログラム】

import cv2
import mediapipe as mp

# Mediapipe の初期化
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils

# カメラのセットアップ
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

# Mediapipe Hands の初期化
with mp_hands.Hands(
    max_num_hands=1,
    min_detection_confidence=0.7,
    min_tracking_confidence=0.5) as hands:

    while cap.isOpened():
        success, image = cap.read()
        if not success:
            print("カメラからの画像取得に失敗しました")
            break

        # 画像の前処理
        image = cv2.flip(image, 1)  # ミラーリング
        image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        results = hands.process(image_rgb)

        # 手の検出結果の処理
        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                # 人差し指の先端座標を取得
                index_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP]
                x = int(index_finger_tip.x * image.shape[1])
                y = int(index_finger_tip.y * image.shape[0])

                # 人差し指の位置を表示
                cv2.circle(image, (x, y), 10, (0, 255, 0), -1)
                cv2.putText(image, "Index Finger", (x + 10, y - 10),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

                # 骨格を描画
                mp_drawing.draw_landmarks(image, hand_landmarks, mp_hands.HAND_CONNECTIONS)

        # 画像を表示
        cv2.imshow('Index Finger Detection', image)

        # 'q'キーで終了
        if cv2.waitKey(5) & 0xFF == ord('q'):
            break

# カメラ解放
cap.release()
cv2.destroyAllWindows()

 

 

プログラムを実行すると、ハンドトラッキングが始まります。

手を動かすと高速で追従して、

人差し指の先端を取得し、人差し指の位置に円(緑色)を描画し、

「IndexFinger」表示しています。

 

全身を骨格検知してみよう

MediaPipeの「Pose」モデルを使用して、

全身のランドマーク(肩・肘・膝・足など)を検出します。

Web カメラ映像から全身の骨格検知を行います。

 

【使用環境】

Jetson Nano Orin 8GB

Webカメラ(ロジクール C920n)

Python3 環境

OpenCV、MediaPipe(全身検出ライブラリ)

 

必要なライブラリは、「mediapipe」を使っています。

インストール方法はこちら。

pip install mediapipe opencv-python numpy

 

全身のランドマーク(肩・肘・膝・足など)を検出する

サンプルプログラムのポイント

 

・MediaPipeのポーズモデルを使い、全身の骨格を検出
・肩、肘、手首、膝、足を、33か所のランドマークを検出
・Webカメラを使用して骨格を検出

 

<全身骨格検知サンプルプログラム>

import cv2
import mediapipe as mp

# MediaPipe Pose の初期化
mp_pose = mp.solutions.pose
mp_drawing = mp.solutions.drawing_utils

# カメラのセットアップ
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

# Pose モデルの初期化
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
    while cap.isOpened():
        success, frame = cap.read()
        if not success:
            print("カメラの映像を取得できませんでした。")
            break

        # 画像をRGBに変換(MediaPipeの入力形式)
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        results = pose.process(frame_rgb)

        # 骨格検出結果の処理
        if results.pose_landmarks:
            # 骨格を描画
            mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)

        # 画像を表示
        cv2.imshow('Full Body Pose Detection', frame)

        # 'q'キーで終了
        if cv2.waitKey(5) & 0xFF == ord('q'):
            break

# カメラの解放とウィンドウの終了
cap.release()
cv2.destroyAllWindows()

 

実行すると、Webカメラの映像に全身の骨格が描画されます。

カメラに映る人の肩・肘・手首・膝・足が検出され

動きに合わせて骨格が瞬時に変化がみれます!

 

まとめ

Jetson NanoとWebカメラを使って、人差し指の先端を検出する

全身を検出する、簡単なAIプログラムを作成しました。

これを応用すれば、指の動きに応じたジェスチャー認識や、仮想ボタン操作、

動作の検知など、さまざまなシステムを作ることができます。

また、複数の指の動きを検出したり、指の動きに応じてアクションを

起こすプログラムを作成するのも面白いですね。

ぜひ、試してみてください!