(初次加载图片可能会比较慢,请耐心等待一下~)

本文意在教你如何在PyCharm上用OpenCV-Python 和 Mediapipe库实现手部识别 (很遗憾,暂时没有什么实际用处,初步了解用)

阅读本文,你将学会:


  1. 学会安装Python

  2. 学会安装PyCharm

  3. 学会给代码配置合适的环境并成功运行代码(手部识别)

演示GIF

使用编译器:PyCharm2023.3.2专业版

编译环境:Python3.7.9

使用库:Numpy,OpenCV-Python,Mediapipe


准备活动:

一. Python的安装与环境变量部署


1. 下载 Python 最新版本




2.Python安装




3.Python环境变量配置


环境变量的配置可以保证在任意路径都能执行程序,而不是拘泥于在命令行所在路径查找

用户变量 / 系统变量: 用户变量是对单一用户生效,系统变量对所有用户生效。




二. PyCharm的安装以及相关环境准备


1. 下载 PyCharm 最新版本




2.PyCharm的安装


以安装免费的PyCharm社区版为例:




3.创建PyCharm项目并正确配置Python解释器


确认 PyCharm 用户协议

(1)新建项目


(2)新建Python程序文件



(3)给PyCharm做汉化,下载中文语音包,下载完重启后启用

转到设置--插件
下载--重启更新

4.程序运行所需软件包安装(OpenCV-Python 和 Mediapipe)


前言:软件包资源大多需要从国外服务器上下载,为保证下载速度和下载成功率,我们选择将下载目标地址转向国内镜像源:

(1)永久设置pip指定国内镜像源(windows内)



(2)然后转回PyCharm设置


安装OpenCV-Python:


接着安装Mediapipe;


然后就是编写程序代码了。

三. 编写代码,运行代码


(1)编写代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import cv2 #导入OpenCv库

import mediapipe as mp #导入Mediapipe库
import time

cap = cv2.VideoCapture(0) #0为打开默认摄像头,1为打开你设备列表的第二个摄像头,以此类推;
mpHands = mp.solutions.hands #使用Mediapipe库的手部姿势估计模型
hands = mpHands.Hands(static_image_mode=False, max_num_hands=4, model_complexity=1, min_detection_confidence=0.5, min_tracking_confidence=0.5) #创建手部姿势估计器对象,设置参数。
mpDraw = mp.solutions.drawing_utils #初始化Mediapipe库绘图工具
handLmsStyle = mpDraw.DrawingSpec(color=(0, 0, 255), thickness=5)
handConStyle = mpDraw.DrawingSpec(color=(0, 255, 0), thickness=10) #设置绘制手部关键点和连接线的样式
pTime = 0
cTime = 0 #用于计算帧率

while True: #无限循环
ret, img = cap.read() #读取摄像头的图像帧
img = cv2.flip(img, 1) #对img图像进行水平翻转
if ret:
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #将图像从BGR格式转换为RGB格式
result = hands.process(imgRGB) #使用手部姿势估计器处理图像,获取结果
# print(result.multi_hand_landmarks)
imgHeight = img.shape[0] #获取图像的高度,并将其赋值给变量imgHeight(其中[0]表示高度的维度)
imgWidth = img.shape[1] #其中,img是一个图像对象,而shape[1]表示图像的宽度

if result.multi_hand_landmarks: #检查是否检测到手部
for handLms in result.multi_hand_landmarks: #遍历检测到的手部
mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS, handLmsStyle, handConStyle) #绘制手部关键点和连接线
for i, lm in enumerate(handLms.landmark): #遍历每个关键点
xPos = int(lm.x * imgWidth) #计算关键点在图像中的x坐标
yPos = int(lm.y * imgHeight) #计算关键点在图像中的y坐标
# cv2.putText(img, str(i), (xPos-25, yPos+5), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0, 0, 255), )
if i == 4: #绘制特定关键点的标记,如果是特定的关键点(在代码中是第5个关键点)
cv2.circle(img, (xPos, yPos), 15, (92, 65, 214), cv2.FILLED)
print(i, xPos, yPos) #在特定关键点处绘制一个填充的圆

cTime = time.time() #获取当前时间
fps = 1/(cTime-pTime) #计算帧率
pTime = cTime #更新上一帧的时间
cv2.putText(img, f"FPS : {int(fps)}", (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3) #在图像上显示帧率

cv2.imshow('img', img) #显示处理后的图像

if cv2.waitKey(1) == ord(' '):
break #如果按下 ' ' 键,则退出循环

概括:这段代码的功能是实时从摄像头获取图像,并使用手部姿势估计器检测手部关键点并绘制在图像上,同时显示帧率。

PS:这段代码是@GrandmaCan我阿嬤都會的,我给代码添加了注释

如果以后有空就补充关键代码的配置调参,咕咕咕

(2)运行代码及注意事项


成果展示:


成果展示


教程到这里就结束了。制作不易还望点赞/评论/关注呀