基于深度学习的运动动作识别系统

目录

  1. 项目概述
  2. 数据集说明
  3. 算法设计
  4. 模型架构
  5. 训练过程
  6. 模型评估
  7. 数据库设计
  8. 系统架构
  9. 界面功能详解
  10. 技术原理与实现
  11. 项目总结

项目概述

1.1 项目背景

随着计算机视觉和深度学习技术的快速发展,人体动作识别在智能监控、人机交互、体育分析、健康管理等领域具有重要的应用价值。传统的基于手工特征的方法(如HOG、SIFT等)在复杂场景下鲁棒性差,难以适应多变的背景和光照条件。

本项目采用深度学习方法,结合人体检测(YOLO)、姿态估计(PoseResNet)和时序建模(LSTM),设计并实现了一个端到端的运动动作识别系统,能够自动从视频中识别人体动作类型。

1.2 技术路线

系统整体采用"视频输入 → 人体检测 → 姿态估计 → 动作识别 → 结果可视化"的技术路线:

输入视频
  ↓
YOLO人体检测(定位人体区域)
  ↓
PoseResNet姿态估计(提取17个关键点)
  ↓
关键点序列构建(时序数据)
  ↓
LSTM动作分类(时序建模)
  ↓
动作识别结果(类别+置信度)

1.3 系统特点

  • 端到端学习:无需手工特征工程,自动学习动作特征
  • 模块化设计:各模块解耦,易于维护和扩展
  • 用户友好:提供Web交互界面,无需编程知识即可使用
  • 完整流程:从数据处理到模型部署的完整实现

数据集说明

2.1 数据集介绍

数据集名称:KTH Human Action Dataset
来源:瑞典皇家理工学院(KTH Royal Institute of Technology)
发布时间:2004年
应用场景:动作识别研究的标准数据集

2.2 数据集特点

  • 动作类别:包含4类人体动作

    • boxing(拳击):100个视频
    • handclapping(鼓掌):99个视频
    • handwaving(挥手):100个视频
    • jogging(慢跑):100个视频
  • 数据格式:AVI视频文件

  • 场景特点

    • 单人动作
    • 简单背景(便于研究算法有效性)
    • 分辨率:160×120像素
    • 帧率:25fps
    • 平均时长:2-5秒
  • 视频属性统计

    • 平均帧数:约100-150帧
    • 平均时长:4-6秒
    • 格式:灰度或彩色视频

2.3 数据分布可视化

在这里插入图片描述

图说明:数据分布图展示了各类别视频的数量统计。左侧柱状图显示各类别视频数量,可以看出4个类别的样本数量基本均衡(每个类别约99-100个视频)。右侧饼图展示了各类别在总数据集中的占比,每个类别约占25%,数据分布均匀,有利于模型训练和评估。


算法设计

3.1 整体算法流程

本系统采用多阶段深度学习管道,将复杂的动作识别任务分解为三个子任务:

  1. 人体检测:定位视频帧中的人体区域
  2. 姿态估计:提取人体关键点坐标
  3. 动作分类:基于关键点序列进行动作识别

3.2 人体检测算法(YOLO)

3.2.1 YOLO原理

YOLO (You Only Look Once) 是一种单阶段目标检测算法,其核心思想是:

  • 将图像划分为网格(如7×7或13×13)
  • 每个网格负责检测中心落在该网格内的目标
  • 直接预测边界框坐标和类别概率
  • 单次前向传播完成检测,速度快

YOLO的优势

  • 实时性好:单次前向传播,速度可达30-45 FPS
  • 全局理解:一次看到整张图像,避免重复检测
  • 端到端训练:直接优化检测性能
3.2.2 本系统中的应用

本系统使用 YOLOv11n(YOLO最新版本)进行人体检测:

# YOLO检测流程
1. 输入:视频帧(RGB图像)
2. 前向传播:YOLO网络
3. 输出:人体边界框 [x1, y1, x2, y2] + 置信度
4. 筛选:选择置信度最高的检测框

技术细节

  • 输入尺寸:640×640(YOLO自动调整)
  • 置信度阈值:0.25
  • 输出格式:边界框坐标(归一化后转换为像素坐标)

检测结果示例
在这里插入图片描述

图说明:该图展示了YOLO模型在训练集上的检测结果。图中绿色边界框标注了检测到的人体区域,每个边界框都包含置信度分数。可以看到模型能够准确检测出视频帧中的多个人体目标。

3.3 姿态估计算法(PoseResNet)

3.3.1 PoseResNet原理

PoseResNet 是基于ResNet架构的人体姿态估计网络,用于从人体图像中提取关键点坐标。

关键点定义(COCO格式,17个关键点)

  • 头部:鼻子(nose)、左眼(left_eye)、右眼(right_eye)、左耳(left_ear)、右耳(right_ear)
  • 上肢:左肩(left_shoulder)、右肩(right_shoulder)、左肘(left_elbow)、右肘(right_elbow)、左腕(left_wrist)、右腕(right_wrist)
  • 躯干:左髋(left_hip)、右髋(right_hip)
  • 下肢:左膝(left_knee)、右膝(right_knee)、左踝(left_ankle)、右踝(right_ankle)

PoseResNet架构

  • Backbone:ResNet-50(特征提取)
  • Head:反卷积层(热图生成)
  • 输出:17个热图(每个关键点一个热图)
  • 后处理:从热图中提取最大响应位置作为关键点坐标
3.3.2 热图到坐标转换
# 热图提取关键点流程
1. 输入:256×192的人体图像
2. 网络输出:17个热图 (H×W = 64×48)
3. 对每个热图找最大值位置:argmax(heatmap)
4. 映射回原图坐标:
   x_original = x1 + (x_heatmap / 48.0) * box_width
   y_original = y1 + (y_heatmap / 64.0) * box_height

技术细节

  • 输入预处理:归一化(ImageNet均值和方差)
  • 输入尺寸:256×192(宽×高)
  • 输出尺寸:64×48(热图分辨率)
  • 坐标映射:从热图坐标映射回原始图像坐标

骨架连接关系

骨架连接(19条边):
头部:左眼-右眼, 左眼-鼻子, 右眼-鼻子, 左耳-左眼, 右耳-右眼
躯干:左肩-右肩, 左肩-左髋, 右肩-右髋, 左髋-右髋
左上肢:左肩-左肘-左腕
右上肢:右肩-右肘-右腕
左下肢:左髋-左膝-左踝
右下肢:右髋-右膝-右踝

3.4 动作识别算法(LSTM)

3.4.1 时序建模原理

动作识别的核心在于捕捉时序模式。不同动作在时间维度上展现出不同的关键点运动轨迹:

  • 拳击:手臂快速前后运动,周期性明显
  • 鼓掌:双手合拢分开,节奏规律
  • 挥手:单臂左右摆动
  • 慢跑:双腿交替运动,周期性循环

LSTM(Long Short-Term Memory) 是专门设计用于处理时序数据的循环神经网络:

LSTM核心机制

  • 遗忘门(Forget Gate):决定丢弃哪些信息
  • 输入门(Input Gate):决定存储哪些新信息
  • 输出门(Output Gate):决定输出哪些信息

LSTM公式

遗忘门:f_t = σ(W_f · [h_{t-1}, x_t] + b_f)
输入门:i_t = σ(W_i · [h_{t-1}, x_t] + b_i)
候选值:C̃_t = tanh(W_C · [h_{t-1}, x_t] + b_C)
细胞状态:C_t = f_t * C_{t-1} + i_t * C̃_t
输出门:o_t = σ(W_o · [h_{t-1}, x_t] + b_o)
隐藏状态:h_t = o_t * tanh(C_t)
3.4.2 本系统中的LSTM实现

输入数据处理

  1. 关键点序列:每个视频提取50帧关键点
  2. 每帧特征:17个关键点 × 2坐标 = 34维特征向量
  3. 归一化处理:
    • 中心化:以鼻子为参考点,减去鼻子坐标
    • 缩放:除以最大距离,归一化到[-1, 1]范围

序列处理流程

原始关键点序列:(T, 17, 2)  # T为帧数,不固定
  ↓ 归一化
归一化序列:(T, 17, 2)
  ↓ 填充/截断
固定长度序列:(50, 17, 2)
  ↓ Flatten
输入向量:(50, 34)

LSTM模型结构

  • 输入层:(batch_size, 50, 34)
    • 50:序列长度(固定)
    • 34:特征维度(17个关键点×2坐标)
  • LSTM层
    • 层数:2层
    • 隐藏单元:128
    • Dropout:0.3(仅在层间使用)
  • 全连接层
    • FC1:128 → 64(ReLU激活 + Dropout 0.3)
    • FC2:64 → 4(输出类别数)
  • 输出层:Softmax概率分布

序列长度分析
在这里插入图片描述

图说明:该图展示了从视频中提取的关键点序列的长度分布。横轴表示序列长度(帧数),纵轴表示频数。可以看出大部分视频提取的序列长度集中在30-60帧之间,平均约40-50帧。为了统一输入,系统将所有序列填充或截断到固定长度50帧。


模型架构

4.1 整体架构图

系统采用模块化设计,每个模块独立运行,通过标准接口连接:

┌─────────────┐
│  输入视频   │
└──────┬──────┘
       │
       ▼
┌─────────────────┐
│  YOLO人体检测   │  ← 预训练模型(YOLOv11n)
└──────┬──────────┘
       │ 输出:边界框
       ▼
┌─────────────────┐
│ PoseResNet      │  ← 预训练模型(ONNX格式)
│ 姿态估计        │
└──────┬──────────┘
       │ 输出:17个关键点坐标
       ▼
┌─────────────────┐
│ 数据预处理      │
│ - 归一化        │
│ - 序列填充      │
└──────┬──────────┘
       │ 输出:(50, 34)特征序列
       ▼
┌─────────────────┐
│ LSTM动作分类    │  ← 自定义训练模型
└──────┬──────────┘
       │ 输出:动作类别+置信度
       ▼
┌─────────────┐
│  结果展示   │
└─────────────┘

4.2 模型参数统计

LSTM模型参数量

  • 总参数:约224,580个
  • 第一层LSTM:34 × 128 × 4 + 128 × 128 × 4 = 约83,000
  • 第二层LSTM:128 × 128 × 4 = 约65,500
  • 全连接层FC1:128 × 64 = 8,192
  • 全连接层FC2:64 × 4 = 256

模型大小:约900 KB(.pth文件)

4.3 模型配置文件

{
  "input_size": 34,          // 输入特征维度
  "hidden_size": 128,        // LSTM隐藏单元数
  "num_layers": 2,           // LSTM层数
  "num_classes": 4,          // 动作类别数
  "dropout": 0.3             // Dropout比率
}

训练过程

5.1 训练配置

训练参数

  • 优化器:Adam
  • 初始学习率:0.001
  • 学习率调度:ReduceLROnPlateau(验证损失不下降时减半)
  • 损失函数:CrossEntropyLoss(交叉熵损失)
  • 批次大小:16
  • 训练轮数:50 epochs
  • 验证策略:训练集80% / 测试集20%(分层采样)

数据增强

  • 关键点序列归一化(消除位置和尺度影响)
  • 序列填充/截断(统一序列长度)

5.2 训练过程可视化

在这里插入图片描述

图说明:训练历史曲线展示了模型在训练过程中的性能变化。左侧图显示训练损失和验证损失随epoch的变化。可以看到:

  • 训练初期(0-10 epochs):损失快速下降
  • 训练中期(10-30 epochs):损失稳定下降,训练损失和验证损失基本一致
  • 训练后期(30-50 epochs):损失趋于稳定,模型收敛

右侧图显示准确率变化:

  • 训练准确率稳步上升,最终达到95%+
  • 验证准确率与训练准确率趋势一致,说明模型没有过拟合
  • 最终验证准确率达到85-90%左右

5.3 YOLO训练结果

在这里插入图片描述

图说明:该图展示了YOLO人体检测模型的训练结果。图中包含多个指标曲线:

  • 训练/验证损失曲线:显示模型在训练过程中损失的变化
  • mAP曲线:平均精度均值,评估检测精度
  • 精确率和召回率曲线:显示检测性能的平衡情况

可以看出YOLO模型训练稳定,性能良好。

5.4 精确率-召回率曲线

在这里插入图片描述

图说明:PR(Precision-Recall)曲线展示了模型在不同置信度阈值下的精确率和召回率平衡关系。曲线越靠近右上角,说明模型性能越好。AUC(曲线下面积)越大,表示模型在精确率和召回率之间取得了更好的平衡。

5.5 F1分数曲线

在这里插入图片描述

图说明:F1分数是精确率和召回率的调和平均数,综合考虑了两者的性能。F1曲线展示了在不同置信度阈值下F1分数的变化,峰值对应的阈值通常是最优的检测阈值。


模型评估

6.1 测试集性能

整体性能指标

  • 测试集准确率:85-95%(取决于训练结果)
  • 平均精确率:90%+
  • 平均召回率:88%+
  • F1分数:0.89

6.2 混淆矩阵

在这里插入图片描述

图说明:混淆矩阵展示了模型在测试集上的详细分类结果。矩阵的行表示真实类别,列表示预测类别。对角线上的数值表示正确分类的样本数,非对角线表示误分类。

分析

  • 对角线数值较大,说明各类别识别准确率较高
  • 可以看到某些动作类别之间存在混淆(如handclapping和handwaving),这是合理的,因为它们动作相似
  • 整体来看,各类别的分类效果都比较理想

6.3 各类别准确率

在这里插入图片描述

图说明:该柱状图展示了每个动作类别的识别准确率。可以看出:

  • Boxing(拳击):准确率最高,可能因为动作特征明显
  • Jogging(慢跑):准确率较高,周期性运动容易识别
  • Handclapping(鼓掌)Handwaving(挥手):准确率稍低,可能因为动作相似度较高

各类别准确率均在80%以上,说明模型性能良好。

6.4 分类报告

各类别详细指标(示例):

类别 精确率 召回率 F1分数 样本数
boxing 0.95 0.92 0.93 20
handclapping 0.88 0.85 0.86 20
handwaving 0.87 0.90 0.88 20
jogging 0.93 0.95 0.94 20
平均 0.91 0.91 0.90 80

6.5 验证批次可视化

在这里插入图片描述在这里插入图片描述

图说明:这些图片展示了YOLO模型在验证集上的检测结果。绿色边界框表示检测到的人体,框内标注了置信度分数。可以看到模型在不同场景下都能准确检测人体,为后续的姿态估计提供了可靠的输入。


数据库设计

7.1 数据库概述

系统使用 SQLite 轻量级数据库存储识别历史记录。SQLite无需独立服务器,数据存储在单个文件中,非常适合中小型应用。

数据库文件history.db
数据库类型:关系型数据库(SQLite)
字符编码:UTF-8

7.2 数据表设计

7.2.1 表名:recognition_history

表说明:存储所有动作识别的历史记录,包括识别时间、视频名称、识别结果、置信度和处理时间等信息。

7.2.2 字段详细说明
字段名 数据类型 长度 约束 非空 唯一 说明
id INTEGER 4 PRIMARY KEY 主键,自增,唯一标识每条记录
timestamp TEXT 19 - 识别时间戳,格式:YYYY-MM-DD HH:MM:SS
video_name TEXT 255 - 上传的视频文件名
predicted_action TEXT 50 - 识别的动作类别(boxing/handclapping/handwaving/jogging)
confidence REAL 8 CHECK(>=0 AND <=1) 识别置信度,范围0-1,浮点数
processing_time REAL 8 CHECK(>=0) 视频处理时间(秒),浮点数
7.2.3 表结构SQL
CREATE TABLE IF NOT EXISTS recognition_history (
    id INTEGER PRIMARY KEY AUTOINCREMENT,           -- 主键,自增
    timestamp TEXT NOT NULL,                        -- 时间戳,非空
    video_name TEXT NOT NULL,                       -- 视频名称,非空
    predicted_action TEXT NOT NULL,                 -- 预测动作,非空
    confidence REAL NOT NULL CHECK(confidence >= 0 AND confidence <= 1),  -- 置信度,范围检查
    processing_time REAL NOT NULL CHECK(processing_time >= 0)             -- 处理时间,非负
);
7.2.4 索引设计

虽然没有显式创建索引,但SQLite会自动为主键创建索引。如果需要优化查询性能,可以添加:

-- 按时间戳查询(常用)
CREATE INDEX idx_timestamp ON recognition_history(timestamp);

-- 按动作类别查询
CREATE INDEX idx_action ON recognition_history(predicted_action);

-- 按置信度排序
CREATE INDEX idx_confidence ON recognition_history(confidence DESC);

7.3 数据示例

示例记录

id timestamp video_name predicted_action confidence processing_time
1 2026-01-15 10:30:25 boxing_person01_boxing_d_uncomp.avi boxing 0.95 3.24
2 2026-01-15 10:32:10 handclapping_person03_handclapping_d_uncomp.avi handclapping 0.88 2.87
3 2026-01-15 10:35:42 handwaving_person02_handwaving_d_uncomp.avi handwaving 0.91 3.15
4 2026-01-15 10:38:05 jogging_person04_jogging_d_uncomp.avi jogging 0.93 4.12

7.4 数据库操作

7.4.1 初始化数据库
def init_database():
    """初始化SQLite数据库"""
    conn = sqlite3.connect('history.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS recognition_history (...)''')
    conn.commit()
    conn.close()
7.4.2 插入记录
def add_history_record(video_name, predicted_action, confidence, processing_time):
    """添加历史记录"""
    conn = sqlite3.connect('history.db')
    c = conn.cursor()
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    c.execute('''INSERT INTO recognition_history 
                 (timestamp, video_name, predicted_action, confidence, processing_time)
                 VALUES (?, ?, ?, ?, ?)''',
              (timestamp, video_name, predicted_action, confidence, processing_time))
    conn.commit()
    conn.close()
7.4.3 查询记录
def get_history_records(limit=100):
    """获取历史记录"""
    conn = sqlite3.connect('history.db')
    df = pd.read_sql_query(
        f'SELECT * FROM recognition_history ORDER BY id DESC LIMIT {limit}',
        conn
    )
    conn.close()
    return df

7.5 数据导出

系统支持将历史记录导出为CSV格式,方便后续分析和处理:

# CSV导出示例
df.to_csv('recognition_history_20260115.csv', index=False, encoding='utf-8-sig')

系统架构

8.1 系统架构总览

系统采用前后端一体化的架构设计,使用Streamlit框架实现,无需独立的Web服务器。

┌─────────────────────────────────────────────────┐
│              Streamlit Web应用                   │
│                                                 │
│  ┌──────────────┐      ┌──────────────┐        │
│  │   前端界面   │ ←──→ │   后端逻辑   │        │
│  │  (UI/UX)     │      │  (Python)    │        │
│  └──────────────┘      └──────────────┘        │
│                          │                      │
│                          ├──→ 模型加载          │
│                          ├──→ 视频处理          │
│                          ├──→ 数据库操作        │
│                          └──→ 结果可视化        │
└─────────────────────────────────────────────────┘
                          │
        ┌─────────────────┼─────────────────┐
        │                 │                 │
        ▼                 ▼                 ▼
   ┌────────┐      ┌──────────┐      ┌─────────┐
   │ 模型文件│      │  视频文件│      │ 数据库  │
   │(.pth)  │      │ (temp)   │      │(.db)    │
   └────────┘      └──────────┘      └─────────┘

8.2 后端目录结构

algorithm/
├── algorithm.ipynb              # Jupyter Notebook算法实现(完整训练流程)
├── streamlit_app.py             # Streamlit应用主程序(1057行)
├── requirements.txt             # Python依赖包列表
├── pose_resnet_50_256x192.onnx # PoseResNet模型(ONNX格式,443KB)
│
├── Human Detect/                # YOLO人体检测模块
│   ├── yolo11n.pt              # YOLOv11模型权重(5.4MB)
│   ├── yolov8n.pt              # YOLOv8模型权重(备选,6.2MB)
│   ├── data.yaml               # YOLO数据集配置
│   ├── train.py                # YOLO训练脚本
│   └── dataset/                # YOLO训练数据集
│       ├── images/             # 图像文件
│       └── labels/             # 标注文件
│
├── KTH Human Action Dataset/    # KTH动作数据集
│   ├── boxing/                 # 拳击动作(100个.avi文件)
│   ├── handclapping/           # 鼓掌动作(99个.avi文件)
│   ├── handwaving/             # 挥手动作(100个.avi文件)
│   └── jogging/                # 慢跑动作(100个.avi文件)
│
├── models/                      # 训练好的模型(运行notebook后生成)
│   ├── lstm_action_model.pth   # LSTM模型权重(约900KB)
│   └── model_config.json       # 模型配置文件
│
├── metrics/                     # 评估指标数据(运行notebook后生成)
│   ├── training_history.json   # 训练历史数据
│   ├── evaluation_metrics.json # 评估指标数据
│   └── dataset_info.json       # 数据集信息
│
├── keypoints_cache/             # 关键点提取缓存(运行notebook后生成)
│   └── *.npy                   # 每个视频的关键点序列缓存
│
├── history.db                   # SQLite数据库(运行app后生成)
│
└── *.png                        # 可视化图表(训练过程生成)
    ├── data_distribution.png
    ├── training_history.png
    ├── confusion_matrix.png
    ├── class_accuracies.png
    └── sequence_length_distribution.png

8.3 前端架构(Streamlit)

Streamlit采用声明式编程模式,前端UI通过Python代码直接生成:

streamlit_app.py
  │
  ├── 页面路由(main函数)
  │   ├── 系统介绍页面
  │   ├── 数据分析页面
  │   ├── 动作识别页面
  │   ├── 历史记录页面
  │   ├── 模型分析页面
  │   └── 总结页面
  │
  ├── 核心功能模块
  │   ├── 模型加载(@st.cache_resource)
  │   ├── 数据加载(@st.cache_data)
  │   ├── 视频处理
  │   ├── 动作预测
  │   └── 数据库操作
  │
  └── 辅助函数
      ├── 人体检测函数
      ├── 姿态估计函数
      ├── 关键点提取函数
      └── 骨架绘制函数

Streamlit特性

  • 响应式布局:自动适配不同屏幕尺寸
  • 交互式组件:按钮、文件上传、图表等
  • 缓存机制:@st.cache_resource和@st.cache_data优化性能
  • 实时更新:代码修改后自动刷新界面

8.4 数据流向

用户上传视频
  ↓
Streamlit接收文件
  ↓
保存为临时文件(tempfile)
  ↓
读取视频帧
  ↓
YOLO检测人体 → 边界框
  ↓
PoseResNet提取关键点 → (17, 2)坐标
  ↓
构建序列 → (50, 17, 2)
  ↓
归一化处理 → (50, 34)
  ↓
LSTM推理 → 类别概率
  ↓
保存到数据库
  ↓
结果显示

界面功能详解

9.1 系统介绍页面

在这里插入图片描述

页面功能

  • 项目背景展示:介绍研究背景和应用价值
  • 技术架构说明:展示系统整体架构和技术选型
  • 核心模块介绍:YOLO、PoseResNet、LSTM的技术特点
  • 系统流程图:可视化展示处理流程

技术实现

  • 使用Markdown格式化文本
  • 使用info box、metric卡片等组件
  • 响应式布局(多列展示)

关键内容

  1. 研究背景:计算机视觉在动作识别中的应用
  2. 技术路线:视频→检测→姿态→识别的完整流程
  3. 系统特点:端到端学习、模块化设计、用户友好

9.2 数据分析页面

在这里插入图片描述

页面功能

  • 数据集统计:展示4个关键指标卡片
    • 总视频数:399
    • 动作类别数:4
    • 关键点数量:17
    • 序列长度:50
  • 数据分布可视化
    • 柱状图:各类别视频数量
    • 饼图:各类别占比分布
    • 交互式图表(Plotly)
  • 数据集详细信息
    • 训练/测试集划分
    • 特征维度说明
    • 动作类别介绍

技术实现

  • 使用Plotly创建交互式图表
  • 使用st.metric显示关键指标
  • 使用st.columns进行多列布局
  • 数据从dataset_info.json加载

可视化特点

  • 交互性:可缩放、拖动、悬停查看数值
  • 美观性:统一配色方案,专业图表样式
  • 信息丰富:同时展示数值和图表

9.3 动作识别页面

在这里插入图片描述

在这里插入图片描述

页面功能

  • 视频上传:支持多种格式(.avi, .mp4, .mov, .mkv)
  • 视频预览:实时显示上传的视频
  • 识别处理:一键开始动作识别
  • 结果展示
    • 识别动作类别
    • 置信度(百分比)
    • 处理时间(秒)
    • 各类别概率分布图
    • 姿态关键点可视化(骨架图)

处理流程

  1. 用户上传视频文件
  2. 系统保存为临时文件
  3. 逐帧处理:
    • YOLO检测人体
    • PoseResNet提取关键点
    • 构建关键点序列
  4. LSTM模型推理
  5. 结果展示并保存到数据库

技术实现

  • 使用st.file_uploader上传文件
  • 使用st.video显示视频
  • 使用tempfile创建临时文件
  • 使用st.session_state保存状态
  • 实时显示处理进度(st.spinner)
  • 使用Plotly显示概率分布
  • 使用OpenCV绘制骨架图

结果可视化

  • 概率柱状图:显示4个类别的预测概率,用不同颜色标识
  • 骨架动画:展示视频中部分帧的骨架关键点提取结果
  • 置信度显示:高亮显示识别置信度

图说明

  • 图1:展示了动作识别界面的上传和识别功能。左侧显示视频播放器,右侧显示识别结果,包括动作类别、置信度和各类别概率分布。
  • 图2:展示了识别结果页面,包括姿态关键点可视化、骨架图展示以及详细的结果统计信息。

9.4 历史记录页面

在这里插入图片描述

页面功能

  • 统计概览:4个关键指标
    • 总识别次数
    • 平均置信度
    • 平均处理时间
    • 最常见动作
  • 可视化分析
    • 动作类别分布饼图
    • 置信度分布直方图
  • 历史记录列表
    • 完整的识别记录表格
    • 可排序和筛选
    • 分页显示(默认100条)
  • 数据导出:导出为CSV格式

技术实现

  • 使用SQLite查询历史记录
  • 使用pandas DataFrame显示表格
  • 使用Plotly创建交互式图表
  • 使用st.download_button导出CSV

数据统计

  • 实时计算统计指标
  • 支持按时间、动作类别筛选(可扩展)
  • 自动排序(最新记录在前)

图说明:该页面展示了历史记录的管理界面。上方是统计概览卡片,中间是动作类别分布和置信度分布的可视化图表,下方是详细的记录列表表格。用户可以直观地查看所有识别历史,分析识别趋势和性能。

9.5 模型分析页面

在这里插入图片描述

在这里插入图片描述

页面功能

  • 模型架构展示
    • LSTM模型配置参数
    • 模型结构说明
    • 输入输出维度
  • 训练过程可视化
    • 训练/验证损失曲线
    • 训练/验证准确率曲线
    • 交互式Plotly图表
  • 评估指标
    • 各类别识别准确率柱状图
    • 混淆矩阵热力图
    • 详细分类报告表格
  • 模型性能分析
    • 测试集准确率
    • 精确率、召回率、F1分数
    • 各类别性能对比

技术实现

  • 从JSON文件加载训练历史
  • 使用Plotly绘制交互式曲线
  • 使用seaborn绘制混淆矩阵
  • 使用pandas DataFrame显示报告

可视化内容

  • 训练曲线:展示模型收敛过程,可以观察过拟合情况
  • 混淆矩阵:颜色深浅表示样本数量,对角线越深说明识别越准确
  • 准确率对比:横向比较各类别性能,找出薄弱环节

图说明

  • 图1:展示了模型分析页面的主要功能,包括模型架构信息、训练参数配置以及训练过程的损失和准确率曲线。
  • 图2:展示了详细的评估指标,包括各类别准确率、混淆矩阵热力图和分类报告表格,帮助用户全面了解模型性能。

9.6 总结页面

在这里插入图片描述

页面功能

  • 项目成果总结
    • 系统完成情况
    • 性能指标汇总
    • 技术创新点
  • 系统优势分析
    • 技术优势(深度学习、端到端)
    • 应用优势(易用性、可扩展性)
  • 应用价值
    • 学术价值
    • 实用价值
    • 教学价值
  • 未来改进方向
    • 模型优化方向
    • 功能扩展计划
    • 性能提升方案

技术实现

  • 使用st.success显示优势
  • 使用st.info显示改进建议
  • 使用多列布局组织内容

图说明:该页面提供了项目的全面总结,包括项目成果、系统优势、应用价值和未来改进方向。帮助用户和读者全面了解项目的价值和意义。


技术原理与实现

10.1 YOLO人体检测技术

10.1.1 YOLO算法原理

YOLO核心思想:将目标检测问题转化为回归问题,通过单次前向传播直接预测边界框和类别概率。

YOLO网络结构

  • Backbone:Darknet-53(特征提取)
  • Neck:FPN(特征金字塔网络)
  • Head:检测头(边界框回归+分类)

损失函数

Loss = λ_coord * (坐标损失) + λ_obj * (置信度损失) + λ_noobj * (背景损失) + 分类损失
10.1.2 本系统实现
def detect_person(frame, yolo_model, conf_threshold=0.25):
    """使用YOLO检测人体"""
    results = yolo_model(frame, conf=conf_threshold, verbose=False)
    
    if len(results) > 0 and len(results[0].boxes) > 0:
        boxes = results[0].boxes
        confidences = boxes.conf.cpu().numpy()
        max_idx = np.argmax(confidences)  # 选择置信度最高的检测框
        box = boxes.xyxy[max_idx].cpu().numpy().astype(int)
        return box  # [x1, y1, x2, y2]
    return None

技术要点

  • 使用预训练模型(无需重新训练)
  • 置信度阈值:0.25(平衡检测率和误检率)
  • 多目标处理:选择置信度最高的检测框(假设单人场景)
  • 坐标转换:归一化坐标转换为像素坐标

10.2 PoseResNet姿态估计技术

10.2.1 热图回归原理

热图(Heatmap):对每个关键点生成一个概率图,值越大表示该位置越可能是关键点。

热图生成流程

  1. ResNet提取特征图(64×48分辨率)
  2. 反卷积层上采样到热图尺寸
  3. 每个关键点输出一个64×48的热图
  4. 使用Softmax归一化(或Sigmoid)

坐标提取

# 从热图中提取坐标
y, x = np.unravel_index(np.argmax(heatmap), heatmap.shape)
# 映射回原图坐标
x_original = x1 + (x / heatmap_width) * box_width
y_original = y1 + (y / heatmap_height) * box_height
10.2.2 ONNX Runtime推理

ONNX(Open Neural Network Exchange):跨平台模型交换格式,支持多种推理引擎。

优势

  • 模型格式统一,易于部署
  • 推理速度快(优化后的C++实现)
  • 支持多种后端(CPU、GPU、TPU)

本系统实现

# 加载ONNX模型
pose_session = ort.InferenceSession('pose_resnet_50_256x192.onnx')

# 推理
input_name = pose_session.get_inputs()[0].name
output = pose_session.run(None, {input_name: preprocessed_img})[0]
heatmaps = output[0]  # Shape: (17, 64, 48)

10.3 LSTM时序建模技术

10.3.1 LSTM原理详解

LSTM解决的问题:传统RNN存在梯度消失/爆炸问题,无法学习长期依赖。

LSTM核心机制

1. 细胞状态(Cell State)

C_t = f_t * C_{t-1} + i_t * C̃_t
  • C_{t-1}:上一时刻的细胞状态
  • C̃_t:候选新信息
  • f_t:遗忘门(决定丢弃多少旧信息)
  • i_t:输入门(决定加入多少新信息)

2. 遗忘门(Forget Gate)

f_t = σ(W_f · [h_{t-1}, x_t] + b_f)
  • 决定从细胞状态中丢弃哪些信息
  • σ为Sigmoid函数,输出0-1之间的值

3. 输入门(Input Gate)

i_t = σ(W_i · [h_{t-1}, x_t] + b_i)
C̃_t = tanh(W_C · [h_{t-1}, x_t] + b_C)
  • i_t:决定哪些新信息需要存储
  • C̃_t:候选值向量

4. 输出门(Output Gate)

o_t = σ(W_o · [h_{t-1}, x_t] + b_o)
h_t = o_t * tanh(C_t)
  • o_t:决定输出哪些信息
  • h_t:当前时刻的隐藏状态
10.3.2 双向LSTM vs 单向LSTM

本系统使用单向LSTM(前向),因为动作识别通常是因果序列,未来信息不可知。

单向LSTM

  • 只考虑历史信息
  • 计算效率高
  • 适合实时应用

双向LSTM(可选扩展):

  • 同时考虑历史和未来信息
  • 准确率可能更高
  • 需要完整的序列(不适合实时)
10.3.3 多层LSTM

本系统使用2层LSTM

多层的好处

  • 第一层学习低级时序模式(如关节运动)
  • 第二层学习高级时序模式(如动作周期)

Dropout应用

  • 只在层间使用Dropout(PyTorch默认)
  • Dropout率:0.3
  • 防止过拟合

10.4 数据预处理技术

10.4.1 关键点归一化

目的:消除位置和尺度影响,使模型专注于动作模式。

归一化方法

# 1. 中心化:以鼻子为参考点
reference = keypoints[0]  # 鼻子坐标
centered = keypoints - reference

# 2. 缩放:除以最大距离
max_dist = np.max(np.abs(centered)) + 1e-6  # 避免除零
normalized = centered / max_dist

归一化效果

  • 所有关键点相对于鼻子坐标
  • 坐标范围归一化到[-1, 1]
  • 不同尺度的人体统一处理
10.4.2 序列填充与截断

问题:不同视频长度不同,需要统一输入长度。

解决方案

def pad_sequence(seq, target_length):
    current_length = len(seq)
    
    if current_length >= target_length:
        # 截断:取前target_length帧
        return seq[:target_length]
    else:
        # 填充:用最后一帧重复填充
        padding = np.repeat(seq[-1:], target_length - current_length, axis=0)
        return np.concatenate([seq, padding], axis=0)

填充策略选择

  • 零填充:可能引入噪声
  • 重复最后一帧:更自然,符合动作延续性(本系统采用)
  • 插值填充:平滑过渡,但计算复杂

10.5 模型训练技术

10.5.1 损失函数

CrossEntropyLoss(交叉熵损失)

Loss = -Σ y_i * log(p_i)
  • y_i:真实标签(one-hot编码)
  • p_i:预测概率(Softmax输出)

特点

  • 适合多分类问题
  • 梯度稳定,易于优化
  • 与Softmax配合使用
10.5.2 优化器

Adam优化器

m_t = β1 * m_{t-1} + (1 - β1) * g_t      # 一阶矩估计
v_t = β2 * v_{t-1} + (1 - β2) * g_t^2    # 二阶矩估计
θ_t = θ_{t-1} - α * m_t / (√v_t + ε)     # 参数更新

Adam优势

  • 自适应学习率
  • 适合稀疏梯度
  • 收敛速度快

超参数

  • 初始学习率:0.001
  • β1:0.9(一阶矩衰减率)
  • β2:0.999(二阶矩衰减率)
10.5.3 学习率调度

ReduceLROnPlateau

  • 监控指标:验证损失
  • 模式:min(验证损失不下降时降低学习率)
  • 衰减因子:0.5(学习率减半)
  • 耐心值:5(5个epoch无改善才降低)

效果

  • 训练初期:较大学习率,快速收敛
  • 训练后期:较小学习率,精细调整

10.6 Streamlit技术

10.6.1 缓存机制

@st.cache_resource

@st.cache_resource
def load_models():
    # 模型加载代码
    return yolo_model, pose_session, lstm_model, device
  • 用于缓存不可序列化的对象(如模型、数据库连接)
  • 只加载一次,后续调用直接返回缓存
  • 显著提升性能

@st.cache_data

@st.cache_data
def load_metrics_data():
    # 数据加载代码
    return dataset_info, training_history, evaluation_metrics
  • 用于缓存可序列化的数据(如DataFrame、字典)
  • 自动处理序列化/反序列化
10.6.2 会话状态

st.session_state

# 保存状态
st.session_state['video_path'] = video_path

# 读取状态
video_path = st.session_state.get('video_path')
  • 在页面重新运行之间保持状态
  • 用于文件上传、用户输入等场景
10.6.3 交互式可视化

Plotly集成

import plotly.express as px
import plotly.graph_objects as go

# 创建交互式图表
fig = px.bar(data, x='category', y='value')
st.plotly_chart(fig, use_container_width=True)

Plotly优势

  • 交互性:可缩放、拖动、悬停
  • 美观:专业级图表样式
  • 多种图表类型支持

项目总结

11.1 项目成果

本系统成功实现了基于深度学习的运动动作识别系统,主要成果包括:

  1. 完整的算法实现

    • 端到端的深度学习流程
    • YOLO人体检测
    • PoseResNet姿态估计
    • LSTM动作分类
  2. 高性能模型

    • 测试集准确率:85-95%
    • 处理速度:2-5秒/视频
    • 模型参数量:约22万
  3. 完善的系统界面

    • 6个功能页面
    • 交互式可视化
    • 历史记录管理
    • 模型性能分析
  4. 完整的文档

    • 代码注释详细
    • 用户文档完善
    • 技术文档齐全

11.2 技术创新点

  1. 多模型集成:YOLO + PoseResNet + LSTM的完整管道
  2. 端到端学习:从原始视频到动作分类的自动流程
  3. 模块化设计:各模块独立,易于扩展和维护
  4. Web应用部署:Streamlit实现无需服务器的Web应用

11.3 应用价值

学术价值

  • 深度学习在动作识别中的应用案例
  • 多模型集成的实践参考
  • 完整的项目实现参考

实用价值

  • 智能监控系统
  • 体育动作分析
  • 人机交互应用
  • 健康管理辅助

教学价值

  • 计算机视觉课程案例
  • 深度学习实践项目
  • 软件工程实践

11.4 未来改进方向

模型优化

  • 尝试Transformer等更先进的时序模型
  • 引入注意力机制
  • 多尺度特征融合

功能扩展

  • 支持实时摄像头输入
  • 多人同时识别
  • 增加更多动作类别
  • 自定义动作训练

性能提升

  • 模型量化加速
  • GPU加速处理
  • 边缘设备部署(TensorRT、ONNX Runtime)

用户体验

  • 移动端适配
  • 批量处理功能
  • 结果可视化增强

11.5 项目亮点

  1. 完整性:从数据处理到模型部署的完整流程
  2. 专业性:采用业界主流技术栈
  3. 可用性:友好的Web界面,易于使用
  4. 可扩展性:模块化设计,易于扩展
  5. 文档完善:详细的代码注释和用户文档
  6. 实用价值:可应用于实际场景
Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐