2021.09.22
Motion Gestures社 認識したジェスチャーを無償評価用のSDKを用いてSocket通信する方法
WEBマガジン非接触
1. はじめに
2. SDKおよびサンプルプログラムについて
3. Socket通信用のシステム構成
4. 改変版SDKサンプルプログラム
5. クライアント側Socket通信プログラム
6. サーバー側Socket通信プログラム
7. 動作手順
8. おわりに
1. はじめに
Motion Gestures社のAIベース・ハンドジェスチャー認識ソフトウェアプラットフォームですが、昨今のコロナ禍の状況から非接触操作のご要望が増え、お客様からの引き合いが多くなっております。
このハンドジェスチャー認識ソフトウェアの認識精度については、以下のYouTube動画を参照ください。
ハンドジェスチャー認識ソフトウェアは、ソフトウェア使用許諾書による同意が必要ですが、無償評価用のSDKが利用可能です。
今回、この無償評価用のSDKを用いた例として、認識したジェスチャーをSocket通信する方法をご紹介します。
2. SDKおよびサンプルプログラムについて
無償評価用SDKはWindows、Linux、Android、Raspberry Pi4のそれぞれの環境で用意されています。
このSDKにはサンプルプログラムが付属されており、各種APIの使用例が記載されています。
サンプルプログラムではAPIを利用することで、
・左手・右手、裏・表、上・下・左・右など手の各種認識結果
・手の平・Vサイン・拳(Fist)などのジェスチャー認識結果
などが取得・表示できるようになっています。
但し、SDKに認識結果取得用APIと取得した認識結果表示用APIは含まれていますが、それ以外のAPI、例えば認識結果を用いて何らかの制御を行う、などの制御用途としてのAPIが存在しません。
よって無償評価SDKを用いて機器や他のソフトウェアの制御を行うためには、SDKサンプルプログラムを改変し、独自の機能を追加する必要があります。
※機能追加に関して、通常はMotion Gestures社に対して有償で開発依頼を行います。ただし、独自で追加することも可能です。(PoC開発時および商用利用時には別途ライセンス費は必要)
なお、今回はWindows用のSDKを使用した場合を例としてご紹介します。また、Windows用SDKは Visual Studio利用を前提にしているため、Visual Studioでの手順を基に説明しています。
3. Socket通信用のシステム構成
初期時点におけるSocket通信用のシステム構成は、以下の通りです。
このシステムは、改変版SDKサンプルプログラム(SDKサンプルプログラムにクライアント側Socket通信機能を追加したもの)とサーバー側Socket通信プログラムの2つのプログラム(2つのexeファイル)から構成されています。
処理手順は以下の通りです。
(1)改変版SDKサンプルプログラムで、ジェスチャー認識を行う。
(2)改変版SDKサンプルプログラム内で、ジェスチャー認識結果をクライアント側Socket通信部に渡す。
(3)改変版SDKサンプルプログラムのクライアント側Socket通信部からサーバー側Socket通信プログラムへ、Socket通信を介してジェスチャー認識結果を送信する。
(4)サーバー側Socket通信プログラム内で、ジェスチャー認識結果を受け取る。
(5)受け取ったジェスチャー認識結果を基に、サーバー側Socket通信プログラム内で、何らかの処理を行う。
しかしながら、SDKサンプルプログラムにSocket通信機能を追加するために
#include <winsock2.h>
と、Windows用Socket通信headerファイルを組み込んだところ、Visual Studioにて下記Errorが発生するようになりました…。
SDKのAPI内で使用している列挙型のメンバに、「IN」「OUT」を使用しているのが原因だと思われます。無償評価用SDKでのAPI自体の修正は不可能なため、何らかの対策が必要です。
上記問題に対応するため、構想初期時点のシステム構成から、以下の仕様に変更します。
・改変版SDKサンプルプログラム内に、Socket通信機能を入れない。
・改変版SDKサンプルプログラム内にジェスチャー認識結果標準出力を追加。
・改変版SDKサンプルプログラムからクライアント側Socket通信を分離し、単独プログラムとする。
・クライアント側Socket通信プログラムは、ジェスチャー認識結果の標準入力を持つ。
変更後のシステム構成を以下に示します。
変更後のシステムは、改変版SDKサンプルプログラム、クライアント側Socket通信プログラム、サーバー側Socket通信プログラムの3つのプログラム(3つのexeファイル)から構成されています。
標準出力/標準入力を使用した場合の処理手順は以下の通りです。
(1)改変版SDKサンプルプログラムで、ジェスチャー認識を行う。
(2)改変版SDKサンプルプログラムから、ジェスチャー認識結果を標準出力で出力する。
(3)クライアント側Socket通信プログラムで、ジェスチャー認識結果を標準入力として取り込む。
(4)クライアント側Socket通信プログラムからサーバー側Socket通信プログラムへSocket通信を介して、ジェスチャー認識結果を送信する。
(5)サーバー側Socket通信プログラム内で、ジェスチャー認識結果をサーバー側Socket通信部から受け取る。
(6)受け取ったジェスチャー認識結果を基に、サーバー側Socket通信プログラム側で、何らかの処理を行う。
以上で、SDKサンプルプログラムを流用したSocket通信用のシステム構成を説明しました。
次からは、各プログラムの中身に関して説明します。
4. 改変版SDKサンプルプログラム
まず、SDKサンプルプログラムですが、Motion Gestures社のSDKに関するソフトウェア使用許諾書による同意を頂いてからの開示となるため、Webマガジン上では公開不可となっております。ご了承下さい。
よって改変版SDKサンプルプログラムについては、修正内容の概要説明のみとなります。
改変版SDKサンプルプログラムにて、ジェスチャー認識後に以下の標準出力記述を追加しています。
std::string str = ジェスチャー認識結果を取得するAPI; str.erase(std::remove(str.begin(), str.end(), ‘ ‘), str.end()); //スペースを削除 std::cout << “SOCKT_COMM:” << str<< std::cout; |
ジェスチャー認識結果は、SDKに取得用APIがあるので、それを使用しています。
str.eraseでスペースを削除しているのは、一部のジャスチャー認識結果(ジェスチャー名)にスペースが含まれているためです。スペースが入ったジャスチャー認識結果をそのまま標準出力した場合、クライアント側Socket通信プログラムの標準入力時に2つのジェスチャー認識結果として取り込んでしまうため、これを回避するためです。
また、ジェスチャー認識結果を標準出力する際に「SOCKET_COMM:」を付けています。後段のクライアント側Socket通信プログラムにて、標準入力で文字列を受け取った後、「SOCKET_COMM:」がついているものだけをSocket通信で送信する仕様にしているためです。
なお、実際は改変版SDKサンプルプログラム内で以下の修正も加えておりますが、ソースコードを表示して説明する必要があるため、今回の説明では省略しています。
・一定の間隔(例えば0.5秒間隔)で、ジェスチャーを認識する。
・ジェスチャー認識結果を標準出力後、これを前回のジェスチャー認識結果として保持する。
・ジェスチャー認識結果が、前回と同じ場合は標準出力しない。
・手が消えた場合は、前回のジェスチャー認識結果をクリアする。
・クライアント側Socket通信プログラムの終了用として、改変版SDKサンプルプログラム終了時に「MG_DEMOSW_END」を標準出力する。
5. クライアント側Socket通信プログラム
クライアント側Socket通信プログラムはVisual Studioでコンソールアプリケーションとして作成します。コンソールアプリの作成については「Visual Studio C++ コンソールアプリケーション 作成」などで検索し、新規プロジェクトとして作成する方法を調べてください。またbuild方法(exeファイル生成)に関しても、「Visual Studio C++ コンソールアプリケーション build」などで検索し、調べてください。
本プログラムのソースコードを以下に示します。コンソールアプリケーションのソースコードとして使用可能です。
なお、クライアント側・サーバー側の両Socket通信に関しては、「技術的特異点」ブログの『Winsock2を使ってC++でネットワークプログラミング』のエントリーでのプログラムを基に改変しております。
当社で追記したコメントには「//★」と星印をつけています。
#include <stdio.h> int main(int argc, char *argv[]) { // Windows Sockets仕様に関する情報を格納する構造体 // WinSockの初期化処理(Version 2.0) // sockaddr_in構造体の作成とポート番号、IPタイプの入力 // 引数は (1) Type(ipv4 or v6) (2) IPアドレスのテキスト形式 (3) IPアドレスのバイナリ形式【(2)→(3)に変換】 // AF_INETはipv4のIPプロトコル & SOCK_STREAMはTCPプロトコル // 接続処理 char send_buf[256]; //★送信用バッファー //★Socket送信処理 // 解放処理 // WinSockの終了処理 |
なお、Visual Studioにて、x86ではなくx64でbuildする場合、リンカツールエラー(LNK2019)が発生します。
その場合は、winsock2.hのinclude後に、以下の記述を追加してbuildしてください。
#pragma comment(lib, “ws2_32.lib”) |
6. サーバー側Socket通信プログラム
サーバー側Socket通信プログラムのソースコードを、以下に示します。
注意事項については、クライアント側Socket通信プログラムと同じです。
#include <stdio.h> #include <winsock2.h> #include <ws2tcpip.h> #include <iostream> int main() { // ポート番号 int port_number = 12345; // Windows Sockets仕様に関する情報を格納する構造体 WSADATA wsa_data; // WinSockの初期化処理(Version 2.0) if (WSAStartup(MAKEWORD(2, 0), &wsa_data) != 0) { std::cerr << “Winsockの初期化失敗(WSAStartup)” << std::endl; } // サーバ側ソケット作成 int src_socket; // sockaddr_in構造体の作成とポート番号、IPタイプの入力 struct sockaddr_in src_addr; memset(&src_addr, 0, sizeof(src_addr)); src_addr.sin_port = htons(port_number); src_addr.sin_family = AF_INET; src_addr.sin_addr.s_addr = htonl(INADDR_ANY); // AF_INETはipv4のIPプロトコル & SOCK_STREAMはTCPプロトコル src_socket = socket(AF_INET, SOCK_STREAM, 0); // クライアント側のソケット設定 // 接続の待受を開始する // 送受信に使用するバッファ // クライアントからの接続待ちループ関数 // クライアントからの接続を受信する // 接続後の処理 //パケットの受信(recvは成功すると受信したデータのバイト数を返却。切断で0、失敗で-1が返却される //★受信したジェスチャー名を表示 //★受信した文字列をrecv_bufに格納 //★受信後の文字列を使って何か処理をする場合はここに追加 // 結果を格納したパケットの送信 |
7. 動作手順
改変版SDKサンプルプログラム、クライアント側Socket通信プログラム、サーバー側Socket通信プログラムのbuildを行い、exeファイルを生成します。exeファイル生成後の動作手順を、以下に示します。
なお、以下の操作はWindowsのコマンドプロンプトまたはPowerShellにて実施します。
・事前準備
(1)Windowsのエクスプローラーなどを使用し、クライアント側Socket通信プログラムのexeファイルを、改変版SDKサンプルプログラムのexeファイルがあるフォルダにコピーしておきます。
(2)サーバー側Socket通信プログラムを実行するWindows PCのIPアドレスを調べておきます。
・サーバー側Socket通信プログラム実行手順 ※こちらを先に起動する必要があります。
(1)コマンドプロンプロ、またはPowerShellを起動します。
(2)サーバー側Socket通信プログラムのexeファイルがあるフォルダに移動します。
(3)サーバー側Socket通信プログラムのexeファイルを起動します。
※サーバー側Socket通信プログラムのexeファイル名がtest_server.exeであれば、.\test_server.exeで起動します。
・改変版SDKサンプルプログラム+クライアント側Socket通信プログラム実行手順
(1)コマンドプロンプト、またはPowerShellを起動します。
(2)改変版SDKサンプルプログラムの、exeファイルがあるフォルダに移動します。
(3)以下のコマンドで、改変版SDKサンプルプログラムとクライアント側Socket通信プログラムを起動します。
.\改変版SDKサンプルプログラムexeファイル名 各種コマンドオプション | .\クライアント側Socket通信プログラムexeフィル名 サーバーIPアドレス 12345
※クライアント側Socket通信プログラムexeファイル名がtest_cliant.exe、サーバー側Socket通信プログラムを実行するWindows PCのIPアドレスが192.168.0.10とした場合、パイプ( | )以降のコマンドを以下に示します。
.\test_cliant.exe 192.168.0.10 12345
上記手順で実行した際の表示結果を、以下に示します。この写真ではサーバー側Socket通信プログラムも同一Windows PC上で動作させていますが、別のWindows PCでも問題なく動作します。
8. 終わりに
今回はMotion Gestures社ハンドジェスチャー認識ソフトウェアの無償評価用SDKのサンプルプログラムを用いて、認識したジェスチャーをSocket通信する方法をご紹介しました。
ちなみに、このシステム構成であれば、改変版SDKサンプルプログラムを他の標準出力を持つプログラムに差し替えて、Socket通信用のプログラムとして流用することが可能となっています。
Motion Gestures社の無償評価用SDKに関して、Windows用SDKインストールマニュアル・SDKサンプルプログラムの使用方法・SDKのAPI使用方法など、各種日本語マニュアルを用意しております。
本コラムに関するご質問やご要望等ございましたら、ページ下部のWEBマガジンお問い合わせフォームより、お気軽にお問い合わせください。