2023.05.02

Motion Gestures社のSDKを用いてハンドジェスチャーでマウス操作をする方法

WEBマガジン非接触

  • TOP>
  • 特集>
  • Motion Gestures社のSDKを用いてハンドジェスチャーでマウス操作をする方法
コーンテクノロジー
この記事の監修者
コーンズテクノロジー編集部
コーンズテクノロジーでは先進的な製品・技術を日本産業界へ紹介する技術専門商社として、通信計測・自動車・防衛セキュリティ・電子機器装置・航空宇宙・産業機械といった技術分野のお役立ち情報を紹介しています。

目次

1.はじめに

2.Windows APIについて

3.ハンドジェスチャーの情報取得

4.コードの実装

5.動作例

6.終わりに

7.参考資料

 

1. はじめに

Motion Gestures社では独自の機械学習技術で構築した高速・高精度のハンドトラッキングSDKを提供しています。Motion Gestures社のSDK(以下、MG SDK)を利用して多様な手指情報の取得、ジェスチャー認識が可能になります。ハンドジェスチャーの認識は、最近重要性が高くなっている非接触操作、ヒューマンフレンドリー・インターフェースの構築に多く活用されている技術です。

今回はMG SDKを用いて、ハンドジェスチャーからWindows環境でマウス操作をするデモプログラムについてご紹介いたします。

デモプログラムの開発環境は次のようになります。

・OS:Windows 10

・MG SDK ver. 1.7.0 (無償評価版) 

・Visual Studio, C++

 

2. Windows APIについて

 Windows API [1] とはMicrosoft社の Wintodws OS上で操作可能なAPI(Application Programming Interface)です。Windows 95以降やWindows NTで利用出来るのはWin32APIとも呼んでいます。Wiindows APIはファイルシステムやデバイスなどのリソース関連、Windowsレジストリやユーザー管理などのカナル関連、グラフィックデバイスインターフェース、ユーザーインターフェースなどのハンドリング関数を提供しています。特にCとC++向けには<windows.h>をはじめとする多数のヘッダーファイルが公開されています。マウス操作、ウィンドウハンドル、キーボード操作などのためにはwindows.hをインクルードする必要があります。今回はWindows APIを利用して、マウスカーソル移動、マウスクリック、マウスホイール操作をおこなうデモプログラムを作成します。

 

3. ハンドジェスチャーの情報取得

 まず、どの情報を取得してマウス操作をするのか決めます。本デモでは 1) 人差し指でマウスカーソル移動、2) ピンチジェスチャー認識でマウスクリック動作、3) Swipe 動作でマウスホイールを操作します。手指の位置情報と動的ジェスチャーの情報はMG SDKから取得します。MG SDKでは図1のように21個の関節 (以下、joint) の情報を取得することができます。本デモでは人差し指でマウスカーソルを移動するため8番jointの位置情報を使います。ピンチジェスチャーの認識は8番jointと4番jointの位置情報を利用します。

 RGBカメラの場合、取得するjointの位置情報の内容はフレームの中でのX、Y座標になります。図2のように8番jointのX、Y座標を得ることが出来ます。この情報の取得をフレーム毎に行います。取得した手指の情報と動的ジェスチャーを利用してマウス操作をするコードは次の章で説明いたします。

 

(図1:MG SDKから取得できるjoints情報)

 

(図2:joint 座標情報の例)

 

 

 

4. コードの実装

 デモプログラムはMG SDKのサンプルコードをベースとして作成しています。MG SDKのサンプルコードは使用許諾書による同意を頂いてからの開示となるため公開不可になっております。そのため処理内容の記述のみとなること、ご了承ください。 

 本デモプログラムの構造は図3のようになります。コードの公開ができる「joint座標取得でマウスカーソル移動関数を呼び出す」、「joints間距離計算をしてマウスクリック関数を呼び出す」、「Swipeジェスチャー認識でマウスホイール関数を呼び出す」、「マウスクリック関数」、「マウスホイール関数」コードを本章で説明いたします。

 * 本デモではWindows APIを使用するため、<windows.h>をインクルードする必要があります。(#include <windows.h>)

 

(図3. デモプログラム(demo.cpp)の構造)

 

 

・マウスカーソルの移動操作:joint 座標取得してカーソル関数を呼び出す

/*demo.cpp*/

(~省略~)

                SDK専用ポイント構造体 fingerp = 8番jointのポイント;
                
                int x = fingerpのX座標;
                int y = fingerpのY座標;
           
                          
                SetCursorPos(x, y);      

(~省略~)

 

 

 次はマウスクリック動作の実装です。本デモではピンチ動作が認識されたらマウス左クリックを行うようにしています。マウスクリックはWindows APIのマウスイベントを利用して簡単な関数を定義して使います。

 

・マウス左クリック関数 ([3])

/*demo.cpp*/

void lclick(int x, int y) {
    SetCursorPos(x, y);
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    Sleep(100);  
}

 マウス右クリックを使う場合は、MOUSEEVENTF_LEFTDOWNとMOUSEEVENTF_LEFTUPの代わりにMOUSEEVENTF_RIGHTDOWN、MOUSEEVENTF_RIGHTUPを使います。

 

 ピンチジェスチャーの認識はMG SDKで提供されていないため、joint位置情報を応用して行います。ピンチジェスチャーは人差し指の8番jointと親指の4番jointの座標の距離から判断します。8番jointの座標はマウスカーソルの移動のためにすでに取得しているので、4番jointの座標だけ追加取得します。4番jointと8番jointの間の距離がしきい値以下になったらピンチ動作と認識します。2次元空間にある2点間の距離はユークリッド距離[2]で計算します。

 

・二次元空間でポイントpとqの間のユークリッド距離を求める式

 

・ピンチ動作の認識 : joints間距離計算をしてマウスクリック関数を呼び出す

/*demo.cpp*/
SDK専用ポイント構造体 fingerb = 4番jointのポイント; /*fingerpは8番jointのポイント*/

int dx = fingerpのX座標 - fingerbのX座標;
int dy = fingerpのY座標 - fingerbのY座標;

float f_diff = pow(dx, 2) + pow(dy, 2);
f_diff = sqrt(f_diff);
 
if (f_diff < threshold) {                       
         lclick(x, y);             
    }

 本デモプログラムではしきい値(threshold)を50(pixel)に設定しました。

 

 次はSwipe UP/DOWN動作を認識してマウスホイールを動かすコードです。Swipe UP/DOWN動作の認識はMG SDKで可能なため、Swipe Up / Downが認識されたらおこなう動作コードのみ作成します。

 まずは次のようにマウスホイールの関数を作ります。

・マウスホイール関数 ([3])

/*demo.cpp*/

void wheel(int d) {
    mouse_event(MOUSEEVENTF_WHEEL, 0, 0, d, 0); /*d = distance*/
    Sleep(100);
   }

 

 設定された d (=distance) の分、ホイールが動きます。本デモプログラムでは d = 100 と設定しました。

 

 Swipe UP/DOWN情報をMG SDKから読み込んで、マウスホイール関数を呼び出すコードは次のようになります。

 

・マウスホイール操作 : Swipe ジェスチャー認識でマウスホイール関数を呼び出す

/*demo.cpp*/

for(ハンドジェスチャー情報がある){
  (~省略~)
  if (動的ジェスチャーが認識された場合)
                 {
                    auto name = 動的ジェスチャーの名称;
                    (~省略~)                    
                   
                                       
                    if (マウスホイール動作が可能 && 他のマウス操作をしていない状態) {

                        if (name == "Swipe Up") {
                            status = Wheel Up 動作の状態;

                        }
                        else if (name == "Swipe Down") {
                            status = Wheel Down 動作の状態;
                        }

                       
                     }
    }


 (~省略~)
  if (他のマウス操作をしていない状態) {
                if ( status==Wheel Up ) {
                    wheel(-d);
                    status初期化;
                                        
                }
                else if (status == Wheel Down ) {
                   wheel(d);
                   status初期化 ;
                }
  }

}

 

本稿では基本的なコードの構造のみ説明しています。各動作が衝突することなくスムーズに行われるステータスの設定などは省略されていますので、皆様の環境や動作目的に合わせて設定ください。

 

 

5. 動作例

MG SDKとWindows APIを用いて、Windows環境でハンドジェスチャーを認識し、マウス操作を行う動作例は次のようになります。

(動画1:ハンドジェスチャーの認識でマウスカーソルの移動とマウスクリックをする様子)

 

 

(動画1:ハンドジェスチャーの認識でマウスホイール操作をする様子)

 

 

6. 終わりに

今回はMG SDKとWindows APIを利用し、「ハンドジェスチャーでマウス操作をする方法」を紹介いたしました。Motion Gestures社の製品は多様なハンドジェスチャー認識基盤のアプリケーション開発に適しており、MG SDKを利用することによりマウス操作以外にも有用な応用プログラムを作成することができます。また、MG SDKはWindowsのみならず、Linux、Androidなど様々なOSや開発プラットフォームをサポートしています。Motion Gestures社の製品にご興味のある方はご遠慮なくお問い合わせください。

 

 

7. 参考資料

[1] Windows API : https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-mouse_event

[2] ユークリッド距離:https://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%BC%E3%82%AF%E3%83%AA%E3%83%83%E3%83%89%E8%B7%9D%E9%9B%A2

[3] マウス操作コード参考 :https://qiita.com/lzpel/items/a397c4631ca591551076