Kinect for Windows V2和V1对比开发___深度数据获取

V1深度分辨率:320x240

V2深度分辨率:512x424


1,  打开深度图像帧的方式

对于V1:

hr = m_PNuiSensor->NuiImageStreamOpen(
                                   NUI_IMAGE_TYPE_DEPTH,NUI_IMAGE_RESOLUTION_320x240,0, 2,
                                   m_hNextDepthFrameEvent, &m_hDepthStreamHandle);
                          if( FAILED( hr ) )
                          {
                                   cout<<"Could notopen image stream video"<<endl;
                                   return hr;
                    }
这种方式可以设置分辨率

对于V2:     

// Initialize the Kinect and get the depth reader
        IDepthFrameSource* pDepthFrameSource =NULL;
首先使用        hr = m_pKinectSensor->Open();//打开Kinect 
        if (SUCCEEDED(hr))
        {
          hr =m_pKinectSensor->get_DepthFrameSource(&pDepthFrameSource);
        }
方法get_DepthFrameSource打开彩色帧的源。
然后使用     if (SUCCEEDED(hr))
        {
            hr =pDepthFrameSource->OpenReader(&m_pDepthFrameReader);
        }
        SafeRelease(pDepthFrameSource);
方法OpenReader打开彩色帧读取器。

 

2,   更新深度帧的方式

对于V1:使用NuiImageStreamGetNextFrame方法

NuiImageStreamGetNextFrame(m_hDepthStreamHandle,0, &pImageFrame);;//得到该帧数据</span>

对于V2:使用AcquireLatestFrame方法

   

 if (!m_pDepthFrameReader)
    {
        return;
    }
 
    IDepthFrame* pDepthFrame = NULL;
 
    HRESULT hr =m_pDepthFrameReader->AcquireLatestFrame(&pDepthFrame);

3,  数据的处理方式

对于V1:这种数据获取方式比较明朗看到数据内部结构,

INuiFrameTexture *pTexture =pImageFrame->pFrameTexture;
                          NUI_LOCKED_RECT LockedRect;
                          pTexture->LockRect(0, &LockedRect,NULL, 0);
 
                          RGBQUAD q;
 
                          if( LockedRect.Pitch != 0 )
                          {
                                  
                                            //BYTE * pBuffer = (BYTE*)(LockedRect.pBits);
                                            //INT size =  LockedRect.size;
                                            //memcpy_s(m_pDepthBuffer,size, pBuffer, size);
                                            //USHORT* pBufferRun =reinterpret_cast<USHORT*>(m_pDepthBuffer);
                                   for (int i=0; i<image.rows; i++)
                                   {
                                   //USHORT* ptr = (USHORT*)depthIndexImage->height;
                                            //USHORT* pDepthRow =(USHORT*)(i);
                                            //BYTE * pBuffer = (BYTE*)(LockedRect.pBits);
                                            uchar *ptr =image.ptr<uchar>(i);  //第i行的指针
                                            uchar * pBuffer =(uchar*)(LockedRect.pBits)+i*LockedRect.Pitch;
                                            USHORT* pBufferRun =(USHORT*) pBuffer;//注意这里需要转换,因为每个数据是2个字节,存储的同上面的颜色信息不一样,这里是2个字节一个信息,不能再用BYTE,转化为USHORT
 
                                            for (int j=0; j<image.cols; j++)
                                            {                                                  
                                                     //ptr[j] = 255 -(BYTE)(256*pBufferRun[j]/0x0fff);//直接将数据归一化处理
                                                     //ptr[j]  = pBufferRun[i * 640 + j];
                                                     // ptr[j] = 255 -(uchar)(256 * pBufferRun[j]/0x0fff);  //直接将数据归一化处理
                                   int player =pBufferRun[j]&7;  
                int data =(pBufferRun[j]&0xfff8) >> 3;  
                  
                uchar imageData = 255-(uchar)(256*data/0x0fff);  
                q.rgbBlue = q.rgbGreen =q.rgbRed = 0;  
  
                switch(player)  
                {  
                    case 0:    
                        q.rgbRed = imageData /2;    
                        q.rgbBlue = imageData / 2;    
                        q.rgbGreen = imageData/ 2;    
                        break;    
                    case 1:     
                        q.rgbRed =imageData;    
                        break;    
                    case 2:    
                        q.rgbGreen =imageData;    
                        break;    
                    case 3:    
                        q.rgbRed = imageData /4;    
                        q.rgbGreen = q.rgbRed*4;  //这里利用乘的方法,而不用原来的方法可以避免不整除的情况  
                        q.rgbBlue =q.rgbRed*4;  //可以在后面的getTheContour()中配合使用,避免遗漏一些情况  
                        break;    
                    case 4:    
                        q.rgbBlue = imageData /4;   
                        q.rgbRed = q.rgbBlue*4;    
                        q.rgbGreen =q.rgbBlue*4;    
                        break;    
                    case 5:    
                        q.rgbGreen = imageData/ 4;   
                        q.rgbRed =q.rgbGreen*4;    
                        q.rgbBlue =q.rgbGreen*4;    
                        break;    
                    case 6:    
                        q.rgbRed = imageData /2;    
                        q.rgbGreen = imageData/ 2;     
                        q.rgbBlue =q.rgbGreen*2;    
                        break;    
                    case 7:    
                        q.rgbRed = 255 - (imageData / 2 );    
                        q.rgbGreen = 255 - (imageData / 2 );    
                        q.rgbBlue = 255 - (imageData / 2 );  
                }     
                ptr[3*j] = q.rgbBlue;  
                ptr[3*j+1] = q.rgbGreen;  
                ptr[3*j+2] = q.rgbRed;
                                            }
                                   }
                                  
                                   imshow("depthImage",image); //显示图像
得到的最终形式可以用OpenCV显示。

对于V2:


RGBQUAD*  m_pDepthRGBX;;//深度数据存储位置
m_pDepthRGBX(NULL)//构造函数初始化
    // create heap storage for color pixel data in RGBXformat
  m_pDepthRGBX = new RGBQUAD[cDepthWidth *cDepthHeight];
 
//下边就是AcquireLatestFrame之后处理数据
        INT64 nTime = 0;
        IFrameDescription* pFrameDescription =NULL;
        int nWidth = 0;
        int nHeight = 0;
        USHORTnDepthMinReliableDistance = 0;
        USHORT nDepthMaxDistance =0;
        UINT nBufferSize = 0;
        UINT16 *pBuffer = NULL;
 
               if (SUCCEEDED(hr))
        {
            hr =pDepthFrame->AccessUnderlyingBuffer(&nBufferSize, &pBuffer);           
        }
 
        if (SUCCEEDED(hr))
        {
            ProcessDepth(nTime, pBuffer,nWidth, nHeight, nDepthMinReliableDistance, nDepthMaxDistance);
        }

感觉目前得到的pBuffer就是存储的深度数据,问题是如何用OpenCV来显示呢?   这种数据的内部结构是神马样子呢?然后如何用OpenCV显示出图像数据呢?待查…

Kinect for Windows V2和V1对比开发___深度数据获取

上一篇:C# 关键字 Static


下一篇:WPF判断日期是工作日还是节假日