MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架,可以直接调用其API完成目标检测、人脸检测以及关键点检测等。本篇文章介绍其手部21个关键点检测(win10,python版)
MediaPipe官网:https://github.com/google/mediapipe
MediaPipe说明文档

安装mediapipe

pip install mediapipe

创建手部检测模型

import cv2
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=True,max_num_hands=2,min_detection_confidence=0.75,min_tracking_confidence=0.5)
hands = mp_hands.Hands(static_image_mode=False,max_num_hands=2,min_detection_confidence=0.75,min_tracking_confidence=0.5)

hands是检测手部关键点的函数,其中有4个输入参数量可以选择

1、static_image_mode:默认为False,如果设置为false, 就是把输入看作一个视频流,在检测到手之后对手加了一个目标跟踪(目标检测+跟踪),无需调用另一次检测,直到失去对任何手的跟踪为止。如果设置为True,则手部检测将在每个输入图像上运行(目标检测),非常适合处理一批静态的,可能不相关的图像。(如果检测的是图片就要设置成True)

2、max_num_hands:可以检测到的手的数量最大值,默认是2

3、min_detection_confidence: 手部检测的最小置信度值,大于这个数值被认为是成功的检测。默认为0.5

4、min_tracking_confidence:目标踪模型的最小置信度值,大于这个数值将被视为已成功跟踪的手部,默认为0.5,如果static_image_mode设置为true,则忽略此操作。

结果输出

results = hands.process(frame)
print(results.multi_handedness)
print(results.multi_hand_landmarks)

results.multi_handedness: 包括label和score,label是字符串"Left"或"Right",score是置信度

results.multi_hand_landmarks: 手部21个关键点的位置信息,包括x,y,z 其中x,y是归一化后的坐标。z代表地标深度,以手腕处的深度为原点,值越小,地标就越靠近相机(我暂时也不清楚啥意思)

视频检测代码

import cv2
import mediapipe as mpmp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False,max_num_hands=2,min_detection_confidence=0.75,min_tracking_confidence=0.75)cap = cv2.VideoCapture(0)
while True:ret,frame = cap.read()frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)# 因为摄像头是镜像的,所以将摄像头水平翻转# 不是镜像的可以不翻转frame= cv2.flip(frame,1)results = hands.process(frame)frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)if results.multi_handedness:for hand_label in results.multi_handedness:print(hand_label)if results.multi_hand_landmarks:for hand_landmarks in results.multi_hand_landmarks:print('hand_landmarks:' hand_landmarks)# 关键点可视化mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)cv2.imshow('MediaPipe Hands', frame)if cv2.waitKey(1) & 0xFF == 27:break
cap.release()

关键点识别结果

手势识别

通过对检测到的手部关键点之间的角度计算便可以实现简单的手势识别(有局限性),比如计算大拇指向量0-2和3-4之间的角度,它们之间的角度大于某一个角度阈值(经验值)定义为弯曲,小于某一个阈值(经验值)为伸直。

加入手势判别完整代码

import cv2
import mediapipe as mp
import mathdef vector_2d_angle(v1,v2):'''求解二维向量的角度'''v1_x=v1[0]v1_y=v1[1]v2_x=v2[0]v2_y=v2[1]try:angle_= math.degrees(math.acos((v1_x*v2_x+v1_y*v2_y)/(((v1_x**2+v1_y**2)**0.5)*((v2_x**2+v2_y**2)**0.5))))except:angle_ =65535.if angle_ > 180.:angle_ = 65535.return angle_
def hand_angle(hand_):'''获取对应手相关向量的二维角度,根据角度确定手势'''angle_list = []#---------------------------- thumb 大拇指角度angle_ = vector_2d_angle(((int(hand_[0][0])- int(hand_[2][0])),(int(hand_[0][1])-int(hand_[2][1]))),((int(hand_[3][0])- int(hand_[4][0])),(int(hand_[3][1])- int(hand_[4][1]))))angle_list.append(angle_)#---------------------------- index 食指角度angle_ = vector_2d_angle(((int(hand_[0][0])-int(hand_[6][0])),(int(hand_[0][1])- int(hand_[6][1]))),((int(hand_[7][0])- int(hand_[8][0])),(int(hand_[7][1])- int(hand_[8][1]))))angle_list.append(angle_)#---------------------------- middle 中指角度angle_ = vector_2d_angle(((int(hand_[0][0])- int(hand_[10][0])),(int(hand_[0][1])- int(hand_[10][1]))),((int(hand_[11][0])- int(hand_[12][0])),(int(hand_[11][1])- int(hand_[12][1]))))angle_list.append(angle_)#---------------------------- ring 无名指角度angle_ = vector_2d_angle(((int(hand_[0][0])- int(hand_[14][0])),(int(hand_[0][1])- int(hand_[14][1]))),((int(hand_[15][0])- int(hand_[16][0])),(int(hand_[15][1])- int(hand_[16][1]))))angle_list.append(angle_)#---------------------------- pink 小拇指角度angle_ = vector_2d_angle(((int(hand_[0][0])- int(hand_[18][0])),(int(hand_[0][1])- int(hand_[18][1]))),((int(hand_[19][0])- int(hand_[20][0])),(int(hand_[19][1])- int(hand_[20][1]))))angle_list.append(angle_)return angle_listdef h_gesture(angle_list):'''# 二维约束的方法定义手势# fist five gun love one six three thumbup yeah'''thr_angle = 65.thr_angle_thumb = 53.thr_angle_s = 49.gesture_str = Noneif 65535. not in angle_list:if (angle_list[0]>thr_angle_thumb) and (angle_list[1]>thr_angle) and (angle_list[2]>thr_angle) and (angle_list[3]>thr_angle) and (angle_list[4]>thr_angle):gesture_str = "fist"elif (angle_list[0]<thr_angle_s) and (angle_list[1]<thr_angle_s) and (angle_list[2]<thr_angle_s) and (angle_list[3]<thr_angle_s) and (angle_list[4]<thr_angle_s):gesture_str = "five"elif (angle_list[0]<thr_angle_s)  and (angle_list[1]<thr_angle_s) and (angle_list[2]>thr_angle) and (angle_list[3]>thr_angle) and (angle_list[4]>thr_angle):gesture_str = "gun"elif (angle_list[0]<thr_angle_s)  and (angle_list[1]<thr_angle_s) and (angle_list[2]>thr_angle) and (angle_list[3]>thr_angle) and (angle_list[4]<thr_angle_s):gesture_str = "love"elif (angle_list[0]>5)  and (angle_list[1]<thr_angle_s) and (angle_list[2]>thr_angle) and (angle_list[3]>thr_angle) and (angle_list[4]>thr_angle):gesture_str = "one"elif (angle_list[0]<thr_angle_s)  and (angle_list[1]>thr_angle) and (angle_list[2]>thr_angle) and (angle_list[3]>thr_angle) and (angle_list[4]<thr_angle_s):gesture_str = "six"elif (angle_list[0]>thr_angle_thumb)  and (angle_list[1]<thr_angle_s) and (angle_list[2]<thr_angle_s) and (angle_list[3]<thr_angle_s) and (angle_list[4]>thr_angle):gesture_str = "three"elif (angle_list[0]<thr_angle_s)  and (angle_list[1]>thr_angle) and (angle_list[2]>thr_angle) and (angle_list[3]>thr_angle) and (angle_list[4]>thr_angle):gesture_str = "thumbUp"elif (angle_list[0]>thr_angle_thumb)  and (angle_list[1]<thr_angle_s) and (angle_list[2]<thr_angle_s) and (angle_list[3]>thr_angle) and (angle_list[4]>thr_angle):gesture_str = "two"return gesture_strdef detect():mp_drawing = mp.solutions.drawing_utilsmp_hands = mp.solutions.handshands = mp_hands.Hands(static_image_mode=False,max_num_hands=1,min_detection_confidence=0.75,min_tracking_confidence=0.75)cap = cv2.VideoCapture(0)while True:ret,frame = cap.read()frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)frame= cv2.flip(frame,1)results = hands.process(frame)frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)if results.multi_hand_landmarks:for hand_landmarks in results.multi_hand_landmarks:mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)hand_local = []for i in range(21):x = hand_landmarks.landmark[i].x*frame.shape[1]y = hand_landmarks.landmark[i].y*frame.shape[0]hand_local.append((x,y))if hand_local:angle_list = hand_angle(hand_local)gesture_str = h_gesture(angle_list)cv2.putText(frame,gesture_str,(0,100),0,1.3,(0,0,255),3)cv2.imshow('MediaPipe Hands', frame)if cv2.waitKey(1) & 0xFF == 27:breakcap.release()if __name__ == '__main__':detect()

手部21个关键点检测+手势识别-[MediaPipe]相关推荐

  1. OpenMMLab-AI实战营第二期——2-1.人体关键点检测与MMPose

    文章目录 1. 人体姿态估计的介绍和应用 2-1. 2D姿态估计概述 2.1 任务描述 2.2 基于回归 2.3 基于热力图 2.3.1 从数据标注生成热力图(高斯函数) 2.3.2 使用热力图训练模 ...

  2. 谷歌发布 MediaPipe Holistic,实现移动端同时进行人脸、手部和人体关键点检测跟踪...

    作者:Ivan Grishchenko & Valentin Bazarevsky 编译:CV君 谷歌MediaPipe Holistic为突破性的 540 多个关键点(33 个姿势.21 个 ...

  3. 更稳定的手势识别方法-基于手部骨架与关键点检测

    导读 本期将介绍并演示基于MediaPipe的手势骨架与特征点提取步骤以及逐步为基础实现手势识别的方法. 介绍 关于MediaPipe以前有相关文章介绍,可以参见以下链接: Google开源手势识别- ...

  4. 更稳定的手势识别方法--基于手部骨架与关键点检测

    导读 本期将介绍并演示基于MediaPipe的手势骨架与特征点提取步骤以及以此为基础实现手势识别的方法. 介绍 关于MediaPipe以前有相关文章介绍,可以参看下面链接: Google开源手势识别- ...

  5. OpenCV手部关键点检测(手势识别)代码示例

    点击我爱计算机视觉标星,更快获取CVML新技术 前几日分享了learnopencv.com博主Satya Mallick发表的关于OpenCV Mask RCNN实例分割的博文(详见:OpenCV4. ...

  6. MediaPipe人体姿态、手指关键点检测

    MediaPipe人体姿态.手指关键点检测 文章目录 MediaPipe人体姿态.手指关键点检测 前言 一.手指关键点检测 二.姿态检测 三.3D物体案例检测案例 前言 Mediapipe是googl ...

  7. Mediapipe人脸关键点检测

    Mediapipe人脸关键点检测 Mediapipe介绍 环境部署 人脸关键点检测 模型调用与配置 输出结果解析 绘制面网 视频演示 Mediapipe介绍 MediaPipe是由google制作的开 ...

  8. 9月6日关键点检测学习笔记——人脸和手部特征点检测

    文章目录 前言 一.干扰因素 1.主动因素 2.固有因素 二.特征点检测 1.PFLD 2.LLCV 三.人脸比对 1.人脸 1:1 2.人脸 1:n 3.人脸 1:N 4.人脸 M:N 四.高清分辨 ...

  9. opencv 图像雾检测_OpenCV图像处理-基于OpenPose的关键点检测

    OpenCV基于OpenPose的手部关键点检测 概述 ✔️ 手部关键点检测,旨在找出给定图片中手指上的关节点及指尖关节点, 其中手部关键点检测的应用场景主要包括: 手势识别 手语识别与理解 手部的行 ...

最新文章

  1. .NET Core微服务之路:不断更新中的目录 (v0.42)
  2. 丁钧:移动,未来的王
  3. Java输出彩色字符
  4. C# 9.0中引入的新特性init和record的使用思考
  5. webpack联邦模块之webpack运行时
  6. WebViewJavascriptBridge 进行js 与native通信。
  7. javascript高级编程笔记04(基本概念)
  8. 设置服务器网站播放flv视频文件,网页制作 flvplayer.swf无法播放服务器上flv文件 如何设置...
  9. ubuntu ffmpeg 录制系统音频
  10. 拟合程度的评估--判定系数
  11. 编译调试 chromium/v8
  12. 用光盘怎样重装电脑系统
  13. Android 截屏并保存到本地(兼容Android 10.0)
  14. matlab用()括住字符串,在matlab中( )用于括住字符串.
  15. 普中tft彩屏驱动程序下载_tft彩屏驱动程序
  16. zcmu oj 1087: 统计字符
  17. SqlHelper的使用
  18. C++中的system(pause);
  19. python中将数据写入excel
  20. 摘录《事实》汉斯·罗斯林

热门文章

  1. 基于Linux的主存空间分配与回收
  2. 未来有事如何?情感对于人工智能的重要性
  3. 【新手必读】微擎nbsp;微赞等系统…
  4. 腾讯云对象存储 COS 服务之 XML Python SDK 实践
  5. Python海象运算符的使用
  6. 程序设计与算法(三)第09周测验(2020春季)
  7. .$ajax{}请求成功,但是跳转到error,错误代码500
  8. JSON.prase()使用报错
  9. python-turtle画铜钱古币
  10. 哪里可以买到真正的华强北耳机呢?