目标下一秒会往哪里走?我用 YOLO + ByteTrack 做了轨迹预测

项目地址:

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 Velocity Kalman
Total Frames 962 962
Unique Tracks 37 37
Tracks With Prediction 34 37
Average History Length 8.1 8.1
Prediction Horizon 2 s 2 s
Calibration perspective perspective
Processing Time 84.0 s 53.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

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

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

相关推荐
AI棒棒牛1 天前
YOLO26 改进:融合 LW-DETR 思想的轻量 TokenMixer,让 Neck 从局部堆叠走向局部-全局协同!嘎嘎创新!
人工智能·深度学习·yolo·目标检测
Reload.1 天前
深度学习-极验叠字点选-yolo-模型调优-高阶数学-opencv
人工智能·深度学习·opencv·yolo·计算机视觉·视觉检测
晨间晓2 天前
目标从哪个区域去了哪里?我用 YOLO + ByteTrack 做了多 ROI 区域流转分析
yolo
YOLO数据集集合2 天前
滑坡检测数据集 | 滑坡检测 地质灾害 无人机巡检 应急响应 目标检测 YOLO格式 深度学习数据集 计算机视觉10670期
深度学习·yolo·目标检测·计算机视觉·无人机·滑坡
晨间晓2 天前
目标进了这个区域多久?我用 YOLO + ByteTrack 做了 ROI 占用与停留分析
yolo
YOLO数据集集合2 天前
小麦穗检测数据集 | 小麦穗检测 植物表型 密集目标检测 农业AI9182期
人工智能·yolo·目标检测·机器学习·目标跟踪·小麦穗
FL16238631293 天前
城市道路叶子叶堆检测数据集VOC+YOLO格式351张2类别
人工智能·yolo·机器学习
AI日报派送佬3 天前
Ultralytics YOLO 模型训练技巧与最佳实践
人工智能·python·深度学习·yolo·机器学习·计算机视觉
FL16238631294 天前
外来入侵植物检测数据集VOC+YOLO格式1111张5类别
人工智能·yolo·机器学习