一板网电子技术论坛

风筝
发表于: 2021-7-1 17:48:27 | 显示全部楼层

由于最近虚拟和增强现实技术的增长和普及,手势识别技术正变得越来越流行。在本篇文字中,我们将使用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
复制代码

跳转到指定楼层
风筝
发表于: 2021-7-2 08:58:12 | 显示全部楼层

为视频控制器编程树莓派

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


首先在代码中导入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] 的坐标,如果指尖低于中点,则拳头握紧,反之张开。

Hand-Gesturer-recognition.jpg

  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')
复制代码

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

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

Gesture-Controlled-Video-Player.jpg


现在,检查摄像头是否正常工作。查看后,启动Python 脚本,您会发现弹出一个窗口,其中包含视频源。现在,您可以通过手势控制视频播放器。希望您喜欢搭建该项目并学到了新东西,如果您有任何问题,请随时在本帖下面进行回复。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



手机版|

GMT+8, 2021-8-1 13:43 , Processed in 0.026584 second(s), 10 queries , MemCache On. Powered by Discuz! X3.4

YiBoard一板网 © 2015-2021 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表