aeroTAP evo API一覧


はじめに

aeroTAP evo API は、aeroTAP evo (タッチレスインターフェイス)を実行しながら手のひらトラッキングの状態を取得するためのAPIです。
カーソルの表示はアクションをaeroTAP evo側ではなく、アプリケーション側で処理する際に利用できます。

サンプルコードは、/aeroTAPAPI プロジェクトにあります。

aeroTAP evo APIを利用するための環境設定

aeroTAP evo APIを利用したアプリを実行するには、以下のaeroTAP 関連ファイルを、最新版のaeroTAPからご自身のアプリと同じフォルダーにコピーします。
以下は、aeroTAP evoを実行するために必要な最低モジュールです。aeroTAP_CAM.DLLを介して、aeroTAP evoの情報を共有します。
aeroTAP.exe
aeroTAP_CAM.DLL
Berldle.dll
aeroBootCheck.exe
aeroTAP を起動して、以下の設定を変更してください。その他、カーソル表示などもアプリ側で表示する場合には、[なし]を選択するなど、アプリに合わせて設定してください。
設定
解説
[ようこそ] タブ
ガイダンス表示 OFF
aeroTAP のガイダンス表示機能をOFFにします。

APIを使って、人物の有無を判断しながら同様なガイダンスをアプリ側で表示することが可能です。
[詳細設定]-タブ シンプルな操作のためにマルチタッチ機能をオフにします。
[詳細設定]タブ
クリックアクション なし
クリックなどのアクションは、アプリ側で行うためにオフにします。
[全般]タブ
プレビュー表示 なし
プレビュー表示をしない


データの定義

using namespace aerotap;

aeroTAP API関連のデータおよび関数はすべて namespace aerotapに定義しています。

カラー画像、深度画像、aeroTAP evoステータスデータの構造体

下記の構造体を準備します。 TAPINFO tapinfoには、aeroTAP evoでの手のひらトラッキング情報が得られます。

aeroTAP evo 手のひらトラッキング ステータスデータ定義
typedef struct _aeroState
 {
    int nSize;    // 構造体サイズ
    bool bActive[2];
    int nObjectType[2];
    POINT3I pos[2];
    bool bPerson;
    POINT3F posG;
    POINT3F pos3D[2];
    POINT3D posHead; //
    char info[16];        // reserved
} AEROSTATE;

API定義

typedef BOOL(__cdecl *AERO_GetAeroState)(void *lpszBuf); の引数として使用
aeroTAP evo データ定義
typedef struct _sharedMEM
{
    int nMode;
    TAPINFO tapinfo;
    int nFrame;
    BITMAPINFOHEADER bmpInfoHeader;
    unsigned char pData[1280 * 720 * 3];
    BITMAPINFOHEADER bmpInfoHeaderDepth;
    WORD pDataW[1280 * 720];
    AEROSTATE aeroState;
} SHAREDMEM;

API解説



aeroTAP evo ステータス情報の取得
typedef BOOL(__cdecl *AERO_GetAeroState)(void *lpszBuf);
現在のaeroTAP evo状態を構造体 AEROSTATに取得します。
引数:
AEROSTATE構造体のポインタを使用します。

戻り値:
成功 TRUE , 失敗 FALSE

bActive[2] ポイントが有効(TRUE)/無効(FALSE)
bObjectType[2]  ポイントの種類 0手のひら、1 クリック(握る)
POINT3i pos[2]  現在の画面解像度での座標系でのポイント位置(X,Y,Z) 
bPerson 人物の有(TRUE)/無(FALSE)
posG 人物の重心点(X,Y,Z)

*座標は 320x240 座標系(左上がX=0,Y=0)
*aeroTAP evoは、最大2点を追跡します。
 

オペレーターの身長の計算

AEROSTATE aeroState.posHead を取得して、カメラ前面のオペレーターの頭部の座標( X,Y,Z ) (単位はmm)からオペレーターの身長を計算することができます。
計算には、カメラの設置している高さ(床からの高さ) mm と、カメラの傾き角度(下向きが+、上向きが-の値)が必要です。
例えば、カメラを床から200cmの位置に設置して、下に10°傾けた設定の場合、以下の計算で求めることができます。

int nCamHeadInclined = 10; // Degree
int nCamHeadPositionY= 200; // cm

POINT3F posHead =aeroState.posHead;   //頭部3D位置の取得

double inclinedR = nCamHeadInclined*M_PI/180;
// 身長 cm
 posHead.y = nCamHeadPositionY - posHead.z*sin(inclinedR)/10 - posHead.y*cos(inclinedR) /10;
//   カメラからの距離 cm
 posHead.z = posHead.z*cos(inclinedR) / 10;

サンプルコード C++

        AEROSTATE aeroState;


        aeroState.nSize = sizeof(AEROSTATE);

       if (g_pAERO_GetAeroState && g_pAERO_GetAeroState(&aeroState))
        {
            CString sTmp;
            // Operator info
            sTmp.Format(_T("%s"), aeroState.bPerson ? _T("Exist") : _T("N/A"));
            GetDlgItem(IDC_STATIC_OPERATOR)->SetWindowTextW(sTmp);

            if (aeroState.bPerson)
                sTmp.Format(_T("x: %d , y: %d,  z: %d"), (int)aeroState.posG.x, (int)aeroState.posG.y, (int)aeroState.posG.z);
            else
                sTmp = _T("N/A");
            GetDlgItem(IDC_STATIC_OP_POS)->SetWindowTextW(sTmp);

            // Palm Tracking info
            sTmp.Format(_T("%s"), aeroState.bActive[0] ? _T("Tracking") : _T("N/A"));
            GetDlgItem(IDC_STATIC_PALM)->SetWindowTextW(sTmp);

            if (aeroState.bActive[0])
                sTmp.Format(_T("x: %d , y: %d,  z: %d"), (int)aeroState.pos[0].x, (int)aeroState.pos[0].y, (int)aeroState.pos[0].z);
            else
                sTmp = _T("N/A");

            GetDlgItem(IDC_STATIC_PALM_POS)->SetWindowTextW(sTmp);


サンプルコード Unity C#

サンプルコード利用方法:

1. Unityで新しいプロジェクトを作成し、保存

2. 作成されたプロジェクトフォルダーのAssets/Plugins/x86_64に aeroTAP_CAM.dll, eSPDI.dll をコピー

3. Unity ProjectにあるAssets/Plugins/x86_64/aeroCAM_DLLをクリックし、Inspectorを設定 (OS:Windows, CPU:x86_64 )

4. GameObject->3D Object -> Cubeで立方体を作成 (任意のオブジェクト)

5. Inspector の[Add Component] ボタンでNew Script を選択し、aeroTAP として[Create and Add]で作成

6. aeroTAP.cs を編集(下記コードを張り付け)

7. Ctrl+Bでビルド実行

*ここでは、ビルドを確認する。

8.ビルドに問題が無いことを確認したら、aeroTAP evoを起動し、作成したUnity プロジェクトを実行する

*人物の検出、手のひら検出をUnity側で受け取っていることを確認

[aeroTAP.cs]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System;

public class aeroTAP : MonoBehaviour
{
    string message = "";
    public struct POINT3I
    {
        public int x;
        public int y;
        public int z;
    }
    public struct POINT3F
    {
        public float x;
        public float y;
        public float z;
    }
    struct _aeroState
    {
        public int nSize;  // size of this structure
        public short bActive1;
        public short bActive2;
        public int nObjectType1;
        public int nObjectType2;
        public POINT3I pos1;
        public POINT3I pos2;
        public short bPerson;
        public POINT3F posG;
        public POINT3F pos3D1;
        public POINT3F pos3D2;
        public POINT3D posHead;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string info;      // reserved
    }

    [DllImport("aeroTAP_CAM")]
    private static extern bool AERO_GetAeroState(ref _aeroState pAeroState);

    _aeroState aeroState = new _aeroState()
    {
        bActive1 = 0,
        bPerson = 0,
        nSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(_aeroState))

    };
    // Start is called before the first frame update
    void Start()
    {
        //        aeroState.info = new char(16);
    }

    // Update is called once per frame
    void Update()  
    {
        message = "API returns error";

   
        if (AERO_GetAeroState( ref aeroState))
        {
            if ( aeroState.bPerson!=0)
            {
                message = "Person exist";
                message += string.Format("\r\n x:{0:F} y:{1:F} z:{2:F}",aeroState.posG.x, aeroState.posG.y, aeroState.posG.z);

                message += string.Format("\r\nPalm Tacking...: {0:D}", aeroState.bActive1);
                if (aeroState.bActive1!=0)
                {
                    // ObjectType 0: Open Palm, 1:Close Palm
                    message = string.Format("\r\nObjectType: {0:D}", aeroState.nObjectType1);
                    message += string.Format("\r\nPosition: x:{0:D} y:{1:D} z:{2:D}", aeroState.pos1.x, aeroState.pos1.y, aeroState.pos1.z);
                    message += string.Format("\r\nPosition in 3D x:{0:F} y:{1:F} z:{2:F}", aeroState.pos3D1.x, aeroState.pos3D1.y, aeroState.pos3D1.z);
                    transform.position = new Vector3((aeroState.pos1.x-700)/100, -(aeroState.pos1.y-400)/100, 0);
                }
            }
            else
                message = "No Person";
        }
    }
    void OnGUI()
    {
        GUI.skin.label.fontSize = 24;
        GUI.color = Color.red;
        GUI.Label(new Rect(20, 20, 800,400), message);
    }
}