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

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

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

  1. Kinect for Windows V2和V1对照开发___深度数据获取并用OpenCV2.4.10显示

    V1深度分辨率:320x240 V2深度分辨率:512x424 1.  打开深度图像帧的方式 对于V1: hr = m_PNuiSensor->NuiImageStreamOpen( NUI_I ...

  2. Kinect for Windows V2开发教程

    教程 https://blog.csdn.net/openbug/article/details/80921437 Windows版Kinect SDK https://docs.microsoft. ...

  3. Kinect for Windows V2.0 新功能

    系统要求: win8  or  win8.1 硬件要求: 64位(x64)处理器 i7 2.5-GHz或更快的处理器 内置USB 3.0总线 4 GB RAM DX11图形适配器 外观: 第二代Kin ...

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

    算是正式进军Kinect了,前段时间学的东西现在就忘了,于是从此开始记录一下. 目前为止大部分的学习资料来自于Heresy的博客,写的非常优秀,清晰明了,十分感谢.开发语言为C++,应该会一直使用,但 ...

  5. Kinect For Windows V2开发日志八:侦测、追踪人体骨架

    简介 Kinect一个很强大的功能就是它可以侦测到人体的骨骼信息并追踪,在Kinect V2的SDK 2.0中,它最多可以同时获取到6个人.每个人25个关节点的信息,并且通过深度摄像头,可以同时获取到 ...

  6. Kinect For Windows V2开发日志六:人体的轮廓的表示

    Kinect中带了一种数据源,叫做BodyIndex,简单来说就是它利用深度摄像头识别出最多6个人体,并且用数据将属于人体的部分标记,将人体和背景区别开来.利用这一特性,就可以在环境中显示出人体的轮廓 ...

  7. Kinect For Windows V2开发日志五:使用OpenCV显示彩色图像及红外图像

    彩色图像 #include <iostream> #include <Kinect.h> #include <opencv2\highgui.hpp> using ...

  8. Kinect For Windows V2开发日志九:侦测并绘制人体骨架

    简介 在上一篇<侦测.追踪人体骨架>里,介绍了关节点的使用办法,这一篇记录将关节点与OpenCV结合的绘图方法. 代码 #include <iostream> #include ...

  9. Kinect For Windows V2开发日志七:照片合成与背景消除

    上一篇里讲到了Kinect可以从环境中区分出人体来.因此可以利用这个功能,来把摄像头前的人合成进照片里,和利用Photoshop不同的是,这样合成进去的人是动态且实时的. 简单的思路 BodyInde ...

随机推荐

  1. Entity Framework 重写OnModelCreating,控制生成表名的单复数

    重写OnModelCreating,控制生成表名的单复数 public class MYDbContext : DbContext { public DbSet<User> Users { ...

  2. java里面List和Array的区别是什么?

    java里面的List和Array的区别是什么? 1:数组是定长,list是自动增长.2:数组效率高,list效率低.总结:数组牺牲功能增加效率,list牺牲效率增加功能. http://bbs.cs ...

  3. activeMQ总结

    队列模式和发布订阅模式的区别 topic只有所有订阅者都消费了,这个消息才会消失.只要有一个订阅者没有消费(持久化模式),这个消息就会存在.订阅者下线然后上线也会读取到这个消息.而且队列的话,消费能力 ...

  4. android studio adb 打不开

    1.cmd-->C:\Users\Administrator>adb start-serveradb server is out of date. killing...error: cou ...

  5. Android Studio中新建项目时Your android sdk is out of date or is missing templates的解决办法

    在Android Studio中新建项目时出现了以下问题:Your android sdk is out of date or is missing templates. Please ensure ...

  6. MFC 堆栈溢出 test dword ptr [eax],eax ; probe page.

    今天调试程序的时候,发现一个奇怪的问题,之前调试都没问题的,今早加了一点东西,就出现错误,跳到调试位置,如下4行红色部分 ; Find next lower page and probe cs20: ...

  7. HTML5 初始文档声明

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. cmd中用PING命令时,出现'Ping'不是内部或外部命令

    在cmd中用PING命令时,出现'Ping' 不是内部或外部命令,也不是可运行的程序或批处理文件.先了解一下内容:1.可执行文件.命令文件和批处理文件以.exe或者.com或者.bat为扩展名的文件分 ...

  9. JSP网页防止sql注入攻击

    SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使 ...

  10. linux文件合并,去重,分割

    第一:两个文件的交集,并集前提条件:每个文件中不得有重复行1. 取出两个文件的并集(重复的行只保留一份)2. 取出两个文件的交集(只留下同时存在于两个文件中的文件)3. 删除交集,留下其他的行1. c ...