aeroTAP SDK Depth Mask(Betaリリース) API 一覧


はじめに

Depth Map(深度マップ)で人物などのオブジェクトを検出する場合、被写体の周りの物体が邪魔になる場合があります。Depth Map APIでは、これらの周辺の3Dマスクデータを生成し、比較することで不要な周辺をマスク(消去)した結果を得ることができます。

補足: Depth Mask APIは、内部処理に統合されているので、比較的簡単に扱うことができます。また、外部から単純にマスクデータの3D管理とマスキングのためのAPIとして使うこともできます。


利用方法

例えば、下記のような環境(左が深度マップ、右がカラー)では、左に壁、右に棚が背景にある場合、

マスクデータを作成した結果、下記のような深度マップが得られます。

人物がカメラの下に入った場合、左は通常の深度画像から、マスク後の深度画像として得られます。





サンプルコード
/aeroTAPSample_Skeleton プロジェクトにあります。
操作方法:   [CREATE MASK] ボタンをクリックすると、DepthMaskデータを新規に生成します。
[ADD MASK]ボタンをクリックすると、DepthMaskを追加します。
[Enable DepthMask]チェックボックスでマスクの適用,マスク適用後のデータからスケルトン処理が行われます。



データの定義

using namespace aerotap;

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

DepthMask API 定義

typedef bool(__cdecl *AERO_InitDepthMask)();
typedef void(__cdecl *AERO_doMaskDepth)(bool bAdd);
typedef void(__cdecl *AERO_SetEnableDepthMask)(bool enable);
typedef void(__cdecl *AERO_SetDepthMaskRange)(int nRange);
typedef void(__cdecl *AERO_SetMaxDepth)(int nMaxDepth);

typedef bool(__cdecl *AERO_InitDepthMaskEx)(int w, int h, float fw, float fh);
typedef void(__cdecl *AERO_buildMaskEx)(bool bAdd, WORD *depthW);
typedef void(__cdecl *AERO_doDepthMaskEx)(WORD *depthSrc, WORD *depthTrg);
typedef bool(__cdecl *AERO_isMaskedEx)(int x, int y, int nDepth);

初期設定( Initialize )

初期化では、次のAPIが準備されています。

typedef bool(__cdecl *AERO_InitDepthMask)(); DepthMask API を使う場合このAPIを呼び出しします。
DepthMap関連のAPIは、この処理が行われていないと利用することはできません。

typedef bool(__cdecl *AERO_InitDepthMaskEx)(int w, int h, float fw, float fh);
DepthMask APIを外部から使う場合は、このAPIを最初に呼び出します。

例えば、InitAeroCam()をRAWデータモードで使っている場合、データのストリーミング中には、DepthMask処理が仲介しないため、アプリ側で実装する必要があります。

w,h: カメラ解像度 ( 例:  640,480 )
fw、fh : カメラのFocalLength。これらの値は、AERO_GetFocalLength() から取得できます。



DepthMaskの生成

次のAPIで、DepthMaskデータを生成します。実際の処理は、API()呼出し直後のフレームを使って処理されます。

typedef void(__cdecl *AERO_doMaskDepth)(bool bAdd);


DepthMaskデータは、複数回重ねて生成することができます。
bool bAdd がtrue の場合、前のデータを維持しながら新しいDepth Maskを追加します。
bAdd = false の場合、新規に生成します。

Depth Mapがある程度ばらつき(背景が少し動いている)場合、bAdd = true を使って複数毎のフレームをDepthMaskを生成してください。
typedef void(__cdecl *AERO_buildMaskEx)(bool bAdd, WORD *depthW);


RAWデータを扱う場合、このAPIを使って、取得したDepth MapからDepth Maskを生成します。

depthW には初期化で指定した解像度の距離データを渡します。





DepthMask パラメータの変更

次のAPIで、DepthMask用のパラメータを変更できます。

typedef void(__cdecl *AERO_SetDepthMaskRange)(int nRange);



nRange パラメータは、マスクする距離(半径)を cm で指定します。
デフォルトは、12cm

例えば、背景の壁から 10cmまでをマスクしたい場合は、nRange =10
typedef void(__cdecl *AERO_SetMaxDepth)(int nMaxDepth);


マスクデータを生成する場合の、有効距離 ( mm ) を指定します。
指摘距離範囲内のオブジェクトをマスクデータとします。
デフォルトは、 2000 mm

値を小さくすることで、マスクデータを小さくできます(高速化)。





DepthMask マスクの実行

次のAPIが準備されています。

次のAPIで、DepthMask用のパラメータを変更できます。

typedef void(__cdecl *AERO_SetEnableDepthMask)(bool enable);



DepthMaskを有効/無効化します。
typedef void(__cdecl *AERO_doDepthMaskEx)(WORD *depthSrc, WORD *depthTrg);



RAWデータを扱う場合は、こちらのAPIでマスク結果を得られます。
typedef bool(__cdecl *AERO_isMaskedEx)(int x, int y, int nDepth);
RAWデータを扱う場合、各Pixel単位でのマスク有効/無効の判定を得ます。




サンプルコード解説

利用方法の詳細は、サンプルコードを参照してください。ここではサンプルコードから一部を簡略して明記しています。
DepthMask APIを使うには、API初期化、マスクデータの生成、マスク処理の有効化の手順で実装します。
マスクデータが生成され、マスク処理が有効化されると、各フレームのDeth Mapデータは、マスク処理され、Skeleton処理に内部で渡されます。
マスク処理後のDepth Mapデータの取得は、AERO_DoMaskDepth() API で得られます。
////////////////////////////////////////////////////
//
// 初期化部分
//
///////////////////////////////////////////////////
using namespace aerotap;
        // API ログの生成を行うか ( TRUE )
#if 0
        if (g_pAERO_EnableLog)
            g_pAERO_EnableLog(TRUE);
#endif
          
int nMode = 1; // 8Bit Depth
            g_nPType = g_pAERO_GetPType(0);  // GS カメラ?
            if (g_nPType)
                g_nMode = aerotap::AERO_14BIT; // 14Bit Depth;
// Initialize
            if ( !g_pInitAeroCam(m_hWnd,AEROCAM_EVENT,-1,30,(void*)m_pInfoHeader[0],(void*)m_pInfoHeader[1],(void*)m_pInfoHeader[2],g_nMode) )
             {
                // Error then terminate
            }
// Set Depth Ranage 200 to 2000mm
    if ( g_pAERO_SetDepthRange )
        g_pAERO_SetDepthRange( 200, 2000 );
// Set Resolution to VGA
    if ( g_pAERO_SetResolution )
    {
        if (g_nPType)  // GSの場合 1280x720
            g_pAERO_SetResolution(0, 1280, 720);
        else
            g_pAERO_SetResolution(0,640,480);
    }
// Disable Near Operation
    g_pAERO_SetEnableNear(0);
// Disable CPU saving mode to gets FULL FPS always
    g_pAERO_SetSavingMode(0);
    // Set Skelton Parameters (  Range to search Heads, Camera Angle, Camera Height )
    g_pAERO_SetSkeletonParams(1500, 50, 2060);

    // DepthMap library の初期化
    if (!g_pAERO_InitDepthMask())
    {
        // Error
    }
   // 以下は、デフォルト以外に設定する場合にのみ必要
    g_pAERO_SetDepthMaskRange(12);   // 12cm is default
    g_pAERO_SetMaxDepth(1200); // 1200mm MaxRange to make Depth Mask


////////////////////////////////////////////////////
//
// フレーム更新時
//
///////////////////////////////////////////////////
    if (g_pAERO_DoSkeletonDetect)
        g_pAERO_DoSkeletonDetect();

// 16Bit 深度画像の取得
    if (m_nImageType == 2)
    {
// マスク後の深度データをDepthMask APIから得られます。
        int nFrame;
        if (g_pAERO_DoMaskDepth)
                g_pAERO_DoMaskDepth(m_pInfoHeader[4], 640, 480, m_nMode);
        pDepthW = (WORD*)(m_pInfoHeader[4] + 1);
    }
   else
    {
// マスク前の深度データ
        int nFrame;
        g_pAERO_GetImage(m_pInfoHeader[4], IMAGE_DEPTH_DISTANCE, NULL, NULL, NULL, &nFrame, NULL, NULL);
        pDepthW = (WORD*)(m_pInfoHeader[4] + 1);
    }

    // Skelton Data is available?
    if ( g_pAERO_isSkeletonValid() )
    {
    // BODYPARTの取得
        SkeletonPoints::BODTPART headPart;
        g_pAERO_GetSkeletonPart(SkeletonPoints::HEAD, &headPart);
    // XYZ 2D座標の取得
        SkeletonPoints::XYZ head;
        g_pAERO_GetSkeletonPos(SkeletonPoints::HEAD, &head);
        SkeletonPoints::BODYPART hand;
        if (!g_pAERO_GetSkeletonPart(SkeletonPoints::LEFT_HAND, &hand))
        {
            if (!g_pAERO_GetSkeletonPart(SkeletonPoints::RIGHT_HAND, &hand))
                hand.age = 0;
        }
        // Hand element is Valid?
        if (hand.age > 0)
        {
            //
        }
////////////////////////////////////////////////////
//
// 各種ボタン操作
//
///////////////////////////////////////////////////
void CaeroTAP3DUSB_SampleDlg::OnBnClickedButtonCapturemask()
{
    // [CAPTURE MASK]ボタンが押されると、マスクの新規生成
    g_pAERO_doMaskDepth(false);
}


void CaeroTAP3DUSB_SampleDlg::OnBnClickedButtonCapturemaskadd()
{
    // 「ADD MASK]ボタンがおされると、マスクデータの追加生成
    g_pAERO_doMaskDepth(true);
}


void CaeroTAP3DUSB_SampleDlg::OnBnClickedCheckMask()
{
    // [Enable DepthMask] チェックボックスでマスク処理の有効/無効化
    m_bMaskEnabled = ((CButton*)GetDlgItem(IDC_CHECK_MASK))->GetCheck() ? TRUE : FALSE;
    g_pAERO_SetEnableDepthMask(m_bMaskEnabled);
}