7

系列篇|编写一个翻转事件极性的package

 3 years ago
source link: https://mp.weixin.qq.com/s/yuV8vW2TxgxkgidvdCtGDA
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

点击上方“3D视觉工坊”,选择“星标”

干货第一时间送达

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款Image 圈里有高质量教程资料、可答疑解惑、助你高效解决问题

Image

上次推送中我们已经能够利用现成的角点检测代码,完成事件相机数据的角点检测,并调用了rpg_dvs_ros这个package进行了显示。这次我们自己完成一个package,实现一个简单的功能:将事件相机的极性进行翻转。这个操作可能没有什么实际意义,但方便我们去熟悉基本Event的数据格式,以及与dvs_renderer、数据集.bag的对接,同时熟悉package编写方法。

一、基础知识

在编写ros中的package代码之前,我们需要首先对Event的数据形式,dvs_renderer的启动等有一定了解。

1、消息类型

在rpg_dvs_ros包的dvs_msgs/msg中定义了两个数据类型,分别是:Event.msg与EventArray.msg。根据名称我们可以推测出来,Event就是单独一个事件,而EventArray是为了避免单个事件发送频率过高,而组成的一组事件流。具体的数据格式如下:

640?wx_fmt=png

图:左:单独event的数据,具有坐标,时间戳和极性;右:EventArray数据,具有图像宽度和高度,以及event数据数组

在catkin_ws执行编译后,会在 ./devel/include/dvs_msgs/ 下生成Event.h与EventArray.h文件,编写代码时需要include这些头文件;另外在CMakeLists中也要加入相关头文件。

2、dvs_renderer相关

dvs_renderer是dvs渲染器/显示器,用于显示dvs相关数据。从dvs_renderer/src/renderer.cpp中可以看出,dvs_renderer主要订阅了的消息有:events, image等,并发布名为”dvs_rendering”的数据。分析可知,dvs_renderer经过处理image和events后,将数据整理生成了”dvs_rendering”,可以由rqt_image_view进行显示。

3、dvs_mono.launch文件

查看launch/dvs_mono.launch文件,可以看出这个文件主要启动了三个node。

node 1:dvs_ros_driver 这个应该是安装实体相机后需要用到的参数,暂时不用考虑

node 2:名为dsv_renderer的node,来自pkg名为dvs_renderer的dvs_renderer节点:主要操作:1. 将/dvs/events数据remap到了events中。即运行rosbag时会产生的topic为”/dvs/evets”,而dvs_renderer节点中订阅的topic名为”events”,所以进行remap,让dvs_renderer能够找到topic

node 3:名为”image_view”的node,是pkg名为”rqt_image_view”中的”rqt_image_view”节点,将dvs_renderer中publish出的”dvs_rendering”话题进行remap到”rqt_image_view”所订阅的”image”话题。

640?wx_fmt=jpeg

图:dvs_mono.launch启动的三个node:dvs驱动、dvs_renderer和显示窗口

4、小结:

若想可视化,需要dvs_renderer订阅rosbag发布的话题,并进行rendering后由rqt_image_view订阅dvs_renderer发布的dvs_rendering。所以我们如果对bag中数据进行加工,需要从rosbag这里接过数据,进行处理,之后发布让dvs_renderer接收,并继续后面的显示即可。最终完成的节点关系如下图:

640?wx_fmt=jpeg

节点订阅关系:/dvs_ivt_render_node是我们设计的用于显示翻转后数据的节点,其接受了由/Inverter_node节点翻转后的数据,以及视频原图,最终输出翻转的事件/events_ivt用于后续显示。而下面一路,是用作对比的,原有的dvs_renderer获取图像进行显示/events_ori的方法。可以看出,上面数据相对于下面这路多了一个/inverter_node节点进行翻转

二、手写一个事件极性翻转节点

所谓翻转极性,就是将事件相机产生数据的极性进行改变:0变1,1变0。整个过程涉及到了:创建一个package,ros话题的发布与订阅,事件相机数据的处理。

1、创建一个package

使用catkin_create_pkg指令在catkin_ws/src文件夹下创建一个名为test的package。

       $ catkin_create_pkg test

此时内部生成了两个最基础的文件,CMakeLists.txt与package.xml,分别是编译时需要用到的文件,与package相关的配置文件。暂时不需要理解。

2、创建一个Inverter类

在test的package下,创建include/inverter.h文件,编写内容如下:

640?wx_fmt=jpeg

a) 首先包含ros最基本的头文件,之后需包含对事件相机数据处理时需要的”EventArray.h”。

b) 一个Inverter需要创建一个ros节点,节点分别订阅和发布消息,同时需要一个回调函数,用于处理订阅收到的事件相机数据

3、编写Inverter的具体内容

640?wx_fmt=jpeg

在构造函数中,将ros节点发布一个名为”/invert_events”的话题,订阅名为”/dvs/events”的话题。在回调函数中,对事件相机数据进行处理:

a) 创建invertMsg数据,并将相关信息进行赋值;

b) 对于EventArray中的每一个事件,分别对极性进行取反并存储到invertMsg的events数组中;

c) 发布极性取反后的数据。

4、main函数

main函数就相对简单许多,只需要创建一个Inverter,便在Inveter的默认构造函数中自动完成了消息订阅发布与回调数据处理

640?wx_fmt=jpeg

5、修改CMakeLists.txt

为了编译文件,需要修改CMakeLists.txt,如下:

640?wx_fmt=jpeg

a) 首先是cmake的基本操作,project名称需要与package一致,为test

b) 之后寻找catkin_simle包,这个包对后面查找头文件、链接库的链接等非常重要

c) 启动catkin_simple()和catkin_package()宏定义

d) 将inverter.h的头文件加进去,同时包含catkin_INCLUDE_DIRS中包含的头文件

e) 使用cs_add_executable()生成inverter可执行程序(节点)

6、修改package.xml文件

包含catkin_simple这个buildtool和dvs_msgs这个数据类型即可,

640?wx_fmt=jpeg

7、编译

回到catkin_ws目录下,执行catkin build指令进行编译。完成后我们就可以启动这些节点了。

8、编写launch文件

launch文件可以一次性启动多个节点,同时修改相关参数。在test目录中创建launch/inverter.launch文件。

640?wx_fmt=jpeg

文件共创建了5个节点,分别是:interter节点,两个dvs_renderer节点和两个可视化rqt_image_view节点。

a) inverter节点:没有过多的解释,启动一个”test”的package下的”inverter”节点,命名为”inverter_node”

b) dvs_renderer节点1:启动一个节点,将其订阅的events数据remap为rosbag运行时发布的数据”/dvs/events”;同时将image数据remap为rosbag运行时发布的”/dvs/image_raw”数据;将发布的”dvs_rendering”数据更名为”/events_ori”,便于区分极性反转前后的rendering后的名称

c) dvs_renderer节点2:这次订阅的是由interter节点发布的”/invert_events”数据。由于inverter节点在代码中发布的topic名就是这个,所以不需要在inverter节点中重新remap;同时将rendering后的话题修改为”/event_ivt”

d) 启动两个rqt_image_view。之后手动选择”/event_ori”和”/event_int”进行显示。

9、运行

a) 运行roscore

b) 运行rosbag数据:rosbag play <path-to-your-dataset>/xxx.bag

c) 运行roslaunch: roslaunch test inverter.launch

10、运行结果

在两个启动的窗口中,分别选择”/event_oir”与”/event_ivt”,可以看出事件极性完全反了过来。

640?wx_fmt=jpeg

三、源码下载

本文中的inverter示例已经上传至github:https://github.com/LarryDong/dvs_inverter,希望可以帮助大家理解这些基础内容。作者尽最大努力将示例代码进行了精简,力争做到简介且便于理解,希望喜欢的朋友给个star。

本文作者目前从事于事件相机SLAM问题的研究,欢迎大家交流。交流请移步相关研究博客:https://blog.csdn.net/tfb760/category_9511063.html,或公众号后台回复「事件相机作者」,即可获得联系方式。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK