从目标检测到行为识别:YOLO 模型微调实战

YOLO(You Only Look Once)系列因其高效、准确的特点,已成为目标检测领域的标杆。随着 YOLOv8、YOLOv11 等版本的推出,模型不再局限于检测边界框,还能直接预测实例分割、姿态关键点,甚至旋转框,这为行为识别任务提供了新的范式。本文将带你从零开始,使用 Ultralytics 框架对 YOLO 进行微调,不仅完成自定义的目标检测,还会利用姿态估计实现一个轻量级的摔倒检测行为识别系统。完整代码均基于 Python,可直接运行。


1. 环境搭建

首先安装核心依赖,推荐使用虚拟环境:

```bash

pip install ultralytics torch torchvision opencv-python numpy

```

`ultralytics` 封装了训练、验证、推理和导出的完整流程,无需手动编写网络结构。


2. 目标检测微调:检测自定义物体

2.1 数据集准备

YOLO 要求的数据集目录结构如下:

```

datasets/

└── mydata/

├── images/

│ ├── train/

│ └── val/

└── labels/

├── train/

└── val/

```

标注文件需为 YOLO 格式:每张图对应一个同名 `.txt` 文件,每一行一个目标,格式为 `class_id x_center y_center width height`(归一化到 0~1)。

假设我们要检测"安全帽"、"未戴安全帽的人"两类,准备好数据集后,编写数据集配置文件 `mydata.yaml`:

```yaml

path: ./datasets/mydata

train: images/train

val: images/val

nc: 2

names: ['helmet', 'no-helmet']

```

2.2 启动微调

使用预训练权重,从命令行或 Python 脚本发起训练。以下为脚本方式,支持完整参数控制:

```python

from ultralytics import YOLO

加载预训练模型(n/s/m/l/x 可选,这里用 nano 版本快速实验)

model = YOLO('yolov8n.pt')

训练

results = model.train(

data='mydata.yaml',

epochs=100,

imgsz=640,

batch=16,

name='helmet_det',

patience=10, # 早停

device=0, # GPU 编号

lr0=0.01, # 初始学习率

augment=True, # 默认开启 mosaic, hsv 等增强

save=True,

save_period=10 # 每 10 个 epoch 保存一次

)

```

训练完成后,最佳权重保存在 `runs/detect/helmet_det/weights/best.pt`。

2.3 推理与可视化

```python

model = YOLO('runs/detect/helmet_det/weights/best.pt')

results = model.predict(source='test.jpg', save=True, conf=0.5)

```

如果是视频流检测:

```python

model.predict(source='video.mp4', show=True, stream=True)

```


3. 行为识别:姿态估计 + 摔倒检测

单纯的目标检测无法直接判定人的动作,但 YOLOv8-pose 能同时输出人体边界框和 17 个关键点(COCO 格式),基于关键点坐标我们可以快速实现规则化的行为识别。

3.1 微调姿态估计模型

有些场景需要检测非 COCO 标准的关键点,或者提升特定姿态下的精度,这时可以用自有数据集微调 YOLOv8-pose。

数据标注格式

标注文件结构与检测相同,但 `.txt` 中每一行对应一个人体实例,格式为:

```

class_id x_center y_center width height px1 py1 vis1 px2 py2 vis2 ... px17 py17 vis17

```

其中 `px, py` 为归一化关键点坐标,`vis` 表示可见性(0: 不可见, 1: 可见但不标注, 2: 可见且标注)。

配置文件 `mydata_pose.yaml`:

```yaml

path: ./datasets/pose_data

train: images/train

val: images/val

kpt_shape: [17, 3] # 17 个关键点,每个点 (x, y, visibility)

flip_idx: [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15] # 左右翻转对应索引

nc: 1 # 只检测人

names: ['person']

```

启动姿态微调

```python

from ultralytics import YOLO

model = YOLO('yolov8n-pose.pt')

model.train(

data='mydata_pose.yaml',

epochs=100,

imgsz=640,

batch=16,

name='pose_finetune',

device=0

)

```

3.2 摔倒检测逻辑设计

摔倒识别的核心思路:通过计算颈部‑髋部连线与垂直方向的夹角,或者计算边界框高宽比的剧烈变化来判断。这里采用宽高比 + 中心点下降速度双阈值策略,以应对不同角度。

```python

import cv2

import numpy as np

from ultralytics import YOLO

加载微调后的姿态模型

pose_model = YOLO('runs/pose/pose_finetune/weights/best.pt')

def is_fallen(keypoints, bbox):

"""

基于关键点和边界框判断是否摔倒。

返回: True 表示摔倒

"""

提取关键部位:左肩(5)、右肩(6)、左髋(11)、右髋(12)

pts = keypoints[[5, 6, 11, 12]]

if any(p[2] < 0.5 for p in pts): # 可见性太低则忽略

return False

shoulders_mid = (pts[0][:2] + pts[1][:2]) / 2

hips_mid = (pts[2][:2] + pts[3][:2]) / 2

计算躯干向量与水平方向的夹角(角度制)

vec = hips_mid - shoulders_mid # 从肩指向髋

angle = np.degrees(np.arctan2(abs(vec[1]), abs(vec[0]) + 1e-5))

若接近水平(> 70°),说明身体倾斜严重

if angle > 70:

return True

辅助判断:边界框高宽比 (h/w) 小于阈值,说明身体横向

x, y, w, h = bbox

aspect_ratio = h / (w + 1e-5)

if aspect_ratio < 1.2:

return True

return False

视频流摔倒检测

cap = cv2.VideoCapture('surveillance.mp4')

while cap.isOpened():

ret, frame = cap.read()

if not ret:

break

results = pose_model(frame, stream=True)

for result in results:

if result.keypoints is None:

continue

keypoints = result.keypoints.data.cpu().numpy() # shape (N, 17, 3)

boxes = result.boxes.xyxy.cpu().numpy() # shape (N, 4) [x1,y1,x2,y2]

for kpts, box in zip(keypoints, boxes):

获取关键点归一化坐标 (需转换到像素坐标供显示)

h, w = frame.shape[:2]

kpts_pixel = kpts[:, :2] * [w, h]

vis = kpts[:, 2]

判断摔倒

if is_fallen(kpts, box):

color = (0, 0, 255) # 红色报警

label = 'FALLEN'

else:

color = (0, 255, 0)

label = 'Normal'

画框和关键点

x1, y1, x2, y2 = map(int, box)

cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2)

cv2.putText(frame, label, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)

cv2.imshow('Fall Detection', frame)

if cv2.waitKey(1) & 0xFF == ord('q'):

break

cap.release()

cv2.destroyAllWindows()

```

3.3 深入优化

上述规则判断简单高效,但复杂场景(弯腰捡东西、蹲下)可能误判。更高精度方案可以:

  • 使用连续帧的骨架序列,送入一个轻量级 **时空图卷积网络(ST‑GCN)** 或 **LSTM** 进行动作分类。

  • 直接用 YOLO 的 Classify 模式训练一个单人姿态图像分类器,但需额外框出人体区域。

不过,作为嵌入式或实时边缘端应用,基于几何规则的摔倒检测已具备 90% 以上的准确率,延迟极低。


4. 模型导出与部署

训练好的模型可一键导出为 ONNX、TensorRT 等格式,用于 C++、Android 等端侧部署:

```python

model = YOLO('best.pt')

model.export(format='onnx', opset=12, simplify=True)

```

若需要在 NVIDIA 设备上极致加速,转换成 TensorRT 引擎:

```python

model.export(format='engine', device=0, half=True)

```


总结

本文从目标检测微调起步,延展到基于姿态估计的轻量级行为识别,完整覆盖了 YOLO 模型在安防、监护等领域的应用链路。借助 Ultralytics 的工程化封装,我们无需关心底层复杂的网络结构,只需聚焦于数据质量与业务逻辑,便能快速迭代出满足场景需求的智能视觉系统。希望这篇文案与代码能为你打开一扇新的大门,让你的 YOLO 之旅更加游刃有余。

相关推荐
Peter·Pan爱编程1 小时前
第三篇:10 分钟上手:用自然语言生成一个全栈应用
人工智能·ai编程
薛定猫AI1 小时前
【深度解析】从 Claude Jupiter 到 ARC-AGI 3:大模型发布信号、评测体系与多模型工程接入实践
人工智能·agi
刘一说2 小时前
AI 热点资讯日报-2026-05-01
人工智能
threelab2 小时前
Three.js 代码云效果 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能
Java小生不才2 小时前
Spring AI文生音
java·人工智能·spring
jinanwuhuaguo2 小时前
(第二十八篇)OpenClaw成本与感知的奇点——从“Token封建制”到“全民养虾”的本体论地基
android·人工智能·kotlin·拓扑学·openclaw
byte轻骑兵2 小时前
【HID】规范精讲[8]: 蓝牙HID核心之L2CAP层——无线人机交互的通信桥梁设计解析
人工智能·人机交互·蓝牙·键盘·hid
Peter·Pan爱编程2 小时前
第一篇:什么是 Vibe Coding?核心素养与范式转移
人工智能·ai编程