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;
}

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

时间: 2024-10-10 21:21:36

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

Kinect for Windows V2和V1对比开发___彩色数据获取

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<

Kinect for Windows V2和V1对比开发___骨骼数据获取

1,       打开骨骼帧的方式 对于V1, 方法NuiSkeletonTrackingEnable实现 m_hNextSkeletonEvent = CreateEvent(NULL, TRUE, FALSE, NULL ); hr =m_PNuiSensor->NuiSkeletonTrackingEnable( m_hNextSkeletonEvent, NUI_SKELETON_TRACKING_FLAG_ENABLE_IN_NEAR_RANGE//| ); if( FAILED( h

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

Kinect for Windows V2和V1对比开发___多台Kinect的使用

对于V1 <span style="white-space:pre"> </span>INuiSensor * pNuiSensor; HRESULT hr; int iSensorCount = 0; hr = NuiGetSensorCount(&iSensorCount); if (FAILED(hr)) { return hr; } //轮询每一个Kinect sensor for (int i = 0; i < iSensorCount;

Kinect for Windows V2开发教程

Windows版Kinect SDK https://docs.microsoft.com/en-us/previous-versions/windows/kinect/dn799271(v=ieb.10)?redirectedfrom=MSDN 开发文档中,前1个小节,What’s New和Known Issues都未有内容.然后Features特点章节中给出了不少参数.新的K4W sdk(Kinect for windows sdk)有以下特点: #使用XBox One Kinect传感器

Kinect for Windows V2.0 新特性

外观: 第二代Kinect for Windows看起来与Kinect for Xbox One相同,用以区别的是Windows版Kinect顶部写着Kinect,Xbox版只有一个绿色的X. Kinect for Windows 2.0 Kinect for Xbox One 主要性能改进: 深度传感:通过更高的深度保真和大幅改进的噪声基底,第二代传感器打造空前的3D视觉效果,通过功能改进,能够看到清晰更小的物体以及提高骨骼追踪的稳定性. 1080p高清视频:1080p 全高清视频呈现高清晰画

Kinect For Windows V2开发日志一:开发环境的配置

算是正式进军Kinect了,前段时间学的东西现在就忘了,于是从此开始记录一下. 目前为止大部分的学习资料来自于Heresy的博客,写的非常优秀,清晰明了,十分感谢.开发语言为C++,应该会一直使用,但是也有可能更换为C#. 文档位于MSDN,所有的用法都可以在这里找到. 首先应该到微软官网下载SDK,安装完后就开始配置. VS 2015的配置: 在写项目之前首先要配置好VS的环境,我用的是VS 2015社区版,SDK版本为2.0,配置方式如下: 首先,新建个项目,然后在[解决方案资源管理器]中右

Kinect For Windows V2开发日志二:Kinect V2的基本参数

以下内容节选自Heresy的博客: 彩色影像:1920 x 1080 @ 30 / 15 FPS(根据环境亮度) 深度影像:512 x 424 @ 30 FPS.16bit 距离值(mm).可侦测范围0.5 ~ 8 M 红外线影像:512 x 424 @ 30 FPS.16bit 强度值 声音资讯 根据上面的原始资料,则可以再透过软体,进行人体的追踪.骨架的辨识(0.5 ~ 4.5 M).在K4Wv2 下,最多六个人.每个人25 个关节点(右图),其中每个关节点都可以取得空间中的位置.以及方向性

Kinect for Windows V2 SDK+ VS2012 环境搭建

目前使用的SDK版本是KinectSDK-v2.0-PublicPreview1409-Setup.exe. 下载地址:点击打开链接 1,在Property Manager窗口中,右键Debug|Win32,选择Add New Project Property Sheet. 2,选择Property Sheet(.props),Name:Kinect_ProjectD,Location:选择工程主目录,这样以后再用Kinect,配置可以直接添加Kinect_ProjectD.props. 3,选