本人开发Kinect程序,采用的是OpenNI2,其中,会用到OpenCV、Nite2等内容。并且,以后我所说的OpenNI如果不是特殊说明,都指的是OpenNI2。
顺便提一下:本人也是新手,是一边学习,一边把自己的心得体会写下来,其中,难免会出现一些疏漏或者错误的地方,如果您不幸看到了我的文章,还请多多包涵~ :D
要做开发,首先要做的就是把开发环境搭好,具体的步骤,由于OpenNI官网上有详细的说明,本文不再赘述。需要注意的一点就是我前些天发的那个文章,如果自己的vs是32位的,即便本机系统是64位系统,也要下载32位的安装包。
下面,开始进入正题。
1. 包含OpenNI.h头文件,并且,将相应的openni2.lib库也要引进来。具体的引入步骤不再细说。
2. 调用openni::OpenNI::initialize()方法进行初始化,initialize方法会加载所有的驱动程序,并且,查找可用的驱动。注意,在使用任何openni方法之前调用该方法,并且,整个应用程序调用一次即可,以后再次调用的时候,将视为无效。该方法首先先查找当前目录下是否存在OpenNI.ini文件,如果存在,则加载其中的内容,默认的配置包括以下内容:
[Log] ; 0 - Verbose; 1 - Info; 2 - Warning; 3 - Error. Default - None Verbosity=3 LogToConsole=0 LogToFile=0 [Device] ;Override=""
其中一部分与log相关,还有一部分与设备相关。除了上面列出的内容,还可以增加一个[Derivers]节,可以配置"Repository"属性值,用来配置其他的驱动。initialize查找驱动的顺序如下:
a. 先查找OpenNI.ini配置文件中的Derivers节的"Repository"属性值,如果有,则加载该驱动;
b. 如果没有在ini中配置驱动,则使用默认的驱动,默认驱动放在当前目录下的OpenNI2\\Drivers目录下。
c. 如果默认驱动加载失败,就会读取环境变量中的“OPENNI2_DRIVERS_PATH”值。
如果以上都没有正确加载,那么initialize方法将返回错误值,具体的错误可以通过openni::OpenNI::getExtendedError()查看。
3. 在初始化完毕,也就是加载驱动之后,接下来就是获取设备信息。如果你的系统上只连接了一台设备,那么,就可以直接通过如下代码打开设备:
...
openni::Device device;
device.open(ANY_DEVICE);
...
如果有多个设备,传入ANY_DEVICE参数,系统就会随机选择一台设备打开。如果想要指定设备打开,那么就需要传入指定设备的URI了。OpenNI获取设备URI的方式有两种:
a. 通过DeviceConnected事件获取
b. 通过openni::OpenNI::enumerateDevices()枚举设备。
注意:如果在第2步中的OpenNI.ini文件中配置了Override属性值,那么在Device::open方法中传递的任何URI,都将被ini的值替换。也就是说优先匹配ini的Device,如果没有设置,则匹配程序里面传入的URI。
4. 驱动与设备都已经准备完毕,接下来就是最主要的功能,获取数据了。一台Kinect可以获取多种数据,比如深度、颜色等。获取数据也有两种方式,分别是事件通知和轮询。两种方式会在以后的文章中进行介绍。
5. 本次示例我们先只获取深度数据。定义一个VideoStream对象。再通过create方法进行创建,代码如下:
VideoStream depthStream; if (device.getSensorInfo(SENSOR_DEPTH) != NULL) { depthStream.create(device, SENSOR_DEPTH); }
depthStream.start();
上面代码先创建深度数据流,然后,再通过start方法,来通知驱动进行数据的接收。
6. 到现在为止,我们的程序已经可以正常的从设备中读取到深度数据流了,那么怎么获取呢?数据流的结构又是如何?下篇文章再进行介绍。
7. 最后,当我们要结束程序的时候,不要忘了释放资源。
depthStream.stop();
depthStream.destroy();
device.close();
OpenNI::shutdown();
好了,本篇先介绍到这里,下面一篇将要介绍如何获取并且处理深度数据。