Kinect体感交互实现

实现Kinect摄影机前的玩家的移动同步控制游戏人物的移动。玩家向左移动,游戏人物向左移动。

Kinect获取数据流接口为:Sensor→Source→Reader→Frame→Data


1.打开Kinect传感器:

hResult = GetDefaultKinectSensor(&pSensor);//获取一个设备

hResult = pSensor->Open();//打开一个设备

2.获取彩色图像帧

hResult = pSensor->get_ColorFrameSource(&pColorSource);
hResult = pColorSource->OpenReader(&pColorReader);

hResult = pColorSource->get_FrameDescription(&pColorDescription);

在使用阅读器时需要判断ID是否追踪,用到了骨骼数据,需要打卡骨骼帧源

3.打开骨骼帧源

IBodyFrameSource* pBodyFrameSource = nullptr;
if (SUCCEEDED(hResult))
{
hr = pSensor->get_BodyFrameSource(&pBodyFrameSource);//得到骨骼帧源
}
if (SUCCEEDED(hr))
{
hr = pBodyFrameSource->OpenReader(&m_pBodyFrameReader);//骨骼帧源打开骨骼帧源读取器

}

在Kienct里所获取的每一个对象都需主动释放,否则无法获取其他变量。

template<class Interface>
inline void SafeRelease(Interface *& pInterfaceToRelease)
{
if (pInterfaceToRelease != NULL){
pInterfaceToRelease->Release();
pInterfaceToRelease = NULL;
}
}

微软提供人脸加框函数,可以利用其获取坐标,每次移动都需要记录其坐标,计算前后坐标数据变化,将参数传给游戏中的人物。

hr = pFaceFrameResult->get_FaceBoundingBoxInColorSpace(&faceBox);//Kinect对人脸进行加框的函数
pt1 = Point(faceBox.Left, faceBox.Top);

pt2 = Point(faceBox.Right, faceBox.Bottom);

参数计算(这里只用到顶点,也可以选择矩形中心)

move_change =(pt1.x - move_f)*0.5;

move_f = pt1.x;

manage.bear.BearPos.x+= move_change;

跳跃实现,只需要用到坐标的Y轴

high_change =(pt1.y - move_h);

move_h = pt1.y;

if(high_change > 10 )

    manage.bear.BearPos.y+= move_h;


手势识别

描述:玩家挥3次手开始游戏。

在更新骨骼数据时,确定手腕和手肘的位置,并判断其位置变化。

//骨骼信息更新代码

if(m_pBodyFrameReader != nullptr)

{

      IBodyFrame* pBodyFrame = nullptr;

      hr =m_pBodyFrameReader->AcquireLatestFrame(&pBodyFrame);

      if (SUCCEEDED(hr))

      {

             hr =pBodyFrame->GetAndRefreshBodyData(BODY_COUNT, ppBodies);

      }

             SafeRelease(pBodyFrame);

}

记录玩家右手手部和手肘位置的两块骨骼坐标,Kinect捕捉到的动作使用的是3D空间坐标,需要将其转化为2D的深度图。利用转换函数MapCameraPointToDepthSpace()

for (int j = 0;j < _countof(joints); ++j)

{

    bodyPoint =joints[j].Position;

    pCoordinateMapper->MapCameraPointToDepthSpace(bodyPoint,&depthPoint); 

    jointPoints[j].Y= static_cast<float>(depthPoint.Y * colorHeight) / 424;

}

r_wr_y =jointPoints[JointType_WristRight].Y;

r_el_y =jointPoints[JointType_ElbowRight].Y;

比较前后两次的位置变化,判断挥手动作,用count变量来统计玩家的挥手次数,当玩家挥手次数大于3次就开始游戏。

if (r_wr_y <=r_el_y) r_hand_s = 1;

if (r_hand_s ==1 && r_wr_y>r_el_y)

{

    r_hand_s = 0;

    count++;

}

if (count>3)

{

    Level = 1;

    cvDestroyWindow("关卡选择");

}



阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页