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 ...
随机推荐
- SQL模糊查询与删除多条语句复习
string IDlist="1,2,3"; 批量删除数据 StringBuilder strsql=new StringBuilder(); strSql.Append(&quo ...
- J2EE的十三种技术(规范)
J2EE的十三种技术(规范) Java数据库连接(JDBC) JDBC API以一个统一的方式访问各种数据库.与ODBC类似,JDBC将开发者和私有数据库之间的问题隔离开来.由于它建立在Java上, ...
- linux下查看防火墙当前状态,开启关闭等
从配置菜单关闭防火墙是不起作用的,索性在安装的时候就不要装防火墙 查看防火墙状态: /etc/init.d/iptables status 暂时关闭防火墙: /etc/init.d/iptables ...
- USACO3.23Spinning Wheels
直接枚举角度 数据比较水吧 /* ID: shangca2 LANG: C++ TASK: spin */ #include <iostream> #include<cstdio&g ...
- c# 提取word文件中的图片问题
最近遇到一个项目就是要从一份word中提取出所有的图片信息,功能看起来不是很难,只要使用office自带的Microsoft.Office.Interop.Word就可以解决问题.网上也有不少的文章来 ...
- 对ASP.NET程序员非常有用的85个工具
介绍 这篇文章列出了针对 ASP.NET 开发人员的有用工具. 工具 1. Visual Studio Visual Studio Productivity Power tool:Visual Stu ...
- POJ 1847 Tram dij
分析:d[i]表示到i点,最少的操作数 #include<cstdio> #include<cstring> #include<queue> #include< ...
- HDU 1285
#include<stdio.h> #include<string.h> int degree[505],vis[505],map[501][501]; int main() ...
- [liu yanling]测试小结
编写测试用例,业务了解是基础,结合业务编写测试用例,重要的逻辑一定要覆盖
- java中字符串切割的方法总结
StringTokenizer最快 ,基本已经不用了,除非在某些需要效率的场合.Scanner最慢. String和Pattern速度差不多.Pattern稍快些. String和Pattern的sp ...