跳到正文

追踪原理 ​

RodentFlow 使用经典的计算机视觉追踪方法:先学会空场地的样子,在每一帧中找出和它不同的区域,挑出最像动物的那一块,再把它的中心作为动物的位置。没有神经网络,也不需要训练。每一步都可以用一句话说清楚,本页就逐步说明。

追踪流程

以旷场验证视频第 412 帧为例。(a) 缩小到分析分辨率的视频帧。(b) 背景:均匀分布在整段视频中的 21 帧的逐像素中位数,小鼠已经“消失”。(c) 场地内的绝对差。(d) 清理后高于自适应阈值(本帧为 39 个灰度级)的像素,以及按对比度加权的质心。(e) 整段实验每秒 10 个样本的轨迹,单位为场地厘米,含中央区。

为什么用经典追踪方法? ​

对于在对比明显的地面上俯拍的单只动物,背景减除定位身体中心的精度,足以满足区域时间、进入次数、距离和僵直的需要。在验证视频上,位置误差的中位数为 0.15–0.5 cm(见验证)。它还有几项在手机上和实验室里很重要的特点:

  • 无需训练,无需标注。 新装置的第一段视频就能用。
  • 结果确定。 同一段视频、同样的设置,结果永远相同。
  • 快且轻量。 在 iPhone 的 CPU 上以 192 像素分辨率运行,不需要上传。
  • 失败原因看得见。 出问题时,原因在预览里一目了然,比如阴影、反光或对比度不足。

它不能提供身体部位,如鼻尖、尾根、爪子。具体局限列在本页末尾。

源代码

本页内容都实现在 NativeMouseTracker.swift 中,整段视频的读取在 FullVideoAnalyzer.swift 中。

1. 以 10 Hz 读取视频 ​

视频从头到尾解码,每隔 0.1 s 取该时刻或之后的第一帧,并保留它的原始时间戳。因此,视频帧率或丢帧都不会扭曲时间。

每一帧转为灰度,并缩放到长边 192 像素。视频亮度(16–235)被展开到完整的 0–255 范围,使帧和背景处在同一尺度上。一帧 1080p 画面会变成 192 × 108 像素,对小鼠身体来说足够,而且处理很快。

2. 背景:时间上的中位数 ​

为了不必专门拍一段空场地,App 从整段视频中均匀取 21 帧,对每个像素计算这 21 个灰度值的中位数。

在任何一个像素上,动物只出现在 21 帧中的少数几帧里。中位数会忽略这些少数值,返回地面的灰度。于是动物从背景中“消失”,就像上图 (b) 那样。

静止动物修补 ​

如果动物在超过一半的取样帧里都待在同一处,中位数就会失效,例如坐在闭合臂里、在角落僵直、在平台上等待。静止的动物会被算进背景。之后动物离开,那里露出的空地面与背景不同,看起来像第二只动物:一个静止的“幽灵”,追踪器可能会去跟踪它。

幽灵修补

十字迷宫验证视频。左:直接取中位数时,背景里包含了在东臂静止的小鼠。中:修补后东臂是空的。右:稍后的一帧,追踪到的是真正的小鼠。如果不修补,空出来的位置(虚线圈)也会成为候选。

追踪器根据真实动物不会产生的一种模式来识别幽灵。在 21 张背景帧中:

  1. 某个前景区域在至少两帧中出现在同一位置;
  2. 每次都伴随着别处一个明暗相反的区域。真实动物比背景暗时,幽灵就比背景亮,反之亦然;
  3. 在这些帧里,该区域的背景值与周围地面明显不同,而当前帧本身与地面一致。

三条都满足时,用那几帧中该位置为空地面的像素重建这部分背景。普通视频不会出现这种模式,背景保持不变。在十段验证视频中,只有十字迷宫视频触发了修补,面积占场地的 5.2 %。

如果动物从头到尾都不动,这种方法和任何其他基于背景的方法都无法把它和背景分开。

3. 差值与自适应阈值 ​

对每一帧,App 只在校准的场地内计算当前帧与背景的绝对差(图 c)。取绝对值意味着浅色地面上的深色动物和深色地面上的浅色动物都能找到。

差值超过阈值的像素算作前景,阈值每帧自适应:

阈值 = 场地内差值的均值 + 1.75 × 标准差,限制在 14 到 48 个灰度级之间。

动物只占场地面积的 1 % 左右,所以均值和标准差主要反映地面的噪声,包括压缩、传感器噪声和轻微的光照变化。阈值因此正好落在每段视频、每种光照的噪声之上。上下限保证在画面特别干净或特别嘈杂时阈值仍然合理。

4. 清理 ​

两次轻度的 3 × 3 多数滤波让二值图更平滑。第一次:一个像素的 3 × 3 邻域(9 个像素)中至少有 3 个是前景,它就成为前景;第二次:至少 2 个。这样可以去掉孤立的噪点、填补小洞,而不会腐蚀身体。

5. 从候选中选出动物 ​

收集相连(8 邻接)的前景区域,去掉小于场地面积 0.07 % 或大于 14 % 的区域,对剩下的每个候选按五项特征打分:

权重特征倾向于
0.28运动连续性离上一位置近的候选(在画面对角线的 16 % 范围内衰减)
0.27大小面积接近场地的 1.2 %(对数正态形状,范围很宽)
0.20对比度与背景的平均差值大
0.17大小连续性面积与上一帧相近
0.08填充度形状紧凑,填满外接矩形

得分最高的候选就是动物。如果没有剩下任何候选,比如动物藏在有盖的箱子里或离开了画面,这个样本标记为未检测到。它的位置停在最后已知的点,只用于绘图。未检测到的样本不计入区域时间和距离(见指标)。

6. 追踪点:按对比度加权的质心 ​

位置是所选区域的质心,每个像素按它与背景的差值加权。只被动物部分覆盖的像素(身体边缘、细尾巴)权重低于完全被身体覆盖的像素。

这一点很重要。在分析分辨率下,尾巴在二值图里时隐时现,不加权的质心会被向后拉约 1 cm,还会抖动。加权之后,验证视频上的位置误差中位数从约 1 cm 降到 0.15–0.5 cm。

7. 轻度平滑 ​

最终位置 = 90 % 新质心 + 10 % 上一位置。这能去掉单像素抖动;在 10 Hz 下,它带来的延迟约 0.01 s,可以忽略。

8. 从像素到厘米 ​

校准把画面像素换算成场地厘米:

  • 矩形:用 4 点单应性变换,把四个角的手柄映射到所填宽高的矩形上。它能校正透视,所以相机不完全在正上方时,地面上的距离仍然正确。
  • 圆形:用圆心和半径手柄,把圆缩放到所填直径。这假设相机在正上方。
  • 迷宫(十字、Y、T):每条臂由校准的中线定义。一个位置被分配到最近的臂上,表示为沿该臂的距离加上横向偏移,每条臂有自己的像素/厘米比例。见迷宫几何。

校准时放置的标记(物体、平台、目标洞)用完全相同的映射换算,所以动物和标记处在同一个坐标系中。

9. 运动指数 ​

与是否找到动物无关,每个样本还会记录场地内灰度变化至少 20 级的像素比例,比较的是 0.1 s 之前的上一个样本。这就是测量僵直所用的信号(详情)。它不依赖检测:一只融入背景、一动不动的动物,运动指数依然接近 0。

预览、完整分析与检查点 ​

10 秒预览和完整分析运行的是同一套代码,所以预览好,完整分析通常也好。完整分析期间,大约每 300 个样本(即 30 s 视频)保存一次检查点,包括位置和追踪器的短期记忆(上一位置和大小)。继续分析时不会出现跳变。

局限 ​

  • 只有身体中心。 依赖鼻尖的指标(嗅探物体、探洞)用身体中心周围的区域近似。不测量头部朝向、直立和理毛。
  • 只能一只动物。 同一场地里的两只动物会合并成一个区域,或被互相混淆。
  • 相机和光照要固定。 背景每段视频只学习一次。分析过程中被碰动的相机、突然打开的灯、被翻动的垫料都会改变背景,产生假候选。
  • 分辨率。 场地在画面里太小时,每厘米像素少,路径长度会偏高(见验证中十字迷宫的例子)。

需要身体部位、多只动物或行为分类时,请使用深度学习姿态估计工具(见延伸阅读)。它们输出的每只动物的数据可以导入 RodentFlow 做统计和作图。