计算机视觉之手势、面部、姿势捕捉以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,具体执行如下…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
