news 2026/7/28 1:44:17

yolo26 pose 推理 人体姿态2026

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
yolo26 pose 推理 人体姿态2026

目录

效果更好:

rtmpose:


效果更好:

rtmpose:

import os import cv2 import argparse import numpy as np from rtmlib import Wholebody def process_video(video_path, output_path=None): """处理视频,进行人体姿态检测""" if not os.path.exists(video_path): raise FileNotFoundError(f"视频路径无效: {video_path}") # 初始化模型 wholebody = Wholebody(mode='performance', backend='onnxruntime', device='cuda') # 打开视频 cap = cv2.VideoCapture(video_path) if not cap.isOpened(): raise ValueError(f"无法打开视频: {video_path}") # 获取视频信息 fps = int(cap.get(cv2.CAP_PROP_FPS)) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 设置输出视频 out = None if output_path: fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) frame_count = 0 print(f"开始处理视频: {video_path}") while True: ret, frame = cap.read() if not ret: break frame_count += 1 frame_rgb=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB) # 推理:获取关键点 keypoints, scores = wholebody(frame_rgb) person_detected = False # 如果检测到人体 if keypoints is not None and len(keypoints) > 0: for kpts in keypoints: # 过滤有效关键点 valid_kpts = [pt for pt in kpts if pt[0] > 0 and pt[1] > 0] if len(valid_kpts) < 5: # 至少5个关键点才认为是有效人体 continue pts = np.array(valid_kpts) x_min, y_min = np.min(pts, axis=0) x_max, y_max = np.max(pts, axis=0) area = (x_max - x_min) * (y_max - y_min) if area < 900: continue # 计算边界框(扩展20%) valid_kpts = [pt for pt in kpts if pt[0] > 0 and pt[1] > 0] pts = np.array(valid_kpts) x_min, y_min = np.min(pts, axis=0) x_max, y_max = np.max(pts, axis=0) # 扩展框 w, h = x_max - x_min, y_max - y_min expand_w, expand_h = int(w * 0.01), int(h * 0.01) x1 = max(0, int(x_min - expand_w)) y1 = max(0, int(y_min - expand_h)) x2 = min(width, int(x_max + expand_w)) y2 = min(height, int(y_max + expand_h)) # 绘制边界框 cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, "ren", (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) # 绘制关键点 for pt in kpts: if pt[0] > 0 and pt[1] > 0: cv2.circle(frame, (int(pt[0]), int(pt[1])), 2, (0, 255, 255), -1) # 显示状态信息 status = "Person Detected" if person_detected else "No Person" color = (0, 255, 0) if person_detected else (0, 0, 255) cv2.putText(frame, f"{status} | Frame: {frame_count}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2) # 保存或显示 # if out: # out.write(frame) cv2.imshow('Pose Detection', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源 cap.release() if out: out.release() cv2.destroyAllWindows() print(f"处理完成!共 {frame_count} 帧") if output_path: print(f"视频已保存: {output_path}") if __name__ == "__main__": parser = argparse.ArgumentParser(description="视频人体姿态检测") parser.add_argument("--video_path", type=str,default=r"C:\Users\Administrator\Videos\yumao\yumao.mp4", help="视频路径") parser.add_argument("--output_path", type=str, default=None, help="输出视频路径(可选)") args = parser.parse_args() process_video(args.video_path, args.output_path)

pip install ultralytics

from ultralytics import YOLO import cv2 import numpy as np import time from pathlib import Path import json class PoseVideoProcessor: def __init__(self, model_path, conf_threshold=0.5): self.model = YOLO(model_path) self.conf_threshold = conf_threshold self.keypoints_names = ['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'] self.skeleton = [[5, 7], [7, 9], # 左臂 [6, 8], [8, 10], # 右臂 [5, 6], [5, 11], [6, 12], # 躯干 [11, 12], [11, 13], [13, 15], # 左腿 [12, 14], [14, 16] # 右腿 ] def draw_pose(self, frame, keypoints, scores, show_confidence=True): """在帧上绘制姿态关键点和骨骼""" h, w = frame.shape[:2] img_copy = frame.copy() # 绘制骨骼 for pair in self.skeleton: p1 = keypoints[pair[0]] p2 = keypoints[pair[1]] s1 = scores[pair[0]] s2 = scores[pair[1]] if s1 > self.conf_threshold and s2 > self.conf_threshold: cv2.line(img_copy, (int(p1[0]), int(p1[1])), (int(p2[0]), int(p2[1])), (0, 255, 0), 2) # 绘制关键点 for i, (kp, score) in enumerate(zip(keypoints, scores)): if score > self.conf_threshold: x, y = int(kp[0]), int(kp[1]) # 绘制圆点 cv2.circle(img_copy, (x, y), 5, (0, 0, 255), -1) # 显示置信度 if show_confidence: cv2.putText(img_copy, f"{score:.2f}", (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1) return img_copy def process_video_one(self, input_path, output_path=None, show_preview=True, save_keypoints=False, keypoints_file=None): cap = cv2.VideoCapture(str(input_path)) if not cap.isOpened(): print(f"无法打开视频: {input_path}") return # 获取视频属性 fps = int(cap.get(cv2.CAP_PROP_FPS)) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 设置输出视频 if output_path is None: input_path_obj = Path(input_path) output_path = input_path_obj.parent / f"{input_path_obj.stem}_pose_advanced.mp4" fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(str(output_path), fourcc, fps, (width, height)) # 准备保存关键点数据 all_keypoints_data = [] print(f"开始处理视频: {input_path}") print(f"总帧数: {total_frames}") frame_count = 0 start_time = time.time() processing_times = [] while True: ret, frame = cap.read() if not ret: break # 推理 frame_start = time.time() results = self.model.predict(frame, conf=self.conf_threshold, verbose=False) frame_time = time.time() - frame_start processing_times.append(frame_time) # 获取关键点 keypoints_data = None annotated_frame = frame.copy() if len(results) > 0 and results[0].keypoints is not None: keypoints = results[0].keypoints.data.cpu().numpy() if len(keypoints) > 0: keypoints = keypoints[0] # 取第一个检测对象 kps = keypoints[:, :2] # x, y坐标 scores = keypoints[:, 2] # 置信度 # 绘制姿态 annotated_frame = self.draw_pose(frame, kps, scores, show_confidence=False) # 保存关键点数据 if save_keypoints: frame_data = {'frame': frame_count, 'keypoints': kps.tolist(), 'scores': scores.tolist()} all_keypoints_data.append(frame_data) # 添加帧信息 cv2.putText(annotated_frame, f"Frame: {frame_count}/{total_frames}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) cv2.putText(annotated_frame, f"FPS: {1 / frame_time:.1f}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) # 写入输出视频 out.write(annotated_frame) # 显示预览 if show_preview: # 缩放显示以适应屏幕 display_frame = cv2.resize(annotated_frame, (width // 2, height // 2)) cv2.imshow('Pose Estimation', display_frame) key = cv2.waitKey(1) & 0xFF if key == ord('q') or key == 27: # q或ESC退出 break elif key == ord(' '): # 空格暂停 cv2.waitKey(0) frame_count += 1 if frame_count % 30 == 0: avg_time = np.mean(processing_times[-30:]) print(f"已处理: {frame_count}/{total_frames} 帧, 平均推理时间: {avg_time * 1000:.1f}ms") # 释放资源 cap.release() out.release() cv2.destroyAllWindows() # 保存关键点数据 if save_keypoints and keypoints_file: with open(keypoints_file, 'w') as f: json.dump(all_keypoints_data, f, indent=2) print(f"关键点数据保存至: {keypoints_file}") # 统计信息 total_time = time.time() - start_time avg_time = np.mean(processing_times) if processing_times else 0 avg_fps = 1 / avg_time if avg_time > 0 else 0 print("\n=== 处理完成 ===") print(f"总处理时间: {total_time:.2f}s") print(f"平均推理时间: {avg_time * 1000:.1f}ms") print(f"平均FPS: {avg_fps:.1f}") print(f"结果保存至: {output_path}") return str(output_path) def process_video(self, input_path, output_path=None, show_preview=True, save_keypoints=False, keypoints_file=None, max_people=None): cap = cv2.VideoCapture(str(input_path)) if not cap.isOpened(): print(f"无法打开视频: {input_path}") return # 获取视频属性 fps = int(cap.get(cv2.CAP_PROP_FPS)) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 设置输出视频 if output_path is None: input_path_obj = Path(input_path) output_path = input_path_obj.parent / f"{input_path_obj.stem}_pose_advanced.mp4" fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(str(output_path), fourcc, fps, (width, height)) # 准备保存关键点数据 all_keypoints_data = [] print(f"开始处理视频: {input_path}") print(f"总帧数: {total_frames}") frame_count = 0 start_time = time.time() processing_times = [] while True: ret, frame = cap.read() if not ret: break frame=frame[150:-50, 230:-150, :] frame=cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 推理 frame_start = time.time() results = self.model.predict(frame, conf=self.conf_threshold, verbose=False) frame_time = time.time() - frame_start processing_times.append(frame_time) # 获取关键点 annotated_frame = frame.copy() frame_people_data = [] if len(results) > 0 and results[0].keypoints is not None: keypoints_all = results[0].keypoints.data.cpu().numpy() # 限制检测人数 if max_people is not None and len(keypoints_all) > max_people: keypoints_all = keypoints_all[:max_people] print(f"帧 {frame_count}: 检测到 {len(keypoints_all)} 个人") # 调试信息 # 处理每个人 for person_idx, keypoints in enumerate(keypoints_all): kps = keypoints[:, :2] # x, y坐标 scores = keypoints[:, 2] # 置信度 # 为每个人使用不同的颜色 color = self.get_person_color(person_idx) # 绘制姿态 annotated_frame = self.draw_pose_with_color(annotated_frame, kps, scores, show_confidence=False, color=color) # 保存关键点数据 if save_keypoints: person_data = {'person_id': person_idx, 'keypoints': kps.tolist(), 'scores': scores.tolist()} frame_people_data.append(person_data) # 保存帧数据 if save_keypoints and frame_people_data: all_keypoints_data.append({'frame': frame_count, 'people': frame_people_data}) # 添加帧信息 cv2.putText(annotated_frame, f"Frame: {frame_count}/{total_frames}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 2) # cv2.putText(annotated_frame, # f"People: {len(keypoints_all) if len(results) > 0 and results[0].keypoints is not None else 0}", # (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) # 写入输出视频 # out.write(annotated_frame) # 显示预览 if show_preview: # 缩放显示以适应屏幕 display_frame = cv2.resize(annotated_frame, (width // 1, height // 1)) cv2.imshow('Pose Estimation', display_frame) key = cv2.waitKey(1) & 0xFF if key == ord('q') or key == 27: # q或ESC退出 break elif key == ord(' '): # 空格暂停 cv2.waitKey(0) frame_count += 1 if frame_count % 30 == 0: avg_time = np.mean(processing_times[-30:]) print(f"已处理: {frame_count}/{total_frames} 帧, 平均推理时间: {avg_time * 1000:.1f}ms") # 释放资源 cap.release() out.release() cv2.destroyAllWindows() # 保存关键点数据 if save_keypoints and keypoints_file: with open(keypoints_file, 'w') as f: json.dump(all_keypoints_data, f, indent=2) print(f"关键点数据保存至: {keypoints_file}") # 统计信息 total_time = time.time() - start_time avg_time = np.mean(processing_times) if processing_times else 0 avg_fps = 1 / avg_time if avg_time > 0 else 0 print("\n=== 处理完成 ===") print(f"总处理时间: {total_time:.2f}s") print(f"平均推理时间: {avg_time * 1000:.1f}ms") print(f"平均FPS: {avg_fps:.1f}") print(f"结果保存至: {output_path}") return str(output_path) def get_person_color(self, person_idx): """为不同的人分配不同的颜色""" colors = [(0, 255, 0), # 绿色 (255, 0, 0), # 蓝色 (0, 0, 255), # 红色 (255, 255, 0), # 青色 (255, 0, 255), # 品红 (0, 255, 255), # 黄色 (128, 0, 128), # 紫色 (0, 128, 128), # 深青色 ] return colors[person_idx % len(colors)] def draw_pose_with_color(self, frame, keypoints, scores, show_confidence=True, color=(0, 255, 0)): """在帧上绘制姿态关键点和骨骼,使用指定颜色""" img_copy = frame.copy() # 绘制骨骼 for pair in self.skeleton: p1 = keypoints[pair[0]] p2 = keypoints[pair[1]] s1 = scores[pair[0]] s2 = scores[pair[1]] if s1 > self.conf_threshold and s2 > self.conf_threshold: cv2.line(img_copy, (int(p1[0]), int(p1[1])), (int(p2[0]), int(p2[1])), color, 2) # 绘制关键点 for i, (kp, score) in enumerate(zip(keypoints, scores)): if score > self.conf_threshold: x, y = int(kp[0]), int(kp[1]) # 绘制圆点 cv2.circle(img_copy, (x, y), 2, color, -1) # 显示置信度 if show_confidence: cv2.putText(img_copy, f"{score:.2f}", (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1) return img_copy # 使用示例 if __name__ == "__main__": # 初始化处理器 processor = PoseVideoProcessor(model_path="yolo26x-pose.pt", conf_threshold=0.05) # 处理视频 processor.process_video(input_path=r"C:\Users\Administrator\Videos\yumao\yumao.mp4", output_path="output_video.mp4", show_preview=True, save_keypoints=True, keypoints_file="keypoints_data.json")
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/28 1:41:19

粉笔直播课vsB站免费课突破瓶颈效率对比

公考备考进入中后期&#xff0c;很多考生会撞上"瓶颈期"&#xff1a;行测分数卡在60分上下波动&#xff0c;申论提分乏力&#xff0c;刷题量持续增加但正确率不见起色。这一阶段&#xff0c;单靠自学往往难以诊断问题症结&#xff0c;外部学习资源的介入成为多数人的…

作者头像 李华
网站建设 2026/7/28 1:39:55

【JAVA毕设源码分享】基于springboot结合人脸识别和实名认证的校园论坛系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/28 1:36:23

BMS量产方案:模块化设计与自动化测试实践

1. BMS量产方案概述&#xff1a;从实验室到工厂的关键跨越BMS&#xff08;电池管理系统&#xff09;作为新能源领域的核心部件&#xff0c;其量产落地一直是行业痛点。我们团队历时18个月打磨的这套量产方案&#xff0c;已经成功应用于3家动力电池企业的生产线&#xff0c;单线…

作者头像 李华
网站建设 2026/7/28 1:35:02

TI bq27542-G1阻抗跟踪电量计EVM:从硬件连接到精准校准的完整指南

1. 项目概述与核心价值如果你正在开发一款依赖单节锂离子电池供电的产品&#xff0c;比如便携式医疗设备、高端无线耳机或者智能门锁&#xff0c;那么最让你头疼的问题之一&#xff0c;可能就是如何准确地向用户报告剩余电量。你肯定遇到过这种情况&#xff1a;设备明明显示还有…

作者头像 李华
网站建设 2026/7/28 1:34:26

如何用ILLA Builder在15分钟内构建企业级管理后台

如何用ILLA Builder在15分钟内构建企业级管理后台 【免费下载链接】illa-builder Low-code platform allows you to build business apps, enables you to quickly create internal tools such as dashboard, crud app, admin panel, crm, cms, etc. Supports PostgreSQL, MySQ…

作者头像 李华