MediaPipeのHandsで手の回転量やBoundingBoxを取得する!

8月 6, 2021

手のトラッキングを気軽にできるソフトウェアとして, Googleの開発しているMediaPipe Handsがあります. デフォルトでHandsは手の代表点と右手左手の判別の結果を出力します. MediaPipeのビルド時にカスタマイズすると, これらに加えて手の回転量やBoundingBoxを取得することができます.

準備したもの

セットアップ

Raspberry Pi

Raspberry Pi Imagerを使ってSDカードにUbuntu OSをインストールします. “Ubuntu Desktop 21.04.2 LTS"を選択し, micro SDカードに書き込みます.

MediaPipe

MediaPipeをビルドするためにビルドツールのbazelをインストールします.

# install npm
sudo apt install npm
# install bazel
sudo npm install -g @bazel/bazelisk

インストール中にpythonコマンドが実行されるので"python3″を"python"で実行できるようにしておきます.

sudo nano ~/.bashrc

alias python = "python3"
alias pip = "pip3"

編集後, 設定を反映します.

source ~/.bashrc

シンボリックリンクを作成しておきます.

sudo ln -s /usr/bin/python3 /usr/bin/python

MediaPipeのビルドに必要なものをインストールします.

#Install build dependencies
sudo apt install -y cmake
sudo apt install -y protobuf-compiler
python -m pip install cython
python -m pip install numpy
python -m pip install pillow

githubからMediaPipeのソースを取得し, ビルド設定ファイルを編集します.

git clone https://github.com/google/mediapipe.git
cd mediapipe
sed -i -e "/\"imgcodecs\"/d;/\"calib3d\"/d;/\"features2d\"/d;/\"highgui\"/d;/\"video\"/d;/\"videoio\"/d" third_party/BUILD
sed -i -e "/-ljpeg/d;/-lpng/d;/-ltiff/d;/-lImath/d;/-lIlmImf/d;/-lHalf/d;/-lIex/d;/-lIlmThread/d;/-lrt/d;/-ldc1394/d;/-lavcodec/d;/-lavformat/d;/-lavutil/d;/-lswscale/d;/-lavresample/d" third_party/BUILD

outputにhand_rects, palm_detectionsを追加

# edit outputs
nano mediapipe/python/solutions/hands.py

+ outputs = ['multi_hand_landmarks', multi_handedness', 'hand_rects', 'palm_detections']
- outputs = ['multi_hand_landmarks', multi_handedness']

最後にビルドコマンドを実行します.

#Build the package
python setup.py gen_protos && python setup.py bdist_wheel

ビルドが完了したらdistフォルダにmediapipe-0.8-cp39-cp39-linux_aarch64.whlが生成されます.
これをpipでインストールします.

# install mediapipe
pip install mediapipe-0.8-cp39-cp39-linux_aarch64.whl

正常にインストールできたら成功です!

使い方

手の回転量

手の代表点と右手左手の判別の結果と同様にprocessメソッドで手の回転量を取得します. 単位はラジアンです.

results = hands.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
if results.hand_rects:
    for rect in results.hand_rects:
        print(rect)

下記結果が得られます.

x_center: 0.7076132893562317
y_center: 0.4579037129878998
height: 1.0035101175308228
width: 0.6690067052841187
rotation: -0.29718053340911865

BoundingBox

手の代表点と右手左手の判別の結果と同様にprocessメソッドでBoundingBoxを取得します.

results = hands.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
if palm_detections:
    for palm_detection in results.palm_detections:
        print(palm_detection.location_data.relative_bounding_box)

下記結果が得られます.

xmin: 0.6212505102157593
ymin: 0.46138930320739746
width: 0.2514756917953491
height: 0.37721356749534607

おわりに

手の回転量やBoundingBoxを取得できると手の代表点の回転量や大きさの補正をするのに役立ちます. ぜひお試しを!