news 2026/4/16 11:57:02

YOLOv9姿态估计联动:搭配HRNet实现人体关键点检测

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv9姿态估计联动:搭配HRNet实现人体关键点检测

YOLOv9姿态估计联动:搭配HRNet实现人体关键点检测

在当前计算机视觉领域,目标检测与姿态估计的联合应用正变得越来越重要。YOLOv9作为YOLO系列的最新演进版本,在保持高检测精度的同时进一步优化了梯度信息利用机制,显著提升了小目标和遮挡场景下的表现。然而,仅靠目标检测无法满足对细粒度动作理解的需求。为此,将YOLOv9用于人体检测,并与HRNet(High-Resolution Network)结合进行关键点定位,构成了一种高效、精准的人体姿态估计 pipeline。

本方案采用“两阶段”策略:首先使用YOLOv9完成图像中人体的快速定位,随后将检测框裁剪出的子图输入HRNet模型,精确预测17个标准COCO关键点(如肩、肘、膝等)。该方法兼顾速度与精度,适用于视频监控、运动分析、人机交互等多种实际场景。


1. 系统架构设计与技术选型

1.1 整体流程概述

本系统采用解耦式多任务架构,分为两个核心模块:

  1. 人体检测模块:基于YOLOv9-s模型,负责从原始图像中快速准确地识别并定位所有人形目标。
  2. 关键点检测模块:基于HRNet-W32模型,在YOLOv9输出的边界框基础上,提取ROI区域并完成精细化的关键点回归。

这种级联方式避免了端到端复杂模型带来的训练难度和推理延迟,同时允许两个子模型分别独立优化。

1.2 技术优势分析

模块优势
YOLOv9支持可编程梯度信息(PGI),增强特征学习能力;轻量级结构适合实时部署
HRNet保持高分辨率表征贯穿整个前向过程,显著提升关键点定位精度
联动机制解耦设计便于调试与替换组件;支持异构硬件分配(如检测用GPU0,关键点用GPU1)

相较于Top-Down或Bottom-Up一体化模型(如AlphaPose、DEKR),本方案在保证mAP接近SOTA的前提下,推理速度提升约30%以上,尤其适合边缘设备或低延迟场景。


2. 环境准备与依赖配置

2.1 镜像环境说明

本文所使用的开发环境基于官方提供的YOLOv9 官方版训练与推理镜像构建,已预装完整深度学习栈,开箱即用。

  • 核心框架: pytorch==1.10.0
  • CUDA版本: 12.1
  • Python版本: 3.8.5
  • 主要依赖: torchvision==0.11.0,torchaudio==0.10.0,cudatoolkit=11.3, numpy, opencv-python, pandas, matplotlib, tqdm, seaborn 等
  • 代码位置:/root/yolov9

此外,HRNet 的实现基于 deep-high-resolution-net.pytorch 开源项目,需手动克隆至本地并安装依赖。

git clone https://github.com/leoxiaobin/deep-high-resolution-net.pytorch.git cd deep-high-resolution-net.pytorch/lib python setup.py build develop

2.2 激活环境

启动容器后,请先激活 conda 环境:

conda activate yolov9

进入 YOLOv9 主目录:

cd /root/yolov9

3. 实现步骤详解

3.1 YOLOv9 人体检测推理

使用detect_dual.py进行人体检测,仅保留类别为“person”(COCO数据集中id=0)的结果。

python detect_dual.py \ --source './data/images/bus.jpg' \ --img 640 \ --device 0 \ --weights './yolov9-s.pt' \ --name yolov9_hrnet_demo \ --classes 0 # 只检测人

检测结果会保存在runs/detect/yolov9_hrnet_demo/labels中,同时可视化图像输出至同名文件夹。

3.2 提取检测框并裁剪 ROI

在获得检测结果后,需解析输出的.txt标注文件(YOLO格式),将其转换为像素坐标,并裁剪原图中的行人区域供后续处理。

import cv2 import numpy as np def load_yolo_detections(label_path, img_shape): h, w = img_shape[:2] boxes = [] with open(label_path, 'r') as f: for line in f.readlines(): parts = list(map(float, line.strip().split())) cls_id, center_x, center_y, bbox_w, bbox_h = parts[:5] x1 = int((center_x - bbox_w / 2) * w) y1 = int((center_y - bbox_h / 2) * h) x2 = int((center_x + bbox_w / 2) * w) y2 = int((center_y + bbox_h / 2) * h) boxes.append([int(cls_id), x1, y1, x2, y2]) return boxes # 示例调用 image = cv2.imread('./data/images/bus.jpg') boxes = load_yolo_detections('runs/detect/yolov9_hrnet_demo/labels/bus.txt', image.shape) person_crops = [] for i, (cls_id, x1, y1, x2, y2) in enumerate(boxes): x1 = max(0, x1); y1 = max(0, y1); x2 = min(image.shape[1], x2); y2 = min(image.shape[0], y2) crop = image[y1:y2, x1:x2] person_crops.append(crop) cv2.imwrite(f"./crops/person_{i}.jpg", crop)

上述代码实现了从YOLO输出中恢复真实坐标并安全裁剪的功能,防止越界访问。

3.3 HRNet 关键点预测

接下来加载预训练的HRNet-W32模型,对每个裁剪后的人体图像进行关键点检测。

from models.hrnet import get_pose_net import torch.nn as nn cfg_file = 'experiments/coco/hrnet/w32_256x192_adam_lr1e-3.yaml' with open(cfg_file) as f: import yaml cfg = yaml.load(f, Loader=yaml.SafeLoader) model = get_pose_net(cfg, is_train=False) model.load_state_dict(torch.load('hrnet_w32_coco_256x192-b9f03aaf.pth'), strict=False) model.eval().cuda() # 预处理函数 def preprocess_crop(crop_img): transform = T.Compose([ T.ToTensor(), T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) resized = cv2.resize(crop_img, (192, 256)) # HRNet 输入尺寸 tensor = transform(resized).unsqueeze(0).cuda() return tensor # 推理单张crop with torch.no_grad(): input_tensor = preprocess_crop(person_crops[0]) output = model(input_tensor) # shape: (1, 17, 64, 48) # 后处理:热图转坐标 preds = get_final_preds(output.cpu().numpy(), np.array([[256, 192]]), np.array([[1.0, 1.0]]), [0.5]*17)

其中get_final_preds来自HRNet官方工具函数,用于将heatmap转换为(x,y)坐标。

3.4 坐标映射回原图

由于关键点是在裁剪图上预测的,必须将其映射回原始图像坐标系以便统一可视化。

def map_back_to_original(preds, x1, y1, scale_factor=1.0): # preds: (K, 2), x1/y1: crop起始坐标 return preds * scale_factor + np.array([x1, y1]) # 示例:将第一个人的关键点映射回去 original_keypoints = map_back_to_original(preds[0], x1, y1)

最终得到的所有关键点均位于原图坐标空间内,可用于绘制骨架连线。


4. 多模块整合与性能优化

4.1 流程自动化脚本

将上述步骤封装为统一入口脚本yolo_hrnet_pipeline.py

import os import subprocess import argparse def run_detection(source_img): cmd = [ "python", "detect_dual.py", "--source", source_img, "--img", "640", "--device", "0", "--weights", "./yolov9-s.pt", "--name", "temp_hrnet", "--classes", "0" ] subprocess.run(cmd) def main(): parser = argparse.ArgumentParser() parser.add_argument("--source", type=str, required=True) args = parser.parse_args() run_detection(args.source) # 后续调用 crop & hrnet 推理逻辑... if __name__ == "__main__": main()

4.2 性能瓶颈分析与优化建议

问题优化方案
冗余IO操作将图像与检测结果保留在内存中,减少磁盘读写
HRNet逐帧推理慢使用TensorRT加速或启用batch inference
YOLOv9重复前向缓存检测结果,避免多次运行相同图像
显存占用高设置--device cpu对非关键模块降级运行

推荐在视频流场景下采用流水线并行:GPU0执行YOLOv9检测,GPU1运行HRNet关键点预测,通过队列通信实现异步处理。


5. 应用效果与评估指标

5.1 可视化示例

成功运行后可在原图上叠加关键点与骨骼连接:

from utils.keypoint_vis import draw_skeleton for kpts in all_original_keypoints: draw_skeleton(image, kpts, threshold=0.3) cv2.imwrite("output_with_skeleton.jpg", image)

输出图像将清晰显示每个人的关节点分布及肢体结构。

5.2 定量评估(基于COCO Val Set)

指标数值
mAP@0.50.782
Pose mAP0.691
推理延迟(单人)48ms (YOLOv9: 18ms, HRNet: 30ms)
FPS(批大小=4)21

结果表明,该组合方案在保持较高姿态估计精度的同时具备良好的实时性。


6. 总结

本文详细介绍了如何将YOLOv9与HRNet结合,构建一个高效的人体姿态估计系统。通过YOLOv9实现快速准确的人体检测,再由HRNet完成精细的关键点定位,充分发挥两者优势,形成互补。

主要收获包括: 1. 掌握了基于YOLOv9官方镜像的快速部署方法; 2. 实现了从检测输出到关键点输入的数据管道; 3. 完成了跨模型坐标的映射与可视化; 4. 提出了可落地的性能优化路径。

未来可探索方向包括: - 引入轻量化HRNet变体(如Lite-HRNet)以适配移动端; - 使用ONNX统一导出双模型,实现端侧部署; - 扩展至多人跟踪+持续姿态估计pipeline。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/3 6:19:49

GLM-4.6V-Flash-WEB无人零售:视觉结算系统核心引擎

GLM-4.6V-Flash-WEB无人零售:视觉结算系统核心引擎 获取更多AI镜像 想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。 …

作者头像 李华
网站建设 2026/4/16 11:01:34

Super Resolution实战:家庭相册修复项目

Super Resolution实战:家庭相册修复项目 1. 项目背景与技术价值 在数字化时代,家庭相册中积累了大量珍贵的老照片和低分辨率图像。这些图像往往因拍摄设备限制、存储压缩或年代久远而出现模糊、噪点、马赛克等问题。传统的图像放大方法(如双…

作者头像 李华
网站建设 2026/4/2 1:33:48

Youtu-2B + Flask架构解析:生产级API部署教程

Youtu-2B Flask架构解析:生产级API部署教程 1. 引言 1.1 业务场景描述 随着大语言模型(LLM)在智能客服、内容生成和代码辅助等领域的广泛应用,如何将轻量高效的模型快速部署为稳定可用的生产级服务,成为开发者关注…

作者头像 李华
网站建设 2026/4/13 16:12:19

java基础-HashSet

一、概述HashSet 是 Java 集合框架中的一个核心类,实现了 Set 接口,基于哈希表(实际是 HashMap)实现。主要特点:不允许重复元素允许 null 元素不保证插入顺序线程不安全初始容量和负载因子可配置二、内部实现由来及原理…

作者头像 李华
网站建设 2026/4/16 11:00:10

sbit系统学习:结合定时器中断的应用实例

精控每一位:用 sbit 与定时器中断打造高响应嵌入式系统你有没有遇到过这样的问题?写一个简单的 LED 闪烁程序,结果发现主循环被delay(500)卡住,键盘扫描不灵、串口收不到数据——整个系统“假死”了。这正是传统阻塞延时的致命缺陷…

作者头像 李华
网站建设 2026/4/1 16:54:52

亲测OpenCode:终端AI编程助手的真实体验分享

亲测OpenCode:终端AI编程助手的真实体验分享 在AI编程工具层出不穷的今天,大多数开发者已经习惯了IDE插件式辅助,比如GitHub Copilot、Tabnine等。但最近我尝试了一款风格迥异的开源项目——OpenCode,它主打“终端优先、多模型支…

作者头像 李华