OpenCV 人体姿态检测实战指南_opencv 检测人体上半身
OpenCV 人体姿态检测实战指南
目录
- 简介
- 环境配置
- 基础知识
- 实现方案
- 代码实战
- 优化技巧
- 应用场景
- 常见问题
简介
人体姿态检测是计算机视觉中的一个重要任务,它可以识别和分析图片中人体的关键点位置,广泛应用于姿势分析、健康评估、运动指导等地方。本文将详细介绍如何使用 OpenCV 和 MediaPipe 实现图片中的人体姿态检测。
效果
输入图片
姿态检测效果图
技术栈
- OpenCV:图像处理
- MediaPipe:人体姿态检测模型
- Python:编程语言
- NumPy:数值计算
[在这里插入人体姿态检测效果图]
建议截图:展示检测到的人体关键点和骨架连接
环境配置
1. 安装必要的库
# requirements.txtopencv-python==4.8.0mediapipe==0.10.0numpy==1.24.0
安装命令:
pip install -r requirements.txt
2. 基本环境检查
import cv2import mediapipe as mpimport numpy as npdef check_environment(): print(f\"OpenCV Version: {cv2.__version__}\") print(f\"MediaPipe Version: {mp.__version__}\") print(f\"NumPy Version: {np.__version__}\")check_environment()
基础知识
1. 人体关键点
MediaPipe Pose 模型可以检测 33 个人体关键点:
- 0-10:面部关键点
- 11-22:上半身关键点
- 23-32:下半身关键点
[在这里插入人体关键点示意图]
建议截图:标注好的人体关键点索引图
2. 坐标系统
- x, y:2D 图像坐标(像素)
- z:深度信息(相对值)
- visibility:可见性分数
- presence:存在性分数
实现方案
1. 基础实现
import cv2import mediapipe as mpimport numpy as npclass PoseDetector: def __init__(self, static_image_mode=True, model_complexity=1, smooth_landmarks=True, min_detection_confidence=0.5): \"\"\" 初始化姿态检测器 \"\"\" self.static_image_mode = static_image_mode self.model_complexity = model_complexity self.smooth_landmarks = smooth_landmarks self.min_detection_confidence = min_detection_confidence self.mp_pose = mp.solutions.pose self.pose = self.mp_pose.Pose( static_image_mode=self.static_image_mode, model_complexity=self.model_complexity, smooth_landmarks=self.smooth_landmarks, min_detection_confidence=self.min_detection_confidence ) self.mp_draw = mp.solutions.drawing_utils def find_pose(self, img, draw=True): \"\"\" 检测姿态并绘制关键点和连接线 \"\"\" img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) self.results = self.pose.process(img_rgb) if self.results.pose_landmarks: if draw: self.mp_draw.draw_landmarks( img, self.results.pose_landmarks, self.mp_pose.POSE_CONNECTIONS ) return img def find_position(self, img, draw=True): \"\"\" 获取所有关键点的位置 \"\"\" lm_list = [] if self.results.pose_landmarks: for id, lm in enumerate(self.results.pose_landmarks.landmark): h, w, c = img.shape cx, cy = int(lm.x * w), int(lm.y * h) lm_list.append([id, cx, cy, lm.visibility]) if draw: cv2.circle(img, (cx, cy), 5, (255, 0, 0), cv2.FILLED) return lm_list
2. 图片处理示例
def process_image(image_path): # 读取图片 img = cv2.imread(image_path) if img is None: raise ValueError(\"无法读取图片\") # 创建检测器 detector = PoseDetector() # 检测姿态 img = detector.find_pose(img) lm_list = detector.find_position(img) # 保存结果 output_path = \"output_\" + image_path.split(\"/\")[-1] cv2.imwrite(output_path, img) return lm_listdef main(): # 处理单张图片 image_path = \"example.jpg\" try: lm_list = process_image(image_path) print(f\"检测到 {len(lm_list)} 个关键点\") except Exception as e: print(f\"处理图片时出错: {str(e)}\")if __name__ == \"__main__\": main()
代码实战
1. 角度计算
def calculate_angle(self, point1, point2, point3): \"\"\" 计算三个点形成的角度 \"\"\" point1 = np.array(point1) point2 = np.array(point2) point3 = np.array(point3) radians = np.arctan2(point3[1]-point2[1], point3[0]-point2[0]) - \\ np.arctan2(point1[1]-point2[1], point1[0]-point2[0]) angle = np.abs(radians*180.0/np.pi) if angle > 180.0: angle = 360-angle return angle
2. 姿势分析示例
def analyze_pose(self, lm_list): \"\"\" 分析图片中的姿势 \"\"\" if len(lm_list) < 33: return \"未检测到姿势\" # 计算手臂角度 right_elbow_angle = self.calculate_angle( [lm_list[12][1:3]], # 右肩 [lm_list[14][1:3]], # 右肘 [lm_list[16][1:3]] # 右手腕 ) # 判断姿势 if right_elbow_angle > 150: return \"手臂伸展\" elif right_elbow_angle < 30: return \"手臂弯曲\" else: return \"中间位置\"
优化技巧
1. 性能优化
# 1. 调整图片大小def resize_image(image, max_size=1024): h, w = image.shape[:2] if max(h, w) > max_size: scale = max_size / max(h, w) new_size = (int(w * scale), int(h * scale)) return cv2.resize(image, new_size, interpolation=cv2.INTER_AREA) return image# 2. 使用GPU加速(如果可用)if cv2.cuda.getCudaEnabledDeviceCount() > 0: gpu_image = cv2.cuda_GpuMat()
2. 准确度优化
def enhance_image(image): \"\"\" 图像增强处理 \"\"\" # 亮度和对比度调整 alpha = 1.2 # 对比度 beta = 10 # 亮度 enhanced = cv2.convertScaleAbs(image, alpha=alpha, beta=beta) # 降噪 denoised = cv2.fastNlMeansDenoisingColored(enhanced) return denoised
应用场景
-
姿势评估
- 瑜伽姿势分析
- 运动姿势评估
- 体态分析
-
健康检查
- 脊椎姿态评估
- 站姿分析
- 步态分析
-
人体测量
- 人体尺寸测量
- 体态评估
- 姿势矫正
常见问题
1. 检测不准确
问题:姿态检测结果不准确
解决方案:
- 确保图片质量良好
- 调整图片亮度和对比度
- 选择合适的拍摄角度
2. 性能问题
问题:处理大图片速度慢
解决方案:
- 压缩图片尺寸
- 使用GPU加速
- 优化处理流程
3. 遮挡处理
问题:部分身体被遮挡时检测失败
解决方案:
- 选择更好的拍摄角度
- 确保光线充足
- 调整检测参数
进阶开发
1. 批量图片处理
def process_image_batch(image_dir): \"\"\" 批量处理图片 \"\"\" detector = PoseDetector() results = {} for image_file in os.listdir(image_dir): if image_file.lower().endswith((\'.png\', \'.jpg\', \'.jpeg\')): image_path = os.path.join(image_dir, image_file) try: img = cv2.imread(image_path) if img is None: continue # 处理图片 img = detector.find_pose(img) lm_list = detector.find_position(img) # 保存结果 output_path = os.path.join(\"output\", image_file) cv2.imwrite(output_path, img) results[image_file] = len(lm_list) except Exception as e: print(f\"处理 {image_file} 时出错: {str(e)}\") return results
2. 姿势分类
class PoseClassifier: def __init__(self): self.pose_detector = PoseDetector() self.pose_templates = {} def add_template(self, name, keypoints): \"\"\" 添加姿势模板 \"\"\" self.pose_templates[name] = keypoints def classify_pose(self, image): \"\"\" 对图片中的姿势进行分类 \"\"\" img = self.pose_detector.find_pose(image) lm_list = self.pose_detector.find_position(img) if not lm_list: return None # 计算与模板的相似度 return self.match_pose(lm_list)
结语
OpenCV 和 MediaPipe 的组合为实现图片中的人体姿态检测提供了强大的工具。通过本文的学习,你应该已经掌握了:
- 基础的姿态检测实现
- 关键点提取和分析
- 图片处理优化技巧
- 实际应用开发方法
建议在实践中:
- 注意图片质量
- 合理处理异常情况
- 考虑性能优化
- 结合实际应用需求