前言:CVPR2018事件表征方法HATS
代码:【here】
HATS: Histograms of Averaged Time Surfaces for Robust Event-based Object Classification
引言
目前,物体分类任务中用事件的方法比不过基于帧的方法,原因归咎于两点
第一,用于事件的表征方法和网络架构有限
第二,缺乏大规模的数据集
因此本文针对这两点,提出了一种新的表征方法和并提出了一个大规模真实数据的分类数据集
方法
(我个人觉得单看文章不容易看懂具体怎么实现的,因此结合网上的一版代码来理解)
时间表面
之前某篇文章提出一种时间表面的表征方法,具体如下
每个事件点由一个半径为ρ的局部的空间运算子作用
即对于单个事件点,找到它附近的一些事件邻点,以如下的函数作用,这些事件邻点就一起构成了一个对这个事件点的time surface
如图所示,框框里的点则是构成属于这个事件点ei的timesuface, 每个坐标里选一个距离当前事件点最近的相同极性的点,
这种方法,每个事件点的时间表面的表示仅仅由这个点周围的一些点表示,很容易受到噪点的影响
局部内存的时间表面
因此,对于之前的事件表面的改进,作者提出了一种局部内存的时间表面表征方法,考虑的是一段时间内的事件累积,来消除噪点的影响
具体表示为
即在一段时间的的delta时间窗口内的所有事件点都被选中,然后按照指数函数的对时间戳的作用,将这些点都累加到这个时间表面内
(对比第一种,它只在每个空间位置上选最近的一个点)
这样可以得到每个点的一个局部半径R范围内的timesurface
代码为
def compute_local_memory_time_surface(event_i, filtered_memory, R, tau):
"""
The function takes the a filtered memory containing only
events in the neighborhood of the event and belonging to the
temporal window that needs to be considered and outputs a time
surface.
"""
# initialize blank time surface
time_surface = np.zeros(shape=(2*R+1, 2*R+1), dtype=np.float32)
# get the timestamp of the triggering event
t_i = event_i['ts']
# for every event in the local memory relevant to the event
# (relevean both in spatial and temporal terms), do:
for event_j in filtered_memory:
# compute the time delta
delta_t = t_i - event_j['ts']
# compute contribution to time surface
event_value = math.exp(-delta_t/tau)
# compute coordinates in the shifted representation
shifted_y = event_j['y'] - (event_i['y'] - R)
shifted_x = event_j['x'] - (event_i['x'] - R)
# sum it to the time surface
time_surface[shifted_y, shifted_x] += event_value
当然,这里并不是每个点找一个它方圆-R,R范围内的邻点,而是将空间内的所有事件点分成不同的固定的cell,一个cell内的所有事件点进行累积生成时间表面
平均时间表面直方图
得到每个点的一个空间局部的时间表面的表示,最后所有的点汇集到一起,则有N个时间表面的表示,并且不同极性分开表示
对于每个Cell内的所有相同极性的事件点的时间表面,通过下式聚合起来,即求和取平均
代码
self.histograms = np.zeros(shape=(self.n_cells, self.n_polarities, 2*self.R+1, 2*self.R+1), dtype=np.float32)
self.event_counter = np.zeros(shape=(self.n_cells, self.n_polarities), dtype=np.uint32)
for i in event_list:
#省略前面的步骤,得到当前event的time_surface
# Add the time surface to the cell histograms
self.histograms[cell, polarity_index, :, :] += time_surface
# Increase the event counter for the cell
self.event_counter[cell, polarity_index] += 1
self.histograms = normalise(self.histograms, self.event_counter)
def normalise(histograms, event_counter):
result = np.zeros_like(histograms)
# normalise
for i in range(histograms.shape[0]):
for p in range(histograms.shape[1]):
result[i,p] = histograms[i,p]/(event_counter[i,p]+0.1)
return result
这样,最终可以得到(N,2,L,L),其中N是分成的cell数,(L,L)是一个timesurface的大小,乘上一个系数可得到
因此,将它展开,可以得到最后的特征,用一个SVM即可实现分类
实验
一些分类结果
运行时间的测试
总结
HATS表征比较经典,由于选择最近邻域的点受到噪声的影响比较大,因此选择一段时间内的事件点取平均,形成时间表面