一、前言
在《动作识别》专栏的《动作识别3------mmpose和mmaction2》中我们介绍了如何通过mmpose获取姿态估计的关键点,然后将关键点转换为pkl格式,就能输入到mmaction2里面基于骨骼关键点的动作识别算法中进行动作识别,比如PoseC3D。
为什么我们要在这个时候重新提到这个呢?因为我们猜测我们之前自建数据集训练TSN进行动作识别,包括我们认识的TSM动作识别算法,它是端到端的,也就是说如果我们的任务是识别人体动作,那么这种端到端的视频分类就可能会比较容易受到背景的干扰,那如果我们先用yolo做目标检测框出人之后再用这种动作识别呢?这样不就规避了背景的干扰吗?但每个人的体型、骨骼结构、衣服等都是不一样的,这些可能仍然会干扰基于RGB的动作识别算法。当然这些都只是我的猜测。不管是不是真的这样,从直觉上来说,对人体动作识别,我们得看看这个基于骨骼点的动作识别算法,也就是先用姿态估计提取骨骼关键点,再根据关键点去动作识别,这样可能会规避一些无关因素的干扰。那为什么选择PoseC3D呢?这是目前从速度和精度综合考虑来看的。
在《动作识别4------mmaction2的demo》的4.8我们可以看到一些demo。
4.8.1 使用Faster RCNN作为人体检测器,HRNetw32作为姿态估计器,PoseC3D作为基于骨架的动作识别器和基于骨架的时空动作检测器。每8帧进行一次动作检测预测,并每1帧输出1帧到输出视频中。输出视频的帧率为24帧每秒。
4.8.2 使用Faster RCNN作为人体检测器,TSN-R50-1x1x3作为基于RGB的动作识别器,SlowOnly-8x8-R101作为基于RGB的时空动作检测器。每8帧进行一次动作检测预测,并每1帧输出1帧到输出视频中。输出视频的帧率为24帧每秒。
4.8.3 使用Faster RCNN作为人体检测器,HRNetw32作为姿态估计器,PoseC3D作为基于骨架的动作识别器,SlowOnly-8x8-R101作为基于RGB的时空动作检测器。每8帧进行一次动作检测预测,并每1帧输出1帧到输出视频中。输出视频的帧率为24帧每秒。
4.8.4 使用Faster RCNN作为人体检测器,HRNetw32作为姿态估计器,TSN-R50-1x1x3作为基于RGB的动作识别器,PoseC3D作为基于骨架的时空动作检测器。每8帧进行一次动作检测预测,并每帧输出1帧到输出视频中。输出视频的帧率为24帧每秒。
上面的动作识别器和时空动作检测器有什么区别?为什么采用Faster RCNN作为人体检测器,HRNetw32作为姿态估计器?而不是使用yolo目标检测和yolo11-pose?
一、动作识别器 vs 时空动作检测器的本质区别
这两个模块在任务目标、输出形式、计算粒度上完全不同:
动作识别器(Action Recognizer)
任务 :对整个视频片段 进行动作分类
输入:预裁剪的视频片段(每8帧一个clip)
输出 :单一动作标签(如"kick")+ 置信度
类比:看图说话,回答"这段视频在做什么"
典型模型:
PoseC3D:输入骨架热图序列,输出动作类别
TSN-R50:输入RGB图像序列,输出动作类别
时空动作检测器(Spatio-Temporal Action Detector)
任务 :在时空维度上定位动作 ,即检测动作发生的时间和空间位置
输入:原始视频流 + 人体检测框
输出 :动作标签 + 时空边界框(空间bbox + 时间起止帧)
类比:在电影中标注"这个动作从第几秒开始,在哪个区域发生"
典型模型:
SlowOnly-8x8-R101:输出每帧的动作概率 + 空间特征
结合检测器:生成带时间维度的动作 tublet(时空管)
Demo中的协作流程
视频流(24fps) ↓ 每8帧取1个clip → 动作识别器 → 整段clip的动作类别 ↓ 每帧检测框 → 时空检测器 → 每帧的动作概率 + 时空定位 ↓ 融合 → 输出带动作标签和定位框的视频核心区别:
动作识别器 :提供语义理解(这是什么动作)
时空检测器 :提供时空定位(动作在哪里、持续多久)
二、为什么用Faster R-CNN + HRNetw32?
这完全是学术惯性 + 功能需求的折中选择:
1. MMAction2框架的学术基因
历史原因 :MMAction2继承自MMDetection,原生支持Faster R-CNN架构
论文复现:多数顶会论文(如AVA数据集)基于Faster R-CNN构建,demo需保持一致性
模块化设计:Faster R-CNN的two-stage结构便于插入时空检测逻辑
2. HRNetw32的精度优势(特定场景)
关键点精度 :在COCO数据集上AP达74.4 ,高于YOLO11-pose的69.5
多尺度融合 :HRNet的并行多分辨率特征融合对遮挡更鲁棒
慢速视频优势 :demo处理的是24fps视频,非实时流,HRNet的速度劣势(~15fps)可接受
3. 时空检测的稳定性需求
Faster R-CNN的RPN :生成高质量候选框,对**小目标(远距离人体)**召回率高
HRNet的密集预测 :为PoseC3D提供高分辨率热图,减少关键点抖动
三、为什么不用YOLO + YOLO11-pose?
技术层面:并非不能,而是没必要在demo中展示
YOLO11的优势在车载场景,不在学术demo
特性 YOLO11-pose HRNetw32 Demo中的影响 速度 50+ FPS 15 FPS Demo是离线处理,速度不敏感 参数量 2.7M 28.5M Demo跑在服务器,显存充足 精度 AP@0.5:0.95 69.5 74.4 HRNet略优,demo追求极限精度 工程适配 ✅ 车载优化 ❌ 通用场景 MMAction2无车载专用分支 功能安全 ✅ ASIL-B潜力 ❌ 无 Demo不涉及车规认证 MMAction2的架构限制
耦合设计:Faster R-CNN的roi_head直接输出检测框给下游,替换为YOLO需重写数据流
预训练权重 :MMAction2官方只提供Faster R-CNN + HRNet的预训练模型,用YOLO需从头训练
指标对齐:AVA等数据集的SOTA指标均基于Faster R-CNN,换YOLO无法直接对比
二、PosC3D
https://mmaction2.readthedocs.io/zh-cn/latest/model_zoo/skeleton.html#posec3d
论文地址:https://arxiv.org/pdf/2104.13586
近年来,人体骨架作为一种人体动作的紧凑表示受到了越来越多的关注。许多基于骨架的动作识别方法采用图卷积网络(GCN)在人体骨架之上提取特征。尽管先前的工作取得了积极成果,但基于GCN的方法在鲁棒性、互操作性和可扩展性方面仍存在局限。在本研究中,我们提出了PoseC3D,一种基于骨架的动作识别新范式,它使用3D热图堆叠而非图序列作为人体骨架的基础表示形式。与基于GCN的方法相比,PoseC3D在学习时空特征方面更加有效,对姿态估计噪声更具鲁棒性,并且在跨数据集场景下具有更好的泛化能力。此外,PoseC3D能够以无需额外计算成本的方式处理多人场景,其特征可方便地在早期融合阶段与其他模态相结合,为进一步提升性能提供了广阔的设计空间。在四个具有挑战性的数据集上,无论是单独用于骨架还是与RGB模态相结合,PoseC3D均稳定地获得了更优的性能。
我们先不看论文,先把 《动作识别4------mmaction2的demo》的4.8.1再跑一遍。(注意切换到conda环境mmaction2_win_env再运行)
python demo/demo_video_structuralize.py \
--skeleton-stdet-checkpoint https://download.openmmlab.com/mmaction/skeleton/posec3d/posec3d_ava.pth \
--det-config demo/demo_configs/faster-rcnn_r50_fpn_2x_coco_infer.py \
--det-checkpoint http://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_2x_coco/faster_rcnn_r50_fpn_2x_coco_bbox_mAP-0.384_20200504_210434-a5d8aa15.pth \
--pose-config demo/demo_configs/td-hm_hrnet-w32_8xb64-210e_coco-256x192_infer.py \
--pose-checkpoint https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth \
--skeleton-config configs/skeleton/posec3d/slowonly_r50_8xb16-u48-240e_ntu60-xsub-keypoint.py \
--skeleton-checkpoint https://download.openmmlab.com/mmaction/skeleton/posec3d/posec3d_k400.pth \
--use-skeleton-stdet \
--use-skeleton-recog \
--label-map-stdet tools/data/ava/label_map.txt \
--label-map tools/data/kinetics/label_map_k400.txt
因为我是手动下载好模型再运行的,而且我是在cmd终端运行的。所以我是运行这个:
python demo/demo_video_structuralize.py ^
--skeleton-stdet-checkpoint checkpoints/posec3d_ava.pth ^
--det-config demo/demo_configs/faster-rcnn_r50_fpn_2x_coco_infer.py ^
--det-checkpoint checkpoints/faster_rcnn_r50_fpn_2x_coco_bbox_mAP-0.384_20200504_210434-a5d8aa15.pth ^
--pose-config demo/demo_configs/td-hm_hrnet-w32_8xb64-210e_coco-256x192_infer.py ^
--pose-checkpoint checkpoints/hrnet_w32_coco_256x192-c78dce93_20200708.pth ^
--skeleton-config configs/skeleton/posec3d/slowonly_r50_8xb16-u48-240e_ntu60-xsub-keypoint.py ^
--skeleton-checkpoint checkpoints/posec3d_k400.pth ^
--use-skeleton-stdet ^
--use-skeleton-recog ^
--label-map-stdet tools/data/ava/label_map.txt ^
--label-map tools/data/kinetics/label_map_k400.txt
输出的视频位置它会在输出信息显示的,在demo/test_stdet_recognition_output.mp4。
我们打开mmaction2/demo/demo_video_structuralize.py,找找它输入视频路径和输出视频路径是在哪定义的。原来是用--video指定输入路径,--out-filename指定输出路径,这两个路径都是mp4的路径,你看你的mp4路径在哪,改成你自己的路径就好了。
python demo/demo_video_structuralize.py ^
--skeleton-stdet-checkpoint checkpoints/posec3d_ava.pth ^
--det-config demo/demo_configs/faster-rcnn_r50_fpn_2x_coco_infer.py ^
--det-checkpoint checkpoints/faster_rcnn_r50_fpn_2x_coco_bbox_mAP-0.384_20200504_210434-a5d8aa15.pth ^
--pose-config demo/demo_configs/td-hm_hrnet-w32_8xb64-210e_coco-256x192_infer.py ^
--pose-checkpoint checkpoints/hrnet_w32_coco_256x192-c78dce93_20200708.pth ^
--skeleton-config configs/skeleton/posec3d/slowonly_r50_8xb16-u48-240e_ntu60-xsub-keypoint.py ^
--skeleton-checkpoint checkpoints/posec3d_k400.pth ^
--use-skeleton-stdet ^
--use-skeleton-recog ^
--label-map-stdet tools/data/ava/label_map.txt ^
--label-map tools/data/kinetics/label_map_k400.txt
--video r'D:\zero_track\mmaction2\demo\input_kick_video\test1.mp4"
--out-filename r'D:\zero_track\mmaction2\demo\output_kick_video\test1.mp4"
结果报错找不到路径
File "d:\zero_track\mmaction2\mmaction\utils\misc.py", line 56, in frame_extract
assert osp.exists(video_path), f'file not exit {video_path}'
AssertionError: file not exit 'demo\input_kick_video/test1.mp4'
我明明是在vscode里面对文件进行右键,复制路径,所以按理说路径不会出错呀?原因是路径不能用单引号,而且cmd终端不认识r。我们改成双引号,然后把r去掉
python demo/demo_video_structuralize.py ^
--skeleton-stdet-checkpoint checkpoints/posec3d_ava.pth ^
--det-config demo/demo_configs/faster-rcnn_r50_fpn_2x_coco_infer.py ^
--det-checkpoint checkpoints/faster_rcnn_r50_fpn_2x_coco_bbox_mAP-0.384_20200504_210434-a5d8aa15.pth ^
--pose-config demo/demo_configs/td-hm_hrnet-w32_8xb64-210e_coco-256x192_infer.py ^
--pose-checkpoint checkpoints/hrnet_w32_coco_256x192-c78dce93_20200708.pth ^
--skeleton-config configs/skeleton/posec3d/slowonly_r50_8xb16-u48-240e_ntu60-xsub-keypoint.py ^
--skeleton-checkpoint checkpoints/posec3d_k400.pth ^
--use-skeleton-stdet ^
--use-skeleton-recog ^
--label-map-stdet tools/data/ava/label_map.txt ^
--label-map tools/data/kinetics/label_map_k400.txt ^
--video "D:\zero_track\mmaction2\demo\input_kick_video\test1.mp4" ^
--out-filename "D:\zero_track\mmaction2\demo\output_kick_video\test1.mp4"
在cmd终端中:
核心要点
每行末尾必须加
^(最后一行除外)路径用双引号
"..."包裹不要用
r'...'这种 Python 语法正斜杠
/和反斜杠\在 CMD 中都可用,但反斜杠要用双引号括起来避免被当作转义符
我们从输出视频可以看到,人物走动、弯腰这些是识别出来了,但是没有识别出我们想要识别的动作,接下来我们得自己建数据集训练PoseC3D。