计算机视觉之手势、面部、姿势捕捉以Python Mediapipe为工具
计算机视觉之手势、面部、姿势捕捉以 Python Mediapipe为工具
文章目录
- 1.`Mediapipe`库概述
- 2.手势捕捉(`hands`)
- 3.面部捕捉(`face`)
- 4.姿势捕捉(`pose`)
1.Mediapipe库概述
Mediapipe是一个开源且强大的Python库,由Google开发和维护。它提供了丰富的工具和功能,用于处理实时多媒体数据。它可以帮助开发者快速构建各种视觉和音频处理应用,并允许他们灵活地定制和扩展库的功能。
Mediapipe库的主要功能包括:
- 视觉处理:Mediapipe可以进行人脸检测、姿势估计、手部跟踪等。它通过使用预训练的模型和算法来分析图像或视频,并提供相应的结果。这使得开发者能够轻松地实现各种视觉处理任务。
- 音频处理:Mediapipe还可以进行音频信号的处理,例如语音识别、音频增强、语音转换等。它提供了一些内置的音频处理模块,开发者可以使用这些模块来快速构建自己的音频处理流水线。
- 数据流处理:Mediapipe库还提供了一套用于处理数据流的工具。开发者可以使用这些工具来构建复杂的数据处理流程,包括数据的输入、输出、转换和合并等。这使得开发者能够更方便地处理实时多媒体数据流。
本期博客,作者将分享使用Mediapipe库实现手势、面部、动作识别的方法。

2.手势捕捉(hands)
该段代码使用OpenCV和MediaPipe库来检测摄像头视频中的手部,并在图像上绘制关键点和连接线。
import cv2
import time
import mediapipe as mpcapture = cv2.VideoCapture(0)
mpHands = mp.solutions.hands
hands = mpHands.Hands()
mpDraw = mp.solutions.drawing_utils
pTime = 0
cTime = 0while (capture.isOpened()):retval, img = capture.read()imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)results = hands.process(imgRGB)if results.multi_hand_landmarks:for handLms in results.multi_hand_landmarks:for id, lm in enumerate(handLms.landmark):h, w, c = img.shapecx, cy = int(lm.x * w), int(lm.y * h)cv2.circle(img, (cx, cy), 15, (0, 255, 0), cv2.FILLED)mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)cTime = time.time()fps = 1 / (cTime - pTime)pTime = cTimecv2.putText(img, "fps:"+str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 2,(0, 0, 255), 2)cv2.imshow("Video", img) key = cv2.waitKey(1)if key == 32:breakcapture.release()
cv2.destroyAllWindows()
效果展示:

关于代码,具体解释如下:
-
导入所需的库:
- cv2:用于处理图像和视频的
OpenCV库。 - time:用于计算帧率的
Python标准库。 - mediapipe as mp:
MediaPipe库,用于手部检测和姿态估计。
- cv2:用于处理图像和视频的
-
创建视频捕获对象:
- 使用
cv2.VideoCapture(0)创建一个视频捕获对象,参数0表示使用默认摄像头。
- 使用
-
初始化MediaPipe手部检测器:
- 使用
mp.solutions.hands.Hands()创建一个手部检测器对象。 hands.process(imgRGB)将每个视频帧传递给检测器进行处理,并返回检测结果。
- 使用
-
处理每个视频帧:
- 使用
capture.read()读取视频帧,并将返回的结果存储在retval和img变量中。 - 使用
cv2.cvtColor(img, cv2.COLOR_BGR2RGB)将图像从BGR格式转换为RGB格式,以便与MediaPipe兼容。 - 使用
hands.process(imgRGB)对图像进行手部检测,返回结果保存在results变量中。
- 使用
-
绘制检测结果:
- 使用
results.multi_hand_landmarks判断是否检测到了手部。 - 对于每个检测到的手部,使用
handLms.landmark遍历所有关键点,并将其坐标从归一化坐标转换为图像上的实际坐标。 - 使用
cv2.circle()在图像中绘制关键点圆圈。 - 使用
mpDraw.draw_landmarks()在图像中绘制手部关键点和连接线。
- 使用
-
计算帧率:
- 使用
time.time()获取当前时间戳,计算时间间隔以确定帧率。 - 使用
cv2.putText()在图像上显示帧率。
- 使用
-
显示图像并等待按键:
- 使用
cv2.imshow()显示处理后的图像。 - 使用
cv2.waitKey(1)等待用户按键,参数1表示等待1毫秒。
- 使用
-
释放资源:
- 在循环结束后,使用
capture.release()释放视频捕获对象。 - 使用
cv2.destroyAllWindows()关闭所有窗口。
- 在循环结束后,使用
-
退出程序:
- 按下空格键(32)可以退出程序。
3.面部捕捉(face)
该段代码使用OpenCV和MediaPipe库来检测摄像头视频中的人脸,并在图像上绘制人脸关键点和轮廓。
import cv2
import time
import mediapipe as mpcapture = cv2.VideoCapture(0)mpFaceMesh = mp.solutions.face_mesh
faceMesh = mpFaceMesh.FaceMesh()
mpDraw = mp.solutions.drawing_utilspTime = 0 # 上一帧的时间
cTime = 0 # 下一帧的时间while (capture.isOpened()):retval, img = capture.read()imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)results = faceMesh.process(imgRGB)if results.multi_face_landmarks:for faceLms in results.multi_face_landmarks:for id, lm in enumerate(faceLms.landmark):h, w, c = img.shapecx, cy = int(lm.x * w), int(lm.y * h)# cv2.circle(img, (cx, cy), 15, (0, 255, 0), cv2.FILLED)mpDraw.draw_landmarks(img, faceLms, mpFaceMesh.FACEMESH_CONTOURS)cTime = time.time()fps = 1 / (cTime - pTime)pTime = cTimecv2.putText(img, "fps:" + str(int(fps)), (10, 60), cv2.FONT_HERSHEY_PLAIN, 3, (0, 0, 255), 3)cv2.imshow("Video", img)key = cv2.waitKey(1)if key == 32:breakcapture.release()
cv2.destroyAllWindows()
以电影情节画面替代摄像头画面,代码效果展示如下:

以下是代码的解释:
-
导入所需的库:
- cv2:用于处理图像和视频的OpenCV库。
- time:用于计算帧率的标准Python库。
- mediapipe as mp:MediaPipe库,用于人脸检测和特征点估计。
-
创建视频捕获对象:
- 使用
cv2.VideoCapture(0)创建一个视频捕获对象,参数0表示使用默认摄像头。
- 使用
-
初始化MediaPipe人脸检测器:
- 使用
mp.solutions.face_mesh.FaceMesh()创建一个人脸检测器对象。 faceMesh.process(imgRGB)将每个视频帧传递给检测器进行处理,并返回检测结果。
- 使用
-
处理每个视频帧:
- 使用
capture.read()读取视频帧,并将返回的结果存储在retval和img变量中。 - 使用
cv2.cvtColor(img, cv2.COLOR_BGR2RGB)将图像从BGR格式转换为RGB格式,以便与MediaPipe兼容。 - 使用
faceMesh.process(imgRGB)对图像进行人脸检测,返回结果保存在results变量中。
- 使用
-
绘制检测结果:
- 使用
results.multi_face_landmarks判断是否检测到了人脸。 - 对于每个检测到的人脸,使用
faceLms.landmark遍历所有关键点,并将其坐标从归一化坐标转换为图像上的实际坐标。 - 使用
mpDraw.draw_landmarks()在图像中绘制人脸关键点和轮廓。
- 使用
-
计算帧率:
- 使用
time.time()获取当前时间戳,计算时间间隔以确定帧率。 - 使用
cv2.putText()在图像上显示帧率。
- 使用
-
显示图像并等待按键:
- 使用
cv2.imshow()显示处理后的图像。 - 使用
cv2.waitKey(1)等待用户按键,参数1表示等待1毫秒。
- 使用
-
释放资源:
- 在循环结束后,使用
capture.release()释放视频捕获对象。 - 使用
cv2.destroyAllWindows()关闭所有窗口。
- 在循环结束后,使用
-
退出程序:
- 按下空格键(32)可以退出程序。
4.姿势捕捉(pose)
该段代码使用OpenCV和MediaPipe库来检测摄像头视频中的人体姿势,并在图像上绘制关键点和连接线。
import cv2
import time
import mediapipe as mpvideo = cv2.VideoCapture(0)
mpPose = mp.solutions.pose
pose = mpPose.Pose()
mpDraw = mp.solutions.drawing_utilspTime = 0 # 上一帧的时间
cTime = 0 # 下一帧的时间while True:retval, img = video.read()imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)results = pose.process(imgRGB)if results.pose_landmarks:for id, lm in enumerate(results.pose_landmarks.landmark):h, w, c = img.shapecx, cy = int(lm.x * w), int(lm.y * h)cv2.circle(img, (cx, cy), 15, (0, 255, 0), cv2.FILLED)mpDraw.draw_landmarks(img, results.pose_landmarks, mpPose.POSE_CONNECTIONS)cTime = time.time()fps = 1 / (cTime - pTime)pTime = cTimecv2.putText(img, "fps:" + str(int(fps)), (10, 60), cv2.FONT_HERSHEY_PLAIN, 3, (0, 0, 255), 3)cv2.imshow("Video", img)key = cv2.waitKey(10)if key == 32:breakvideo.release()
cv2.destroyAllWindows()
效果展示:

以下是代码的解释:
-
导入所需的库:
- cv2:用于处理图像和视频的OpenCV库。
- time:用于计算帧率的标准Python库。
- mediapipe as mp:MediaPipe库,用于人体姿势检测。
-
创建视频捕获对象:
- 使用
cv2.VideoCapture(0)创建一个视频捕获对象,参数0表示使用默认摄像头。
- 使用
-
初始化MediaPipe人体姿势检测器:
- 使用
mp.solutions.pose.Pose()创建一个人体姿势检测器对象。 pose.process(imgRGB)将每个视频帧传递给检测器进行处理,并返回检测结果。
- 使用
-
处理每个视频帧:
- 使用
video.read()读取视频帧,并将返回的结果存储在retval和img变量中。 - 使用
cv2.cvtColor(img, cv2.COLOR_BGR2RGB)将图像从BGR格式转换为RGB格式,以便与MediaPipe兼容。 - 使用
pose.process(imgRGB)对图像进行人体姿势检测,返回结果保存在results变量中。
- 使用
-
绘制检测结果:
- 使用
results.pose_landmarks判断是否检测到了人体姿势。 - 对于每个检测到的关键点,使用
landmark遍历所有关键点,并将其坐标从归一化坐标转换为图像上的实际坐标。 - 使用
cv2.circle()在图像中绘制关键点圆圈。 - 使用
mpDraw.draw_landmarks()在图像中绘制人体姿势关键点和连接线。
- 使用
-
计算帧率:
- 使用
time.time()获取当前时间戳,计算时间间隔以确定帧率。 - 使用
cv2.putText()在图像上显示帧率。
- 使用
-
显示图像并等待按键:
- 使用
cv2.imshow()显示处理后的图像。 - 使用
cv2.waitKey(10)等待用户按键,参数10表示等待10毫秒。
- 使用
-
释放资源:
- 在循环结束后,使用
video.release()释放视频捕获对象。 - 使用
cv2.destroyAllWindows()关闭所有窗口。
- 在循环结束后,使用
-
退出程序:
- 按下空格键(32)可以退出程序。
附:侯小啾Python基础领航计划专栏已上线,特价专栏只需9.9即可扫清入门路上一切障碍。
跟着小啾,入门无忧!无论是系统化学习,还是碎片化学习都是很好的选择,点击下方链接即可订阅:
https://blog.csdn.net/weixin_48964486/category_12510091.html
更多精彩内容敬请期待,作者侯小啾持续为您推出!
相关文章:
计算机视觉之手势、面部、姿势捕捉以Python Mediapipe为工具
计算机视觉之手势、面部、姿势捕捉以 Python Mediapipe为工具 文章目录 1.Mediapipe库概述2.手势捕捉(hands)3.面部捕捉(face)4.姿势捕捉(pose) 1.Mediapipe库概述 Mediapipe是一个开源且强大的Python库,由Google开发和维护。它提供了丰富的工具和功能,…...
基于AWS Serverless的Glue服务进行ETL(提取、转换和加载)数据分析(一)——创建Glue
1 通过Athena查询s3中的数据 此实验使用s3作为数据源 ETL: E extract 输入 T transform 转换 L load 输出 大纲 1 通过Athena查询s3中的数据1.1 架构图1.2 创建Glue数据库1.3 创建爬网程序1.4 创建表1.4.1 爬网程序创建表1.4.2 手动创建表 1…...
Vue学习计划-Vue2--VueCLi(二)vuecli脚手架创建的项目内部主要文件分析
1. 文件分析 1. 补充: 什么叫单文件组件? 一个文件中只有一个组件 vue-cli创建的项目中,.vue的文件都是单文件组件,例如App.vue 2. 进入分析 1. package.json: 项目依赖配置文件: 如图,我们说主要的属性…...
spring boot项目如何自定义参数校验规则
spring boot项目对参数进行校验时,比如非空校验,可以直接用validation包里面自带的注解。但是对于一些复杂的参数校验,自带的校验规则无法满足要求,此时需要我们自定义参数校验规则。自定义校验规则和自带的规则实现方式一样&…...
springboot整合xxl-job,通过代码进行调度中心注册开启任务等
背景:由于工作需要,当用户在登录时自动触发定时任务。而不需要我们手动到调度中心管理页面去创建任务。 工程介绍:分为两个项目,第一个是调度中心的项目(xxl-job-admin)。第二个是我们自己的项目࿰…...
k8s集群部分使用gpu资源的pod出现UnexpectedAdmissionError问题
记录一次排查UnexpectedAdmissionError问题的过程 1. 问题 环境 3master节点N个GPU节点 kubelet版本:v1.19.4 kubernetes版本:v1.19.4 生产环境K8S集群,莫名其妙的出现大量UnexpectedAdmissionError状态的Pod,导致部分任务执…...
自定义 el-select 和 el-input 样式
文章目录 需求分析el-select 样式el-input 样式el-table 样式 需求 自定义 选择框的下拉框的样式和输入框 分析 el-select 样式 .select_box{// 默认placeholder:deep .el-input__inner::placeholder {font-size: 14px;font-weight: 500;color: #3E534F;}// 默认框状态样式更…...
解决本地centos虚拟机重启,自动变换 ip 地址的问题
修改网卡配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33 原配置: TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no" BOOTPROTO"dhcp" DEFROUTE"yes" IPV4_FAILURE_FATAL"no" IPV6INI…...
pt36项目短信OAth2.0
5、短信验证码 1、注册容联云账号,登录并查看开发文档(以下分析来自接口文档) 2、开发文档【准备1】:请求URL地址1.示例:https://app.cloopen.com:8883/2013-12-26/Accounts/{}/SMS/TemplateSMS?sig{}ACCOUNT SID# s…...
教师们如何一对一私发成绩?
在传统的教育中,老师通常会通过班级群或家长会等方式发布学生的成绩信息。然而,这种公开的方式可能会让一些学生感到尴尬和不安,因为他们可能不愿意让其他人知道他们的成绩情况。为了解决这个问题,今天我就给老师们推荐一款免费的…...
12.11
1.q,w,e亮led1,2,3; a,s,d灭led1,2,3; main.c #include "uar1.h"#include "led.h"void delay(int ms){int i,j;for(i0;i<ms;i){for…...
Spring JdbcTemplate
一、简介 Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作。它是 spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。spring 框架为我们提供了很多的操作模板类。 针对操作关系型数据: jdbcTemplateHibe…...
力扣编程题算法初阶之双指针算法+代码分析
目录 第一题:复写零 第二题:快乐数: 第三题:盛水最多的容器 第四题:有效三角形的个数 第一题:复写零 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 思路: 上期…...
实现安装“自由化”!在Windows 11中如何绕过“您尝试安装的应用程序未通过微软验证”
这篇文章描述了如果你不能安装应用程序,而是当你在Windows 11中看到消息“您尝试安装的应用程序未通过微软验证”时该怎么办。完成这些步骤将取消你安装的应用程序必须经过Microsoft验证的要求。 使用设置应用程序 “设置”应用程序提供了绕过此警告消息的最简单方法,以便你…...
【mysql】下一行减去上一行数据、自增序列场景应用
背景 想获取if_yc为1连续账期数据 思路 获取所有if_yc为1的账期数据下一行减去上一行账期,如果为1则为连续,不等于1就为断档获取不等于1的最小账期,就是离当前账期最近连续账期 代码 以下为mysql语法: select acct_month f…...
CLIP在Github上的使用教程
CLIP的github链接:https://github.com/openai/CLIP CLIP Blog,Paper,Model Card,Colab CLIP(对比语言-图像预训练)是一个在各种(图像、文本)对上进行训练的神经网络。可以用自然语…...
入职字节外包一个月,我离职了。。。
有一种打工人的羡慕,叫做“大厂”。 真是年少不知大厂香,错把青春插稻秧。 但是,在深圳有一群比大厂员工更庞大的群体,他们顶着大厂的“名”,做着大厂的工作,还可以享受大厂的伙食,却没有大厂…...
SpringBoot的web开发
与其明天开始,不如现在行动! 文章目录 web开发1 web场景1.1 自动配置1.2 默认效果 💎总结 web开发 SpringBoot的web开发能力是由SpringMVC提供的 1 web场景 1.1 自动配置 整合web场景 <dependency><groupId>org.springframewo…...
传染病传播速度
题干 R0值是基本传染数的简称,指的是在没有采取任何干预措施的情况下,平均每位感染者在传染期内使易感者个体致病的数量。数字越大说明传播能力越强,控制难度越大。一个人传染的人的数量可以用幂运算来计算。假设奥密克戎的R0为10࿰…...
前端打包环境配置步骤
获取node安装包并解压 获取node安装包 wget https://npmmirror.com/mirrors/node/v16.14.0/node-v16.14.0-linux-x64.tar.xz 解压 tar -xvf node-v16.14.0-linux-x64.tar.xz 创建软链接 sudo ln -s 此文件夹的绝对路径/bin/node /usr/local/bin/node,具体执行如下…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
