Kinect for windows SDK v1.X 流程参数详解

来源:互联网 发布:彩虹六号低配优化补丁 编辑:程序博客网 时间:2024/04/26 21:48

1:获取Kinect 感应器
  INuiSensor*             m_pNuiSensor;
  BSTR                    m_instanceId;     
  HRESULT hr;
  hr = NuiCreateSensorByIndex(0, &m_pNuiSensor);
 
NuiCreateSensorByIndex函数的标注
功能:创建一个Kinect感应器的实例
参数一:感应器的标号,有多台的话,从0开始标记的,最后一台为NuiGetSensorCount -1
参数二:指向打开的感应器
返回值: S_OK if successful;
Ps
NuiGetSensorCount函数标注:
功能:返回连接到电脑的Kinect的数目
参数:int *pCount pCount指向一个int类型的数据值,这个int用来存放一个整个,这个整个就是电脑中的Kinect的数目
  返回值:S_OK if successful; otherwise, returns a failure code
 
m_instanceId = m_pNuiSensor->NuiDeviceConnectionId();
INuiSensor::NuiDeviceConnectionId method标注
  功能:获取传感器连接ID
  参数:无
  返回值:返回感应器的连接ID


2:为彩色数据 深度数据 骨架数据创建相应的事件函数
PS:根据bate版本的说明,为每一种流数据类型创建一种对应的事件,当数据到达的时候,采用相应的事件来处理相应相应数据。分以下六步:
1:创建事件关联到每一种数据上,程序等待数据的到达,根据数据类型采用相应的事件进行处理[C#]
2:初始化结构骨骼渲染
3:初始化图像结构渲染
4:初始化Kinect感应器
5:打开深度和彩色数据流
6:创建Kinect感应器数据处理线程
  HANDLE        m_hNextDepthFrameEvent;
  HANDLE        m_hNextVideoFrameEvent;
  HANDLE        m_hNextSkeletonEvent;             
  m_hNextDepthFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  m_hNextVideoFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  m_hNextSkeletonEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
 
CreateEvent 函数标注
功能:创建事件句柄
参数一:安全性描述符,新版本必须设置为NULL
参数二:BOOL类型,如果事件需要手动重置则设置为TRUE
参数三:BOOL类型,指示事件的初始状态
参数四:string类型,包含事件的名字


3:初始化感应器的NUI函数库(初始化感应器)
     DWORD nuiFlags = NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX | NUI_INITIALIZE_FLAG_USES_SKELETON |  NUI_INITIALIZE_FLAG_USES_COLOR;
     // m_pNuiSensor是感应器的接口
    hr = m_pNuiSensor->NuiInitialize(nuiFlags);
    if (E_NUI_SKELETAL_ENGINE_BUSY == hr)
    {
nuiFlags =
NUI_INITIALIZE_FLAG_USES_DEPTH |  NUI_INITIALIZE_FLAG_USES_COLOR;
        hr = m_pNuiSensor->NuiInitialize(nuiFlags);
}
INuiSensor::NuiInitialize Method批注
功能:初始化NUI引擎
参数:NUI_ INITIALIZE
返回值:S_OK if successful

Constant

Description

NUI_INITIALIZE_FLAG_USES_AUDIO

Provide audio data.

NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX

Provide depth data and identify the player index.

NUI_INITIALIZE_FLAG_USES_COLOR

Provide color data.

NUI_INITIALIZE_FLAG_USES_SKELETON

Provide skeleton data.

NUI_INITIALIZE_FLAG_USES_DEPTH

Provide depth data.

NUI_INITIALIZE_DEFAULT_HARDWARE_THREAD

Initialize a default hardware thread.


 
4:打开骨架提取功能 //骨架功能特有的
if (HasSkeletalEngine(m_pNuiSensor))
 {
   hr =m_pNuiSensor->NuiSkeletonTrackingEnable( m_hNextSkeletonEvent, 0 );
 }  
HasSkeletalEngine 批注
功能:Determines whether the sensor instance has a skeletal(骨骼) engine
参数:感应器实例
返回值: true if the sensor instance has a skeletal engine; otherwise, false
 
INuiSensor::NuiSkeletonTrackingEnable Method 批注
功能:Enables skeleton tracking功能
参数一:一个与应用程序相关联的人工重置类型的事件的句柄。这个句柄要满足,不论在什么情形下,都做人工重置的工作
参数二: Flags that control skeleton tracking , combination of the values in the following table.
返回值:S_OK if successful


5:创建彩色和深度数据流
  hr = m_pNuiSensor->NuiImageStreamOpen(
    NUI_IMAGE_TYPE_COLOR,
    NUI_IMAGE_RESOLUTION_640x480,
    0,
    2,
    m_hNextVideoFrameEvent,
    &m_pVideoStreamHandle );
 
  hr = m_pNuiSensor->NuiImageStreamOpen(
    NUI_IMAGE_TYPE_DEPTH,
    NUI_IMAGE_RESOLUTION_320x240,
    0,
    2,
    m_hNextDepthFrameEvent,
   &m_pDepthStreamHandle );
     INuiSensor::NuiImageStreamOpen Method 批注
功能:打开图像数据流-image stream
参数一:决定图像数据流的类型。NUI_IMAGE_TYPE类型的数据
参数二:决定图像的分辨率。NUI_IMAGE_RESOLUTION类型的数据
参数三:图像预处理字段,目前为0
参数四:应用程序能够同时控制的缓存数目。
参数五:处理数据的事件句柄。
参数六:一个位置,用于接受一个用于打开数据流功能的句柄
返回值:S_OK if successful


6:开始处理NUI数据
  m_hEvNuiProcessStop=CreateEvent(NULL,FALSE,FALSE,NULL);
  m_hThNuiProcess=CreateThread(NULL,0,Nui_ProcessThread,this,0,NULL);


7:获取彩色数据
void CSkeletalViewerApp::Nui_GotVideoAlert( )
{
    NUI_IMAGE_FRAME imageFrame;
HRESULT hr =
    m_pNuiSensor->NuiImageStreamGetNextFrame(
        m_pVideoStreamHandle,
        0,
        &imageFrame );
    INuiFrameTexture * pTexture = imageFrame.pFrameTexture;
    NUI_LOCKED_RECT LockedRect;
    pTexture->LockRect( 0, &LockedRect, NULL, 0 );
    if( LockedRect.Pitch != 0 )
    {
        BYTE * pBuffer = (BYTE*) LockedRect.pBits;
        m_DrawVideo.DrawFrame( (BYTE*) pBuffer );
    }
hr= m_pNuiSensor->NuiImageStreamReleaseFrame( m_pVideoStreamHandle, &imageFrame );
}
INuiSensor::NuiImageStreamGetNextFrame Method批注
功能:从图像数据流里面提取下一帧的数据
参数一:图像数据流的句柄,这里的数据流必须是NuiImageStreamOpen 方法打开的数据流,实际上就是深度数据帧的句柄
参数二:等待一个帧需要的时间
参数三:一个NUI_IMAGE_FRAME结构的变量,用来指向接受到的帧的存储位置
返回值:S_OK if successful; otherwise, returns a failure code.
 
INuiSensor::NuiImageStreamReleaseFrame Method批注
功能:从数据流里面释放数据帧
参数一:图像数据流的句柄,这里的数据流必须是NuiImageStreamOpen 方法打开的数据流,实际就是m_pNuiSensor->NuiImageStreamGetNextFrame的第一个参数,有打开就有关闭
参数二:一个指针,指向将要释放的数据帧的位置,实际就是m_pNuiSensor->NuiImageStreamGetNextFrame的第三个参数
返回值:S_OK if successful; returns one of the following failure codes: E_INVALIDARG
INuiFrameTexture::LockRect Method批注
功能:锁定缓存
参数一:Unused; must be 0.
参数二:一个 指向NUI_LOCKED_RECT 结构的指针,结构体里面储存锁定区域的信息
参数三:Unused
参数四:Unused
返回值: S_OK if successful; otherwise, returns a failure code.


8:获取深度数据流
void CSkeletalViewerApp::Nui_GotDepthAlert( )
{
    NUI_IMAGE_FRAME imageFrame;
    HRESULT hr = m_pNuiSensor->NuiImageStreamGetNextFrame(
        m_pDepthStreamHandle,
        0,
        &imageFrame );
    INuiFrameTexture * pTexture = imageFrame.pFrameTexture;
    NUI_LOCKED_RECT LockedRect;
    pTexture->LockRect( 0, &LockedRect, NULL, 0 );
    if( LockedRect.Pitch != 0 )
    {
        BYTE * pBuffer = (BYTE*) LockedRect.pBits;
        // draw the bits to the bitmap
        RGBQUAD * rgbrun = m_rgbWk;
        USHORT * pBufferRun = (USHORT*) pBuffer;
        for( int y = 0 ; y < 240 ; y++ )
        {
            for( int x = 0 ; x < 320 ; x++ )
            {
                RGBQUAD quad = Nui_ShortToQuad_Depth( *pBufferRun );
                pBufferRun++;
                *rgbrun = quad;
                rgbrun++;
            }
        }
        //这句在具体的代码实现的时候不是这么做的,要注意
        m_DrawDepth.DrawFrame( (BYTE*) m_rgbWk );
    }
    hr = m_pNuiSensor->NuiImageStreamReleaseFrame( m_pDepthStreamHandle, &imageFrame );
}
以下代码的功能是实现人物远近的体现
PS
  USHORT RealDepth = (s & 0xfff8) >> 3;
  USHORT Player = s & 7;
  BYTE l = 255 - (BYTE)(256*RealDepth/0x0fff);


9:获取人物骨骼数据
  void CSkeletalViewerApp::Nui_GotSkeletonAlert( )
  {
    NUI_SKELETON_FRAME SkeletonFrame = {0};
 
    bool bFoundSkeleton = false;
 
    if( SUCCEEDED(m_pNuiSensor->NuiSkeletonGetNextFrame( 0, &SkeletonFrame )) )
    {
      for( int i = 0 ; i < NUI_SKELETON_COUNT ; i++ )
      {
if( SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_TRACKED ||
(SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_POSITION_ONLY && m_bAppTracking))
        {
          bFoundSkeleton = true;
      }
    }
  }


10:光滑骨骼数据
HRESULT hr = m_pNuiSensor->NuiTransformSmooth(&SkeletonFrame,NULL);
    if(FAILED(hr))
    {
        return;
}
  
11:输出骨骼数据
if( SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_TRACKED &&
      SkeletonFrame.SkeletonData[i].eSkeletonPositionTrackingState[NUI_SKELETON_POSITION_SHOULDER_CENTER] != NUI_SKELETON_POSITION_NOT_TRACKED)
  {
      Nui_DrawSkeleton( &SkeletonFrame.SkeletonData[i], GetDlgItem( m_hWnd, IDC_SKELETALVIEW ), i );
  }
     
  void CSkeletalViewerApp::Nui_DrawSkeleton(NUI_SKELETON_DATA * pSkel, HWND hWnd, int WhichSkeletonColor )
  {
    HGDIOBJ hOldObj = SelectObject(m_SkeletonDC,m_Pen[WhichSkeletonColor % m_PensTotal]);
 
    RECT rct;
    GetClientRect(hWnd, &rct);
    int width = rct.right;
    int height = rct.bottom;
 
    if( m_Pen[0] == NULL )
    {
      for (int i = 0; i < m_PensTotal; i++)
      {
          m_Pen[i] = CreatePen( PS_SOLID, width / 80, g_SkeletonColors[i] );
      }
    }
 
    int i;
    for (i = 0; i < NUI_SKELETON_POSITION_COUNT; i++)
    {
        USHORT depth;
        NuiTransformSkeletonToDepthImage( pSkel->SkeletonPositions[i], &m_Points[i].x, &m_Points[i].y, &depth );
 
        m_Points[i].x = (m_Points[i].x * width) / 320;
        m_Points[i].y = (m_Points[i].y * height) / 240;
        }
 
        SelectObject(m_SkeletonDC,m_Pen[WhichSkeletonColor%m_PensTotal]);
 
// Nui_DrawSkeletonSegment是自定义函数。
        Nui_DrawSkeletonSegment(pSkel,4,NUI_SKELETON_POSITION_HIP_CENTER, NUI_SKELETON_POSITION_SPINE, NUI_SKELETON_POSITION_SHOULDER_CENTER, NUI_SKELETON_POSITION_HEAD);
        Nui_DrawSkeletonSegment(pSkel,5,NUI_SKELETON_POSITION_SHOULDER_CENTER, NUI_SKELETON_POSITION_SHOULDER_LEFT, NUI_SKELETON_POSITION_ELBOW_LEFT, NUI_SKELETON_POSITION_WRIST_LEFT, NUI_SKELETON_POSITION_HAND_LEFT);
        Nui_DrawSkeletonSegment(pSkel,5,NUI_SKELETON_POSITION_SHOULDER_CENTER, NUI_SKELETON_POSITION_SHOULDER_RIGHT, NUI_SKELETON_POSITION_ELBOW_RIGHT, NUI_SKELETON_POSITION_WRIST_RIGHT, NUI_SKELETON_POSITION_HAND_RIGHT);
        Nui_DrawSkeletonSegment(pSkel,5,NUI_SKELETON_POSITION_HIP_CENTER, NUI_SKELETON_POSITION_HIP_LEFT, NUI_SKELETON_POSITION_KNEE_LEFT, NUI_SKELETON_POSITION_ANKLE_LEFT, NUI_SKELETON_POSITION_FOOT_LEFT);
        Nui_DrawSkeletonSegment(pSkel,5,NUI_SKELETON_POSITION_HIP_CENTER, NUI_SKELETON_POSITION_HIP_RIGHT, NUI_SKELETON_POSITION_KNEE_RIGHT, NUI_SKELETON_POSITION_ANKLE_RIGHT, NUI_SKELETON_POSITION_FOOT_RIGHT);
 
        // Draw the joints in a different color
        for (i = 0; i < NUI_SKELETON_POSITION_COUNT ; i++)
    {
        if (pSkel->eSkeletonPositionTrackingState[i] != NUI_SKELETON_POSITION_NOT_TRACKED)
        {
            HPEN hJointPen;
       
            hJointPen=CreatePen(PS_SOLID,9, g_JointColorTable[i]);
            hOldObj=SelectObject(m_SkeletonDC,hJointPen);
 
            MoveToEx( m_SkeletonDC, m_Points[i].x, m_Points[i].y, NULL );
            LineTo( m_SkeletonDC, m_Points[i].x, m_Points[i].y );
 
            SelectObject( m_SkeletonDC, hOldObj );
            DeleteObject(hJointPen);
        }
    }
    return;
}
NuiGetSensorCount批注
功能:Returns the number of Kinect sensors that are connected to the computer
参数一:指向一个int的数据类型,这个int类型的数据储存感应器的数目
返回值:S_OK if successful; otherwise, returns a failure code
 
NuiCreateSensorByIndex批注
功能:创建一个指定索引的Kinect实例,使我们的应用程序能够打开和使用他
参数一:Kinect的索引值从0开始,有效的值是NuiGetSensorCount  1
参数二:A pointer that receives a reference to the created INuiSensor interface
返回值:S_OK if successful; otherwise, returns one of the failure codes in the following table

NUI_INITIALIZE

Kinect sensor initialization options when calling NuiInitialize. These may be combined using a bitwise OR.

 

RGBQUAD CSkeletalViewerApp::Nui_ShortToQuad_Depth( USHORT s )

{

USHORT RealDepth = NuiDepthPixelToDepth(s);

功能:从像素格式中解压出深度数据值

参数:压缩的深度像素值

返回值:Returns the unpacked pixel depth

USHORT Player    = NuiDepthPixelToPlayerIndex(s);

功能:从像素格式中解压出玩家的索引代码号

参数:压缩的深度像素值

返回值:Returns the unpacked player index

    // transform 13-bit depth information into an 8-bit intensity appropriate

    // for display (we disregard information in most significant bit)

    BYTE intensity = (BYTE)~(RealDepth >> 4);

    // tint the intensity by dividing by per-player values

    RGBQUAD color;

    color.rgbRed   = intensity >> g_IntensityShiftByPlayerR[Player];

    color.rgbGreen = intensity >> g_IntensityShiftByPlayerG[Player];

    color.rgbBlue  = intensity >> g_IntensityShiftByPlayerB[Player];

    return color;

}

 NuiSkeletonGetNextFrame的批注

功能:从数据流中获取下一骨架帧数据

参数一:在没有新的一帧时,返回之前帧暂停

参数二:一个指向NUI_SKELETON_FRAME结构的指针。NUI_SKELETON_FRAME 结构用于储存下一帧骨架数据。

返回值:S_OK if successful; returns E_POINTER OR E_NUI_FRAME_NO_DATA.

INuiSensor::NuiTransformSmooth Method 批注

功能:对帧进行过滤,减少两帧之间的抖动。

参数一:调用的时候,是一个指向NUI_SKELETON_FRAME 结构的指针。NUI_SKELETON_FRAME 结构里面储存需要需要光滑处理的数据。结束的时候这个指向指向的结构里面是光滑处理后的结果。如果函数调用失败,则不变化。

参数二:The parameters for the smoothing function,没有给予参数的时候,使用的是默认值

返回值:S_OK if successful

0 0