在计算机视觉领域,人体姿态检测与轨迹跟踪是很多应用场景的核心技术,例如运动分析、行为识别、智能监控等。本文将介绍如何在 PiscCode 平台上,利用 YOLO-Pose 模型进行姿态估计,并实现多人关键点轨迹跟踪。
一、什么是 PiscCode
PiscCode 是一个面向开发者的计算机视觉编程平台,它提供了灵活的 Python API 封装、多模型管理和高性能视频处理能力。在 PiscCode 平台上,开发者可以方便地:
-
调用不同的目标检测、实例分割、姿态估计模型;
-
对视频帧进行实时处理、绘制和结果渲染;
-
快速构建可复用的视觉算法模块。
在本文示例中,我们使用 PiscCode 的视频处理能力,将 YOLO-Pose 模型封装为一个 FrameObject
类,实现多人体关键点检测与轨迹绘制。
二、YOLO-Pose 模型简介
YOLO-Pose 是 YOLO 系列模型的扩展版本,它在传统目标检测的基础上增加了 人体关键点预测 功能。特点如下:
-
高效、快速,可用于实时视频分析;
-
支持多人姿态检测;
-
与 YOLOv8/v11 系列兼容,可通过
track()
方法获取稳定的跟踪 ID。
通过 YOLO-Pose,我们可以得到每个人体的关键点位置,并结合跟踪 ID,实现轨迹记录和绘制。
三、FrameObject 封装实现
下面是基于 YOLO-Pose 的 FrameObject
类,集成了关键点检测、轨迹缓存和绘制功能:
import cv2
import random
from ultralytics import YOLO
class FrameObject:
def __init__(
self,
model_path="E:/影迹-p/Support Files/data/model/yolo11x-pose.pt",
device="cuda",
line_thickness=2,
point_size=6,
max_frames=30,
draw_bbox=False,
):
self.model = YOLO(model_path)
self.model.to(device)
self.device = device
self.tf = line_thickness
self.point_size = point_size
self.max_frames = max_frames
self.draw_bbox = draw_bbox
self.trajectories = {}
@staticmethod
def _rand_color():
return [random.randint(0, 255) for _ in range(3)]
def _ensure_tracks_init(self, track_id: int, kpt_count: int):
if track_id not in self.trajectories:
self.trajectories[track_id] = [[] for _ in range(kpt_count)]
self.trajectories[track_id].append(self._rand_color())
else:
cur_len = len(self.trajectories[track_id]) - 1
if cur_len != kpt_count:
color = self.trajectories[track_id][-1]
self.trajectories[track_id] = [[] for _ in range(kpt_count)]
self.trajectories[track_id].append(color)
def do(self, frame):
if frame is None:
return None
im = frame.copy()
results = self.model.track(im, verbose=False, persist=True, device=self.device)
if not results or len(results) == 0:
return im
res = results[0]
ids = res.boxes.id.cpu().numpy() if res.boxes.id is not None else []
boxes = res.boxes.xyxy.cpu().numpy() if (self.draw_bbox and res.boxes is not None) else []
kpts = getattr(res, "keypoints", None)
if kpts is None or kpts.data is None or len(kpts.data) == 0:
return im
kpts_data = kpts.data
for i, keypoints in enumerate(kpts_data):
track_id = int(ids[i]) if i < len(ids) else i
kpt_count = len(keypoints)
self._ensure_tracks_init(track_id, kpt_count)
color = self.trajectories[track_id][-1]
for j, point_tensor in enumerate(keypoints):
x, y = map(int, point_tensor[:2].detach().cpu().numpy())
if x == 0 and y == 0:
continue
self.trajectories[track_id][j].append((x, y))
if len(self.trajectories[track_id][j]) > self.max_frames:
self.trajectories[track_id][j].pop(0)
cv2.circle(im, (x, y), self.point_size, color, -1)
for track_id, traj_list in self.trajectories.items():
color = traj_list[-1]
for traj in traj_list[:-1]:
if len(traj) > 1:
for i in range(1, len(traj)):
cv2.line(im, traj[i - 1], traj[i], color, thickness=max(1, self.point_size // 3))
if self.draw_bbox and len(boxes) > 0:
for i, box in enumerate(boxes):
x1, y1, x2, y2 = map(int, box[:4])
track_id = int(ids[i]) if i < len(ids) else i
color = self.trajectories.get(track_id, [[None], self._rand_color()])[-1]
cv2.rectangle(im, (x1, y1), (x2, y2), color, 2)
return im
四、应用示例 Demo
五、总结
本文展示了如何在 PiscCode 平台上:
-
使用 YOLO-Pose 模型进行多人关键点检测;
-
结合 track() 方法,实现稳定 ID 的轨迹跟踪;
-
将关键点轨迹可视化到原始视频中。
通过封装成 FrameObject
类,开发者可以轻松集成到视频分析、运动识别、智能监控等应用中,并方便扩展更多功能,例如姿态动作识别或异常行为检测。