yolo8实时识别目标(和平精英敌人+骨骼关键点)

发布于:2025-07-23 ⋅ 阅读:(17) ⋅ 点赞:(0)

现在需要识别人物的肢体(姿态/骨骼关键点),即所谓的「姿态估计(pose estimation)」,以下是一些主流、训练好可直接使用的开源模型推荐,支持多人识别与骨骼关键点检测,适合你后续用于游戏人物识别、交互、动作捕捉等场景:

✅ 推荐姿态识别模型(已训练好)

模型名称 框架 支持多人 关键点数量 优势 预训练模型
OpenPose Caffe / PyTorch ✅ 是 COCO:18个 开源先驱,稳定
MediaPipe Pose Google ❌ 单人 33个 极快、跨平台、轻量
YOLOv8-Pose Ultralytics ✅ 是 COCO:17个 YOLO框架下最简单、集成好
MMPose PyTorch ✅ 是 自定义 精度高、支持多种后端

✅ 最推荐:YOLOv8-Pose(Ultralytics 出品)

之前已经使用 YOLOv8 检测人物,所以最推荐你用它的姿态版本 yolov8n-pose.pt上手最快,兼容性最好。

🔧 安装

pip install ultralytics

📦 下载模型

Ultralytics 官方已训练好模型,可以使用以下模型之一:

# 模型文件将自动下载,无需手动操作
yolov8n-pose.pt     # 最快(轻量)
yolov8s-pose.pt     # 较准
yolov8m-pose.pt     # 精度更高
yolov8l-pose.pt     # 更大模型

✅ 示例代码:YOLOv8-Pose 实时检测人物骨骼

from ultralytics import YOLO
import cv2

# 加载模型
model = YOLO('yolov8n-pose.pt')  # 或 yolov8m-pose.pt 等

# 打开视频(可用手机视频流)
cap = cv2.VideoCapture('/path/to/your/video.mp4')

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    results = model(frame)
    annotated_frame = results[0].plot()  # 画出骨骼关键点

    cv2.imshow("Pose Estimation", annotated_frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

这段代码使用了 yolov8n-pose.pt(YOLOv8 的轻量级姿态识别模型),但在播放视频过程中卡顿,很可能是由于以下原因造成的:

✅ 卡顿可能原因分析

原因类别 说明
模型性能瓶颈 yolov8n-pose.pt 虽然是最小模型,但仍可能对低配 CPU 压力大
显示速度瓶颈 cv2.imshow() 是同步操作,每帧都等待窗口刷新(受屏幕刷新率、OpenCV渲染影响)
视频分辨率过高 如果视频是 1080P 或更高,会加重解码和模型推理的负担
无硬件加速 YOLOv8 默认使用 CPU 推理,若没有启用 GPU,会慢很多

 

✅ 优化方案

✅ 1. 设置模型为半精度模式(加速推理)

model.half() # 仅在 CUDA/GPU 可用时有效(需确保模型也支持) 

✅ 2. 降低输入图像尺寸

results = model(frame, imgsz=416) # 默认是 640,可改为 416 提高速度 

✅ 3. 使用线程预读取视频帧(避免显示阻塞)

可以用 cv2.VideoCapture 配合线程读取帧(如需我提供代码也可说)。


✅ 4. 保存视频结果,避免实时显示卡顿

如果你主要是处理分析而不是观看,可以改为保存视频(显示太慢):

out = cv2.VideoWriter("pose_output.mp4", cv2.VideoWriter_fourcc(*'mp4v'), 20, (frame.shape[1], frame.shape[0])) while cap.isOpened(): ret, frame = cap.read() if not ret: break results = model(frame, imgsz=416) annotated_frame = results[0].plot() out.write(annotated_frame) out.release() cap.release() 

✅ 5. 确认是否使用 GPU

如果你安装的是 ultralytics 的默认版本,它会自动调用 CUDA(如果有 GPU),否则使用 CPU:

 

import torch print("CUDA:", torch.cuda.is_available()) 

如果你没有用 GPU,但机器上有显卡,建议配置 PyTorch 的 CUDA 支持版本(我可以帮你装)。


✅ 6. 使用 TensorRT / OpenVINO 加速模型(高级优化)

适用于部署阶段,你可以将 YOLOv8 模型导出为:

yolo export model=yolov8n-pose.pt format=onnx 
yolo export model=yolov8n-pose.pt format=tensorrt 

 

✅ 总结推荐

方案 推荐程度 说明
降低 imgsz=416 ⭐⭐⭐⭐ 简单直接,提升明显
保存视频而非显示 ⭐⭐⭐⭐ 避免实时显示阻塞
使用 GPU 加速 ⭐⭐⭐⭐⭐ 最大性能提升
导出为 TensorRT 加速 ⭐⭐⭐ 部署时推荐,高性能

 🧪【优化版代码】(使用小模型、降分辨率、GPU、帧跳过)

import cv2
import numpy as np
from ultralytics import YOLO
from filterpy.kalman import KalmanFilter
import torch

# 加载 YOLOv8 Nano Pose 模型
model = YOLO("yolov8n-pose.pt")
if torch.cuda.is_available():
    model.to('cuda')

# 打开视频流
cap = cv2.VideoCapture('/Users/lianying/Desktop/yolo/和平精英/hpjy3.mp4')

# 输出视频保存(可选)
out = cv2.VideoWriter("pose_output3.mp4", cv2.VideoWriter_fourcc(*'mp4v'), 25,
                      (int(cap.get(3)), int(cap.get(4))))

# 初始化卡尔曼滤波器
kf = KalmanFilter(dim_x=4, dim_z=2)
kf.x = np.array([0, 0, 0, 0])
kf.F = np.array([[1, 0, 1, 0],
                 [0, 1, 0, 1],
                 [0, 0, 1, 0],
                 [0, 0, 0, 1]])
kf.H = np.array([[1, 0, 0, 0],
                 [0, 1, 0, 0]])
kf.P *= 1000.0
kf.R = 5
kf.Q = np.eye(4)

skeleton = [(5, 7), (7, 9), (6, 8), (8, 10), (11, 13), (13, 15),
            (12, 14), (14, 16), (5, 6), (11, 12), (0, 1), (1, 2),
            (2, 3), (3, 4)]

frame_id = 0
skip_rate = 1  # 每隔几帧识别一次

while True:
    ret, frame = cap.read()
    if not ret:
        break
    frame_id += 1
    display_frame = frame.copy()

    # 降低分辨率处理
    resized = cv2.resize(frame, (416, 416))

    if frame_id % skip_rate == 0:
        results = model(resized, imgsz=416)[0]

        for pose in results.keypoints:
            keypoints = pose.xy[0].cpu().numpy()

            # 坐标映射回原图
            scale_x = frame.shape[1] / 416
            scale_y = frame.shape[0] / 416
            keypoints *= [scale_x, scale_y]

            cx, cy = keypoints[5:7].mean(axis=0)
            kf.predict()
            kf.update(np.array([cx, cy]))
            cx_kf, cy_kf = int(kf.x[0]), int(kf.x[1])

            cv2.circle(display_frame, (cx_kf, cy_kf), 5, (255, 0, 0), -1)

            for x, y in keypoints:
                cv2.circle(display_frame, (int(x), int(y)), 3, (0, 255, 0), -1)

            for i, j in skeleton:
                if keypoints[i][0] > 0 and keypoints[j][0] > 0:
                    pt1 = tuple(np.int32(keypoints[i]))
                    pt2 = tuple(np.int32(keypoints[j]))
                    cv2.line(display_frame, pt1, pt2, (0, 255, 255), 2)

    cv2.imshow("Pose Tracking", display_frame)
    out.write(display_frame)  # 如果需要保存
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
out.release()
cv2.destroyAllWindows()

yolo8模型训练+实时识别目标+骨骼关键点识别(和平精英敌人)

 🎯添加动作识别(比如:蹲下、跳跃、开枪)

✅ 第一步:用关键点判断动作(规则法)

我们先用一种 简单有效的规则法,通过人体关键点的位置和角度判断动作。

🎯 支持识别的动作

动作 判定逻辑
蹲下 膝盖高度接近或低于髋部
跳跃 脚部 Y 坐标明显上升
开枪 手部(腕)前伸、肩膀抬高

✅ 第二步:代码示例(集成到 YOLOv8 Pose 结果中)

以下是 在你现有代码基础上添加动作识别逻辑 的修改版:

def detect_action(keypoints):
    """
    简单规则:根据关键点判断人物动作
    关键点索引说明(COCO格式):
    0:鼻 1:左眼 2:右眼 3:左耳 4:右耳
    5:左肩 6:右肩 7:左肘 8:右肘
    9:左腕 10:右腕 11:左髋 12:右髋
    13:左膝 14:右膝 15:左脚踝 16:右脚踝
    """
    def y(i):  # 返回某关键点y坐标
        return keypoints[i][1]

    def distance(p1, p2):
        return np.linalg.norm(keypoints[p1] - keypoints[p2])

    # 获取关键点存在性(某些关键点可能检测失败)
    valid = lambda i: keypoints[i][0] > 0 and keypoints[i][1] > 0

    if all(valid(i) for i in [11, 12, 13, 14]):
        hip_y = (y(11) + y(12)) / 2
        knee_y = (y(13) + y(14)) / 2
        if knee_y < hip_y - 20:  # 蹲下,膝盖高于髋
            return "蹲下"

    if all(valid(i) for i in [15, 16]):
        ankle_avg_y = (y(15) + y(16)) / 2
        if ankle_avg_y < 300:  # 跳跃(需要根据视频画面高度调整)
            return "跳跃"

    if all(valid(i) for i in [5, 6, 9, 10]):
        arm_len = (distance(5, 9) + distance(6, 10)) / 2
        if arm_len > 120:  # 手臂伸直的距离(根据画面缩放调整)
            return "开枪"

    return None

✅ 整合到主循环中

你只需在你的 YOLOv8 主循环中这样调用:

for pose in results.keypoints:
    keypoints = pose.xy[0].cpu().numpy()

    # 调用动作识别函数
    action = detect_action(keypoints)
    if action:
        cv2.putText(frame, f"动作: {action}", (30, 60),
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

 

✅ 显示完整融合效果

你运行时将能看到:

  • 骨架识别 ✅

  • 人物动作识别并显示到屏幕 ✅

📌 提升建议(如需更准)

  1. 基于时序特征:

    • 使用 LSTMTransformer 模型,对连续帧的关键点数据进行训练。

    • 比如:开枪=“手臂突然向前伸+ recoil 反弹动作”。

  2. 自定义动作数据集:

    • keypoints 序列做样本,结合标签训练自己的动作分类模型。

 


网站公告

今日签到

点亮在社区的每一天
去签到