Mediapipe人体识别库

news2024/11/26 18:36:07

一、简介

官网:MediaPipe  |  Google for Developershttps://developers.google.cn/mediapipe

Mediapipe 是2012年起开始公司内部使用,2019年google的一个开源项目,可以提供开源的、跨平台的常用机器学习(machine learning)方案。Mediapipe实际上是一个集成的机器学习视觉算法的工具库,包含了人脸检测、人脸关键点、手势识别、头像分割和姿态识别等各种模型。

  • Github开源项目地址: GitHub - google/mediapipe: Cross-platform, customizable ML solutions for live and streaming media.
  • 一些模型的web体验地址(用到电脑摄像头):
   人脸检测:https://code.mediapipe.dev/codepen/face_detection
   人脸关键点:https://code.mediapipe.dev/codepen/face_mesh
   手势识别:https://code.mediapipe.dev/codepen/hands
   姿态识别:https://code.mediapipe.dev/codepen/pose
   自拍头像分割:https://code.mediapipe.dev/codepen/selfie_segmentation

二、安装

2.1安装OpenCV

pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple

 2.2安装Mediapipe

pip install mediapipe -i  https://pypi.tuna.tsinghua.edu.cn/simple

2.3原理

将Mediapipe用于行为检测是比较复杂的一件事;如果这样做,那么行为检测的精度就完全取决于Mediapipe关键点的检测精度。于是可以根据下图中人的关节夹角来对人的位姿进行检测。

 先看一下效果图:

 2.4夹角计算

已知两点A(x1,y1),B(x2,y2),则向量AB=\vec{a}=(x2-x1,y2-y1)

即向量AB为B点坐标减A点坐标。

假设两个向量a=(x1,y1),b=(x2,y2),两个向量之间的夹角为θ,根据向量数量积的运算规则,可以很方便地用坐标值表示夹角的余弦值:

2.5姿势界标

随便取一个点,比如32:

32 x: 0.506013035774231
y: 3.0955116748809814
z: 0.06963550299406052
visibility: 9.286402200814337e-05

  • x和y:这些界标坐标分别通过图像的宽度和高度归一化为[0.0,1.0]。

  • z:通过将臀部中点处的深度作为原点来表示界标深度,并且z值越小,界标与摄影机越近。z的大小几乎与x的大小相同。

  • 可见性:[0.0,1.0]中的值,指示界标在图像中可见的可能性。

三、参数设置

Pose:

def __init__(self,
               static_image_mode=False,#如果设置为false,则解决方案将输入图像视为视频流。它将尝试在第一张图像中检测最突出的人,并在成功检测后进一步定位姿势和其他地标。在随后的图像中,它只是简单地跟踪那些地标,而不会调用另一个检测,直到它失去跟踪,以减少计算和延迟。如果设置为true,则人物检测会运行每个输入图像,非常适合处理一批静态的、可能不相关的图像。默认为false.
               model_complexity=1,#姿势地标模型的复杂度:0,1或2。地标准确性以及推理延迟通常随模型复杂性而增加。默认为1.
               smooth_landmarks=True,#如果设置为true,解决方案过滤器会在不同的输入图像之间设置地标以减少抖动,但如果static_image_mode也设置为,则忽略true。默认为true.
               enable_segmentation=False,#如果设置为true,除了姿势、面部和手部地标之外,该解决方案还会生成分割掩码。默认为false.
               smooth_segmentation=True,#如果设置为true,该解决方案会过滤不同输入图像的分割掩码以减少抖动。如果enable_segmentation为false或static_image_mode为 ,则忽略true。默认为true.
               min_detection_confidence=0.5,#[0.0, 1.0]来自人员检测模型的最小置信值 ( ),用于将检测视为成功。默认为0.5.
               min_tracking_confidence=0.5):#[0.0, 1.0]来自地标跟踪模型的最小置信值(将其设置为更高的值可以提高解决方案的稳健性,但代价是更高的延迟。如果static_image_mode是true,则忽略,其中人员检测仅在每个图像上运行。默认为0.5.
	void cv::putText(
		cv::Mat& img, // 待绘制的图像
		const string& text, // 待绘制的文字
		cv::Point origin, // 文本框的左下角
		int fontFace, // 字体 (如cv::FONT_HERSHEY_PLAIN)
		double fontScale, // 尺寸因子,值越大文字越大
		cv::Scalar color, // 线条的颜色(RGB)
		int thickness = 1, // 线条宽度
		int lineType = 8, // 线型(4邻域或8邻域,默认8邻域)
		bool bottomLeftOrigin = false // true='origin at lower left'
	);

四、向量的夹角

def np_pi(arr):
    """
    三个坐标A B  C ,B为关联
    [A 0,0  0,1
     B 1,0  1,1
     C 2,0  2,1]
    :param arr:
    :return:
    """
    b_a = np.array([arr[0][0] - arr[1][0], arr[0][1] - arr[1][1]])
    # print('向量1:{},{}'.format(b_a[0], b_a[1]))
    b_c = np.array([arr[2][0] - arr[1][0], arr[2][1] - arr[1][1]])
    # print('向量2:{},{}'.format(b_c[0], b_c[0]))
    cos_angle = np.dot(b_a, b_c) / (np.linalg.norm(b_a) * np.linalg.norm(b_c))
    # 弧度
    angle = np.arccos(cos_angle)
    # 角度
    angle = angle * 180 / np.pi
    # print('夹角为:',angle , '度')
    return angle

五、实现

例子:仰卧起坐

import cv2
import mediapipe as mp
import numpy as np


def np_pi(arr):
    """
    三个坐标A B  C ,B为关联
    [A 0,0  0,1
     B 1,0  1,1
     C 2,0  2,1]
    :param arr:
    :return:
    """
    b_a = np.array([arr[0][0] - arr[1][0], arr[0][1] - arr[1][1]])
    # print('向量1:{},{}'.format(b_a[0], b_a[1]))
    b_c = np.array([arr[2][0] - arr[1][0], arr[2][1] - arr[1][1]])
    # print('向量2:{},{}'.format(b_c[0], b_c[0]))
    cos_angle = np.dot(b_a, b_c) / (np.linalg.norm(b_a) * np.linalg.norm(b_c))
    # 弧度
    angle = np.arccos(cos_angle)
    # 角度
    angle = angle * 180 / np.pi
    # print('夹角为:',angle , '度')
    return angle


if __name__ == '__main__':

    # 获取视频对象,0为摄像头,也可以写入视频路径
    capture = cv2.VideoCapture(0)
    mpPose = mp.solutions.pose  # 姿态识别
    pose_mode = mpPose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5)  # 模式参数设置
    mpDraw = mp.solutions.drawing_utils  # 绘图
    biaoji = 0
    i = 0
    # mpPose.POSE_CONNECTIONS
    POSE_CONNECTIONS = frozenset([(11, 23), (23, 25), (12, 24), (24, 26)])
    # results.pose_landmarks

    while True:
        # sucess是布尔型,读取帧正确返回True;img是每一帧的图像(BGR存储格式)
        sucess, frame = capture.read()
        # BGR-通常用于图像处理应用程序,顺序为蓝色、绿色和红色。
        # RGB-通常用于图像编辑和显示应用程序,顺序为红色、绿色和蓝色。
        # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        #
        frame = cv2.flip(
            frame,
            1  # 1:水平镜像,-1:垂直镜像 =0,垂直翻转图像
        )
        # 输出图像,第一个为窗口名字
        # imshow = cv2.imshow('PC Camera', frame)
        results = pose_mode.process(frame)
        landmarks = results.pose_landmarks
        if results.pose_landmarks:
            # 右 11-23-25
            point23_11 = []
            point23_25 = []
            # 左 12-24-26
            point24_12 = []
            point24_26 = []
            landmarks = []
            z_11 = 0
            z_12 = 0
            point29 = []
            point30 = []
            for id, lm in enumerate(results.pose_landmarks.landmark):
                # print(id, lm)
                h, w, c = frame.shape
                # 转换成像素点坐标
                cx, cy = int(lm.x * w), int(lm.y * h)
                # cv2.circle(frame, (cx, cy), 0, (255, 0, 0), -1)  # 骨连接处
                if id in [23, 25]:
                    point23_25.append([cx, cy])
                elif id in [11]:
                    point23_11.append([cx, cy])
                    z_11 = lm.z
                elif id in [24, 26]:
                    point24_26.append([cx, cy])
                elif id in [12]:
                    point24_12.append([cx, cy])
                    z_12 = lm.z
                elif id in [29]:
                    point29.append([cx, cy])
                elif id in [30]:
                    point30.append([cx, cy])
            mpDraw.draw_landmarks(frame, landmarks, POSE_CONNECTIONS)
            # 判断远近
            # 11-12
            # 左肩 11, 左脚跟 29
            if (z_12 > z_11):
                cv2.line(frame, (point23_25[0][0], point23_25[0][1]), (point23_25[1][0], point23_25[1][1]), (0, 0, 255),
                         5)
                cv2.line(frame, (point23_25[0][0], point23_25[0][1]), (point23_11[0][0], point23_11[0][1]), (0, 0, 255),
                         5)
                array = np.array([[point23_25[1][0], point23_25[1][1]],  # 25
                                  [point23_25[0][0], point23_25[0][1]],  # 23
                                  [point23_11[0][0], point23_11[0][1]]  # 11
                                  ])
                pi_left = np_pi(array)  # 腰-腿的夹角
                np_array = np.array(
                    [[0, 0], [point23_11[0][0], point23_11[0][1]], [point23_25[0][0], point23_25[0][1]]])
                pi_flag_left = np_pi(np_array)
                if (pi_flag_left < 60):
                    if biaoji == 1:
                        i += 1
                        biaoji = 0
                        cv2.putText(frame, "count:{}".format(i), (10, 50), cv2.FONT_HERSHEY_PLAIN, 3, (0, 0, 255), 3)
                else:
                    biaoji = 1
                    cv2.putText(frame, "count:{}".format(i), (10, 450), cv2.FONT_HERSHEY_PLAIN, 3, (0, 0, 255), 3)

           
        # "姿态识别".encode("gbk").decode('UTF-8', errors='ignore')
        # cv2.namedWindow("Pose", cv2.WINDOW_NORMAL)
        cv2.imshow('Pose', frame)
        # 等待5秒显示图像,若过程中按“Esc”(key=27)退出
        c = cv2.waitKey(5) & 0xff
        if c == 27:
            # 释放所有窗口
            cv2.destroyAllWindows()
            break

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/585665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python-sqlite3使用指南

python下sqlite3使用指南 文章目录 python下sqlite3使用指南开发环境sqlite3常用APICRUD实例参考 开发环境 vscode ​ 开发语言&#xff1a; python vscode SQLite插件使用方法&#xff1a; 之后在这里就可以发现可视化数据&#xff1a; sqlite3常用API Python 2.5.x 以上…

信息安全实践1.3(HTTPS)

前言 做这个实验对Tomcat的版本有要求&#xff0c;最好是使用Tomcat8。因为我之前使用Tomcat10&#xff0c;然后一直做不出来。 要求 部署Web服务器端HTTPS功能&#xff0c;通过网络嗅探分析HTTPS通过SSL实施安全保护的效果 关键步骤 首先要给tomcat配置https&#xff0c;也…

设计模式之美-实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?

领域驱动设计&#xff08;Domain Driven Design&#xff0c;简称DDD&#xff09;盛行之后&#xff0c;这种基于贫血模型的传统的开发模式就更加被人诟病。而基于充血模型的DDD开发模式越来越被人提倡。所以&#xff0c;我打算用两节课的时间&#xff0c;结合一个虚拟钱包系统的…

超低功耗三通道低频无线唤醒ASK接收 125k soc芯片UM2082F08

UM2082F08 是基于单周期 8051 内核的超低功耗 8 位、、具有三通道低频无线唤醒 ASK 接收功能的 SOC 芯片。芯片可检测 30KHz~300KHz 范围的 LF&#xff08;低频&#xff09;载波频率数据并触发唤醒信号&#xff0c;同时可以调节接收灵敏度&#xff0c;确保在各种应用环境下实现…

代码随想录算法训练营15期 Day 6 | 242.有效的字母异位词 、349. 两个数组的交集 、202. 快乐数、1. 两数之和

由于昨天是周日&#xff0c;周日是休息日&#xff0c;所以就是什么也没有写啦。今天是day06天&#xff0c;继续加油。 哈希表理论基础 建议&#xff1a;大家要了解哈希表的内部实现原理&#xff0c;哈希函数&#xff0c;哈希碰撞&#xff0c;以及常见哈希表的区别&#xff0c;…

Toolkit.getDefaultToolkit()获得的java.awt.Toolkit是不是同一个? 是否为单例设计模式?答案是**是**

Toolkit.getDefaultToolkit()获得的java.awt.Toolkit是不是同一个? 是否为单例设计模式? 答案是是 反复调用Toolkit.getDefaultToolkit()获得的 java.awt.Toolkit 是同一个 import java.awt.Toolkit;public class GetDefaultToolkit是不是获得单例Toolkit {static public …

【P43】JMeter 吞吐量控制器(Throughput Controller)

文章目录 一、吞吐量控制器&#xff08;Throughput Controller&#xff09;参数说明二、测试计划设计2.1、Total Executions2.2、Percent Executions2.3、Per User 一、吞吐量控制器&#xff08;Throughput Controller&#xff09;参数说明 允许用户控制后代元素的执行的次数。…

中级软件设计师考试总结

目录 前言考前学习宏观什么是软考涉及的知识范围软考整体导图总结 微观我的分享——希尔排序学习过程结构化做题 考试阶段确定不确定 考后总结 前言 作为一名中级软件设计师&#xff0c;考试是衡量自己技能和水平的一项重要指标。在备考和考试过程中&#xff0c;我通过总结经验…

【TI毫米波雷达笔记】IWR6843AOPEVM-G的DCA1000EVM模式配置及避坑(官方手册有误)

【TI毫米波雷达笔记】IWR6843AOPEVM-G的DCA1000EVM模式配置及避坑&#xff08;官方手册有误&#xff09; IWR6843AOPEVM-G版本可以直接与DCA1000EVM连接 进行数据获取 不需要连接MMWAVEICBOOST版 直接使用 DCA1000mmWave Studio 软件进行数据采集 在官方手册中 User’s Guide…

linux环境下安装gitlab

前几天跟朋友聊天时说到gitlab版本控制。其实&#xff0c;之前也对它只是知道有这个东西&#xff0c;也会用。只是对于它的安装和配置&#xff0c;那我还是没整过。这两天&#xff0c;我找了一下网上的资料&#xff0c;还是写下吧。 一安装&#xff1a; 按网上所说&#xff0c;…

2023年上半年信息系统项目管理师下午真题及答案解析

试题一(25分) 为实现空气质量的精细化治理&#xff0c;某市规划了智慧环保项目。该项目涉及网格化监测、应急管理、执法系统等多个子系统。作为总集成商&#xff0c;A公司非常重视&#xff0c;委派李经理任项目经理&#xff0c;对公司内研发部门与项目相关的各产品线研发人员及…

带你开发一个远程控制项目---->STM32+标准库+阿里云平台+传感器模块+远程显示-------之 阿里云平台项目建造。

第一篇章&#xff1a; (13条消息) 带你开发一个远程控制项目----&#xff1e;STM32标准库阿里云平台传感器模块远程显示。_海口飞鹏岛科技有限公司的博客-CSDN博客 本次文章是指引开发者进行开发阿里云平台建造设备项目&#xff0c;可观看UP主教程&#xff0c;完成如下&#x…

今天面了一个9个月测试经验的人,开口就跟我要18K,我都愣住了....

2月初我入职了深圳某家创业公司&#xff0c;刚入职还是很兴奋的&#xff0c;到公司一看我傻了&#xff0c;公司除了我一个测试&#xff0c;公司的开发人员就只有3个前端2个后端还有2个UI&#xff0c;在粗略了解公司的业务后才发现是一个从零开始的项目&#xff0c;目前啥都没有…

测试之路,你知道这些变化吗?突破后助你走得更远...

前言 Python自动化测试&#xff1a;7天练完这60个实战项目&#xff0c;年薪过35w。 目前的面试求职市场上&#xff0c;测试领域有哪些变化&#xff1f; 以这两年软件测试发展经历来看&#xff0c;现在的求职市场&#xff0c;已经不仅仅只考察个人的项目经验和技术能力了&#…

十五、多线程(上)

文章目录 一、线程&#xff08;一&#xff09;什么是线程&#xff08;二&#xff09;Linux下的多线程&#xff08;三&#xff09;总结&#xff08;四&#xff09;线程优点&#xff08;五&#xff09;线程缺点&#xff08;六&#xff09;线程异常&#xff08;七&#xff09;线程…

字节跳动测试开发岗 3+1 面经+经验分享(收到offer,入职月薪27K)

现在&#xff0c;招聘黄金时间已经过了&#xff0c;在网上看了很多大佬的面经&#xff0c;也加了很多交流群&#xff0c;受到了很多朋友的提点&#xff0c;今天终于轮到我来分享面经啦&#xff0c;之前面试了几家公司&#xff0c;最后在八月初拿到了字节跳动测试岗的 offer&…

数据结构 -- AVL树

1、定义 平衡搜索二叉树&#xff0c;相对于搜索二叉树而言&#xff0c;AVL树又多了一个性质&#xff1a;左右子树的高度差不大于1. 2、平衡因子&#xff0c;balance factor&#xff0c;以下简称bf&#xff0c;是左子树高度减去右子树的高度 bf > 1&#xff0c;左边子树高bf …

Java最新版发送阿里短信教程

一、概述&#xff1a; 为什么现在的企业越来越多使用阿里云短信服务&#xff0c;究其原因是阿里云短信服务是一种可靠、高效、安全的短信发送服务&#xff0c;它具有以下优点&#xff1a; 高可靠性&#xff1a;阿里云短信服务采用全球领先的短信网关进行短信发送&#xff0c;确…

自定义线程池

自定义线程池原理 线程池中分为核心线程和临时线程&#xff1b;首先创建核心线程使用&#xff0c;创建之后一直存在线程池&#xff0c;核心线程被占用并且队列任务已满&#xff0c;才会创建临时线程&#xff1b;临时线程使用超过自定义临时线程最大数时会触发自定义的任务拒绝策…

你猜,一个TCP连接能发多少HTTP请求?

又见面了&#xff0c;我的网工朋友 曾经有这么一道经典面试题&#xff1a;从 URL 在浏览器被被输入到页面展现的过程中发生了什么&#xff1f; 相信大多数准备过的同学都能回答出来&#xff0c;但是如果继续问&#xff1a; 收到的 HTML 如果包含几十个图片标签&#xff0c;这…