【翻译】Kinect v2程序设计(C++) Depth编

Kinect SDK v2预览版,取得Depth数据的方法说明。

上一节,介绍了通过使用Kinect for Windows SDK v2预览版(以下简称为,Kinect SDK v2预览版)从Kinect for Windows v2开发者预览版(后面称,Kinect v2 预览版)取得Color的方法。

这一节,介绍的是从Kinect取得Depth数据的方法。

Depth传感器

Kinect搭载Depth传感器,可以取得Depth数据(和传感器的距离信息)。

Kinect v1,可以读取投射的红外线pattern,从pattern的变形获取Depth的信息,搭载了「Light Coding」方式的Depth传感器。

Kinect v2预览版,通过从投射的红外线脉冲反射回来的时间来获得Depth的信息,变更为「Time of Flight(ToF)」方式的Depth传感器。

「Light Coding」是以色列PrimeSense公司的Depth传感技术。详细请参照专利信息,美国申请专利公开(US 2010/0118123 A1)- Depth Mapping using Projected Patterns。

「Time of Flight(ToF)」是美国微软公司收购的拥有Time of Flight(ToF)方式的Depth传感技术的公司(3DV Systems公司,Canesta公司),一般认为使用的是这个技术。

Depth数据的分辨率,Kinect v1是320×240,不过,Kinect v2预览版提升为512×424。另外,深度方向的分辨率也提高了。

可以取得Depth的数据范围,Kinect v1是0.8~4.0[m]的范围, Kinect v2预览版可以取得0.5~4.5[m]的范围。

上面说的是Default Mode的Depth数据范围。Kinect v1提供了取得近距离的Depth数据的Near Mode(0.4~3.0[m])和取得远距离Depth数据的Extended Depth(~约10.0[m])。但是,偏离Default Mode的范围的Depth数据的精度会下降。

这节,介绍从Depth传感器取得Depth数据的方法。

图1「Light Coding」方式和「Time of Flight(ToF)」方式的差异(Depth传感器的工作原理的图像)

示例程序

Kinect SDK v2预览版取得Depth数据,可视化展示的示例程序。上一节的介绍的数据取得阶段的摘录解说。这个示例程序的全部内容,在下面的github里全部公开了。

https://github.com/UnaNancyOwen/Kinect2Sample

图2 Kinect SDK v2预览版的数据取得流程(重发)

「Sensor」

取得「Sensor」

// Sensor
IKinectSensor* pSensor;   ……1
HRESULT hResult = S_OK;
hResult = GetDefaultKinectSensor( &pSensor );  ……2
if( FAILED( hResult ) ){
  std::cerr << "Error : GetDefaultKinectSensor" << std::endl;
  return -1;
}
hResult = pSensor->Open();  ……3
if( FAILED( hResult ) ){
  std::cerr << "Error : IKinectSensor::Open()" << std::endl;
  return -1;
}

列表1.1 相当于图1「Sensor」的部分(重发)

1 处理Kinect v2预览版的Sensor接口。

2 取得默认的Sensor。

3 打开Sensor。

「Source」

从「Sensor」取得「Source」。

// Source
IDepthFrameSource* pDepthSource;  ……1
hResult = pSensor->get_DepthFrameSource( &pDepthSource );  ……2
if( FAILED( hResult ) ){
  std::cerr << "Error : IKinectSensor::get_DepthFrameSource()" << std::endl;
  return -1;
}

列表1.2 相当于图1「Source」的部分

1 取得Depth Frame的Source接口。

2 从Sensor取得Source。

Kinect SDK v1,要取得Depth数据主要是利用可以同时取得的Depth和Player(人体区域)的「Stream」。因此,必须要有Depth数据和Player数据的分割处理。(注:Kinect SDK v1提供2种方式来处理Depth和Player Index,老的方法返回一组USHORT,通过位移分离两者;新的方法返回各为2个USHORT的结构)

Kinect SDK v2预览版,Depth和BodyIndex(相当于Kinect SDK v1的Player)分别作为「Source」取得,关于BodyIndex在下一节介绍。

Kinect SDK v1也准备了取得Depth的「Stream」,因为获取Player和Skeleton(人体姿势)数据的情况也很多,主要可以同时取得Depth和Player的「Stream」。

「Reader」

「Source」从打开「Reader」。

// Reader
IDepthFrameReader* pDepthReader;  ……1
hResult = pDepthSource->OpenReader( &pDepthReader );  ……2
if( FAILED( hResult ) ){
  std::cerr << "Error : IDepthFrameSource::OpenReader()" << std::endl;
  return -1;
}

列表1.3 相当于图1「Reader」的部分

1 取得Depth Frame的Reader接口。

2 从Source打开Reader。

「Frame」~「Data」

从「Reader」取得最新的「Frame」。

int width = 512;  ……1
int height = 424;  ……1
unsigned int bufferSize = width * height * sizeof( unsigned short );  ……2
cv::Mat bufferMat( height, width, CV_16SC1 );  ……3
cv::Mat depthMat( height, width, CV_8UC1 );  ……3
cv::namedWindow( "Depth" );
while( 1 ){
  // Frame
  IDepthFrame* pDepthFrame = nullptr;  ……4
  hResult = pDepthReader->AcquireLatestFrame( &pDepthFrame );  ……5
  if( SUCCEEDED( hResult ) ){
    hResult = pDepthFrame->AccessUnderlyingBuffer( &bufferSize, reinterpret_cast<UINT16**>( &bufferMat.data ) );  ……6
    if( SUCCEEDED( hResult ) ){
      bufferMat.convertTo( depthMat, CV_8U, -255.0f / 4500.0f, 255.0f );  ……7
    }
  }
  SafeRelease( pDepthFrame );
  // Show Window
  cv::imshow( "Depth", depthMat );
  if( cv::waitKey( 30 ) == VK_ESCAPE ){
    break;
  }
}

列表1.4 相当于图1「Frame」,「Data」的部分

1 Depth数据的尺寸(512×424)。

这里为了简化说明,画像尺寸用硬代码来设定,示例程序可以Source取得着Frame信息。

2 Depth数据的尺寸。

3 为了处理Depth数据而准备的OpenCV的cv::Mat类型。

「bufferMat」是16bit的原始的Depth数据,「depthMat」为了作为图像显示,把Depth数据储存到8bit的范围里的处理。

「CV_16SC1」,是把无符号16bit整数(16S) 放入1个channel(C1)并列来表现1个像素的数据格式。(注:应该是CV_16UC1才对)

「CV_8UC1」,是表现无符号8bit整数  (8U)的数据格式。

4 取得Depth数据的Frame接口。

5 从Reader取得最新的Frame。

6 从Frame取得Depth数据。

取得Depth数据存储数组的指针。这里为了Depth数据可视化,方便变化处理,用cv::Mat类型来获取。

7 为了显示Depth数据图像,从16bit转换为8bit。

如果得到「Frame」,就可以把取出Depth数据,作成图像来可视化。

取出的Depth数据,像图3一样以16bit(0~4500)为1像素来构成。

因为这样的图像不能显示(注:OpenCV只能显示8bit的图像数据),需要把格式转化为8bit(0~255)的范围。示例程序,使用cv::Mat的转换命令(cv::Mat::convertTo())把离传感器距离近的显示很白(255),远的显示为很黑(0)的方式来转化。

图3 Depth数据的排列

运行结果

运行这个示例程序的话,在Kinect v2预览版取得深度图像,就像图4一样。

图4 运行结果

总结

本节介绍了通过Kinect SDK v2预览版取得Depth数据的示例程序。下一节介绍取得BodyIndex数据的示例程序。

时间: 2024-10-14 19:47:24

【翻译】Kinect v2程序设计(C++) Depth编的相关文章

【翻译】Kinect v2程序设计(C++-) AudioBeam篇

Kinect v2,Microphone Array可以用来对于水平面音源方向的推测(AudioBeam)和语音识别(Speech Recognition).这一节是介绍如何取得AudioBeam. 上一节,介绍如何使用通过Kinect SDK v2预览版,从Kinect v2预览版的Color Camera和Depth 传感器中获取数据的方法. 本节,将介绍从Kinect的Microphone Array中取得AudioBeam(水平面音源方向的推测)的方法. Microphone Array

【翻译】Kinect v2程序设计(C++) BodyIndex篇

通过Kinect SDK v2预览版,取得BodyIndex(人体区域)的方法和示例代码. 上一节,介绍了从Kinect v2预览版用Kinect SDK v2预览版获取Depth数据的方法. 这一节,介绍从Kinect取得BodyIndex(人体区域)的方法. BodyIndex 基于从Kinect取得的Depth数据(传感器的距离信息)获取人体区域. 因为人体区域基于Depth数据,同时也依赖Depth传感器的分辨率.像上一节介绍的一样,因为Kinect v2 预览版(512×424)的De

Kinect v2程序设计(C++) Body 篇

Kinect SDK v2预览版的主要功能的使用介绍,基本上完成了.这次,是关于取得Body(人体姿势)方法的说明. 上一节,是使用Kinect SDK v2预览版从Kinect v2预览版取得BodyIndex(人体区域)的方法. 这一节,介绍从Kinect取得Body(人体姿势)的方法. Body 到目前为止,Kinect能取得Depth(通过传感器的距离信息)和BodyIndex(人体区域).并且,基于这些数据可以取得人体姿势. Kinect的人体姿势,是向学习了基于庞大数量的姿势信息的识

Kinect V2程序设计(C++) Color篇

Kinect SDK v2预览版,获取数据的基本流程的说明.以及取得Color图像的示例程序的介绍. 上一节,是关于当前型号Kinect for Windows(后面称作Kinect v1)和次世代型的Kinect for Windows的开发者预览版(后面称作Kinect v2 预览版)的配置比较和介绍. 从这一节开始,是Kinect的各种数据的取得方法的比较和介绍. Color Camera Kinect和通常的Web摄像头一样,搭载了 Color Camera,可以取得Color图像.关于

Kinect v1和Kinect v2的彻底比较

本连载主要是比较Kinect for Windows的现行版(v1)和次世代型的开发者预览版(v2),以C++开发者为背景介绍进化的硬件和软件.本文主要是对传感的配置和运行条件进行彻底的比较. 本连载介绍的Kinect for Windows Developer Preview是暂定的,软件.硬件以及API有可能因为最终的产品版发生变更,还请谅解. 关于本连载 本连载主要是比较次世代型的Kinect for Windows(后面称作Kinect v2预览版)和现行型的Kinect for Win

标定Kinect v2彩色摄像头:使用iai_kinect2,采用qhd(960*540)大小的彩色图像

开篇一作,这篇博文是纯应用的,没有任何理论说明,就当是一个实践提醒啦. 安装kinect v2相机驱动和标定程序得益于下面二位前辈的引荐工作: http://www.cnblogs.com/gaoxiang12/p/5161223.html http://www.cnblogs.com/hitcm/p/5118196.html 十分感谢! 请读者先按照上面前辈的博文安装好libfreenect2和iai_kinect2. 在iai_kinect2标定步骤中(https://github.com/

unity Kinect v2 with MS-SDK20绿屏抠像shader修改 透明背景

用的是kinect2.0 Kinect v2 with MS-SDK20插件 例子中的默认greenscreen里面是绿色的,要求改成透明的,下面直接上代码 改完后放背景看看吧 是不是透明了 Shader "DX11/GreenScreenShader" { SubShader { //透明就需要这个 Blend SrcAlpha OneMinusSrcAlpha Tags {"Queue"="AlphaTest" } Pass { CGPROG

ubuntu14.04下 Kinect V2+Ros接口安装

1. 首先git下载代码,放到主文件夹下面 git clone https://github.com/OpenKinect/libfreenect2.git 2. 然后安装依赖项如下,最好事先编译安装好OpenCV sudo apt-get install build-essential cmake pkg-config libturbojpeg libjpeg-turbo8-dev mesa-common-dev freeglut3-dev libxrandr-dev libxi-dev 3.

ubuntu连接kinect v2

经过这个过程才悟到,有的时候不是方法不对,也不是问题解决的不对,只是因为配置问题,如果配置不对,自然会出现各种各样问题,不如一开始就确定配置.不过,如果不是经历了这个过程,我也不知道是因为我的配置问题导致的问题,哎. 我用的是ubuntu14.04LTS,ROS 版本是indigo,kinect v2,我是用双系统装的ubuntu,用虚拟机装的ubuntu是不行的,会出现各种各样问题,因为虚拟机用的是它自带的驱动器,这显然是不行的. 下面正式进入安装 1.安装libfreenect2,这个lib