首先声明一下,本系统所使用的开发环境版本是计算机系统Windows 10、Visual Studio 2013、Opencv3.0和Kinect SDK v2.0。这些都可以在百度上找到,download下来安装一下即可。
这个很简单没什么好说的,一直点下一步下一步就可以了,这里不再赘述。给出旗舰版下载链接http://download.microsoft.com/download/B/1/9/B1932B8C-1046-4773-A1DD-4AB5C0978637/vs2013.2_ult_chs.iso
还有版本秘钥,直接百度查找就会有,这里给出我当时用的: BWG7X-J98B3-W34RT-33B3R-JVYW9。
2.Opencv3.0安装
Opencv的全称是Open Source Computer Vision Library,是一个开源的跨平台计算机视觉库,把图像处理和计算机视觉方面的很多常用算法封装成API,方便开发者直接调用,可以运行当前主流的各种操作系统上。其官网:http://opencv.org
Opencv3.0的安装十分简单,只是环境配置相比其他软件有一丢丢麻烦。这里将分步演示每一步,包教包会。
你要记住你安装的路径。像本人的就是G:\Program Files\opencv3.0\opencv。第一步,配置环境变量。【计算机】-【(右键)属性】-【高级系统设置】-【环境变量】。如图
在path后面加一个英文分号,然后添加安装路径下的bin文件,包括X86和X64文件夹下的,像本人的就是这样的G:\Program Files\opencv3.0\opencv\build\x64\vc12\bin;G:\Program Files\opencv3.0\opencv\build\x86\vc12\bin;不同的安装路径添加到内容不一样,不要直接复制本文的,找到自己的安装路径。这样环境变量就配置好了。
温馨提示:环境变量配置好后一般需要重启电脑才会生效。
第二步,新建一个VS2013的控制台工程,添加一个空cpp源文件。在菜单栏有个【视图】-【其他窗口】-【属性管理器】。如图
打开属性窗口后,双击【Debug|Win32】下的第一个文件【Microsoft.Cpp.Win32.user】会打开一个属性页。(1)配置包含目录。【通用属性】-【VC++目录】-【包含目录】,再点击【编辑】按钮,添加opencv安装路径下的include文件夹和其子文件下,本人的是:
G:\Program Files\opencv3.0\opencv\build\include
G:\Program Files\opencv3.0\opencv\build\include\opencv
G:\Program Files\opencv3.0\opencv\build\include\opencv2
截图如下:
(2)配置库目录,方法类似包含目录的配置方法,【通用属性】-【VC++目录】-【库目录】,再点击【编辑】按钮,添加安装路径下的X86文件夹里面的lib文件夹,因为我们一般都是使用win32编译器。本人的是
G:\Program Files\opencv3.0\opencv\build\x86\vc12\lib
截图如下:
(3)配置链接库,方法类似。【通用属性】-【连接器】-【输入】-【附加依赖项】,再点击【编辑】按钮。添加安装路径下lib文件夹里面的,lib文件名,opencv3.0的lib文件包含有
opencv_ts300d.lib
opencv_world300d.lib
opencv_ts300.lib
opencv_world300.lib
其中带d的是debug版本lib文件,不带d的是release版本的lib文件。
截图如下:
经过以上两大步五小步的配置之后,opencv3.0就配置好了。自己可以找个小程序测试一下,有其他问题欢迎留言,也可以自行百度或者谷歌解决。
3.Kinect SDK v2.0
去官网直接下载下来,双击安装就行,然后在VS2013里面添加一下相关的库目录和链接库的附加依赖项。在【包含目录】中加入【$(KINECTSDK20_DIR)\inc】
在【库目录】中加入【$(KINECTSDK20_DIR)\Lib\x86】
在【链接器】的【输入】里,【附加依赖项】中加入【kinect20.lib】。下载地址https://www.microsoft.com/en-us/download/details.aspx?id=44561
好了,以上这么多就是配置开发环境的过程了,有问题欢迎留言交流。接下来就要进入正题了。
就目前来说,市面还没有Kinect v2相关的学习书籍。本人觉得最好的学习资料就是SDK里面的一些samples了,好好研究里面的代码会让你收获不少,,当然也可以上网看一些别人的学习心得和学习笔记。
深入研读Kinect SDK v2.0里面示例的程序(samples),会发现Kinect v2的API是有规律可循的。拿上文提到的数据源举例,每种数据源都有3个类与之对应,分别是Source,Reader,Frame,在程序里面只需要实例化这三个类并调用相关类的成员函数就可以了。获取彩色图像时,就需要使用IColorFrameSource, IColorFrameReader, IColorFrame这三个类。获取红外图像时,就会使用IInfraredFrameSource, IInfraredFrameReader, IInfraredFrame这三个类。剩下的也是类似的,如骨骼数据(Body),人物索引二值图(BodyIndex),深度图(Depth)。继续深究:
(1)Source 在初始化好Kinect后,需要请求Kinect打开一个目标源,后面从这个源获得数据。以骨骼数据源为例,下同,示例代码为:
m_pKinectSensor->get_BodyFrameSource(&pBodyFrameSource);
其中m_pKinectSensor是一个IKinectSensor类的实例化对象,是Kinect的源,所有数据都是从这个源获取的,pBodyFrameSource是一个IBodyFrameSource类的实例化对象,它可以打开读口(reader)传输数据到电脑。
(2)Reader 由于Source是从Kinect获得的数据源,在电脑端需创建一个Reader和上面的Source绑定,然后可以通过这个Reader来获取数据。示例代码:
pBodyFrameSource->OpenReader(&m_pBodyFrameReader);
其中m_pBodyFrameReader是一个IBodyFrameReader类的实例化对象,获取最新的图像帧(AcquireLatestFrame)以及该类数据的其他属性。
(3)Frame 真正存储数据的类,一般是先从Reader读取数据到Frame里面,Frame里面有各种各样的数据,可以按自己的需求获取。示例代码:
m_pBodyFrameReader->AcquireLatestFrame(&pBodyFrame);
其中pBodyFrame是一个IBodyFrame类的实例对象,调用其相关成员函数就可以把数据转换到数组或者其他格式,进而可以用Opencv显示出来。
这里的每个对象都需主动释放,否则无法获取其他变量。
在这里以获取深度图为例,直接先贴上代码,稍后详细解析。
#include //Kinect的头文件
#include
#include //opencv头文件
using namespace std;
using namespace cv;
int main(void)
{
IKinectSensor * mySensor = nullptr;
GetDefaultKinectSensor(&mySensor); //获取感应器
mySensor->Open(); //打开感应器
IDepthFrameSource * mySource = nullptr; //取得深度数据
mySensor->get_DepthFrameSource(&mySource);
int height = 0, width = 0;
IFrameDescription * myDescription = nullptr; //取得深度数据的分辨率
mySource->get_FrameDescription(&myDescription);
myDescription->get_Height(&height);
myDescription->get_Width(&width);
myDescription->Release();
IDepthFrameReader * myReader = nullptr;
mySource->OpenReader(&myReader); //打开深度数据的Reader
IDepthFrame * myFrame = nullptr;
Mat temp(height,width,CV_16UC1); //建立图像矩阵
Mat img(height,width,CV_8UC1);
while (1)
{
if (myReader->AcquireLatestFrame(&myFrame) == S_OK) //通过Reader尝试获取最新的一帧深度数据,放入深度帧中,并判断是否成功获取
{
myFrame->CopyFrameDataToArray(height * width, (UINT16 *)temp.data); //先把数据存入16位的图像矩阵中
temp.convertTo(img,CV_8UC1,255.0 / 4500); //再把16位转换为8位
imshow("TEST", img);
myFrame->Release();
}
if (waitKey(30) == VK_ESCAPE)
break;
}
myReader->Release(); //释放不用的变量并且关闭感应器
mySource->Release();
mySensor->Close();
mySensor->Release();
return 0;
}
注意:为了简便起见,此段代码略掉了大部分错误和异常检测,只是为了做个示例获取Kinect的深度图像。
首先,声明了两个矩阵,一个为16位单通道,一个为8位单通道,之所以开16位的,是因为在Kinect的基本参数这篇里可以看到,深度数据是16位的。开8位的原因等下说。然后同样的,利用AcquireLatestFrame()来获取最新的一帧,不同的是下面一句,不再用AccessUnderlyingBuffer(),而是用CopyFrameDataToArray来把数据复制到openCV的图像矩阵Mat里,注意第三个参数的类型是UINT16*,所以需要强制转换一下。接下来要把16位的Mat转换成8位来输出显示,为什么不直接用16位?其实也可以用,但是直接用16位的话显示的图像很接接近于全黑,不方便观察,于是转换为8位。convertTo()这个函数的第一个参数是输出矩阵,第二个是转换的类型,第三个是缩放因子,其中4500是深度数据的最大距离。如图所示。
其他各种图像获取方法都是类似的,除了骨骼数据获取稍微复杂一点点,这些将在文章末尾打包下载,程序都会有详细注释。
Kinect for Windows C++ Reference(Kinect v2的API最全面和最权威的文档):
https://msdn.microsoft.com/en-us/library/hh855364.aspx?f=255&MSPPError=-2147217396
Github上的一系列讲义:http://kinect.github.io/tutorial/
还有很多人的博客和论坛也有讲解Kinect的入门开发:(1)http://blog.csdn.net/dustpg/article/category/2408183
(2)
http://blog.csdn.net/bbdxf/article/details/44857099
(3)体感游戏论坛
http://www.cnkinect.com/forum-41-1.html
(4)k4w网
http://www.k4w.cn/index
。。。。。。。
好了,本篇文章到这里就要结束了。通过本篇文章,主要可以掌握Kinect v2的部分API的使用和学会如何获取Kinect的数据源。下面附上一些源码下载地址,0积分下载。
http://download.csdn.net/detail/baolinq/9616276
下一篇见。