添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

由于最近虚拟和增强现实技术的增长和普及,手势识别技术正变得越来越流行。在本篇文字中,我们将使用MediaPipe Python 库来检测我们的手势并使用它来控制树莓派媒体播放器。本文中,我们将使用总共六个手势,即松开和握紧拳头以及向上、向下、向左和向右移动手掌。松开和握紧拳头手势用于播放和暂停视频。上下移动手势用于增大和减小音量,左右移动手势用于快进和快退视频。


所需的组件

●    树莓派

●    摄像头模块

在这里,我们只需要安装了OpenCV和MediaPipe的树莓派和摄像头模块。OpenCV用于数字图像处理,而MediaPipe用于手势跟踪。数字图像处理最常见的应用是物体检测、人脸识别和人员计数器。


什么是MediaPipe?

MediaPipe 是一个框架,用于构建跨平台(即 Android、iOS、Web、边缘设备)多模式(例如视频、音频、任何时间序列数据)应用的机器学习管道,包括快速ML推理、经典计算机视觉和媒体处理(例如视频解码)。 MediaPipe 已经发布了各种预构建的Python和其他语言包,例如:

●    物体检测

●    人脸检测

●    手部追踪

●    姿态估计

●    多手追踪

●    头发分割

MediaPipe Python 包在适用于 Linux、macOS和Windows的PyPI上可用。使用以下命令在树莓派上安装MediaPipe:

  1. sudo pip3 install mediapipe-rpi4
复制代码

如果您使用的是树莓派3,则可以使用以下命令安装:

  1. sudo pip3 install mediapipe-rpi3
复制代码

在树莓派上安装OpenCV

在安装OpenCV 和其他依赖项之前,需要全面更新树莓派。使用以下命令将树莓派更新到最新版本:

  1. sudo apt-get update
复制代码

然后使用以下命令在树莓派上安装OpenCV所需的依赖项。

  1. sudo apt-get install libhdf5-dev -y
  2. sudo apt-get install libhdf5-serial-dev –y
  3. sudo apt-get install libatlas-base-dev –y
  4. sudo apt-get install libjasper-dev -y
  5. sudo apt-get install libqtgui4 –y
  6. sudo apt-get install libqt4-test –y
复制代码

之后,使用以下命令在树莓派上安装 OpenCV。

  1. pip3 install opencv-contrib-python==4.1.0.25
复制代码

在树莓派上安装 PyAutoGUI

PyAutoGUI 是一个跨平台的GUI 自动化Python 模块,可让您的Python 脚本控制鼠标和键盘以自动与其他应用程序交互。 PyAutoGUI可以在Windows、macOS和Linux 上运行,并支持Python 2和3。要在树莓派上安装PyAutoGUI,请运行:

  1. pip3 install pyautogui
复制代码

为视频控制器编程树莓派

本节中我们将介绍代码的重要部分,以便更好地理解。


首先在代码中导入OpenCV、MediaPipe和PyAutoGUI包。如前所述,MediaPipe是手势追踪的核心包,而OpenCV用于图像处理。 PyAutoGUI 用于根据手势控制键盘。

  1. import cv2
  2. import mediapipe as mp
  3. import pyautogui
复制代码

接下来,我们新建了两个变量。第一个是 mp_drawing ,它将用于从MediaPipe python包中获取所有绘图实用程序,第二个是 mp_hands ,用于导入手部跟踪模型。

  1. mp_drawing = mp.solutions.drawing_utils
  2. mp_hands = mp.solutions.hands
复制代码

之后定义一个名为 findPosition() 的函数。顾名思义,它用于查找食指、中指、无名指和小指的 X、Y 坐标。所有指尖的坐标将存储在一个名为 lmList[] 的变量中。

  1. def fingerPosition(image, handNo=0):
  2. lmList = []
  3. if results.multi_hand_landmarks:
  4. myHand = results.multi_hand_landmarks[handNo]
  5. for id, lm in enumerate(myHand.landmark):
  6. # print(id,lm)
  7. h, w, c = image.shape
  8. cx, cy = int(lm.x * w), int(lm.y * h)
  9. lmList.append([id, cx, cy])
  10. return lmList
复制代码

然后开始从树莓派摄像头模块中输出视频流,帧高和帧宽分别为720、640。

  1. cap = cv2.VideoCapture(0)
  2. cap.set(3, wCam)
  3. cap.set(4, hCam)
复制代码

然后为mediapipe feed设置一个新实例以访问我们之前导入的Hand Tracking模型。我们还传递了两个关键字参数,即最小检测置信度和最小跟踪置信度。接下来,我们将读取视频帧并将它们存储在 image 变量中。


以mp_hands.Hands(min_detection_confidence=0.8, min_tracking_confidence=0.5) 作为手势:

  1. while cap.isOpened():
  2. success, image = cap.read()
复制代码

我们从视频源中获得的图像最初是BGR格式。因此,在这一行中,我们将首先水平翻转图像以供稍后自拍显示,然后将BGR图像转换为RGB。图像可写标志设置为false。

  1. image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
  2. image.flags.writeable = False
复制代码

之后,我们将通过手部跟踪模型传递图像以进行检测并将结果存储在名为“results”的变量中。

  1. results = hands.process(image)
复制代码

检测完成后,我们将图像可写标志设置为 true 并将RGB图像转换为BGR。

  1. image.flags.writeable = True
  2. image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
复制代码

现在,当我们得到检测结果时,我们将调用 mp_drawing 变量在图像上绘制这些检测,并使用我们之前导入的绘图实用程序连接所有检测。

  1. image.flags.writeable = True
  2. image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
复制代码

之后,我们将调用 findPosition() 函数来获取所有检测的id和坐标。这些值将存储在名为lmList 的变量中。

  1. lmList = findPosition(image, draw=True)
复制代码

现在我们有了所有手部标志的坐标,我们将使用它们来检测不同的手势,其中第一个是检测拳头是松开还是握紧。为此,我们将比较指尖 [8, 12, 16, 20] 和中点 [6, 10, 14, 19] 的坐标,如果指尖低于中点,则拳头握紧,反之张开。

  1. for id in range(1, 5):
  2. if lmList[tipIds[id]][2] < lmList[tipIds[id] - 2][2]:
  3. fingers.append(1)
  4. if (lmList[tipIds[id]][2] > lmList[tipIds[id] - 2][2]):
  5. fingers.append(0)
复制代码

然后在接下来的代码中获取计数的手指总数并将其保存在名为totalFingers 的变量中。

  1. totalFingers = fingers.count(1)
  2. print(totalFingers)
复制代码

现在我们得到了手指的数量,使用它们来播放和暂停视频。

  1. if totalFingers == 4:
  2. state = "Play"
  3. if totalFingers == 0 and state == "Play":
  4. state = "Pause"
  5. pyautogui.press('space')
  6. print("Space")
复制代码

然后我们要检测的下一个手势是向左、向右、向上和向下移动。要检测左右移动,首先,我们将获得食指尖的 X 坐标,如果值小于 300 则为左滑动,如果值大于 400 则为右滑动。

  1. if totalFingers == 1:
  2. if lmList[8][1]<300:
  3. print("left")
  4. pyautogui.press('left')
  5. if lmList[8][1]>400:
  6. print("Right")
  7. pyautogui.press('Right')
复制代码

同样的,检测上下手势我们会得到中指的Y坐标,如果小于210就是上滑,大于230就是下滑.

  1. if totalFingers == 2:
  2. if lmList[9][2] < 210:
  3. print("Up")
  4. pyautogui.press('Up')
  5. if lmList[9][2] > 230:
  6. print("Down")
  7. pyautogui.press('Down')
复制代码

测试我们的手势控制视频控制器脚本

现在视频控制器脚本已准备就绪,让我们继续测试它。将摄像头模块与树莓派连接,如下所示: