☰
目标下一秒会往哪里走?我用 YOLO + ByteTrack 做了轨迹预测
2026/10/14 5:20:50 网站建设 项目流程

项目地址:
yolo-object-detection-lab:基于 FastAPI 与 Ultralytics YOLO 的图像目标检测实验项目 - AtomGit

前面几篇里,这个项目已经陆续加入了目标检测、目标跟踪、过线统计、ROI 区域分析、轨迹热力图、多 ROI 流转分析、速度估计,以及四点透视标定。

做到这里以后,其实已经能够回答很多问题:

目标是谁?
目标在哪里?
目标走过哪里?
目标进入了哪个区域?
目标速度大概有多快?

但还有一个更有意思的问题:

它接下来会往哪里走?

所以这一次,我继续在现有 YOLO + ByteTrack 的基础上加入了:

Trajectory Prediction

也就是基于目标的历史运动轨迹,对未来 1~3 秒的位置进行预测。

这次实现了两种方法:

Constant Velocity
和
Kalman Prediction

并且继续支持前面已经做好的 Perspective 4-Point 透视标定。


一、为什么要做轨迹预测?

传统目标检测只能告诉我:

这一帧目标在哪里。

加入 ByteTrack 后,可以进一步知道:

连续多帧中的这个目标是不是同一个目标。

于是可以得到:

Track ID
历史位置
运动方向
运动速度
完整轨迹

再往前一步,就可以根据过去一段时间的运动状态,推测它未来可能出现的位置。

整个思路变成:

YOLO
↓
ByteTrack
↓
历史轨迹
↓
运动状态估计
↓
未来轨迹预测

这也是这次 Trajectory Prediction 的核心。


二、轨迹数据从哪里来?

这次依然没有重新设计一套目标位置,而是继续沿用项目里一直使用的:

Bottom-center Anchor

也就是目标检测框底边中心点。

计算方式:

anchor_x = (x1 + x2) / 2
anchor_y = y2

为什么不用 Bounding Box 中心?

因为对于道路视频来说,Bottom-center 更接近目标与地面的实际接触位置。

例如:

行人更接近脚的位置
车辆更接近车轮和道路接触的位置

所以它更适合:

Line Crossing
ROI
Heatmap
Speed Estimation
Trajectory Prediction

整个项目的空间分析逻辑也能保持统一。


三、每个 Track 都保存一段历史轨迹

对每一个 ByteTrack 的 Track ID,我会保存最近 N 个轨迹点。

这次测试设置:

History Length:10

也就是说,每个目标最多保留最近 10 个有效位置。

每个历史点至少包含:

时间戳
x 坐标
y 坐标

于是一个目标的历史轨迹可以理解为:

P1 → P2 → P3 → P4 → ... → P10

有了这些历史点以后,就可以估算:

运动方向
速度变化
轨迹稳定程度

然后进一步预测未来位置。


四、第一种方法:Constant Velocity

第一种方法是最简单、也最容易解释的:

Constant Velocity

也就是匀速模型。

核心假设是:

目标接下来短时间内,会继续保持最近的运动方向和速度。

程序会根据最近的历史轨迹估计:

vx = Δx / Δt
vy = Δy / Δt

然后预测未来某个时刻的位置:

future_x = current_x + vx × t
future_y = current_y + vy × t

这次不是只预测一个终点,而是生成一整条未来轨迹。

比如:

Prediction Horizon:2 s
Prediction Steps:10

意味着:

在未来 2 秒内,生成 10 个预测位置点。

于是就能在视频中画出一条:

未来预测轨迹线


五、为什么不能只预测一个点?

如果只预测:

“2 秒后会在哪里”

其实不太直观。

因为我更想知道的是:

它未来的运动趋势是什么?

所以这次预测的是一系列点。

例如:

当前点
↓
0.2 s
↓
0.4 s
↓
0.6 s
↓
...
↓
2.0 s

这样 Result Video 里看到的就不是一个孤立圆点,而是一条完整的未来轨迹。

图中的历史轨迹和预测轨迹采用不同样式显示,避免把真实轨迹和未来预测混在一起。


六、Constant Velocity 真实测试结果

这次仍然使用之前一直测试的同一段道路视频。

视频信息:

Resolution:1920×1080
FPS:29.97
Total Frames:962
Duration:约 32.10 s

预测参数:

Prediction Method:Constant Velocity
Prediction Horizon:2 s
Prediction Steps:10
History Length:10
Confidence Threshold:0.50
Frame Interval:Every Frame

同时开启:

Perspective 4-Point

标定区域继续使用:

Width:6 m
Height:12 m

最终完整处理:

962 / 962 Frames
100%

结果:

Unique Tracks:37
Tracks With Prediction:34
Average History Length:8.1
Elapsed:84.0 s
Calibration Mode:perspective


七、为什么 37 个 Track 只有 34 个生成预测?

这个结果是正常的。

Constant Velocity 需要至少有足够的历史位置和有效时间差,才能计算速度。

如果某个 Track:

出现时间太短
历史点不足
有效 Δt 不足
轨迹不连续

就不会强行生成预测。

所以这次:

37 Unique Tracks

其中:

34 Tracks With Prediction

没有预测的 3 个目标,并不是程序出错,而是轨迹历史不足以支持可靠的匀速预测。


八、第二种方法:Kalman Prediction

第二种方法就是:

Kalman Filter

这次使用的是一个简单的二维匀速状态模型。

状态可以写成:

[x, y, vx, vy]

其中:

x、y 表示当前位置
vx、vy 表示当前速度

每一帧主要做两件事:

Predict
↓
Update

Predict 负责根据上一时刻的运动状态,预测当前位置。

Update 则利用当前实际检测到的位置,对预测进行修正。

这样相比直接计算平均速度,Kalman 能不断融合:

历史运动状态
当前观测位置

从而维持一个连续的状态估计。


九、Kalman 并没有直接使用 ByteTrack 内部状态

这里有一个设计细节。

虽然 ByteTrack 本身内部也包含运动模型,但这次没有直接去读取或修改 ByteTrack 的内部 Kalman 状态。

而是单独维护:

Trajectory Prediction State

这样可以避免影响原本的目标跟踪逻辑。

整个结构变成:

YOLO
↓
ByteTrack
↓
Track ID
↓
独立 Prediction State
↓
Kalman Predict / Update
↓
Future Trajectory

这样 Tracking 和 Prediction 是解耦的。


十、Kalman 真实测试结果

为了和 Constant Velocity 对比,我保持了基本相同的参数,只把:

Prediction Method

切换成:

Kalman

其余仍然是:

Prediction Horizon:2 s
Prediction Steps:10
History Length:10
Confidence:0.50
Every Frame
Perspective Calibration:ON

这次最终结果:

962 / 962 Frames
100%

Unique Tracks:37
Tracks With Prediction:37
Average History Length:8.1
Elapsed:53.8 s
Calibration Mode:perspective

也就是说:

37 个 Track 全部生成了预测轨迹。


十一、Constant Velocity 和 Kalman 实测对比

这次两组真实实验结果如下:

指标Constant VelocityKalman
Total Frames962962
Unique Tracks3737
Tracks With Prediction3437
Average History Length8.18.1
Prediction Horizon2 s2 s
Calibrationperspectiveperspective
Processing Time84.0 s53.8 s

从这次实验结果来看:

Constant Velocity:34 / 37 生成预测
Kalman:37 / 37 生成预测

Kalman 在这次数据中覆盖率更高。

不过这里要注意:

不能因为这一轮 Kalman 用时更短,就直接得出 Kalman 一定比 Constant Velocity 更快。

整体处理时间还受到:

YOLO 推理
视频编码
磁盘 IO
系统负载
当前运行环境

等因素影响。

所以更准确的表述是:

在本次相同视频实验中,Kalman 版本的总处理时间更短。


十二、分类统计结果

Kalman 这一轮中:

bicycle:3 个 Unique Track,3 个生成预测
car:18 个 Unique Track,18 个生成预测
person:16 个 Unique Track,16 个生成预测

也就是说三类目标全部完成预测。

这说明预测逻辑并不是只针对车辆,而是对 ByteTrack 产生的不同类别 Track 都可以工作。


十三、Perspective Calibration 也参与了预测

这一版还有一个比较有意思的地方:

Trajectory Prediction 可以继续使用前面 Speed Estimation 已经实现的:

Perspective 4-Point Calibration

也就是:

原图目标位置
↓
Homography
↓
Bird's-eye Plane
↓
进行轨迹预测
↓
Inverse Homography
↓
映射回原视频

这样预测可以先在更适合道路运动分析的鸟瞰平面中完成,再映射回原始图像显示。

这次真实实验里,Prediction Summary 已经明确显示:

Calibration Mode:perspective

说明这不是单纯前端画了一个标定框,而是真正进入了预测流程。


十四、为什么还要映射回原图?

最终用户看的还是原始视频。

所以即使预测是在 Bird's-eye Plane 中完成的,最后还是需要把预测位置映射回原图。

这也是为什么 Track Prediction Table 里的:

Predicted End X
Predicted End Y

仍然可以理解为最终原图中的预测终点坐标。

这样就可以直接在视频上画:

未来轨迹
预测终点
Track ID

而不是只能看一张单独的鸟瞰图。


十五、Result Video 里到底显示了什么?

最终 Result Video 中同时包含:

Bounding Box
Track ID
Class
真实历史轨迹
未来预测轨迹
预测终点
Prediction Method
Prediction Horizon

这时候就可以非常直观地看到:

目标之前怎么走
↓
现在在哪里
↓
未来两秒可能往哪里走

这比单纯在表格里看坐标直观很多。


十六、Prediction Horizon 是什么意思?

这次设置的是:

Prediction Horizon:2 s

也就是说:

程序预测的是目标未来 2 秒内的运动趋势。

同时:

Prediction Steps:10

所以会把未来 2 秒分成多个预测点。

需要注意:

Prediction Horizon 越长,并不代表结果越好。

因为随着预测时间变长,不确定性也会越来越大。

例如车辆可能:

刹车
转弯
变道

行人也可能:

突然停下
改变方向

所以这种简单运动模型更适合:

短时间轨迹预测

而不是预测十几秒之后的位置。


十七、Reliability 不是概率

这次还加入了:

Reliability

结果分为:

Low
Medium
High

但这里一定要说明:

Reliability 不是神经网络输出的概率。

它只是一个启发式指标。

主要参考:

历史轨迹点数量
最近运动速度稳定程度
轨迹波动情况

例如:

历史点很少
速度变化很大

就更容易得到 Low。

反过来:

历史点较多
运动比较稳定

则可能得到 Medium 或 High。

所以:

High Reliability

并不代表:

“预测有 90% 概率正确”。

它只是帮助判断:

当前这条 Track 的历史状态是否适合进行短时运动预测。


十八、Current Speed 为什么还是 px/s?

在 Track Prediction Table 中,还可以看到:

Current Speed

目前这里仍然主要作为图像空间中的辅助运动量使用。

所以不要直接把它解释成:

真实 m/s
真实 km/h

Trajectory Prediction 的重点是:

未来位置和运动趋势

而不是重新做一遍 Speed Estimation。

如果需要真实世界速度,还是应该使用之前已经完成的:

Perspective Speed Estimation

两者关注的目标不同。


十九、轨迹预测并不等于“知道未来”

这点也需要说清楚。

当前实现基于的是:

Constant Velocity
Kalman Constant Velocity Model

它们本质上都是根据:

过去的运动状态

去推测:

短时间未来运动趋势

它并不知道:

红绿灯
道路规则
驾驶员意图
行人意图
障碍物
车辆转向灯

所以如果一个目标突然:

转弯
停车
变道

模型之前的预测轨迹就可能失效。

因此这里更准确的说法是:

短时运动轨迹预测

而不是:

精准预测目标未来行为。


二十、这次测试增加到 511 个

Trajectory Prediction 完成以后:

511 pytest passed

相比之前的:

428

新增了:

83 个后端测试。

前端:

308 assertions passed

相比之前:

288

新增了:

20 个前端断言。

覆盖内容包括:

Bottom-center
History Buffer
Constant Velocity
Stationary Target
Horizontal Motion
Vertical Motion
Prediction Horizon
Prediction Steps
Kalman Initialization
Kalman Predict / Update
Insufficient History
Zero dt
Reliability
Prediction Clipping
Zero Tracks
Export
Stale Reset
Detector Failure

而前面已经完成的其他模式也全部保留。


二十一、开发分支

这次开发使用:

Branch:

feat/trajectory-prediction

最终 commit:

2a5a45366af58139eeb5360577bd323377538e12

主要新增:

app/trajectory_prediction.py
static/prediction.js
tests/test_trajectory.py

同时对:

app/main.py
app/schemas.py
static/index.html
static/app.js
tests/test_frontend_logic.js

进行了对应集成。


二十二、项目已经从“检测”走到了“预测”

一路做到现在,这个项目的能力已经从最开始的:

Single Image Detection

逐步发展成:

Single Image
↓
Batch Images
↓
Video Detection
↓
ByteTrack Tracking
↓
Line Crossing
↓
ROI Analysis
↓
Trajectory Heatmap
↓
Multi-ROI Flow
↓
Speed Estimation
↓
Perspective Calibration
↓
Trajectory Prediction

整个过程已经不只是:

“YOLO 能不能识别一个目标”

而是在逐渐回答:

它是谁?
它在哪里?
它从哪里来?
它去了哪里?
它在区域里待了多久?
它移动得有多快?
它接下来可能往哪里走?


总结

这次真实实验中,我分别跑了 Constant Velocity 和 Kalman 两种预测方式。

Constant Velocity:

962 Frames
37 Unique Tracks
34 Tracks With Prediction
Average History Length:8.1
Prediction Horizon:2 s
Elapsed:84.0 s

Kalman:

962 Frames
37 Unique Tracks
37 Tracks With Prediction
Average History Length:8.1
Prediction Horizon:2 s
Elapsed:53.8 s

同时启用了:

Perspective 4-Point Calibration

最终完整流程已经变成:

YOLO
↓
ByteTrack
↓
Bottom-center Anchor
↓
History Buffer
↓
Perspective Homography
↓
Constant Velocity / Kalman
↓
Future Trajectory
↓
Inverse Homography
↓
Result Video

相比之前只能回答:

目标现在在哪里?

这一次已经可以进一步尝试回答:

目标未来两秒大概会往哪里走?

当然,这仍然属于基于运动状态的短时预测,并不能理解真正的驾驶意图或行人意图。

但对于一个从 YOLO 检测项目逐步扩展出来的视频行为分析系统来说,这一步已经让它从:

Detection

开始走向:

Motion Understanding

项目地址:
yolo-object-detection-lab:基于 FastAPI 与 Ultralytics YOLO 的图像目标检测实验项目 - AtomGit

下一步如果继续做,我准备在现有 Trajectory Prediction 上加入:

Collision Risk / TTC Analysis

也就是利用两个目标的相对运动状态,进一步判断:

它们会不会发生潜在冲突,以及大概还有多久接近危险区域。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询