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 ...
随机推荐
- Android MediaStore与Media.EXTERNAL_CONTENT_URI
MediaStore这个类是Android系统提供的一个多媒体数据库,android中多媒体信息都可以从这里提取.这个MediaStore包括了多媒体数据库的所有信息,包括音频,视频和图像,andro ...
- Oracle系列之视图
涉及到表的处理请参看原表结构与数据 Oracle建表插数据等等 创建视图,把tb_Employee表sal<1000的雇员,映射到该视图( view) create or replace vi ...
- mapreduce: InputFormat详解 -- RecordReader篇
InputFormat是MapReduce中一个很常用的概念,它在程序的运行中到底起到了什么作用呢? InputFormat其实是一个接口,包含了两个方法: public interface Inpu ...
- 函数page_rec_get_next_const
/************************************************************//** Gets the pointer to the next recor ...
- Cookie的前后台应用
1.jquery.cookie.js的基本应用 这个是第三方js插件,可以更方便的设置和使用cookie $.cookie("UserName", "kingtiger& ...
- Oracle MySQL Server 安全漏洞
漏洞名称: Oracle MySQL Server 安全漏洞 CNNVD编号: CNNVD-201401-317 发布时间: 2014-01-22 更新时间: 2014-01-22 危害等级: 中危 ...
- js模拟Map对象,实现key---value
js模拟Map对象,实现key---value 根据java中map的属性,实现key----value保存 function Map() { var struct = function (key, ...
- Xcode工程中全局搜索汉字的方法
打开”Find Navigator” 切换搜索模式到 “Find > Regular Expression” 输入@"[^"]*[\u4E00-\u9FA5]+[^" ...
- Android Matrix用法
Matrix,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放.平移.旋转等操作. 首先介绍一下矩阵运算.加法和减法就不用说了,太简单了,对应位相加就好.图像处理,主要用到的是乘法 ...
- 用excel打造报表查询系统
网络数据库以及ERP在中小型企业中日益风行,虽然ERP功能强大,但有的ERP报表系统中规范的报表较少,主要提供二次开发接口或通过如CRYSTALREPORT等其他报表工具进行管理,其实我们可以使用Ex ...