
2.2 Intel RealSense SDK架构
2.2.1 SDK架构
SDK架构由多层部件组成,如图2-4所示。最核心SDK功能为输入/输出(I/O)模块和算法模块。I/O模块用于获得输入设备的信号或者输出信息到相应设备。算法模块包括各种模式检测和识别算法,作为创新性人机体验的重要手段,例如人脸识别、手势识别、语音识别、文字转语音等。

图2-4 SDK架构
SDK对I/O模块和算法模块进行标准化,使得应用程序可以不用关心底层实现而轻松获得所需功能。某些SDK接口可能存在共存的多重实现。SDK可以从各种算法模块中对某个特定实现进行搜索或者创建某个算法的实例。SDK的语言与架构封装如图2-5所示。

图2-5 SDK语言与框架封装
2.2.2 会话和模块
SDK的结构单元包括I/O模块和算法模块。SDK会话控制这些模块的上下文场景,是SDK应用的主控模块。所有SDK应用程序都会创建一个或多个SDK会话。每个会话将维护专属的控制I/O和算法模块的上下文场景。
在一个SDK会话内部有多个I/O和算法模块,用来实现特定的SDK接口。在某些情况下,一个SDK接口可能会有多重实现。可以在会话中创建模块的实例、使用或注销模块实例。模块的生命周期就是模块的工作时间。
SDK会话必须在所有模块操作之前创建,并且在所有模块注销后最后注销。
2.2.3 SenseManager中的流
SenseManager接口是所有预定义模块的主要接口,在一个SenseManager实例中存在一个或多个算法模块和一个单独的摄像头输入设备。可以创建多个SenseManager接口实例对接不同的摄像头。摄像头为算法模块提供数据。
SDK会话、SenseMangager、算法模块、I/O模块间的关系如图2-6所示。

图2-6 SDK会话、SenseMangager、算法模块、I/O模块间的关系图
如图2-7所示,应用程序安装SenseManager接口用来读取摄像头原始采样数据,并处理手势跟踪和面部跟踪。

图2-7 SenseManager接口
从概念上来说,应用程序可以把每个通道的摄像头数据采样和算法处理并发独立地运行。每个通道将通过一个模块标识符来识别获取到的图像采样和算法输出。
第一个配置采样的图像通道使用模块标识符Capture.CUID,第二个使用标识符Capture.CUID+1,以此类推。
算法模块标识符直接使用它们的接口标识符,例如HandModule.CUID或FaceModule.CUID。
典型的SenseManager接口编程流程包括以下步骤:
1)创建实例。使用CreateInstance函数创建SenseManager接口实例。
由于SenseManager接口是覆盖很多模块的最主要接口,SDK创建了一个函数Create-Instance来快速、方便地创建Session。可以使用CreateInstance函数来快速获得Sense-Manager接口函数。例如:
PXCMSenseManager sm=PXCMSenseManager.CreateInstance();
2)配置组件。使用EnableXXX函数组(或者算法模块中的Activate函数)来启动原始采样获取或激活不同的算法模块。例如:
sm.EnableStream(PXCMCapture.StreamType.STREAM_TYPE_COLOR,0,0);
3)控制执行过程及获取结果。这依赖于应用程序的线程模型,可以选择使用消息循环或事件回调方式来控制执行过程。无论采用哪一种方式,SenseManager都会在数据准备好时进行数据传送(已获取到的图像样本或模块输出)。
两种方式的典型流程实现代码如例2-1所示。如例2-1左边所示,应用程序使用AcquireFrame函数等待帧数据准备好,然后使用QuerySample函数(或者访问样本属性)来获取图像样本,最后使用ReleaseFrame函数重新开始处理下一帧。如例2-1右边所示,应用程序在OnNewSample函数(或者SampleArrived事件)中监听图像准备完毕的事件。
例2-1 控制数据流并获取结果

在执行过程中,应用程序可以暂停或重置某一算法模块。若对这些模块的执行结果并不关心,暂停或重置将使得应用程序更高效、节能。
4)释放实例。
一个简单完整的SenseManager例子如例2-2所示。
例2-2 配置彩色数据流
PXCMSenseManager sm=PXCMSenseManager.CreateInstance();
sm.EnableStream(PXCMCapture.StreamType.STREAM_TYPE_COLOR,0,0,0);
sm.Init();
while (sm.AcquireFrame(true).isSuccessful()) {
PXCMCapture.Sample sample=sm.QuerySample();
.... // 处理图像
sm.ReleaseFrame();
}
sm.close();