该部分介绍了如何通过 API 接口使用融合相机。
打开相机
获取融合数据
时间对齐
空间对齐
获取异步数据
保存数据
具体的代码例程可以在sdk安装目录下的Sample中找到
打开相机
在 DvsenseDriver 中,所有相机使用 dvsense::DvsCameraManager 类进行统一管理。
查找相机
std::vector<dvsense::CameraDescription> cameraDescs = cameraManager.
getCameraDescs();
相机管理器类
定义 DvsCameraManager.hpp:35
std::vector< CameraDescription > getCameraDescs()
获取相机描述符向量
dvsense::CameraDescription 中包含相机的制造商、产品型号、序列号等信息。
可以通过产品型号
来区分事件相机或融合相机。
打开融合相机
dvsense.DvsCameraManager.openFusionCamera接口可以使用序列号打开指定的融合相机
FusionCameraDevice openFusionCamera(Serial serial)
DVSENSE_API std::shared_ptr< FusionCamera > FusionCameraDevice
定义 DvsCameraManager.hpp:29
dvsense::FusionCameraDevice 是对 dvsense.FusionCamera的易用性封装 typedef std::shared_ptr<FusionCamera> FusionCameraDevice
开始和停止取流
打开相机后,相机默认是不进行取流的,需要手动开启。
注意!! 在取流开始之前,请参照下面的 获取并处理事件 注册 异步处理事件 的回调函数。
fusion_camera->start();
fusion_camera->stop();
start跟stop 函数可以指定流模式dvsense::STREAM_TYPE来控制自己想获取的数据,当前流模式有 DVS_STREAM, APS_STREAM, FUSION_STREAM(Alpha版本仅支持获取融合流)
获取并处理融合数据
由于RGB图像跟事件流为两个不同的数据流,需要对这两个数据进行时间对齐与空间对齐。
我们提供融合示例代码,请参考 DvsenseDriver\include\DvsenseDriver\DataProcess\DvsApsFusionProccessor.hpp 及 Samples\DvsenseSyncViewerSample\DVSyncViewer.cpp 文件
使用方式如下:
dvsense::Calibrator calibrator
if(camera->readCalibrationParam(cali_param))
{
dvsense::paramToJsonFile(cali_param, "./calibration.json");
calibrator_.loadCalibrationParam(cali_param);
}
fusion_processor.
addFusionDataCallback([&sync_displayer](dvsense::ApsFrame &frame,
const dvsense::Event2D *begin,
const dvsense::Event2D *end)
{
dvsense::ApsFrame aps_to_dvs_frame = calibrator.mapApsToDvs(frame);
sync_displayer.processApsFrame(aps_to_dvs_frame);
sync_displayer.fusionDvsToAps(begin, end); });
camera->addApsFrameCallback([&fusion_processor](const dvsense::ApsFrame &frame)
camera->addEventsStreamHandleCallback([&fusion_processor](const dvsense::Event2D *begin, const dvsense::Event2D *end)
camera->addTriggerInCallback([&fusion_processor](const dvsense::EventTriggerIn &trigger_in)
{ fusion_processor.addTriggerInData(trigger_in); });
定义 DvsApsFusionProccessor.hpp:17
void addFusionDataCallback(DsFusionDataCallback cb)
添加融合数据回调函数
定义 DvsApsFusionProccessor.hpp:53
void addApsData(const ApsFrame &frame)
添加aps数据用于融合
定义 DvsApsFusionProccessor.hpp:79
void addDvsData(const Event2D *begin, const Event2D *end)
添加dvs数据用于融合
定义 DvsApsFusionProccessor.hpp:70
时间对齐
我们提供了dvsense::DvsApsFusionProccessor 类来做时间对齐,在使用时仅需要将事件流、视频流、以及trigger同步信号这三个回调函数注册为dvsense::DvsApsFusionProccessor数据接口中,dvsense::DvsApsFusionProccessor类会自动进行时间同步同步好之后通过addFusionDataCallback回调的方式来供客户接收数据。
如果您有需求也可以DIY自己的dvsense::DvsApsFusionProccessor类来进行时间同步以及回调函数的处理。
具体的时间对齐代码可以参考 DvsApsFusionProccessor
空间对齐
由于融合相机内部结构及光路影响,RGB图像与事件数据(DVS)在空间上会存在偏差。因此,我们将在生产过程中对此偏差进行校准,并将校准结果保存于设备内部。
**标定补偿映射**: 我们用Calibrator
类用来进行标定补偿映射,并提供APS和DVS双向映射的接口,完成DVS和RGB相机的空间对齐。
- 加载标定参数
camera = cameraManager.openFusionCamer(open_camera_serial);
dvsense::Calibrator calibrator_;
camera->readCalibrationParam(cali_param)
calibrator_.loadCalibrationParam(cali_param);
APS映射到DVS
dvsense::ApsFrame aps_to_dvs_frame = calibrator_.mapApsToDvs(aps_frame);
- DVS映射到APS
cv::Mat dvs_to_aps_frame = calibrator_.mapDvsToAps(dvs_frame);
可参考我们提供的样例程序:Samples/DvsenseSyncViewerSample/DVSyncViewer.cpp
。
获取异步数据
融合相机当前仅支持异步获取数据。
异步处理DVS事件
相机提供了 dvsense::FusionCamera::addEventsStreamHandleCallback 接口,这个接口可以实时访问事件流。每当一小包事件完成传输和解码后,注册进入的回调函数就会被调用。
以下是一个使用示例,该示例中,对一张空白图片 img
中发生了事件的位置赋予颜色,以进行后续的可视化:
camera->addEventsStreamHandleCallback([&img](const dvsense::Event2D* begin, const dvsense::Event2D* end) {
for (auto it = begin; it != end; ++it) {
img.at<cv::Vec3b>(it->y, it->x) = (it->polarity) ? color_on : color_off;
}
});
警告:在使用回调函数接口时,必须尽可能减少回调函数的执行时间,否则会导致数据累积并导致程序崩溃。
您可以使用 dvsense::FusionCamera::addEventsStreamHandleCallback 函数添加多个回调函数,当事件流可用时,这些回调函数将按照注册顺序依次执行。您也可以记录回调函数的ID号,使用 dvsense::FusionCamera::addEventsStreamHandleCallback 的返回值,然后通过 dvsense::FusionCamera::removeEventsStreamHandleCallback 函数删除不再需要的回调函数。
auto cb_id = camera->addEventsStreamHandleCallback([](const dvsense::Event2D* begin, const dvsense::Event2D* end) {
});
camera->removeEventsStreamHandleCallback(cb_id);
异步处理RGB图像
相机提供了dvsense::FusionCamera::addApsFrameCallback 接口,这个接口可以实时访问事件流。每当一帧RGB图像完成传输和解码后,注册的回调函数就会被调用。
以下是一个使用示例,该示例中,对一张空白图片 aps_image_
进行赋值,以进行后续的可视化:
aps_image_ = cv::Mat(aps_height_, aps_width_, CV_8UC3);
camera->addFrameCallback([&aps_image_](dvsense::ApsFrame &aps_frame) {
std::memcpy(aps_image_.data, aps_frame.data(), aps_frame.getDataSize());
});
警告:在使用回调函数接口时,必须尽可能减少回调函数的执行时间,否则会导致数据累积并导致程序崩溃。
您可以使用 dvsense::FusionCamera::addApsFrameCallback 函数添加多个回调函数,当事件流可用时,这些回调函数将按照注册顺序依次执行。您也可以记录回调函数的ID号,使用 dvsense::FusionCamera::addApsFrameCallback 的返回值,然后通过 dvsense::FusionCamera::removeApsFrameCallback 函数删除不再需要的回调函数。
auto cb_id = camera->addApsFrameCallback([](dvsense::ApsFrame &) {
});
camera->removeApsFrameCallback(cb_id);
保存数据
在相机开始取流之后,可以使用 dvsense::FusionCamera::startRecording 和 dvsense::FusionCamera::stopRecording 将融合相机的事件流保存为 raw 文件,视频流保存为mp4文件,以便后续回放和处理。
camera->startRecording(out_file_path, filename);
camera->stopRecording();
下一节