Kinect for Windows V2和V1对照开发___深度数据获取并用OpenCV2.4.10显示
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);
}
4,OpenCV显示
int width = 0;
int height = 0;
pDescription->get_Width( &width ); // 512
pDescription->get_Height( &height ); // 424
unsigned int bufferSize = width * height * sizeof( unsigned short ); // Range
unsigned short min = 0;
unsigned short max = 0;
pDepthSource->get_DepthMinReliableDistance( &min ); // 500
pDepthSource->get_DepthMaxReliableDistance( &max ); // 4500
cout << "Range : " << min << " - " << max << std::endl; //创建尺寸为height x width 的1通道8位图像
Mat bufferMat( height, width, CV_16UC1 );
Mat depthMat( height, width, CV_8UC1 ); while( 1 ){
// 更新深度帧
IDepthFrame* pDepthFrame = nullptr;
hResult = pDepthReader->AcquireLatestFrame( &pDepthFrame );
if( SUCCEEDED( hResult ) ){
hResult = pDepthFrame->AccessUnderlyingBuffer( &bufferSize, reinterpret_cast<UINT16**>( &bufferMat.data ) );
if( SUCCEEDED( hResult ) ){
bufferMat.convertTo( depthMat, CV_8U, -255.0f / 4500.0f, 255.0f );
}
}
SafeRelease( pDepthFrame ); imshow( "Depth", depthMat );
5。V2+VS2012+OpenCV代码
#include <Windows.h>
#include <Kinect.h>
#include <opencv2/opencv.hpp>
#include <cstdlib> 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;
} // 深度帧源
IDepthFrameSource* pDepthSource;
hResult = pSensor->get_DepthFrameSource( &pDepthSource );
if( FAILED( hResult ) ){
cerr << "Error : IKinectSensor::get_DepthFrameSource()" << std::endl;
return -1;
} // 深度帧读取
IDepthFrameReader* pDepthReader;
hResult = pDepthSource->OpenReader( &pDepthReader );
if( FAILED( hResult ) ){
cerr << "Error : IDepthFrameSource::OpenReader()" << std::endl;
return -1;
} // Description
IFrameDescription* pDescription;
hResult = pDepthSource->get_FrameDescription( &pDescription );
if( FAILED( hResult ) ){
cerr << "Error : IDepthFrameSource::get_FrameDescription()" << std::endl;
return -1;
} int width = 0;
int height = 0;
pDescription->get_Width( &width ); // 512
pDescription->get_Height( &height ); // 424
unsigned int bufferSize = width * height * sizeof( unsigned short ); // Range
unsigned short min = 0;
unsigned short max = 0;
pDepthSource->get_DepthMinReliableDistance( &min ); // 500
pDepthSource->get_DepthMaxReliableDistance( &max ); // 4500
cout << "Range : " << min << " - " << max << std::endl; //创建尺寸为height x width 的1通道8位图像
Mat bufferMat( height, width, CV_16UC1 );
Mat depthMat( height, width, CV_8UC1 ); while( 1 ){
// 更新深度帧
IDepthFrame* pDepthFrame = nullptr;
hResult = pDepthReader->AcquireLatestFrame( &pDepthFrame );
if( SUCCEEDED( hResult ) ){
hResult = pDepthFrame->AccessUnderlyingBuffer( &bufferSize, reinterpret_cast<UINT16**>( &bufferMat.data ) );
if( SUCCEEDED( hResult ) ){
bufferMat.convertTo( depthMat, CV_8U, -255.0f / 4500.0f, 255.0f );
}
}
SafeRelease( pDepthFrame ); imshow( "Depth", depthMat ); if( cv::waitKey( 30 ) == VK_ESCAPE ){
break;
}
} SafeRelease( pDepthSource );
SafeRelease( pDepthReader );
SafeRelease( pDescription );
if( pSensor ){
pSensor->Close();
}
SafeRelease( pSensor ); return 0;
}
Kinect for Windows V2和V1对照开发___深度数据获取并用OpenCV2.4.10显示的更多相关文章
- Kinect for Windows V2和V1对照开发___彩色数据获取并用OpenCV2.4.10显示
V1彩色分辨率:640x480 V2彩色分辨率:1920x1080 1,打开彩色图像帧的方式 对于V1: 使用NuiImageStreamOpen方法打开 hr = m_PNuiSensor-> ...
- Kinect for Windows V2开发教程
教程 https://blog.csdn.net/openbug/article/details/80921437 Windows版Kinect SDK https://docs.microsoft. ...
- Kinect for Windows V2.0 新功能
系统要求: win8 or win8.1 硬件要求: 64位(x64)处理器 i7 2.5-GHz或更快的处理器 内置USB 3.0总线 4 GB RAM DX11图形适配器 外观: 第二代Kin ...
- Kinect For Windows V2开发日志一:开发环境的配置
算是正式进军Kinect了,前段时间学的东西现在就忘了,于是从此开始记录一下. 目前为止大部分的学习资料来自于Heresy的博客,写的非常优秀,清晰明了,十分感谢.开发语言为C++,应该会一直使用,但 ...
- Kinect For Windows V2开发日志八:侦测、追踪人体骨架
简介 Kinect一个很强大的功能就是它可以侦测到人体的骨骼信息并追踪,在Kinect V2的SDK 2.0中,它最多可以同时获取到6个人.每个人25个关节点的信息,并且通过深度摄像头,可以同时获取到 ...
- Kinect For Windows V2开发日志六:人体的轮廓的表示
Kinect中带了一种数据源,叫做BodyIndex,简单来说就是它利用深度摄像头识别出最多6个人体,并且用数据将属于人体的部分标记,将人体和背景区别开来.利用这一特性,就可以在环境中显示出人体的轮廓 ...
- Kinect For Windows V2开发日志五:使用OpenCV显示彩色图像及红外图像
彩色图像 #include <iostream> #include <Kinect.h> #include <opencv2\highgui.hpp> using ...
- Kinect For Windows V2开发日志九:侦测并绘制人体骨架
简介 在上一篇<侦测.追踪人体骨架>里,介绍了关节点的使用办法,这一篇记录将关节点与OpenCV结合的绘图方法. 代码 #include <iostream> #include ...
- Kinect For Windows V2开发日志七:照片合成与背景消除
上一篇里讲到了Kinect可以从环境中区分出人体来.因此可以利用这个功能,来把摄像头前的人合成进照片里,和利用Photoshop不同的是,这样合成进去的人是动态且实时的. 简单的思路 BodyInde ...
随机推荐
- asp.net DropDownList无刷新ajax二级联动实现详细过程
只适合新手制作DropDownList无刷新ajax二级联动效果: 数据库实现,添加两表如图:表1,pingpai,表2,type,具体数据库实现看自己的理解: //页面主要代码: <asp:S ...
- JAVA三大框架的各自作用
http://christhb.blog.163.com/blog/static/98982492011727114936239/ 一.Spring Spring是一个解决了许多在J2EE开发中常见的 ...
- javaweb学习总结(四十三)——Filter高级开发
在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目 ...
- 《linux程序设计》笔记 第一章 入门
linux程序存放位置linux主要有一下几个存放程序的目录: /bin 系统启动程序目录 /usr/bin 用户使用的标准程序 /usr/local/bin 用于存放软件安装目录 /usr ...
- 【HDOJ】2295 Radar
DLX+二分. /* 2295 */ #include <iostream> #include <string> #include <map> #include & ...
- Xcode 不提示, 引用失效等情况
在编写xcode的项目的时候出现过代码不高亮的症状,而且所有的warning都不再提示,include的内容也显示symbol not found,非常奇怪,解决方案如下: 方法一: 1.把.pch里 ...
- 【转】JNI学习积累之一 ---- 常用函数大全
原文网址:http://blog.csdn.net/qinjuning/article/details/7595104 本文原创,转载请注明出处:http://blog.csdn.net/qinjun ...
- css滑动门制作圆角按钮
之前做项目的时候,基本都是将圆角背景图切成三块,故而每次用的标签都超级多,a标签中总是包含三个span,然后里面还得放按钮,导航冗余标签极多. 事实上是之前理解的滑动门的精髓不够到位. 现在有两种方式 ...
- ArcSDE 10.1安装、配置、连接 (SQL Server 2008)
转自:http://blog.csdn.net/esrichinacd/article/details/8510224 1 概述 ArcSDE 10.1的安装配置相较于ArcSDE 10.0和之前版 ...
- 事件流处理框架NEsper for .NET z
复合事件处理(Complex Event Processing)介绍提到了开源的Esper,NEsper 是一个事件流处理(Event Stream Processing,ESP)和复杂事件处理(Co ...