YOLO 实例分割与目标跟踪实战:基于 Ultralytics 的seg_bbox可视化指南
【免费下载链接】yolov10YOLOv10: Real-Time End-to-End Object Detection [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/yo/yolov10
导读
本指南围绕 Ultralytics 官方文档「Instance Segmentation and Tracking」展开,面向希望在视频流中同时获得像素级物体轮廓与跨帧身份追踪能力的开发者。通过阅读本文,你将掌握基于 YOLO 分割模型(如yolov8n-seg.pt)调用model.predict与model.track的两种实战模式,并深入理解Annotator.seg_bbox的底层绘图原理,可直接将完整脚本复用于自己的检测与跟踪项目。
什么是实例分割
实例分割(Instance Segmentation)是计算机视觉中比目标检测更精细的一层任务:它不仅要像普通检测器那样给出物体的边界框(bounding box),还要逐像素识别并勾勒出每个独立物体的轮廓,从而提供对场景空间分布的细致理解。
与语义分割(Semantic Segmentation)不同——语义分割将整幅图像按类别划分(例如"所有汽车归为一类"),实例分割则要求唯一标记并精确勾勒每一个个体。即使同一帧画面中存在多个同类物体,每个物体也会被当作独立实例分别处理。正因如此,实例分割在目标检测、医疗影像分析、自动驾驶感知、工业质检等需要"逐个体区分"的场景中至关重要。
在 Ultralytics 工具包中,基于 YOLO 分割模型进行实例分割跟踪,官方提供了两种可视化模式:
- 按类别对象的实例分割(Instance Segmentation with Class Objects):为每个类别分配唯一颜色,实现清晰的视觉区分。同一类别的所有实例共享同一种颜色。
- 按对象轨迹的实例分割(Instance Segmentation with Object Tracks):为每一条**跟踪轨迹(Track ID)**分配独特颜色,方便在多帧视频中一眼识别同一个物体的运动轨迹。
两者的核心区别在于着色依据:前者按"是什么"着色,后者按"是谁"着色。以下两份完整脚本将分别演示这两种模式。
环境准备
两份脚本均依赖opencv-python(代码中导入为cv2)与当前仓库的ultralytics包。安装依赖后即可运行:
pip install ultralytics opencv-python脚本中的model = YOLO("yolov8n-seg.pt")会在首次运行时自动下载分割权重。若希望用更大模型提升精度,可将权重替换为yolov8s-seg.pt、yolov8m-seg.pt等;本仓库的分割模型配置可在 ultralytics/cfg/models/v8/yolov8-seg.yaml 中查看(当前仓库的 YOLOv10 系列配置位于 ultralytics/cfg/models/v10,而官方文档中的分割演示默认采用 v8 分割系列权重)。
模式一:纯实例分割(按类别着色)
第一个脚本的目标是:读取视频的每一帧 → 用分割模型推理 → 在原始帧上画出每个实例的轮廓与其类别标签 → 写回输出视频并实时显示。当检测到掩码(masks)不为空时,脚本取出类别编号clss与掩码轮廓点集masks.xy,逐实例调用annotator.seg_bbox完成绘制。
import cv2 from ultralytics import YOLO from ultralytics.utils.plotting import Annotator, colors model = YOLO("yolov8n-seg.pt") # segmentation model names = model.model.names cap = cv2.VideoCapture("path/to/video/file.mp4") w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) out = cv2.VideoWriter('instance-segmentation.avi', cv2.VideoWriter_fourcc(*'MJPG'), fps, (w, h)) while True: ret, im0 = cap.read() if not ret: print("Video frame is empty or video processing has been successfully completed.") break results = model.predict(im0) annotator = Annotator(im0, line_width=2) if results[0].masks is not None: clss = results[0].boxes.cls.cpu().tolist() masks = results[0].masks.xy for mask, cls in zip(masks, clss): annotator.seg_bbox(mask=mask, mask_color=colors(int(cls), True), det_label=names[int(cls)]) out.write(im0) cv2.imshow("instance-segmentation", im0) if cv2.waitKey(1) & 0xFF == ord('q'): break out.release() cap.release() cv2.destroyAllWindows()要点拆解:
results[0].masks是 Ultralytics 的Masks对象(定义于 ultralytics/engine/results.py),其xy属性返回像素坐标下的分段轮廓点列表,xyn则返回归一化坐标;这正是seg_bbox所需的mask输入。colors(int(cls), True)通过类别编号取色。Colors类内置 20 色调色板(源码见 ultralytics/utils/plotting.py),取色时以编号 % 20循环复用,bgr=True参数返回 OpenCV 绘图所需的 BGR 通道顺序。Annotator负责在帧上叠加绘制;line_width=2控制轮廓线宽。- 输出视频使用
MJPG编码写入instance-segmentation.avi,按q键可提前退出循环。
模式二:实例分割 + 目标跟踪(按轨迹着色)
第二个脚本在模式一的基础上引入了目标跟踪。核心差异在于:
- 推理调用由
model.predict(im0)改为model.track(im0, persist=True),为每个实例分配跨帧稳定的Track ID; - 颜色依据从"类别编号"改为"跟踪编号"(
track_ids); - 标签从类别名改为
Track ID字符串; - 额外维护
track_history字典(defaultdict(lambda: [])),可用于后续扩展轨迹点记录。
import cv2 from ultralytics import YOLO from ultralytics.utils.plotting import Annotator, colors from collections import defaultdict track_history = defaultdict(lambda: []) model = YOLO("yolov8n-seg.pt") # segmentation model cap = cv2.VideoCapture("path/to/video/file.mp4") w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS)) out = cv2.VideoWriter('instance-segmentation-object-tracking.avi', cv2.VideoWriter_fourcc(*'MJPG'), fps, (w, h)) while True: ret, im0 = cap.read() if not ret: print("Video frame is empty or video processing has been successfully completed.") break annotator = Annotator(im0, line_width=2) results = model.track(im0, persist=True) if results[0].boxes.id is not None and results[0].masks is not None: masks = results[0].masks.xy track_ids = results[0].boxes.id.int().cpu().tolist() for mask, track_id in zip(masks, track_ids): annotator.seg_bbox(mask=mask, mask_color=colors(track_id, True), track_label=str(track_id)) out.write(im0) cv2.imshow("instance-segmentation-object-tracking", im0) if cv2.waitKey(1) & 0xFF == ord('q'): break out.release() cap.release() cv2.destroyAllWindows()要点拆解:
model.track是模型入口方法(定义于 ultralytics/engine/model.py),内部会调用跟踪器完成 ID 关联;persist=True表示跟踪状态在连续帧间保持,是跨帧 ID 一致性的关键。results[0].boxes.id保存每个实例的跟踪 ID;当boxes.id is not None且masks is not None时,说明当前帧同时具备跟踪与分割结果,才进行绘制。colors(track_id, True)让不同轨迹拥有不同颜色,直观呈现每个物体的运动轨迹。- 由于按 Track ID 着色,同一物体在不同帧中颜色保持稳定,这正是"按对象轨迹的实例分割"模式的核心价值。
seg_bbox参数详解
两个脚本的核心绘图都落在Annotator.seg_bbox方法上,其完整签名位于 ultralytics/utils/plotting.py:
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
mask | array | None | 分割掩码坐标(实例轮廓点集) |
mask_color | tuple | (255, 0, 255) | 每个分割框的掩码颜色(默认品红色) |
det_label | str | None | 分割对象的标签(用于检测模式) |
track_label | str | None | 分割并跟踪对象的标签(用于跟踪模式) |
底层绘图原理
结合源码(ultralytics/utils/plotting.py),seg_bbox的实际绘制流程可概括为三步:
- 绘制轮廓:通过
cv2.polylines(self.im, [np.int32([mask])], isClosed=True, color=mask_color, thickness=2)将掩码轮廓点连接成闭合多边形。这是"实例分割可视化"的本质动作——用多边形逼近物体边界。 - 生成标签文本:标签优先级为
track_label优先,f"Track ID: {track_label}";若未提供track_label则回退到det_label。随后用cv2.getTextSize测量文本尺寸以确定背景框大小。 - 绘制标签背景与文字:在轮廓起始点附近绘制与
mask_color同色的填充矩形作为标签背景,再以白色文本cv2.putText叠加标签内容,保证文字可读性。
从源码可以看到Annotator类同时支持 PIL 与 OpenCV 两种绘图后端(self.pil标志,见 ultralytics/utils/plotting.py),当图像为 PIL 格式或包含非 ASCII 文本时自动切换为 PIL 渲染;seg_bbox本身则固定使用 OpenCV 的cv2绘图函数。
两种模式的选型建议
- **按类别着色(模式一)**适合需要快速区分"画面中有哪些类别的物体"的场景,例如交通监控中的行人/车辆/自行车统计,颜色语义与类别一一对应,画面整体简洁。
- **按轨迹着色(模式二)**适合需要"持续追踪个体行为"的场景,例如顾客动线分析、动物行为研究、体育动作拆解等,同一轨迹的恒定颜色让观察者能轻松跟随单个对象。
- 两者共享同一套
Masks.xy轮廓数据与seg_bbox绘制管线,切换成本极低:只需将循环体内的着色依据与标签字段替换即可。
注意事项与常见问题
masks为空:当模型未检测到任何可分割实例时,results[0].masks为None。脚本中通过if results[0].masks is not None保护绘制逻辑,避免空指针错误。boxes.id为空:跟踪模式下若跟踪器未成功关联(例如视频起始帧),boxes.id可能为None,需与masks一起联合判断后再访问。- 视频读取结束:
cap.read()返回ret=False时表示读取完毕,脚本会打印提示并跳出循环,随后统一release()释放视频写入器与摄像头资源。 - 颜色循环:
Colors调色板共 20 色(见 ultralytics/utils/plotting.py),当类别数或 Track ID 数超过 20 时颜色会循环复用,但不同实例仍可通过标签文本区分。
延伸阅读
- 想系统了解分割任务的预测、训练与验证用法,可阅读 docs/en/tasks/segment.md;
- 深入理解
model.track的参数(如persist、conf、iou、tracker等)与跟踪器配置,可参考 docs/en/modes/track.md 以及仓库中的跟踪器配置 ultralytics/cfg/trackers(botsort.yaml与bytetrack.yaml); - 实例分割与跟踪的完整 API 说明见 docs/en/reference/engine/results.md 与 docs/en/reference/utils/plotting.md;
- 更多基于视觉解决方案的实用案例(目标计数、速度估计、热力图等)可在 docs/en/guides/index.md 中浏览。
【免费下载链接】yolov10YOLOv10: Real-Time End-to-End Object Detection [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/yo/yolov10
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考