本記事のテーマ
指に連動してキャラクターが動くアプリを制作する。
制作環境
・Unity2020.3.26.f1
・Mediapipe Python
・NodeJs
本記事ではPythonで指認識を行い、Websocketサーバーへキャラクターの移動量を送信する機能の作り方を説明します。
■前記事
カメラを用いた指認識コントローラーの作り方①リアルタイム同期通信【Unity, Mediapipe, Websocket】 - 人工知性を作りたい
仕様書(指認識コントローラー)
■機能
1. 指の形を認識する
”1”、”2”、”3”、”4”、”5”、”OK”、キツネ”、”いいね”
※上記以外は”1”とする
2. Pythonスクリプトを起動したときに指認識で動かすオブジェクトを生成
画像の黒い球
3. 手を”1”にしたときの人差し指先端を基準位置として、指の移動量を計算する
4. 3で計算した移動量を随時Websocketサーバーへ送信する。
作成したコード
・JavaScriptsフォルダ:Websocketサーバー用
・Pythonフォルダ:指認識(Mediapipe)、Websocketクライアント用
・Unityフォルダ:リアルタイム同期通信アプリ、Websocketクライアント用
GitHub - hiro877/FingerController-Unity-Mediapipe
実行方法
GitHub - hiro877/FingerController-Unity-Mediapipe
上記のコードをダウンロードする。
1. mediapipe Pythonの環境を構築する(手順は下記サイト参照)
MediaPipe in Python - mediapipe
2. JavaScriptsフォルダ内のws.jsを起動する
$ node we.js
3. UnityHub→リストに追加でUnityProjectsフォルダを選択し起動する。
4. 1で作成した環境からPythonフォルダ内のclient.pyを実行する。
※Pythonなどで必要な求められたパッケージをインストールしてください。
作り方
指認識にはMediapipeのhand trackingを使用します。
コードはKazuhito00さんが作成しているサンプルを編集しています。
■元コード
・sample_hand.py
https://github.com/Kazuhito00/mediapipe-python-sample
■完成コード
・Python/client.py
実装手順
0. sample_hand.pyをダウンロード
1. 指の形認識の処理を追加
2. 指の移動量の計算処理を追加
3. Websocketへの送信
1. 指の形認識の処理を追加
下記記事で説明されているJavaScriptのコードをPythonに置き換えました。
すみませんが、内容については把握していません。
ご存知の方はコメント欄で教えください!
MediaPipe 入門 (6) - 指ポーズの検出|npaka|note
■実装部分
Python/client.py
・calcDistance()
・calcAngle()
・cancFingerAngle()
・detectFingerPose()
2. 指の移動量の計算処理を追加
detectFingerPoseで指の形を認識します。
基準値となるx, y座標を記録するorigin_posを定義しておきます。(初期値は空リスト)
最初のみ、認識した指の形が”1”のときorigin_posに基準値となるx, y座標を記録します。
2回目以降は現在の人差し指の位置と基準値との距離を計算して、基準値で割ることで正規化(-1 ~ 1の間に収める)をしています。
■実装コード
finger_pose = detectFingerPose(landmark_point)
if finger_pose == "1":
if origin_pos:
cv.circle(debug_image, origin_pos, 5, (0, 0, 255), 2)
cv.circle(debug_image, index_finger_pos, 5, (0, 0, 255), 2)
finger_x, finger_y = (origin_pos[0]-index_finger_pos[0])/origin_pos[0], (origin_pos[1]-index_finger_pos[1])/origin_pos[1]
data["pos_x"] = -1*finger_x
data["pos_y"] = finger_y
ws.send(json.dumps(data))
result = ws.recv()
else:
origin_pos = index_finger_pos
cv.circle(debug_image, origin_pos, 5, (0, 0, 255), 2)
else:
origin_pos = []
3. Websocketへの送信
まず、起動後にWebsocketサーバーとのコネクションを確立します。
次に、指認識で移動させるオブジェクトを生成するJsonデータを生成します。
その後は、カメラが指を認識している間Websocketサーバーへ移動量を送信します。
最後に、生成したオブジェクトを退出させる処理をスクリプトが終了する直前に行います。
以上、ご参考になると幸いです!
質問などは下のコメント欄でお待ちしております!
分かりにくいなどのクレームもお待ちしております!