我使用VisualGestureBuilder C ++ API跟踪三个简单的离散手势。
当Kinect前面只有一名玩家时,效果很好。 但是一旦第二个玩家到来,手势分析似乎就变得疯狂了,对于这两个玩家来说,我得到的是不稳定而且流畅的结果,好像两个玩家和三个手势的数据混合在一起,以及随机数据被添加......
虽然VGB API出错了,但我仍然可以获得有效的身体数据(我同时绘制骨架)
我发现只要有一个以上的IVisualGestureBuilderFrameReader处于未暂停状态,就会触发这种现象。
以下是我的代码的一些部分:
class GESTURES_STREAM
{
friend class MY_KINECT;
private:
struct SLOT
{
IVisualGestureBuilderDatabase* database = nullptr;
IGesture** gestures = nullptr;
UINT gestures_count = 0;
IVisualGestureBuilderFrameSource* source = nullptr;
IVisualGestureBuilderFrameReader* reader = nullptr;
IVisualGestureBuilderFrame* frame = nullptr;
};
SLOT slots[BODY_COUNT];
public:
GESTURES_RESULTS gestures_results[BODY_COUNT];
};
GESTURES_STREAM gestures_stream;
//----------------------------------------------------------------------------------------------------
void MY_KINECT::start_gestures_stream(wstring vgb_file)
{
for (int i = 0; i < BODY_COUNT; i++)
{
hr = CreateVisualGestureBuilderDatabaseInstanceFromFile(vgb_file.c_str(), &gestures_stream.slots[i].database);
if (FAILED(hr)) MY_UTILITIES::fatal_error("Erreur initialisation Kinect : gestures");
gestures_stream.slots[i].gestures_count = 0;
hr = gestures_stream.slots[i].database->get_AvailableGesturesCount(&gestures_stream.slots[i].gestures_count);
if (FAILED(hr)) MY_UTILITIES::fatal_error("Erreur initialisation Kinect : gestures");
if (gestures_stream.slots[i].gestures_count == 0)
{
MY_UTILITIES::fatal_error("Erreur initialisation Kinect : gestures");
}
gestures_stream.slots[i].gestures = new IGesture*[gestures_stream.slots[i].gestures_count];
hr = gestures_stream.slots[i].database->get_AvailableGestures(gestures_stream.slots[i].gestures_count, gestures_stream.slots[i].gestures);
if (FAILED(hr)) MY_UTILITIES::fatal_error("Erreur initialisation Kinect : gestures");
/////
hr = CreateVisualGestureBuilderFrameSource(kinect_sensor, 0, &gestures_stream.slots[i].source);
if (FAILED(hr)) MY_UTILITIES::fatal_error("Erreur initialisation Kinect : gestures");
hr = gestures_stream.slots[i].source->AddGestures(gestures_stream.slots[i].gestures_count, gestures_stream.slots[i].gestures);
if (FAILED(hr)) MY_UTILITIES::fatal_error("Erreur initialisation Kinect : gestures");
hr = gestures_stream.slots[i].source->OpenReader(&gestures_stream.slots[i].reader);
if (FAILED(hr)) MY_UTILITIES::fatal_error("Erreur initialisation Kinect : gestures");
hr = gestures_stream.slots[i].reader->put_IsPaused(TRUE);
if (FAILED(hr)) MY_UTILITIES::fatal_error("Erreur initialisation Kinect : gestures");
/////
safe_release(&gestures_stream.slots[i].database);
}
}
//----------------------------------------------------------------------------------------------------
void MY_KINECT::update()
{
//...
//...
// handling all the different stream, including body
//...
//...
if (body_stream.data_is_new == true)
{
for (int i = 0; i < BODY_COUNT; i++)
{
if (gestures_stream.slots[i].source != nullptr)
{
BOOLEAN is_tracked;
if (body_stream.bodies[i]->get_IsTracked(&is_tracked) == S_OK)
{
if (is_tracked == TRUE)
{
UINT64 a;
if (body_stream.bodies[i]->get_TrackingId(&a) == S_OK)
{
UINT64 b;
if (gestures_stream.slots[i].source->get_TrackingId(&b) == S_OK)
{
if (a != b)
{
gestures_stream.slots[i].source->put_TrackingId(a);
}
}
}
BOOLEAN paused;
if (gestures_stream.slots[i].reader->get_IsPaused(&paused) == S_OK)
{
if (paused == TRUE)
{
gestures_stream.slots[i].reader->put_IsPaused(FALSE);
}
}
}
else
{
BOOLEAN paused;
if (gestures_stream.slots[i].reader->get_IsPaused(&paused) == S_OK)
{
if (paused == FALSE)
{
gestures_stream.slots[i].reader->put_IsPaused(TRUE);
}
}
}
}
}
if (gestures_stream.slots[i].reader != nullptr)
{
if (gestures_stream.slots[i].reader->CalculateAndAcquireLatestFrame(&gestures_stream.slots[i].frame) == S_OK)
{
BOOLEAN is_valid;
if (gestures_stream.slots[i].frame->get_IsTrackingIdValid(&is_valid) == S_OK)
{
if (is_valid == TRUE)
{
for (int j = 0; j < gestures_stream.slots[i].gestures_count; j++)
{
wchar_t gesture_name[256];
if (gestures_stream.slots[i].gestures[j]->get_Name(sizeof(gesture_name), gesture_name) == S_OK)
{
IDiscreteGestureResult* discrete_result = nullptr;
if (gestures_stream.slots[i].frame->get_DiscreteGestureResult(gestures_stream.slots[i].gestures[j], &discrete_result) == S_OK)
{
BOOLEAN detected;
if (discrete_result->get_Detected(&detected) == S_OK)
{
if (detected == TRUE)
{
float confidence;
if (discrete_result->get_Confidence(&confidence) == S_OK)
{
gestures_stream.gestures_results[i].results[gesture_name] = confidence;
}
}
else
{
gestures_stream.gestures_results[i].results[gesture_name] = 0;
}
}
safe_release(&discrete_result);
}
}
}
}
}
safe_release(&gestures_stream.slots[i].frame);
}
}
}
}
}
//----------------------------------------------------------------------------------------------------