Kinect for Windows V2和V1对比开发___彩色数据获取并用OpenCV2.4.10显示

19 篇文章 106 订阅 ¥39.90 ¥99.00

~~有兴趣的小伙伴,加kinect算法交流群:462964980。


V1彩色分辨率:640x480

V2彩色分辨率:1920x1080


1,打开彩色图像帧的方式

对于V1: 使用NuiImageStreamOpen方法打开

  1. hr = m_PNuiSensor->NuiImageStreamOpen(  
  2.                                    NUI_IMAGE_TYPE_COLOR,NUI_IMAGE_RESOLUTION_640x480,0, 2,  
  3.                                    m_hNextColorFrameEvent,&m_hColorStreamHandle);  
  4.                           if( FAILED( hr ) )  
  5.                           {  
  6.                                    cout<<"Could notopen image stream video"<<endl;  
  7.                                    return hr;  
  8.                     }  
  9. 这种方式可以设置分辨率  
 

对于V2:     

  1. 首先使用  m_pKinectSensor->Open();//打开Kinect  
  2.    
  3.         if (SUCCEEDED(hr))  
  4.         {  
  5.             hr =m_pKinectSensor->get_ColorFrameSource(&pColorFrameSource);  
  6.         }  
  7. 方法get_ColorFrameSource打开彩色帧的源。  
  8. 然后使用     if (SUCCEEDED(hr))  
  9.         {  
  10.             hr =pColorFrameSource->OpenReader(&m_pColorFrameReader);  
  11.         }  
  12.         SafeRelease(pColorFrameSource);  
  13. 方法OpenReader打开彩色帧读取器。  


 

2,更新彩色帧的方式

对于V1:使用NuiImageStreamGetNextFrame方法

  1. NuiImageStreamGetNextFrame(m_hColorStreamHandle,0, &pImageFrame);//得到该帧数据  

对于V2:使用AcquireLatestFrame方法

   

  1. if (!m_pColorFrameReader)  
  2.    {  
  3.        return;  
  4.    }  
  5.   
  6.    IColorFrame* pColorFrame = NULL;  
  7.   
  8. RESULT hr =m_pColorFrameReader->AcquireLatestFrame(&pColorFrame);  


3,数据的处理方式

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

  1. INuiFrameTexture *pTexture =pImageFrame->pFrameTexture;  
  2.                           NUI_LOCKED_RECT LockedRect;  
  3.                           pTexture->LockRect(0, &LockedRect,NULL, 0);//提取数据帧到LockedRect,它包括两个数据对象:pitch每行字节数,pBits第一个字节地址  
  4.                           if( LockedRect.Pitch != 0 )  
  5.                           {  
  6.                                    cvZero(colorImage);  
  7.                                    for (int i=0; i<480; i++)  
  8.                                    {  
  9.                                             uchar* ptr =(uchar*)(colorImage->imageData+i*colorImage->widthStep);  
  10.                                             BYTE * pBuffer =(BYTE*)(LockedRect.pBits)+i*LockedRect.Pitch;//每个字节代表一个颜色信息,直接使用BYTE  
  11.                                             for (int j=0; j<640; j++)  
  12.                                             {  
  13.                                                      ptr[3*j] =pBuffer[4*j];//内部数据是4个字节,0-1-2是BGR,第4个现在未使用  
  14.                                                      ptr[3*j+1] =pBuffer[4*j+1];  
  15.                                                      ptr[3*j+2] =pBuffer[4*j+2];  
  16.                                             }  
  17.                                    }  
  18.                                    //cvWriteFrame(wr_color,colorImage);  
  19.                                    cvShowImage("colorImage", colorImage);//显示图像  

得到的最终形式可以用OpenCV显示。

 

对于V2:   这种数据的内部结构是神马样子呢?然后如何用OpenCV显示出图像数据呢?待查…

    

  1. RGBQUAD* m_pColorRGBX;//彩色数据存储位置  
  2. m_pColorRGBX(NULL)//构造函数初始化  
  3.     // create heap storage for color pixel data in RGBXformat  
  4.     m_pColorRGBX = new RGBQUAD[cColorWidth *cColorHeight];  
  5.    
  6.    
  7. //下边就是AcquireLatestFrame之后处理数据  
  8.  INT64 nTime = 0;  
  9.         IFrameDescription* pFrameDescription =NULL;  
  10.         int nWidth = 0;  
  11.         int nHeight = 0;  
  12.         ColorImageFormat imageFormat = ColorImageFormat_None;  
  13.         UINT nBufferSize = 0;  
  14.         RGBQUAD *pBuffer = NULL;  
  15.    
  16.         if (SUCCEEDED(hr))  
  17.         {  
  18.             if (imageFormat == ColorImageFormat_Bgra)  
  19.             {  
  20.                 hr =pColorFrame->AccessRawUnderlyingBuffer(&nBufferSize, reinterpret_cast<BYTE**>(&pBuffer));  
  21.             }  
  22.             else if (m_pColorRGBX)  
  23.             {  
  24.                 pBuffer = m_pColorRGBX;  
  25.                 nBufferSize = cColorWidth *cColorHeight * sizeof(RGBQUAD);  
  26.                 hr = pColorFrame->CopyConvertedFrameDataToArray(nBufferSize,reinterpret_cast<BYTE*>(pBuffer), ColorImageFormat_Bgra);             
  27.             }  
  28.             else  
  29.             {  
  30.                 hr = E_FAIL;  
  31.             }  
  32.         }  
  33.         if (SUCCEEDED(hr))  
  34.         {  
  35.             ProcessColor(nTime, pBuffer,nWidth, nHeight);  
  36.         }  

感觉目前得到的pBuffer就是存储的彩色数据,问题是如何用OpenCV来显示呢?


4,OpenCV显示

  1. <span style="white-space:pre">    </span>int width = 0;  
  2.     int height = 0;  
  3.     pDescription->get_Width( &width ); // 1920  
  4.     pDescription->get_Height( &height ); // 1080  
  5.     unsigned int bufferSize = width * height * 4 * sizeof( unsigned char );  
  6.   
  7.     //创建尺寸为height x width 的4通道8位图像  
  8.     Mat bufferMat( height, width, CV_8UC4 );  
  9.     Mat colorMat( height / 2, width / 2, CV_8UC4 );  
  10.   
  11.     while( 1 ){  
  12.         // 更新彩色帧  
  13.         IColorFrame* pColorFrame = nullptr;  
  14.         hResult = pColorReader->AcquireLatestFrame( &pColorFrame );  
  15.         if( SUCCEEDED( hResult ) ){  
  16.             hResult = pColorFrame->CopyConvertedFrameDataToArray( bufferSize, reinterpret_cast<BYTE*>( bufferMat.data ), ColorImageFormat::ColorImageFormat_Bgra );  
  17.             if( SUCCEEDED( hResult ) ){  
  18.                 resize( bufferMat, colorMat, cv::Size(), 0.5, 0.5 );  
  19.             }  
  20.         }  
  21.         SafeRelease( pColorFrame );  
  22.   
  23.   
  24.         imshow( "Color", colorMat );  

其中用到kinect的CopyConvertedFrameDataToArray函数,将图像帧转换为矩阵数据用来显示。


5,V2+VS2012+OpenCV代码

  1. #include <Windows.h>  
  2. #include <Kinect.h>  
  3. #include <opencv2/opencv.hpp>  
  4.   
  5. using namespace std;  
  6. using namespace cv;  
  7.   
  8. //释放接口需要自己定义  
  9. template<class Interface>  
  10. inline void SafeRelease( Interface *& pInterfaceToRelease )  
  11. {  
  12.     if( pInterfaceToRelease != NULL ){  
  13.         pInterfaceToRelease->Release();  
  14.         pInterfaceToRelease = NULL;  
  15.     }  
  16. }  
  17.   
  18. int main( int argc, char **argv[] )  
  19. {  
  20.     //OpenCV中开启CPU的硬件指令优化功能函数  
  21.     setUseOptimized( true );  
  22.   
  23.     // 打开kinect  
  24.     IKinectSensor* pSensor;  
  25.     HRESULT hResult = S_OK;  
  26.     hResult = GetDefaultKinectSensor( &pSensor );  
  27.     if( FAILED( hResult ) ){  
  28.         cerr << "Error : GetDefaultKinectSensor" << std::endl;  
  29.         return -1;  
  30.     }  
  31.   
  32.     hResult = pSensor->Open();  
  33.     if( FAILED( hResult ) ){  
  34.         cerr << "Error : IKinectSensor::Open()" << std::endl;  
  35.         return -1;  
  36.     }  
  37.   
  38.     // 彩色帧源  
  39.     IColorFrameSource* pColorSource;  
  40.     hResult = pSensor->get_ColorFrameSource( &pColorSource );  
  41.     if( FAILED( hResult ) ){  
  42.         cerr << "Error : IKinectSensor::get_ColorFrameSource()" << std::endl;  
  43.         return -1;  
  44.     }  
  45.   
  46.     //彩色帧读取  
  47.     IColorFrameReader* pColorReader;  
  48.     hResult = pColorSource->OpenReader( &pColorReader );  
  49.     if( FAILED( hResult ) ){  
  50.         cerr << "Error : IColorFrameSource::OpenReader()" << std::endl;  
  51.         return -1;  
  52.     }  
  53.   
  54.     // Description  
  55.     IFrameDescription* pDescription;  
  56.     hResult = pColorSource->get_FrameDescription( &pDescription );  
  57.     if( FAILED( hResult ) ){  
  58.         cerr << "Error : IColorFrameSource::get_FrameDescription()" << std::endl;  
  59.         return -1;  
  60.     }  
  61.   
  62.     int width = 0;  
  63.     int height = 0;  
  64.     pDescription->get_Width( &width ); // 1920  
  65.     pDescription->get_Height( &height ); // 1080  
  66.     unsigned int bufferSize = width * height * 4 * sizeof( unsigned char );  
  67.   
  68.     //创建尺寸为height x width 的4通道8位图像  
  69.     Mat bufferMat( height, width, CV_8UC4 );  
  70.     Mat colorMat( height / 2, width / 2, CV_8UC4 );  
  71.   
  72.     while( 1 ){  
  73.         // 更新彩色帧  
  74.         IColorFrame* pColorFrame = nullptr;  
  75.         hResult = pColorReader->AcquireLatestFrame( &pColorFrame );  
  76.         if( SUCCEEDED( hResult ) ){  
  77.             hResult = pColorFrame->CopyConvertedFrameDataToArray( bufferSize, reinterpret_cast<BYTE*>( bufferMat.data ), ColorImageFormat::ColorImageFormat_Bgra );  
  78.             if( SUCCEEDED( hResult ) ){  
  79.                 resize( bufferMat, colorMat, cv::Size(), 0.5, 0.5 );  
  80.             }  
  81.         }  
  82.         SafeRelease( pColorFrame );  
  83.   
  84.         imshow( "Color", colorMat );  
  85.   
  86.         if( waitKey( 30 ) == VK_ESCAPE ){  
  87.             break;  
  88.         }  
  89.     }  
  90.   
  91.     SafeRelease( pColorSource );  
  92.     SafeRelease( pColorReader );  
  93.     SafeRelease( pDescription );  
  94.     if( pSensor ){  
  95.         pSensor->Close();  
  96.     }  
  97.     SafeRelease( pSensor );  
  98.   
  99.     return 0;  
  100. }  


分辨率是大大的提高了啊~~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值