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単位でのマスク有効/無効の判定を得ます。
|
|
|
サンプルコード解説
// 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);
}