由于最近虚拟和增强现实技术的增长和普及,手势识别技术正变得越来越流行。在本篇文字中,我们将使用MediaPipe Python 库来检测我们的手势并使用它来控制树莓派媒体播放器。本文中,我们将使用总共六个手势,即松开和握紧拳头以及向上、向下、向左和向右移动手掌。松开和握紧拳头手势用于播放和暂停视频。上下移动手势用于增大和减小音量,左右移动手势用于快进和快退视频。
所需的组件
● 树莓派
● 摄像头模块
在这里,我们只需要安装了OpenCV和MediaPipe的树莓派和摄像头模块。OpenCV用于数字图像处理,而MediaPipe用于手势跟踪。数字图像处理最常见的应用是物体检测、人脸识别和人员计数器。
什么是MediaPipe?
MediaPipe
是一个框架,用于构建跨平台(即 Android、iOS、Web、边缘设备)多模式(例如视频、音频、任何时间序列数据)应用的机器学习管道,包括快速ML推理、经典计算机视觉和媒体处理(例如视频解码)。 MediaPipe 已经发布了各种预构建的Python和其他语言包,例如:
● 物体检测
● 人脸检测
● 手部追踪
● 姿态估计
● 多手追踪
● 头发分割
MediaPipe Python 包在适用于 Linux、macOS和Windows的PyPI上可用。使用以下命令在树莓派上安装MediaPipe:
-
sudo pip3 install mediapipe-rpi4
复制代码
如果您使用的是树莓派3,则可以使用以下命令安装:
-
sudo pip3 install mediapipe-rpi3
复制代码
在树莓派上安装OpenCV
在安装OpenCV 和其他依赖项之前,需要全面更新树莓派。使用以下命令将树莓派更新到最新版本:
然后使用以下命令在树莓派上安装OpenCV所需的依赖项。
-
sudo apt-get install libhdf5-dev -y
-
sudo apt-get install libhdf5-serial-dev –y
-
sudo apt-get install libatlas-base-dev –y
-
sudo apt-get install libjasper-dev -y
-
sudo apt-get install libqtgui4 –y
-
sudo apt-get install libqt4-test –y
复制代码
之后,使用以下命令在树莓派上安装 OpenCV。
-
pip3 install opencv-contrib-python==4.1.0.25
复制代码
在树莓派上安装 PyAutoGUI
PyAutoGUI
是一个跨平台的GUI 自动化Python 模块,可让您的Python 脚本控制鼠标和键盘以自动与其他应用程序交互。 PyAutoGUI可以在Windows、macOS和Linux 上运行,并支持Python 2和3。要在树莓派上安装PyAutoGUI,请运行:
为视频控制器编程树莓派
本节中我们将介绍代码的重要部分,以便更好地理解。
首先在代码中导入OpenCV、MediaPipe和PyAutoGUI包。如前所述,MediaPipe是手势追踪的核心包,而OpenCV用于图像处理。
PyAutoGUI
用于根据手势控制键盘。
-
import cv2
-
import mediapipe as mp
-
import pyautogui
复制代码
接下来,我们新建了两个变量。第一个是
mp_drawing
,它将用于从MediaPipe python包中获取所有绘图实用程序,第二个是
mp_hands
,用于导入手部跟踪模型。
-
mp_drawing = mp.solutions.drawing_utils
-
mp_hands = mp.solutions.hands
复制代码
之后定义一个名为
findPosition()
的函数。顾名思义,它用于查找食指、中指、无名指和小指的 X、Y 坐标。所有指尖的坐标将存储在一个名为
lmList[]
的变量中。
-
def fingerPosition(image, handNo=0):
-
lmList = []
-
if results.multi_hand_landmarks:
-
myHand = results.multi_hand_landmarks[handNo]
-
for id, lm in enumerate(myHand.landmark):
-
# print(id,lm)
-
h, w, c = image.shape
-
cx, cy = int(lm.x * w), int(lm.y * h)
-
lmList.append([id, cx, cy])
-
return lmList
复制代码
然后开始从树莓派摄像头模块中输出视频流,帧高和帧宽分别为720、640。
-
cap = cv2.VideoCapture(0)
-
cap.set(3, wCam)
-
cap.set(4, hCam)
复制代码
然后为mediapipe feed设置一个新实例以访问我们之前导入的Hand Tracking模型。我们还传递了两个关键字参数,即最小检测置信度和最小跟踪置信度。接下来,我们将读取视频帧并将它们存储在 image 变量中。
以mp_hands.Hands(min_detection_confidence=0.8, min_tracking_confidence=0.5) 作为手势:
-
while cap.isOpened():
-
success, image = cap.read()
复制代码
我们从视频源中获得的图像最初是BGR格式。因此,在这一行中,我们将首先水平翻转图像以供稍后自拍显示,然后将BGR图像转换为RGB。图像可写标志设置为false。
-
image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
-
image.flags.writeable = False
复制代码
之后,我们将通过手部跟踪模型传递图像以进行检测并将结果存储在名为“results”的变量中。
-
results = hands.process(image)
复制代码
检测完成后,我们将图像可写标志设置为 true 并将RGB图像转换为BGR。
-
image.flags.writeable = True
-
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
复制代码
现在,当我们得到检测结果时,我们将调用
mp_drawing
变量在图像上绘制这些检测,并使用我们之前导入的绘图实用程序连接所有检测。
-
image.flags.writeable = True
-
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
复制代码
之后,我们将调用 findPosition() 函数来获取所有检测的id和坐标。这些值将存储在名为lmList 的变量中。
-
lmList = findPosition(image, draw=True)
-
复制代码
现在我们有了所有手部标志的坐标,我们将使用它们来检测不同的手势,其中第一个是检测拳头是松开还是握紧。为此,我们将比较指尖 [8, 12, 16, 20] 和中点 [6, 10, 14, 19] 的坐标,如果指尖低于中点,则拳头握紧,反之张开。
-
for id in range(1, 5):
-
if lmList[tipIds[id]][2] < lmList[tipIds[id] - 2][2]:
-
fingers.append(1)
-
if (lmList[tipIds[id]][2] > lmList[tipIds[id] - 2][2]):
-
fingers.append(0)
复制代码
然后在接下来的代码中获取计数的手指总数并将其保存在名为totalFingers 的变量中。
-
totalFingers = fingers.count(1)
-
print(totalFingers)
复制代码
现在我们得到了手指的数量,使用它们来播放和暂停视频。
-
if totalFingers == 4:
-
state = "Play"
-
if totalFingers == 0 and state == "Play":
-
state = "Pause"
-
pyautogui.press('space')
-
print("Space")
复制代码
然后我们要检测的下一个手势是向左、向右、向上和向下移动。要检测左右移动,首先,我们将获得食指尖的 X 坐标,如果值小于 300 则为左滑动,如果值大于 400 则为右滑动。
-
if totalFingers == 1:
-
if lmList[8][1]<300:
-
print("left")
-
pyautogui.press('left')
-
if lmList[8][1]>400:
-
print("Right")
-
pyautogui.press('Right')
复制代码
同样的,检测上下手势我们会得到中指的Y坐标,如果小于210就是上滑,大于230就是下滑.
-
if totalFingers == 2:
-
if lmList[9][2] < 210:
-
print("Up")
-
pyautogui.press('Up')
-
if lmList[9][2] > 230:
-
print("Down")
-
pyautogui.press('Down')
复制代码
测试我们的手势控制视频控制器脚本
现在视频控制器脚本已准备就绪,让我们继续测试它。将摄像头模块与树莓派连接,如下所示: