如何构建手势控制Raspberry Pi媒体播放器

发布时间:2023-06-06  

  在本教程中,我们将使用MediaPipePython 库来检测我们的手势并使用它来控制 Raspberry Pi 媒体播放器。在这里,我们将使用总共六个手势,即开合拳和手的上、下、左、右移动。打开和关闭拳头手势用于播放和暂停视频。上下手势用于增大和减小音量,左右手势用于快进和倒退视频。


  构建手势控制媒体播放器所需的组件


  树莓派 4


  Pi 相机模块


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


  什么是媒体管道?


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


  物体检测


  人脸检测


  手部追踪


  姿势估计


  多手追踪


  头发分割


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


须藤 pip3 安装 mediapipe-rpi4


如果您没有 Pi 4,则可以使用以下命令将其安装在 Raspberry Pi 3 上:


须藤 pip3 安装 mediapipe-rpi3


在树莓派上安装 OpenCV


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


sudo apt-get 更新


然后使用以下命令安装在 Raspberry Pi 上安装 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


之后,使用以下命令在您的 Raspberry Pi 上安装 OpenCV。


pip3 安装 opencv-contrib-python==4.1.0.25


在树莓派上安装PyAutoGUI


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


pip3 安装 pyautogui


为媒体控制器编程树莓派


文档末尾给出了使用手势控制媒体播放器的完整代码。在这里,我们将解释代码的重要部分,以便更好地解释。


通过导入 OpenCV、MediaPipe 和 PyAutoGUI 包来启动代码。如前所述,MediaPipe 是手部跟踪的核心包,而 OpenCV 用于图像处理。PyAutoGUI 用于根据手势控制键盘。


导入简历2

将媒体管道导入为 mp

导入pyautogui


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


mp_drawing = mp.solutions.drawing_utils

mp_hands = mp.solutions.hands


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


def 手指位置(图像,handNo=0):

    lmList = []

    如果结果.multi_hand_landmarks:

        myHand = results.multi_hand_landmarks[handNo]

        对于 id, lm in enumerate(myHand.landmark):

            # 打印(id,lm)

            h, w, c = image.shape

            cx, cy = int(lm.x * w), int(lm.y * h)

            lmList.append([id, cx, cy])

    返回 lmList


然后从 Raspberry Pi 相机开始视频流,帧高和宽分别为 720、640。


上限 = cv2.VideoCapture(0)

cap.set(3, wCam)

cap.set(4, hCam)


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


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


  而 cap.isOpened():

  成功,图像 = cap.read()

 

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


图像 = cv2.cvtColor(cv2.flip(图像, 1), cv2.COLOR_BGR2RGB)

image.flags.writeable = False


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


结果=hands.process(图像)


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


image.flags.writeable = True

图像 = cv2.cvtColor(图像,cv2.COLOR_RGB2BGR)


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


    如果结果.multi_hand_landmarks:

      对于 results.multi_hand_landmarks 中的 hand_landmarks:

        mp_drawing.draw_landmarks(

            图片、hand_landmarks、mp_hands.HAND_CONNECTIONS)


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


lmList = findPosition(图像,绘制=真)


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

poYBAGLnl_qAJGQOAAIpk278HHQ182.png

  对于范围内的 id(1, 5):


            如果 lmList[tipIds[id]][2] < lmList[tipIds[id] - 2][2]:

                手指.append(1)

            如果(lmList[tipIds[id]][2] > lmList[tipIds[id] - 2][2]):

                手指.append(0)


然后在接下来的几行中,获取计数的手指总数并将其保存在一个名为totalFingers的变量中。


totalFingers = Fingers.count(1)

        打印(总手指)


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


        如果 totalFingers == 4:

            状态 = “播放”

        如果 totalFingers == 0 并且 state == "Play":

            状态 = “暂停”

            pyautogui.press('空格')

            打印(“空间”)


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


        如果 totalFingers == 1:

            如果 lmList[8][1]<300:

                打印(“左”)

                pyautogui.press('左')

            如果 lmList[8][1]>400:

                打印(“正确”)

                pyautogui.press('对')


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


        如果 totalFingers == 2:

            如果 lmList[9][2] < 210:

                打印(“向上”)

                pyautogui.press('向上')

            如果 lmList[9][2] > 230:

                打印(“向下”)

                pyautogui.press('向下')


  测试我们的手势控制媒体控制器脚本


  现在媒体计数器脚本已经准备好了,让我们继续测试它。因此,将 Raspberry Pi 摄像头模块与 Pi 连接,如下所示:


poYBAGLnl92AW8YyAAQKLhW8QrU136.png

  现在,检查 Pi 相机是否正常工作。查看相机后,启动 Python 脚本,您会发现弹出一个窗口,其中包含视频源。现在,您可以通过手势控制视频播放器。您可以在下面找到该项目的工作视频。您可以将视频源更改为您选择的任何视频,并享受通过手势控制它的乐趣。

导入简历2
将媒体管道导入为 mp
导入pyautogui
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
##################################
tipIds = [4, 8, 12, 16, 20]
状态 = 无
手势 = 无
wCam, hCam = 720, 640
############################
def 手指位置(图像,handNo=0):
lmList = []
如果结果.multi_hand_landmarks:
myHand = results.multi_hand_landmarks[handNo]
对于 id, lm in enumerate(myHand.landmark):
# 打印(id,lm)
h, w, c = image.shape
cx, cy = int(lm.x * w), int(lm.y * h)
lmList.append([id, cx, cy])
返回 lmList
# 对于网络摄像头输入:
上限 = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, hCam)
与 mp_hands.Hands(
min_detection_confidence=0.8,
min_tracking_confidence=0.5) 作为手牌:
而 cap.isOpened():
成功,图像 = cap.read()
如果不成功:
print("忽略空相机帧。")
# 如果加载视频,请使用“break”而不是“continue”。
继续
# 水平翻转图像以供稍后自拍视图显示,并转换
# 将 BGR 图像转为 RGB。
图像 = cv2.cvtColor(cv2.flip(图像, 1), cv2.COLOR_BGR2RGB)
image.flags.writeable = False
结果=hands.process(图像)
# 在图像上绘制手部注释。
image.flags.writeable = True
图像 = cv2.cvtColor(图像,cv2.COLOR_RGB2BGR)
如果结果.multi_hand_landmarks:
对于 results.multi_hand_landmarks 中的 hand_landmarks:
mp_drawing.draw_landmarks(
图片、hand_landmarks、mp_hands.HAND_CONNECTIONS)
lmList = 手指位置(图像)
#打印(lmList)
如果 len(lmList) != 0:
手指 = []
对于范围内的 id(1, 5):
如果 lmList[tipIds[id]][2] < lmList[tipIds[id] - 2][2]:
#state = "播放"
手指.append(1)
如果 (lmList[tipIds[id]][2] > lmList[tipIds[id] - 2][2] ):
# state = "暂停"
# pyautogui.press('空格')
# print("空格")
手指.append(0)
totalFingers = Fingers.count(1)
打印(总手指)
#print(lmList[9][2])

如果 totalFingers == 4:
状态 = “播放”
# finger.append(1)
如果 totalFingers == 0 并且 state == "Play":
状态 = “暂停”
pyautogui.press('空格')
打印(“空间”)
如果 totalFingers == 1:
如果 lmList[8][1]<300:
打印(“左”)
pyautogui.press('左')
如果 lmList[8][1]>400:
打印(“正确”)
pyautogui.press('对')
如果 totalFingers == 2:
如果 lmList[9][2] < 210:
打印(“向上”)
pyautogui.press('向上')
如果 lmList[9][2] > 230:
打印(“向下”)
pyautogui.press('向下')
#cv2.putText(image, str("Gesture"), (10,40), cv2.FONT_HERSHEY_SIMPLEX,
# 1, (255, 0, 0), 2)
cv2.imshow("媒体控制器", image)
键 = cv2.waitKey(1) & 0xFF
# 如果 `q` 键被按下,则退出循环
如果键 == ord("q"):
休息
cv2.destroyAllWindows()


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>