目标从哪个区域去了哪里?我用 YOLO + ByteTrack 做了多 ROI 区域流转分析

项目地址:

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

前面几篇里,这个项目已经从单张图片检测一路做到了:

复制代码
Single Image
→ Batch Images
→ Video
→ Tracking
→ Line Crossing
→ ROI Analysis
→ Trajectory Heatmap

做到 ROI Analysis 以后,我已经能够回答:

哪些目标进入过指定区域?

区域里最多同时有多少目标?

每个目标在里面停留了多久?

但单个 ROI 还有一个明显的限制:

它只能告诉我目标"进过这里",却不能告诉我目标"从哪里去了哪里"。

所以这一次,我继续在 YOLO + ByteTrack 的基础上加入了第八种模式:

复制代码
Multi-ROI Flow

用多个 Polygon ROI 统计目标在不同区域之间的真实流转关系。


一、从单 ROI 到多个 Zone

这一次不是只画一个区域,而是可以在视频第一帧上连续创建多个多边形 Zone。

例如:

复制代码
Zone A
Zone B
Zone C

每个区域都可以自由画成 Polygon,而不是限制为矩形。

前端支持:

复制代码
New Zone
Finish Zone
Undo Point
Delete Active Zone
Reset All Zones

所有顶点仍然使用归一化坐标:

复制代码
0.0 ~ 1.0

所以浏览器预览尺寸变化不会影响真实视频里的区域位置。


二、还是用 Bottom-center 判断目标位置

这次继续沿用前面 Line Crossing、ROI、Heatmap 中已经使用过的:

复制代码
Bottom-center Anchor

也就是目标框底边中点:

复制代码
anchor_x = (x1 + x2) / 2anchor_y = y2

相比 bbox 中心,它更接近目标真正落在地面上的位置。

对于行人来说接近脚的位置,对于车辆来说也更接近实际道路位置。

所以判断"目标到底属于哪个区域"时更自然。


三、目标到底属于 Zone A、B 还是 C?

后端仍然使用:

复制代码
cv2.pointPolygonTest()

判断一个 Track 的 anchor 是否位于 Polygon 内部。

每一个 Track 都会维护自己的区域状态,例如:

复制代码
OUTSIDE
→ Zone A
→ Zone B
→ Zone C
→ OUTSIDE

于是现在不仅能记录:

复制代码
ENTRY
EXIT

还能进一步得到:

复制代码
Zone A → Zone B
Zone B → Zone C

这种真正的区域流转事件。


四、Border Tolerance 继续防止边界抖动

多个 Zone 的边界附近同样会遇到检测框抖动问题。

例如一个人在 A、B 边界附近:

复制代码
A
B
A
B
A

如果每帧直接判断,就会生成大量假的 Transition。

所以这次仍然加入:

复制代码
Border Tolerance

真实测试参数为:

复制代码
8 px

目标进入边界缓冲区域时,不立即改变稳定 Zone。

只有真正进入另一个区域后,才确认状态变化。


五、Transition 是这次最核心的东西

假设某个 Track 的区域序列是:

复制代码
Zone A
→ Zone B
→ Zone C

那么会生成:

复制代码
A → B
B → C

两个 Transition。

如果是:

复制代码
Zone A
→ OUTSIDE
→ Zone B

也不一定立刻断掉。

这次增加了:

复制代码
Transition Gap

真实测试使用:

复制代码
5 s

如果目标离开 A 后,在 5 秒内进入 B,仍然可以认为这是:

复制代码
A → B

这样可以处理不同 Zone 之间留有空隙的情况。


六、同一区域再次进入不算 A→A

例如:

复制代码
Zone A
→ OUTSIDE
→ Zone A

这代表目标第二次访问 Zone A。

所以:

复制代码
Visits += 1

但是不会生成:

复制代码
A → A

这种 Self Transition。

Transition Matrix 的对角线始终保持为 0。


七、真实测试:37 个目标产生了 33 次区域流转

这次仍然使用之前那段道路视频:

复制代码
Resolution: 1920×1080
FPS: 29.97
Total Frames: 962
Duration: 32.10 s

参数:

复制代码
Confidence: 0.50
Frame Interval: Every Frame
Border Tolerance: 8 px
Transition Gap: 5 s
Track Trails: ON
Trail Length: 30

完整处理:

复制代码
962 / 962 Frames
100%

最终结果:

复制代码
Unique Tracks = 37
Events = 66
Transitions = 33
Elapsed ≈ 86.6 s

相比之前的单 ROI,这一次最关键的变化就是:

复制代码
Transitions > 0

说明系统已经真正统计到了不同区域之间的流动。


八、Transition Matrix:区域流转一眼看清

这次增加了一个很直观的:

复制代码
Transition Matrix

横轴表示目标流向哪个 Zone,纵轴表示从哪个 Zone 出发。

真实测试中主要流转关系为:

复制代码
B → C:16 次
C → B:11 次
A → B:5 次
C → A:1 次

加起来正好:

复制代码
16 + 11 + 5 + 1 = 33

和顶部:

复制代码
Transitions = 33

完全一致。

这比单纯看 Track ID 要直观很多。

一眼就能看到:

哪两个区域之间流动最频繁?

这次最明显的是:

复制代码
B ↔ C

九、Top Routes:最常见的区域路线

除了 Matrix,这次还单独整理了:

复制代码
Top Routes

真实结果:

复制代码
B → C
Transitions: 16
Unique Tracks: 6

C → B
Transitions: 11
Unique Tracks: 5

A → B
Transitions: 5
Unique Tracks: 3

C → A
Transitions: 1
Unique Tracks: 1

这里有两个数字不能混淆。

例如:

复制代码
B → C
Transitions = 16
Unique Tracks = 6

并不是有 16 个不同目标。

而是 6 个不同 Track 一共完成了 16 次 B→C。

同一个 Track 可以多次真实往返。


十、为什么 Average Transfer Time 基本是 0?

这次结果里一个比较明显的现象是:

复制代码
Avg Transfer Time ≈ 0.00 s

这不是程序一定有问题。

因为我这次画的三个 Zone 本身存在明显重叠。

目标可能在同一帧附近直接完成:

复制代码
Zone B → Zone C

而不是:

复制代码
B
→ OUTSIDE
→ 等待几秒
→ C

所以 Direct Transition 的 transfer time 很接近 0。

如果后续把 Zone 之间留出明显间隔,再运行一次,就更容易看到非零的:

复制代码
Transfer Time

十一、Flow Map 比表格更直观

这次我觉得最好看的功能其实是:

复制代码
Flow Map

系统会在原视频画面上:

  • 画出 Zone A / B / C
  • 标出各区域
  • 在 Zone 之间绘制方向箭头
  • 根据 Transition Count 调整箭头粗细

比如:

复制代码
B ─────────▶ C

如果 B→C 次数最多,对应箭头也会更明显。

这样区域之间的流动关系,不看数字也能快速理解。


十二、Track Journey:每个目标到底怎么走的?

除了整体流量,还可以继续追踪每一个 Track。

例如某个目标可能经历:

复制代码
A → B → C

另一个可能是:

复制代码
C → B

甚至还会出现:

复制代码
A → B → C → B → C ...

这就是:

复制代码
Track Journey

它记录的是单个目标真实访问过的 Zone 序列。

OUTSIDE 不会出现在最终 Journey 中,连续重复的同一个 Zone 也会被压缩。

例如:

复制代码
A → A → A → B → B → C

最后保存为:

复制代码
A → B → C

十三、每个 Zone 仍然有完整的 ROI 统计

Multi-ROI 并没有丢掉之前 ROI Analysis 的能力。

每个 Zone 仍然会统计:

复制代码
Unique Tracks
Entries
Exits
Visits
Current Occupancy
Max Occupancy
Total Dwell
Average Dwell
Max Dwell

所以现在不仅知道:

A→B 有多少个目标

还能够继续知道:

Zone A 一共被多少目标访问?
Zone B 最多同时有多少目标?
Zone C 里的平均停留时间是多少?

这就把:

复制代码
区域状态分析

和:

复制代码
区域流转分析

组合在了一起。


十四、第一次看到目标就在 Zone 里怎么办?

这次也继续保留了:

复制代码
first_seen_inside

逻辑。

如果 Track 第一次被检测到的时候已经在 Zone C:

复制代码
UNKNOWN → C

它会被计入:

复制代码
Unique Tracks in C

但不会凭空生成:

复制代码
OUTSIDE → C

这种不存在的 Entry。

更不会伪造一个 Transition。


十五、结果视频也会实时显示当前 Zone

最终输出视频中会同时显示:

复制代码
Bounding Box
Track ID
Polygon Zones
Current Zone
Occupancy
Transition

这样如果统计结果里出现:

复制代码
B → C

可以直接回到视频里观察目标到底是怎么完成这次区域切换的。


十六、支持 4 种数据导出

这次一共支持:

复制代码
Export Flow JSON
Export Transitions CSV
Export Journeys CSV
Export Matrix CSV

Flow JSON

保存完整分析:

复制代码
video metadata
settings
zones
summary
zone summary
transition matrix
top routes
tracks
journeys
transitions

Transitions CSV

一条 Transition 一行。

适合后续统计:

复制代码
Track
Class
From Zone
To Zone
Time
Transfer Time

Journeys CSV

一个 Track 一行:

复制代码
Track ID
Class
Journey
Visits
Transitions
Total Dwell

Matrix CSV

可以直接导入 Excel:

复制代码
from_zone,A,B,C
A,0,5,0
B,0,0,16
C,1,11,0

导出全部基于已经完成的真实结果,不会重新跑 YOLO。


十七、这次测试增加到了 314 个

新增 Multi-ROI Flow 后:

复制代码
pytest
314 passed

前端:

复制代码
196 assertions passed

新增的测试主要覆盖:

复制代码
Polygon ROI
Border Tolerance
First Seen Inside
Entry / Exit
Transition Gap
Journey
Dwell
Occupancy
Transition Matrix
Top Routes
Flow Map
Export
Stale Result Reset
YOLO Error

而且之前的:

复制代码
Single Image
Batch Images
Video
Tracking
Line Crossing
ROI
Heatmap

都没有回归。


十八、从"目标检测"走到"目标流动分析"

现在回头看整个项目,已经走了很长一段:

复制代码
YOLO Detection
↓
Video Detection
↓
ByteTrack
↓
Unique Objects
↓
Line Crossing
↓
ROI Occupancy
↓
Dwell Time
↓
Trajectory Heatmap
↓
Multi-ROI Flow

最开始只能回答:

画面里有什么?

后来可以回答:

哪些框其实是同一个目标?

再后来:

它有没有经过这里?
有没有进入这个区域?
停留了多久?

现在终于可以进一步回答:

它从哪个区域去了哪个区域?


总结

这次真实实验中:

复制代码
962 Frames
37 Unique Tracks
66 Zone Events
33 Transitions

其中:

复制代码
B → C:16
C → B:11
A → B:5
C → A:1

整个分析链路变成:

复制代码
YOLO
↓
ByteTrack
↓
Track ID
↓
Bottom-center Anchor
↓
Multiple Polygon Zones
↓
Entry / Exit
↓
Transition Gap
↓
Journey
↓
Transition Matrix
↓
Top Routes
↓
Flow Map

相比传统 YOLO 只输出 Bounding Box,现在这个项目已经开始从:

复制代码
目标检测

逐渐走向:

复制代码
视频行为与空间流动分析

项目地址:

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

下一步如果继续做,我准备在现有 Tracking + Zone Flow 的基础上尝试:

复制代码
速度估计

也就是进一步回答:

目标不仅从哪里去了哪里,它到底移动得有多快。

相关推荐
YOLO数据集集合5 小时前
滑坡检测数据集 | 滑坡检测 地质灾害 无人机巡检 应急响应 目标检测 YOLO格式 深度学习数据集 计算机视觉10670期
深度学习·yolo·目标检测·计算机视觉·无人机·滑坡
晨间晓6 小时前
目标进了这个区域多久?我用 YOLO + ByteTrack 做了 ROI 占用与停留分析
yolo
YOLO数据集集合8 小时前
小麦穗检测数据集 | 小麦穗检测 植物表型 密集目标检测 农业AI9182期
人工智能·yolo·目标检测·机器学习·目标跟踪·小麦穗
FL16238631291 天前
城市道路叶子叶堆检测数据集VOC+YOLO格式351张2类别
人工智能·yolo·机器学习
AI日报派送佬1 天前
Ultralytics YOLO 模型训练技巧与最佳实践
人工智能·python·深度学习·yolo·机器学习·计算机视觉
FL16238631292 天前
外来入侵植物检测数据集VOC+YOLO格式1111张5类别
人工智能·yolo·机器学习
菜鸟变凤凰20232 天前
基于深度学习 YOLOv8 的各种识别系统(Vue3 + Element Plus + Django 全栈项目)
深度学习·yolo·django
冷雨夜中漫步2 天前
YOLO快速入门——(2)YOLO V26安装与快速入门
图像处理·算法·yolo·计算机视觉
YOLO数据集集合2 天前
遥感滑坡图像识别数据集 | 滑坡识别 遥感影像 语义分割 灾害监测 无人机航拍 目标检测 深度学习数据集 计算机视觉9172期
人工智能·yolo·目标检测·计算机视觉·无人机·滑坡