各位同学好,今天和大家分享一下如何使用MediaPipe完成手部关键点实时检测跟踪。先放张图看效果,15代表FPS值


1. 导入工具包

# 安装opencv
pip install opencv-contrib-python
# 安装mediapipe
pip install mediapipe
# pip install mediapipe --user  #有user报错的话试试这个# 安装之后导入各个包
import cv2  #opencv
import mediapipe as mp
import time

MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架。它能够完成人脸识别,虹膜检测,体态跟踪等。今天我们介绍一下手部关键点检测,剩下的后续章节讲述,感兴趣的点个关注呦。


2. 显示手部关键点及连线

2.1 相关函数解释

(1)cv2.VideoCapture(0)  获取电脑自带的摄像头,修改参数1代表外接摄像头

(2)mediapipe.solutions.hands.Hands()  手部关键点检测方法

参数:

static_image_mode: 默认为 False,将输入图像视为视频流。它将尝试在第一个输入图像中检测手,并在成功检测后进一步定位手的坐标。在随后的图像中,一旦检测到所有 max_num_hands 手并定位了相应的手的坐标,它就会跟踪这些坐标,而不会调用另一个检测,直到它失去对任何一只手的跟踪。这减少了延迟,非常适合处理视频帧。如果设置为 True,则在每个输入图像上运行手部检测,用于处理一批静态的、可能不相关的图像。

max_num_hands: 最多检测几只手,默认为2

min_detection_confidence: 手部检测模型的最小置信值(0-1之间),超过阈值则检测成功。默认为 0.5

min_tracking_confidence: 坐标跟踪模型的最小置信值 (0-1之间),用于将手部坐标视为成功跟踪,不成功则在下一个输入图像上自动调用手部检测。将其设置为更高的值可以提高解决方案的稳健性,但代价是更高的延迟。如果 static_image_mode 为真,则忽略这个参数,手部检测将在每个图像上运行。默认为 0.5

返回值:

MULTI_HAND_LANDMARKS: 被检测/跟踪的手的集合,其中每只手被表示为21个手部地标的列表,每个地标由x, y, z组成。x和y分别由图像的宽度和高度归一化为[0,1]。Z表示地标深度。

MULTI_HANDEDNESS: 被检测/追踪的手是左手还是右手的集合。每只手由label(标签)score(分数)组成。 label 是 'Left' 或 'Right' 值的字符串。 score 是预测左右手的估计概率。

(3)mediapipe.solutions.drawing_utils.draw_landmarks()  绘制手部关键点的连线

参数: 

image: 需要画图的原始图片

landmark_list: 检测到的手部关键点坐标

connections: 连接线,需要把那些坐标连接起来

landmark_drawing_spec: 坐标的颜色,粗细

connection_drawing_spec: 连接线的粗细,颜色等

(4)手部标记点如图所示


2.2 只绘制手部关键点和连线

由于读入视频图像通道一般为RGB,而opencv中图像通道的格式为BGR,因此需要cv2.cvtColor()函数将opencv读入的视频图像转为RGB格式results中存放每个关键点的xyz坐标,通过.multi_hand_landmarks读取出来。

#(1)视频捕获
cap = cv2.VideoCapture(0)  # 0代表电脑自带的摄像头#(2)创建检测手部关键点的方法
mpHands = mp.solutions.hands  #接收方法
hands = mpHands.Hands(static_image_mode=False, #静态追踪,低于0.5置信度会再一次跟踪max_num_hands=2, # 最多有2只手min_detection_confidence=0.5, # 最小检测置信度min_tracking_confidence=0.5)  # 最小跟踪置信度 # 创建检测手部关键点和关键点之间连线的方法
mpDraw = mp.solutions.drawing_utils# 查看时间
pTime = 0 #处理一张图像前的时间
cTime = 0 #一张图处理完的时间#(3)处理视频图像
while True:  # 对每一帧视频图像处理# 返回是否读取成功和读取的图像success, img = cap.read()# 在循环中发送rgb图像到hands中,opencv中图像默认是BGR格式imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 把图像传入检测模型,提取信息results = hands.process(imgRGB)# 检查是否检测到什么东西了,没有检测到手就返回None# print(results.multi_hand_landmarks)# 检查每帧图像是否有多只手,一一提取它们if results.multi_hand_landmarks: #如果没有手就是Nonefor handlms in results.multi_hand_landmarks:# 绘制每只手的关键点mpDraw.draw_landmarks(img, handlms, mpHands.HAND_CONNECTIONS) #传入想要绘图画板img,单只手的信息handlms# mpHands.HAND_CONNECTIONS绘制手部关键点之间的连线# 记录执行时间      cTime = time.time()      # 计算fpsfps = 1/(cTime-pTime)# 重置起始时间pTime = cTime# 把fps显示在窗口上;img画板;取整的fps值;显示位置的坐标;设置字体;字体比例;颜色;厚度cv2.putText(img, str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,0), 3)# 显示图像cv2.imshow('Image', img)  #窗口名,图像变量if cv2.waitKey(1) & 0xFF==27:  #每帧滞留1毫秒后消失;ESC键退出break# 释放视频资源
cap.release()
cv2.destroyAllWindows()

这里设置了最大可识别2只手,如果有需要可通过result.multi_handedness,分别处理左右手的坐标。


3. 编辑关键点坐标,更改显示图像

上面我们通过results.multi_hand_landmarks得到的xyz坐标是归一化后的比例坐标,即某一像素点在图像的某一比例位置[0.5, 0.5]。我们需要将其转为像素坐标,如[200,200],像素坐标一定是整数。通过图像宽度乘以比例即可得到像素长度。为了能更明显的显示关键点,把关键点画的大一些,只需以关键点的像素坐标为圆心画圆cv2.circle()即可。

因此我们在上面的代码中补充

#(1)视频捕获
cap = cv2.VideoCapture(0)  # 0代表电脑自带的摄像头#(2)创建检测手部关键点的方法
mpHands = mp.solutions.hands  #接收方法
hands = mpHands.Hands(static_image_mode=False, #静态追踪,低于0.5置信度会再一次跟踪max_num_hands=2, # 最多有2只手min_detection_confidence=0.5, # 最小检测置信度min_tracking_confidence=0.5)  # 最小跟踪置信度 # 创建检测手部关键点和关键点之间连线的方法
mpDraw = mp.solutions.drawing_utils# 查看时间
pTime = 0 #处理一张图像前的时间
cTime = 0 #一张图处理完的时间# 存放坐标信息
lmList = []#(3)处理视频图像
# 文件设为True,对每一帧视频图像处理
while True:# 返回是否读取成功和读取的图像success, img = cap.read()# 在循环中发送rgb图像到hands中,opencv中图像默认是BGR格式imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 把图像传入检测模型,提取信息results = hands.process(imgRGB)# 检查每帧图像是否有多只手,一一提取它们if results.multi_hand_landmarks: #如果没有手就是Nonefor handlms in results.multi_hand_landmarks:# 获取每个关键点的索引和坐标for index, lm in enumerate(handlms.landmark):# 索引为0代表手底部中间部位,为4代表手指关键或指尖# print(index, lm)  # 输出21个手部关键点的xyz坐标(0-1之间),是相对于图像的长宽比例# 只需使用x和y查找位置信息# 将xy的比例坐标转换成像素坐标h, w, c = img.shape # 分别存放图像长\宽\通道数# 中心坐标(小数),必须转换成整数(像素坐标)cx ,cy =  int(lm.x * w), int(lm.y * h) #比例坐标x乘以宽度得像素坐标# 打印显示21个关键点的像素坐标print(index, cx, cy)# 存储坐标信息lmList.append([index, cx, cy])# 在21个关键点上换个圈,img画板,坐标(cx,cy),半径5,蓝色填充cv2.circle(img, (cx,cy), 12, (0,0,255), cv2.FILLED)# 绘制每只手的关键点mpDraw.draw_landmarks(img, handlms, mpHands.HAND_CONNECTIONS) #传入想要绘图画板img,单只手的信息handlms# mpHands.HAND_CONNECTIONS绘制手部关键点之间的连线# 记录执行时间      cTime = time.time()      # 计算fpsfps = 1/(cTime-pTime)# 重置起始时间pTime = cTime# 把fps显示在窗口上;img画板;取整的fps值;显示位置的坐标;设置字体;字体比例;颜色;厚度cv2.putText(img, str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,0), 3)# 显示图像cv2.imshow('Image', img)  #窗口名,图像变量if cv2.waitKey(1) & 0xFF==27:  #每帧滞留1毫秒后消失break# 释放视频资源
cap.release()
cv2.destroyAllWindows()

得到的结果如下,fps=19,右下输出框中打印每帧图像的21个手部关键点xy坐标,并保存在列表中。

【MediaPipe】(1) AI视觉,手部关键点实时跟踪,附python完整代码相关推荐

  1. 【MediaPipe】(3) AI视觉,人脸识别,附python完整代码

    各位同学好,今天和大家分享一下如何使用MediaPipe完成人脸实时跟踪检测,先放张图看效果,FPS值为14,右侧的输出为:每帧图像是人脸的概率,检测框的左上角坐标及框的宽高. 有需要的可以使用 cv ...

  2. 【机器视觉案例】(15) 虚拟答题板,手部关键点识别,附python完整代码

    各位同学好,今天和大家分享一下如何使用 opencv+Mediapipe 制作虚拟问答,先放张图看效果. 当食指在某个答案框内部,并且食指指尖和中指指尖之间的距离小于预设值,那么就认为是点击该答案框, ...

  3. 【机器视觉案例】(11) 眨眼计数器,人脸关键点检测,附python完整代码

    各位同学好,今天和大家分享一下如何使用 mediapipe+opencv 实现眨眼计数器.先放张图看效果. 下图左侧为视频图像,右侧为平滑后的人眼开合比曲线.以左眼为例,若眼眶上下边界的距离与左右边界 ...

  4. 【MediaPipe】(4) AI视觉,远程手势调节电脑音量,附python完整代码

    各位同学好,今天和大家分享一下如何使用MediaPipe完成手势调节电脑音量,先放张图看效果. 注意!! 本节需要用到手部关键点的实时跟踪,我已经在之前的文章中详细写过了,本节会直接使用,有疑问的同学 ...

  5. 【机器视觉案例】(5) AI视觉,手势调节物体尺寸,附python完整代码

    各位同学好,今天和大家分享一下如何使用opencv+mediapipe完成远程手势调节图片尺寸的案例.先放张图看效果.当拇指和食指竖起时,根据食指间的连线的长度自由缩放图片尺寸.图片的中点始终位于指尖 ...

  6. 【机器视觉案例】(5) AI视觉,远程手势控制虚拟计算器,附python完整代码

    各位同学好,今天和大家分享一下如何使用MediaPipe+Opencv完成虚拟计算器,先放张图看效果.FPS值为29,食指和中指距离小于规定阈值则认为点击按键,为避免重复数字出现,规定每20帧可点击一 ...

  7. 【MediaPipe】(2) AI视觉,人体姿态关键点实时跟踪,附python完整代码

    各位同学好,今天和大家分享一下如何使用MediaPipe完成人体姿态关键点的实时跟踪检测,先放张图看效果,FPS值为17,右下输出框为32个人体关键点的xy坐标. 有需要的可以使用 cv2.Video ...

  8. 【机器视觉案例】(6) AI视觉,距离测量,自制AI小游戏,附python完整代码

    各位同学好,今天和大家分享一下如何使用 opencv + mediapipe 创建一个AI视觉小游戏,先放图看效果. 游戏规则,用手按下屏幕上的圆形按钮,每按一次后松开,按钮就随机出现在屏幕上的一个位 ...

  9. 【机器视觉案例】(10) AI视觉搭积木,手势移动虚拟物体,附python完整代码

    各位同学好,今天和大家分享一下如何使用 opencv+mediapipe 完成手势移动虚拟物体,可自定义各种形状的物体,通过手势搭积木.先放张图看效果. 规则:当食指在某个物体内部,并且中指指尖和食指 ...

最新文章

  1. 027_jdbc-mysql几个常用的日期类型
  2. robots.txt网站爬虫文件设置
  3. Node.js 使用axios读写influxDB
  4. 线性回归,logistic回归和一般回归
  5. 第六十八期:程序员与医生
  6. MySql | 为什么大家都在说 Select * 效率低
  7. vue路由传参丢失问题
  8. IOS学习之斯坦福大学IOS开发课程笔记(第六课)
  9. PostgreSQL内核扩展之 - ElasticSearch同步插件
  10. 常见条形码的用法和格式
  11. JavaSE 计算机基础知识 Java语言概述 JDK的下载,安装 HelloWorld案例 环境变量的配置 注释 关键字 标识符
  12. 多元线性回归方差分析表理解
  13. jQuery灯箱插件lightBox使用方法
  14. 为什么程序员很难找到合适的另一半?
  15. amd显卡怎么设置风扇?
  16. RDD优化--RDD共享变量(广播变量与累加器)
  17. 木纤维(WF)保温材料UKCA认证—EN 13171
  18. 学习总结20-04-18:包装类
  19. 配色分享|梵高的薄荷绿
  20. 711问题-优化蛮力求解

热门文章

  1. Android shape 画的圆角带四个黑变 问题
  2. canvas绘制的文字如何换行
  3. 3.request response
  4. Maven 无法下载 json-lib
  5. hadoop集群安装
  6. 机器学习入门(09)— 偏导数、梯度概念、梯度下降法理论和实现
  7. 机器学习概念 — 监督学习、无监督学习、半监督学习、强化学习、欠拟合、过拟合、后向传播、损失和优化函数、计算图、正向传播、反向传播
  8. H3 BPM钉钉接入配置
  9. mysql处理上百万条的数据库如何优化语句来提高处理查询效率
  10. 1199: 房间安排