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


    V1彩色分辨率:640x480

    V2彩色分辨率:1920x1080


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

    对于V1: 使用NuiImageStreamOpen方法打开

    hr = m_PNuiSensor->NuiImageStreamOpen(
                                       NUI_IMAGE_TYPE_COLOR,NUI_IMAGE_RESOLUTION_640x480,0, 2,
                                       m_hNextColorFrameEvent,&m_hColorStreamHandle);
                              if( FAILED( hr ) )
                              {
                                       cout<<"Could notopen image stream video"<<endl;
                                       return hr;
                        }
    这样的方式能够设置分辨率
    
    

    对于V2:     

    首先使用  m_pKinectSensor->Open();//打开Kinect
     
            if (SUCCEEDED(hr))
            {
                hr =m_pKinectSensor->get_ColorFrameSource(&pColorFrameSource);
            }
    方法get_ColorFrameSource打开彩色帧的源。
    然后使用     if (SUCCEEDED(hr))
            {
                hr =pColorFrameSource->OpenReader(&m_pColorFrameReader);
            }
            SafeRelease(pColorFrameSource);
    方法OpenReader打开彩色帧读取器。


    
    

    2,更新彩色帧的方式

    对于V1:使用NuiImageStreamGetNextFrame方法

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

    对于V2:使用AcquireLatestFrame方法

       

     if (!m_pColorFrameReader)
        {
            return;
        }
     
        IColorFrame* pColorFrame = NULL;
     
    HRESULT hr =m_pColorFrameReader->AcquireLatestFrame(&pColorFrame);


    3,数据的处理方式

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

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

    得到的终于形式能够用OpenCV显示。

     

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

        

    RGBQUAD* m_pColorRGBX;//彩色数据存储位置
    m_pColorRGBX(NULL)//构造函数初始化
        // create heap storage for color pixel data in RGBXformat
        m_pColorRGBX = new RGBQUAD[cColorWidth *cColorHeight];
     
     
    //下边就是AcquireLatestFrame之后处理数据
     INT64 nTime = 0;
            IFrameDescription* pFrameDescription =NULL;
            int nWidth = 0;
            int nHeight = 0;
            ColorImageFormat imageFormat = ColorImageFormat_None;
            UINT nBufferSize = 0;
            RGBQUAD *pBuffer = NULL;
     
            if (SUCCEEDED(hr))
            {
                if (imageFormat == ColorImageFormat_Bgra)
                {
                    hr =pColorFrame->AccessRawUnderlyingBuffer(&nBufferSize, reinterpret_cast<BYTE**>(&pBuffer));
                }
                else if (m_pColorRGBX)
                {
                    pBuffer = m_pColorRGBX;
                    nBufferSize = cColorWidth *cColorHeight * sizeof(RGBQUAD);
                    hr = pColorFrame->CopyConvertedFrameDataToArray(nBufferSize,reinterpret_cast<BYTE*>(pBuffer), ColorImageFormat_Bgra);           
                }
                else
                {
                    hr = E_FAIL;
                }
            }
            if (SUCCEEDED(hr))
            {
                ProcessColor(nTime, pBuffer,nWidth, nHeight);
            }

    感觉眼下得到的pBuffer就是存储的彩色数据。问题是怎样用OpenCV来显示呢?


    4,OpenCV显示

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

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


    5。V2+VS2012+OpenCV代码

    #include <Windows.h>
    #include <Kinect.h>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    //释放接口须要自定义
    template<class Interface>
    inline void SafeRelease( Interface *& pInterfaceToRelease )
    {
    	if( pInterfaceToRelease != NULL ){
    		pInterfaceToRelease->Release();
    		pInterfaceToRelease = NULL;
    	}
    }
    
    int main( int argc, char **argv[] )
    {
    	//OpenCV中开启CPU的硬件指令优化功能函数
    	setUseOptimized( true );
    
    	// 打开kinect
    	IKinectSensor* pSensor;
    	HRESULT hResult = S_OK;
    	hResult = GetDefaultKinectSensor( &pSensor );
    	if( FAILED( hResult ) ){
    		cerr << "Error : GetDefaultKinectSensor" << std::endl;
    		return -1;
    	}
    
    	hResult = pSensor->Open();
    	if( FAILED( hResult ) ){
    		cerr << "Error : IKinectSensor::Open()" << std::endl;
    		return -1;
    	}
    
    	// 彩色帧源
    	IColorFrameSource* pColorSource;
    	hResult = pSensor->get_ColorFrameSource( &pColorSource );
    	if( FAILED( hResult ) ){
    		cerr << "Error : IKinectSensor::get_ColorFrameSource()" << std::endl;
    		return -1;
    	}
    
    	//彩色帧读取
    	IColorFrameReader* pColorReader;
    	hResult = pColorSource->OpenReader( &pColorReader );
    	if( FAILED( hResult ) ){
    		cerr << "Error : IColorFrameSource::OpenReader()" << std::endl;
    		return -1;
    	}
    
    	// Description
    	IFrameDescription* pDescription;
    	hResult = pColorSource->get_FrameDescription( &pDescription );
    	if( FAILED( hResult ) ){
    		cerr << "Error : IColorFrameSource::get_FrameDescription()" << std::endl;
    		return -1;
    	}
    
    	int width = 0;
    	int height = 0;
    	pDescription->get_Width( &width ); // 1920
    	pDescription->get_Height( &height ); // 1080
    	unsigned int bufferSize = width * height * 4 * sizeof( unsigned char );
    
    	//创建尺寸为height x width 的4通道8位图像
    	Mat bufferMat( height, width, CV_8UC4 );
    	Mat colorMat( height / 2, width / 2, CV_8UC4 );
    
    	while( 1 ){
    		// 更新彩色帧
    		IColorFrame* pColorFrame = nullptr;
    		hResult = pColorReader->AcquireLatestFrame( &pColorFrame );
    		if( SUCCEEDED( hResult ) ){
    			hResult = pColorFrame->CopyConvertedFrameDataToArray( bufferSize, reinterpret_cast<BYTE*>( bufferMat.data ), ColorImageFormat::ColorImageFormat_Bgra );
    			if( SUCCEEDED( hResult ) ){
    				resize( bufferMat, colorMat, cv::Size(), 0.5, 0.5 );
    			}
    		}
    		SafeRelease( pColorFrame );
    
    		imshow( "Color", colorMat );
    
    		if( waitKey( 30 ) == VK_ESCAPE ){
    			break;
    		}
    	}
    
    	SafeRelease( pColorSource );
    	SafeRelease( pColorReader );
    	SafeRelease( pDescription );
    	if( pSensor ){
    		pSensor->Close();
    	}
    	SafeRelease( pSensor );
    
    	return 0;
    }
    


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

  • 相关阅读:
    CF353D Queue(结论)
    CF1147C Thanos Nim(博弈论、结论推导)
    牛客:CBX and children(平衡树+二分+贪心)
    牛客:Gambling Monster(权值线段树+离散化+离线)
    剑指49.把字符串转换成整数
    剑指48.不用加减乘除做加法
    剑指47.求1+2+3+...+n
    剑指46.孩子们的游戏(圆圈中最后剩下的数字)
    剑指45.扑克牌顺子
    剑指44.翻转单词顺序
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5238225.html
Copyright © 2020-2023  润新知