OpenCV と Python で手を識別して追跡する方法を学ぶ
ハンド トラッキングは、コンピューター ビジョンを使用して人の手の動きをリアルタイムで検出して追跡するプロセスです。ハンド トラッキングの最も一般的な用途は、バーチャル リアリティ ヘッドセットです。ヘッドセットを使用すると、タッチ コントローラーの代わりに手を入力として使用できます。これにより、体験がより没入感のあるものになります。
Python、コンピューター ビジョン用の OpenCV、および MediaPipe を使用して人の手を追跡する方法をご覧ください。
MediaPipe フレームワークはどのように手を追跡しますか?
Google は、多くの機械学習ソリューションを含む MediaPipe フレームワークを開発しました。解決策の 1 つは、 MediaPipe Handsと呼ばれる手と指の追跡ソリューションです。手を追跡するために、MediaPipe Hands は手のひら検出とランドマーク検出の 2 つのプロセスを実行します。
手のひら検出
MediaPipe は、入力画像内で手のひらがどこにあるかを特定することから始めます。硬いオブジェクトの境界ボックスを推定することは、関節のある指で手を識別するよりも簡単です。
手のランドマークの検出
手のひらの検出後、MediaPipe は手のランドマーク検出を実行します。ハンド ランドマーク モデルは、各ハンド ランドマークの位置の 21 の正確な座標を予測できます。
番号は、各ランドマークの一意の識別子を表します。
環境の設定
このプロジェクトを進めるには、Python の基本に精通している必要があります。次のライブラリを環境にインストールします。
- OpenCV: このライブラリをコンピューター ビジョンに使用し、入力画像に対して画像処理手法を実行します。
- MediaPipe: このライブラリを使用して、入力画像で手の検出と追跡を実行します。
- imutils: このライブラリを使用して、入力のビデオ フレームのサイズを変更します。
端末で次のコマンドを実行して、OpenCV、MediaPipe、および imutils ライブラリをインストールします。必要に応じて、Python パッケージ マネージャーである pip をインストールします。ライブラリをスペース区切りのリストとして渡すようにしてください。
pip install OpenCV-Python MediaPipe imutils
更新が完了すると、コーディングを開始できる環境が整います。
必要なライブラリのインポート
インストールしたライブラリをインポートして使用できるようにする必要があります。任意の Python IDE を開き、Python ファイルを作成して、次のインポートを追加します。
import cv2
import mediapipe as mp
import imutils
OpenCV を cv2 としてインポートし、MediaPipe を小文字でインポートしてください。そうしないと、エラーがスローされます。
トラッキング中に使用する MediaPipe オブジェクトの作成
mpHands を使用して MediaPipe hands ソリューションを呼び出し、hands オブジェクトを使用して手の入力を検出して追跡します。mpDraw オブジェクトを使用して、識別された手のランドマーク間の接続を描画します。
mpHands = mp.solutions.hands
hands = mpHands.Hands()
mpDraw = mp.solutions.drawing_utils
Hands() コンストラクターにさまざまなパラメーターを渡すことで、MediaPipe ハンド モデルを微調整できます。このプロジェクトには既定値で十分ですが、実験してモデルにどのように影響するかを確認できます。
static_image_modeを Falseのままにして、追跡を開始する前にモデルが手を 1 回検出するようにする必要があります。検出の信頼度が宣言されたパラメーターよりも低くなった場合にのみ追跡プロセスを繰り返し、全体的な入力処理を高速化します。
ハンドトラッキングの実行
ハンド トラッキングを実行するには 3 つの関数が必要です。入力を処理する関数、手のランドマーク接続を描画する関数、プログラム フローを制御するメイン関数です。
入力処理機能
この関数は、入力を受け取ってグレースケールに変換し、それを MediaPipe の手モデルに渡して、入力内の手の検出と追跡を行います。
# Processing the input image
def process_image(img):
# Converting the input to grayscale
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
results = hands.process(gray_image)
# Returning the detected hands to calling function
return results
この関数は、入力で手が検出されたかどうかの結果を返します。
手のランドマーク接続描画機能
この関数は、入力処理関数が手を検出したかどうかをチェックします。検出された手がある場合は、各ランドマークをループしてその周りに円を描画し、Python の列挙関数を使用してランドマークを追跡します。次に、元のビデオ入力のランドマーク間の接続を描画します。
# Drawing landmark connections
def draw_hand_connections(img, results):
if results.multi_hand_landmarks:
for handLms in results.multi_hand_landmarks:
for id, lm in enumerate(handLms.landmark):
h, w, c = img.shape
# Finding the coordinates of each landmark
cx, cy = int(lm.x * w), int(lm.y * h)
# Printing each landmark ID and coordinates
# on the terminal
print(id, cx, cy)
# Creating a circle around each landmark
cv2.circle(img, (cx, cy), 10, (0, 255, 0),
cv2.FILLED)
# Drawing the landmark connections
mpDraw.draw_landmarks(img, handLms,
mpHands.HAND_CONNECTIONS)
return img
関数は、各ランドマークを丸で囲んで開始します。
次に、手の接続を描画します。
最後に、その出力を呼び出し元の関数に返します。
主な機能
プログラムの流れを制御するメイン関数を作成します。入力を受け取り、ビデオ フレームのサイズを変更して、出力の一貫性を確保します。入力を処理関数に渡し、ハンドを検出して追跡します。返された結果を手のランドマーク接続描画関数に渡して、元のビデオ入力に接続を描画します。最後に、出力をユーザーに表示します。
def main():
# Replace 0 with the video path to use a
# pre-recorded video
cap = cv2.VideoCapture(0)
while True:
# Taking the input
success, image = cap.read()
image = imutils.resize(image, width=500, height=500)
results = process_image(image)
draw_hand_connections(image, results)
# Displaying the output
cv2.imshow("Hand tracker", image)
# Program terminates when q key is pressed
if cv2.waitKey(1) == ord('q'):
cap.release()
cv2.destroyAllWindows()
最後のステップは、プログラムの実行です。以下のコードは、プログラムを実行すると、メイン関数が最初に実行されることを保証します。
if __name__ == "__main__":
main()
プログラムを実行すると、次のような出力が生成されます。
プログラムはリアルタイムで手を追跡します。
没入型バーチャル リアリティのためのハンド トラッキング
バーチャル リアリティでのハンド トラッキングは、テクノロジーをより魅力的にします。バーチャル リアリティ ヘッドセットは、ハンド トラッキングの導入を開始しており、バーチャルの世界に高い現実感をもたらしています。ヘッドセットを使用すると、ユーザーはバーチャルハンドを使用してコマンドを入力できます。
仮想ヘッドセットでのハンド トラッキングは、このテクノロジの 1 つのアプリケーションにすぎません。ハンド トラッキングは、お好みの適用可能な領域に組み込むことができます。
コメントを残す