OpenCV 人体姿态检测实战指南

#新星杯·14天创作挑战营·第11期#

OpenCV 人体姿态检测实战指南

目录

  1. 简介
  2. 环境配置
  3. 基础知识
  4. 实现方案
  5. 代码实战
  6. 优化技巧
  7. 应用场景
  8. 常见问题

简介

人体姿态检测是计算机视觉中的一个重要任务,它可以识别和分析图片中人体的关键点位置,广泛应用于姿势分析、健康评估、运动指导等领域。本文将详细介绍如何使用 OpenCV 和 MediaPipe 实现图片中的人体姿态检测。

效果

输入图片
在这里插入图片描述
姿态检测效果图
在这里插入图片描述

技术栈

  • OpenCV:图像处理
  • MediaPipe:人体姿态检测模型
  • Python:编程语言
  • NumPy:数值计算

[在这里插入人体姿态检测效果图]
建议截图:展示检测到的人体关键点和骨架连接

环境配置

1. 安装必要的库

# requirements.txt
opencv-python==4.8.0
mediapipe==0.10.0
numpy==1.24.0

安装命令:

pip install -r requirements.txt

2. 基本环境检查

import cv2
import mediapipe as mp
import numpy as np

def 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 cv2
import mediapipe as mp
import numpy as np

class 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_list

def 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. 健康检查

    • 脊椎姿态评估
    • 站姿分析
    • 步态分析
  3. 人体测量

    • 人体尺寸测量
    • 体态评估
    • 姿势矫正

常见问题

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 的组合为实现图片中的人体姿态检测提供了强大的工具。通过本文的学习,你应该已经掌握了:

  1. 基础的姿态检测实现
  2. 关键点提取和分析
  3. 图片处理优化技巧
  4. 实际应用开发方法

建议在实践中:

  • 注意图片质量
  • 合理处理异常情况
  • 考虑性能优化
  • 结合实际应用需求
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值