4 获取流数据¶
流的类型¶
Astra SDK 支持各种类型的流类型。底层的流类型由摄像头生成并且通过SDK传输给应用程序。上层的流类型则是通过SDK的插件从底层的流类型高效地运算得到的。一般来说,我们应该首选可用的上层流。
底层¶
流类型 | 描述 |
---|---|
ColorStream | 来自摄像头的RGB像素数据。每个 ColorFrame 中的数组 data 包含 0-255之间的数值,这些数值代表每个像素每个色彩通道的值 |
DepthStream | 来自摄像头的深度数据。每个 DepthFrame 中的数组 data 包含了摄像头 视场范围内每个像素的值,单位是毫米 |
上层¶
流类型 | 描述 |
---|---|
PointStream | 从深度数据计算的世界坐标点云(XYZ)。 每个 PointFrame 的 data 数组元素是 astra:Vector3f 类型的, 通过访问其 x , y 和 z 值可以方便地访问每个像素 |
HandStream | 从深度数据计算出来的手点。 对每一个 HandFrame , 在任一给定时间点从 HandFrame::handpoint_count 函数可以得到点的数量, 通过 HandFrame::handpoints 函数还可以得到 astra::HandFrame::HandPointList |
获取数据¶
Astra SDK 提供了两个方法来获取流数据。根据您应用的特定需求和其复杂度, 两个方法中总有一个更为适用的方法。
轮询¶
通过轮询的方法来获取流数据是一种比较直接的方法。在Hello World教程里我们采用的就是这种方法。使用这种方法很简单,你只需要调用 StreamReader
的 get_latest_frame
函数,然后用模板函数 get<T>
来返回得到特定类型的帧。在这里 “T
” 必须是一个有效的帧类型。函数 get_latest_frame
是阻塞式的,在下一帧数据到来之前,程序将被挂起。如果你想限制阻塞时间,可以给 get_latest_frame
函数传递一个 timeout
变量。
astra::initialize();
astra::StreamSet streamSet;
astra::StreamReader reader = streamSet.create_reader();
reader.stream<astra::DepthStream>().start();
astra::Frame frame = reader.get_latest_frame();
const auto depthFrame = frame.get<astra::DepthFrame>();
astra::terminate();
- 通过轮询的方法读取一帧深度帧
侦听¶
通过侦听的方法来获取数据需要事先做一些设置,这种方法允许开发者将帧的处理委托给一个或多个不同的类。 Astra SDK 提供了一个叫 FrameListener
的抽象类,该类只实现了一个叫 FrameListener::on_frame_ready
的函数。当数据帧到来的时候, 该类会立即调用 FrameListener::on_frame_ready
并且将帧的引用作为参数传入。
class DepthFrameListener : public astra::FrameListener
{
virtual void on_frame_ready(astra::StreamReader& reader,
astra::Frame& frame) override
{
const astra::DepthFrame depthFrame = frame.get<astra::DepthFrame>();
if (depthFrame.is_valid())
{
// do all the things
}
}
};
- 从
frame_listener
继承的listener类示例
定义了 listener 类,您还必须在您的应用程序里将这个listener实例化并且用 StreamReader::add_listener
函数将其添加到 StreamReader
之后才能使用它。
astra::initialize();
astra::StreamSet streamSet;
astra::StreamReader reader = streamSet.create_reader();
reader.stream<astra::DepthStream>().start();
DepthFrameListener listener;
reader.add_listener(listener);
while(true)
{
astra_update();
}
- listener使用示例。实际使用的时候,对
astra_update
的循环调用必须持续到程序要关闭的时候,或者别的特定事件发生的时候。
添加了listener之后,我们需要通过循环调用 astra_update
函数来触发事件。通过这种调用,SDK可以检查是否有新的一帧数据到来,如果是,比如在本例子里,将调用 DepthFrameListener::on_frame_ready
函数,并且传入当前帧的引用。
如果想要了解更实际的listener使用,可以查看 Simple Depth Reader Tutorial.