5.3 对象跟踪


5.3 对象跟踪

本节摘要:跟踪给运动目标一个持续的身份,避免每帧重跑昂贵的检测。本节从 MeanShift 的直方图迭代讲到 CSRT 的判别式相关滤波,给出 OpenCV Tracker 家族的选型对比,重点讲"检测初始化、跟踪保持、丢失重检测"的工程闭环与目标外观变化、遮挡两大挑战的应对。这是本教程的收官一节。

学习目标

阅读完本节,你应当能够:

  1. 解释"每帧检测"与"检测加跟踪"两种模式的算力账
  2. 用 MeanShift/CamShift 完成基于颜色直方图的跟踪
  3. 用 CSRT 等现代跟踪器完成初始化、逐帧更新、失败判定
  4. 按精度与速度在跟踪器家族中选型
  5. 组合"背景减除找目标 + 跟踪器跟随 + 丢失重检"的完整方案

先跑起来:三个跟踪器

MeanShift——经典的颜色跟踪:

import cv2 hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv, (0, 60, 60), (10, 255, 255)) # 红色区间示例 hist = cv2.calcHist([hsv], [0], mask, [180], [0, 180]) cv2.normalizeHist = None hist = cv2.normalize(hist, hist).flatten() back_proj = cv2.calcBackProject([hsv], [0], hist, [0, 180], 1) ret, box = cv2.meanShift(back_proj, (x, y, w, h), (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1))

初始化时算目标区域的色调直方图,此后每帧做反向投影(把图变成"哪里像目标的颜色热度图"),MeanShift 在热度图上迭代地把框推向密度中心。CamShift 是它的升级版,框大小随目标远近自适应。

现代跟踪器——CSRT 一族的标准三步:

tracker = cv2.legacy.TrackerCSRT_create() # 或 TrackerCSRT_create 视版本 tracker.init(frame, (x, y, w, h)) # 第一帧框定目标 ok, box = tracker.update(frame) # 每帧更新 if ok: p1 = (int(box[0]), int(box[1])) p2 = (int(box[0]+box[2]), int(box[1]+box[3])) cv2.rectangle(frame, p1, p2, (0, 255, 0), 2)

初始化一次、每帧 update、按返回值判定成败——所有 Tracker 系列跟踪器共用这个接口。新版本 OpenCV 把部分跟踪器挪到 legacy 或 contrib 包,名字对不上时查一下当前版本的模块归属(第 1 章第 2 节的版本意识在此再次应验)。

第三种"跟踪器"其实不是跟踪器:第 5 章第 2 节的光流法,goodFeaturesToTrack 在目标框内取点、LK 光流逐帧跟点、点的位移平均即目标运动——结构最透明,也最容易定制。

核心原理:从迭代搜索到判别式滤波

2.1 为什么不每帧检测

检测器每帧全图扫描,CPU 上百毫秒到秒级;跟踪器只围着上一帧的目标位置小范围找,毫秒级。算力账之外还有质量账:检测输出的是"这一帧的框",两个目标交错后身份会互换;跟踪器维护的是"同一个目标的连续历史",遮挡后恢复时身份仍在。所以工程标配是 detect then track:低频检测(每 N 帧或跟踪失败时)、高频跟踪(每帧)。检测贵而准、跟踪便宜而脆,二者互补。

2.2 MeanShift:在热度图上爬坡

反向投影把每帧变成"目标颜色热度图"后,MeanShift 做的事纯粹:从当前框位置出发,反复计算框内加权重心、把框中心移向重心,直到收敛。局部爬山注定两个短板:目标快速移动超出搜索范围就跟丢;框尺寸不更新,目标靠近变大就"框不住"(CamShift 修正了这一点)。适合背景颜色与目标差异明显的慢速目标,比如白墙前的彩色球。

2.3 相关滤波家族:KCF 与 CSRT

KCF(核相关滤波)的思路:把跟踪表述为"在上一帧学一个能把目标从背景里分离出来的滤波器",学习时不仅用目标正样本,还利用循环移位生成大量负样本(周围的背景),判别力因此强于纯模板匹配。定位快、实现巧,是速度与精度的经典平衡点。

CSRT(通道与空间可靠性判别相关滤波)是 OpenCV 里精度档的代表:多通道特征加空间可靠性图,边界处理更讲究,能更好地应对形变与部分遮挡,代价是速度明显慢于 KCF。家族选型速查:

跟踪器 精度 速度 特点 适用
Boosting/MIL 老算法,教学意义为主 不推荐新项目
KCF 循环移位负样本,性价比高 实时、目标变化不剧烈
CSRT 多通道加空间可靠性 精度优先、可容忍低帧率
MedianFlow 正反向一致性评估,遮挡即报失败 遮挡频繁需要快速知道失败的场景
光流 LK 透明可控、易于定制 与其他方案组合使用

2.4 两大难题:外观变化与遮挡

目标外观会变(转身、变形、光照改变),跟踪器学到的模型必须更新——但更新太快,遮挡物会被学进模型("模型污染");更新太慢,外观变化就跟不上。跟踪失败判定(update 返回 ok 为假)因此是工程上的关键设计:与其让框飘走误导下游,不如尽早宣告失败、触发重检测。MedianFlow 的正反向校验(帧 A 跟到 B、再从 B 反跟回 A,位置对不上即失败)就是为这个设计服务的。

工程实践要点

3.1 完整方案:背景减除加跟踪加重检

把本章三节串成收官方案:MOG2 背景减除产出运动候选框(第 5 章第 2 节),新目标出现时初始化跟踪器;每帧 tracker.update 跟随(本节);每 N 帧或 update 失败时用背景减除的候选框校正或重新初始化。这套组合在 CPU 上轻松实时,且身份连续、抗短时遮挡。若目标类别重要(要区分人和车),把背景减除换成第 4 章的轻量检测器即可,骨架不变。

3.2 多目标的身份管理

多人场景要开多个跟踪器并维护"目标表"(编号、跟踪器、丢失计数)。新检测框与现有跟踪框做 IoU 匹配(第 4 章第 2 节的 IoU 在此复用):匹配上则校正对应跟踪器,匹配不上的检测框开新目标,连续多帧未匹配的跟踪目标移除。丢失计数的容错(比如连续 15 帧丢失才移除)能避免目标被短暂遮挡就"注销重入"造成计数虚高。

3.3 初始化框的质量决定一切

跟踪器 init 时给的框不干净(框进了背景或只框住半张脸),学到的模型天生带病,后面怎么调参都救不回来。宁可人工确认第一帧的框,也不要拿一个勉强的自动检测结果直接 init。这个原则与第 4 章第 3 节"数据质量决定上限"一脉相承。

⚠️ 常见坑:跟踪失败后不重置直接继续 update,框在画面里"鬼漂"——看起来还在跟踪,实际输出的是垃圾。永远检查返回值,失败即走重检分支。另一个坑是拿视频里某帧的跟踪器去跟另一段视频,模型与目标不匹配,自然失败;跟踪器是有状态的,生命周期跟着目标走。

💡 关键直觉:跟踪器的强弱不在"跟得多紧"而在"失败时说不说真话"。快速报告失败的跟踪器(MedianFlow 类)配一个可靠的重检测,实战效果常好于"死不承认失败"的高精度跟踪器。工程上,失败判定与恢复路径的设计比跟踪器本身的选型更值得花时间。

3.4 动手实验清单

  1. 用鼠标回调在视频第一帧框选目标(第 2 章第 2 节的交互取点思路),跑 CSRT 跟踪整段,统计失败帧。
  2. 同一段视频分别跑 KCF 与 CSRT,对比跟踪框的稳定度与每帧耗时。
  3. 让目标被遮挡两秒,观察各跟踪器的表现与恢复行为,体会失败判定的价值。
  4. 实现"MOG2 加跟踪加重检"的组合方案,跑一段有多人走动的视频,给每个目标画编号框。

3.5 收官方案的全景架构

检测跟踪闭环系统架构

检测跟踪闭环系统架构

3.6 常见疑问与解答

跟踪器的模型更新会不会把遮挡物学进去?

会,这正是"模型污染"。缓解手段:CSRT 类跟踪器有自适应更新率参数可调低;更稳的结构性解法是把"跟踪"与"确认"分开——跟踪器只管给框,每 N 帧用检测器确认框内还是不是目标(详见本节完整方案),确认失败立即停用该跟踪器。牺牲一点算力,换来对污染的免疫。

多目标跟踪要开多少个跟踪器?

每个目标一个实例,几十个目标就是几十个跟踪器,CPU 上 CSRT 会吃紧。规模上去之后的务实选择:目标多时换 KCF(快),或干脆退回"纯背景减除加 IoU 关联"的轻量方案——第 5 章第 2 节的候选框配上传帧间的位置关联,在很多场景已经是够用的"穷人版跟踪"。

跟踪和光流能不能混着用?

能且推荐。跟踪器框住目标,框内跑稀疏光流,既能得到目标的运动向量(方向速度),又能在跟踪器短暂失效时用光流的位移"惯性外推"目标位置,兜住一两帧的空窗。第 5 章第 2 节的光流与本节的跟踪器在实战里经常这样互相搭桥。

3.7 实战配方:多目标跟踪的最小可用系统

把本章内容总装成一个多目标跟踪系统(入口大堂的人流持续跟踪),给出最小可用版本的设计。

状态表设计。每个目标一条记录:编号、跟踪器实例、丢失计数、上次框位置。新目标入场由背景减除的候选框触发(IoU 与现有目标都不匹配的框,本节 3.2 的匹配规则),初始化跟踪器、分配递增编号。

每帧主循环。所有跟踪器 update;成功的更新记录与画框(框上标编号),失败的递增丢失计数;丢失计数达到十五的目标注销(容错窗口,本节 3.3)。每三十帧跑一次背景减除做关联校正,防止长时间漂移。

参数初值。跟踪器选 KCF(人多时快);IoU 匹配阈值 0.3(低于它算同一目标);冷却与注销窗口按行人通过画面的时间尺度估(步行横穿约十秒,十五帧的窗口约合半秒遮挡容忍,可放宽到三十帧)。

验收实验。回放一段录像,统计三个数:编号跳变次数(身份不连续)、平均跟踪时长、每帧跟踪目标数与肉眼数的偏差。三个数都在可接受范围,系统可用;编号跳变集中在交叉走动处,就把 IoU 匹配加上运动预测(上一帧速度外推)再验。

这套系统没有用到任何本教程之外的概念——背景减除(第 5 章第 2 节)、跟踪器三步(本节)、IoU(第 4 章第 2 节)、形态学净化(第 2 章第 3 节)——五章的内容在一个一百来行的程序里各就各位。把它跑起来,你就完成了这门课从"认识函数"到"搭建系统"的跨越。

本节要点回顾

  • 检测加跟踪是标配:检测贵而准、跟踪便宜而脆,低频检测加高频跟踪是算力与质量的双优解。
  • MeanShift 在热度图爬坡:反向投影加迭代寻心,简单但怕快速移动与尺度变化,CamShift 补尺度。
  • KCF 与 CSRT 是主力:KCF 快而均衡,CSRT 精而慢,按帧率预算与精度需求二选。
  • 失败判定比跟踪精度更重要:update 返回值必须检查,失败走重检测,别让框鬼漂。
  • 初始化框质量是天花板:带病的 init 框无药可救,第一帧值得人工确认。
  • 收官组合:背景减除找目标、跟踪器保身份、周期重检防漂移——五章知识的总装。

五章至此收官。从第 1 章的数组世界观,到第 2 章六件套、第 3 章特征匹配、第 4 章检测识别,再到本章的视频闭环,你已经具备搭建完整视觉应用的全部基础。下一步建议找一个真实小项目(如工位人数统计)从头到尾做完,教程里每个"动手实验清单"都是它的零件。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U