目录
python3.9.7 opencv-python4.6.0.66 mediapipe0.8.11
运行之前先要安装opencv-python、opencv-contrib-python、mediapipe
pip install opencv-python
pip install opencv-contrib-python
pip install mediapipe
项目可能对版本的要求较为严格,安装不上的可以按我版本
这篇文章只介绍mediapipe的简单实现,拖拽和放大效果后续更新
OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,提供了Python的接口,实现了图像处理和计算机视觉方面的很多通用算法。
这里用opencv实现调用摄像头,绘制图像等操作。
opencv的简单使用
通过while循环,每次循环读取每一帧的图片,并对每一帧的图片进行处理,并设置一个1毫秒的延迟,再进入下一次循环,实现摄像头的调用和读取
import cv2
# 调用摄像头 0为默认摄像头
cap = cv2.VideoCapture(0)
# 通过循环将每一帧的图片读出来
while True:
# read方法返回两个参数
# success 判断摄像头是否打开成功,img 为读取的每一帧的图像对象
success, img = cap.read()
if not success:
print('摄像头打开失败')
break
# 0为开启上下镜像 1为开启左右镜像 -1为左右并上下镜像
img = cv2.flip(img,1)
# imshow方法展示窗口,第一个参数为窗口的名字,第二个参数为帧数
cv2.imshow("frame", img);
# 延迟一毫秒
cv2.waitKey(1)
首先要在while循环之前对mediapipe进行配置
hand_drawing_utils:为手部特征点和连线的绘制工具
mp_hands:因为mediapipe中有很多的识别,包括手部,面部,姿态等,mp_hands获取到的是手部识别的api
my_hands:通过api获取到手部识别的类
# 配置mediapipe
hand_drawing_utils = mp.solutions.drawing_utils # 绘图工具
mp_hands = mp.solutions.hands # 手部识别api
my_hands = mp_hands.Hands() # 获取手部识别类
Hands类中可以填入参数,也可以使用默认参数,在pycharm中按住ctrl,点击函数名查看此函数的介绍

static_image_mode=True适用于静态图片的手势识别,Flase适用于视频等动态识别,比较明显的区别是,若识别的手的数量超过了最大值,True时识别的手会在多个手之间不停闪烁,而False时,超出的手不会识别,系统会自动跟踪之前已经识别过的手。默认值为False。
max_num_hands 用于指定识别手的最大数量。默认值为2。
model_complexity 表示手部模型的复杂程度,手部模型越复杂,需要的响应时间就越长。默认值为1。
min_detection_confidence 表示最小检测信度,取值为[0.0,1.0]这个值约小越容易识别出手,用时越短,但是识别的准确度就越差。越大识别的越精准,但是响应的时间也会增加。默认值为0.5。
min_tracking_confience 表示最小的追踪可信度,越大手部追踪的越准确,相应的响应时间也就越长。默认值为0.5。
若不填任何参数,那么将会使用默认参数。
import mediapipe as mp
import cv2
# 配置meidapipe
hand_drawing_utils = mp.solutions.drawing_utils # 绘图工具
mp_hands = mp.solutions.hands # 手部识别api
my_hands = mp_hands.Hands() # 获取手部识别类
# 调用摄像头 0为默认摄像头
cap = cv2.VideoCapture(0)
# 通过循环将每一帧的图片读出来
while True:
# read方法返回两个参数
# success 判断摄像头是否打开成功,img 为读取的每一帧的图像对象
success, img = cap.read()
if not success:
print('摄像头打开失败')
break
# 0为开启上下镜像 1为开启左右镜像 -1为左右并上下镜像
img = cv2.flip(img, 1)
# imshow方法展示窗口,第一个参数为窗口的名字,第二个参数为帧数
cv2.imshow("frame", img);
# 延迟一毫秒
cv2.waitKey(1)
完成mediapipe手部识别的基本配置后,此时还不能识别出手势,接下来要在while循环中的每一帧图像中,进行手部的识别
process()是手势识别最核心的方法,通过调用这个方法,将窗口对象作为参数,mediapipe就会将手势识别的信息存入到res对象中。
# 将BGR转换为RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 识别图像中的手势,并返回结果
results = my_hands.process(img)
# 再将RGB转回BGR
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
因为在opencv中使用的色彩格式为BGR,而mediapipe能识别的为RGB,所以要先用
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 将BGR转换为RGB,为了保证窗口显示正常,还要在识别完成后,将RGB再转回BGR
接下来就是对results中保存的信息进行处理

在pycharm中按住ctrl点击process就可以看到这个方法的相关介绍和返回值的信息,在下方的Returns中,返回的对象中含有以下三个字段:1.multi_hand_landmarks 2.multi_hand_world_landmarks 3.multi_handedness
包括识别出的所有手的手部的所有信息点,可以将这个参数打印出来观察一下
print(results.multi_hand_landmarks)

简单来说,参数的形式为 [手1所有信息点,手2所有信息点,……],识别出来手的个数取决于画面中手的个数以及设置的手部最大识别个数。若画面中没有手,那么这个参数值为None。
landmark表示每个信息点中有三个参数 x y z。要注意的是x,y是小数,是相对整个屏幕到左侧和上侧的距离,若识别出的信息点的x为0.5,那么在x方向上信息点在屏幕中心位置,若为0,那么手指在屏幕左侧边缘,若为1,那么信息点在屏幕右侧边缘。y方向同理。z为相对与手掌根处的距离。
这个参数跟multi_hand_landmarks 的形式一致,但是坐标的组织方式不同,根据官方说明,检测到跟踪的手的集合,其中每只手都表示为世界坐标中 21 个手地标的列表。每个地标由x、y和z组成,以米为单位的真实世界 3D 坐标,原点位于手部的近似几何中心。

这个参数记录了识别出的每只手的描述。包括手的索引值,是惯用手的概率,和左手还是右手。
在搞懂具体的参数后,就开始绘制手部的信息点和连线。
# results.multi_hand_landmarks为None时进行for循环会报错,所以要先判断
if results.multi_hand_landmarks:
for hand_landmark in results.multi_hand_landmarks:
hand_drawing_utils.draw_landmarks(img, hand_landmark)
通过for循环遍历出每只手的全部信息点,然后就可以对信息点进行绘制。
这里要在for循环之前用if进行判断,因为在未识别到手势时,multi_hand_landmarks的值为None,此时进行for循环就会报错。
通过在前面定义的绘图工具,绘制手部信息点,第一个参数传入要绘制的图片,也就是当前的帧,第二个参数要填入信息点的集合。现在就可以绘制出信息点了

但是此时只有信息点,信息点中没有连线,接下来我们可以在
draw_landmarks()方法中继续传入参数
hand_drawing_utils.draw_landmarks(img, hand_landmark, mp_hands.HAND_CONNECTIONS)
此时的连线就出现了

hand_drawing_utils.draw_landmarks(img,
hand_landmark,
mp_hands.HAND_CONNECTIONS,
mp.solutions.drawing_styles.get_default_hand_landmarks_style(),
mp.solutions.drawing_styles.get_default_hand_connections_style())
向方法中传入样式的参数,便会显示出更丰富的样式

所有代码
import mediapipe as mp
import cv2
# 配置meidapipe
hand_drawing_utils = mp.solutions.drawing_utils # 绘图工具
mp_hands = mp.solutions.hands # 手部识别api
my_hands = mp_hands.Hands() # 获取手部识别类
# 调用摄像头 0为默认摄像头
cap = cv2.VideoCapture(0)
# 通过循环将每一帧的图片读出来
while True:
# read方法返回两个参数
# success 判断摄像头是否打开成功,img 为读取的每一帧的图像对象
success, img = cap.read()
if not success:
print('摄像头打开失败')
break
# 将BGR转换为RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 识别图像中的手势,并返回结果
results = my_hands.process(img)
# 再将RGB转回BGR
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
# results.multi_hand_landmarks为None时进行for循环会报错,所以要先判断
if results.multi_hand_landmarks:
for hand_landmark in results.multi_hand_landmarks:
hand_drawing_utils.draw_landmarks(img,
hand_landmark,
mp_hands.HAND_CONNECTIONS,
mp.solutions.drawing_styles.get_default_hand_landmarks_style(),
mp.solutions.drawing_styles.get_default_hand_connections_style())
# 0为开启上下镜像 1为开启左右镜像 -1为左右并上下镜像
img = cv2.flip(img, 1)
# imshow方法展示窗口,第一个参数为窗口的名字,第二个参数为帧数
cv2.imshow("frame", img)
# 延迟一毫秒
cv2.waitKey(1)
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶