Jetson 24 基于 MediaPipe 的姿态检测

来自Waveshare Wiki
跳转至: 导航搜索

基于 MediaPipe 的姿态检测

本章节介绍如何使用 MediaPipe + OpenCV 来实现姿态检测。

什么是 MediaPipe?

MediaPipe 是 Google 开发的一种开源框架,用于构建基于机器学习的多媒体处理应用程序。它提供了一组工具和库,可以用于处理视频、音频和图像数据,并应用机器学习模型来实现各种功能,如姿态估计、手势识别、人脸检测等。MediaPipe 的设计目标是提供高效、灵活和易用的解决方案,使开发者能够快速构建出各种多媒体处理应用。

准备工作

由于产品开机默认会自动运行主程序,主程序会占用摄像头资源,这种情况下是不能使用本教程的,需要结束主程序或禁止主程序自动运行后再重新启动机器人。

这里需要注意的是,由于机器人主程序中使用了多线程且由 crontab 配置开机自动运行,所以常规的 sudo killall python 的方法通常是不起作用的,所以我们这里介绍禁用主程序自动运行的方法。

如果你已经禁用了机器人主程序的开机自动运行,则不需要执行下面的结束主程序章节。

结束主程序

1. 点击上方本页面选项卡旁边的 “+”号,会打开一个新的名为 Launcher 的选项卡。

2. 点击 Other 内的 Terminal,打开终端窗口。

3. 在终端窗口内输入 bash 后按回车。

4. 现在你可以使用 Bash Shell 来控制机器人了。

5. 输入命令: sudo killall -9 python


例程

以下代码块可以直接运行:

1. 选中下面的代码块

2. 按 Shift + Enter 运行代码块

3. 观看实时视频窗口

4. 按 STOP 关闭实时视频,释放摄像头资源

如果运行时不能看到摄像头实时画面

  • 需要点击上方的 Kernel - Shut down all kernels
  • 关闭本章节选项卡,再次打开
  • 点击 STOP 释放摄像头资源后重新运行代码块
  • 重启设备

注意事项

如果使用USB摄像头则需要取消注释 frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 这一句。

本章节特性

当代码块正常运行时,当画面中出现人脸,MediaPipe 会自动标记出人肢体的关节。

import cv2  # 导入 OpenCV 库,用于图像处理
import imutils, math  # 辅助图像处理和数学运算的库
from picamera2 import Picamera2  # 用于访问 Raspberry Pi Camera 的库
from IPython.display import display, Image  # 用于在 Jupyter Notebook 中显示图像
import ipywidgets as widgets  # 用于创建交互式界面的小部件,如按钮
import threading  # 用于创建新线程,以便异步执行任务
import mediapipe as mp  # 导入 MediaPipe 库,用于姿态检测

# 创建一个“停止”按钮,用户可以通过点击它来停止视频流
# ================
stopButton = widgets.ToggleButton(
    value=False,
    description='Stop',
    disabled=False,
    button_style='danger', # 'success', 'info', 'warning', 'danger' or ''
    tooltip='Description',
    icon='square' # (FontAwesome names without the `fa-` prefix)
)

# 初始化 MediaPipe 的绘图工具和姿态检测模型
mpDraw = mp.solutions.drawing_utils


# MediaPipe Hand GS
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(static_image_mode=False, 
                    model_complexity=1, 
                    smooth_landmarks=True, 
                    min_detection_confidence=0.5, 
                    min_tracking_confidence=0.5)

# 定义显示函数,用于处理视频帧并进行姿态检测
def view(button):
    picam2 = Picamera2()  # 创建 Picamera2 的实例
    picam2.configure(picam2.create_video_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))  # 配置摄像头参数
    picam2.start()  # 启动摄像头
    display_handle=display(None, display_id=True)  # 创建显示句柄用于更新显示的图像
    
    while True:
        frame = picam2.capture_array()
        # frame = cv2.flip(frame, 1) # if your camera reverses your image

        # uncomment this line if you are using USB camera
        # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        img = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        
        results = pose.process(img) # 使用 MediaPipe 处理图像,获取姿态检测结果

         # 如果检测到姿态关键点
        if results.pose_landmarks:
            frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)  # 将图像从 RGB 转换为 BGR 以供绘制使用
            mpDraw.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)  # 使用 MediaPipe 的绘图工具绘制姿态关键点和连接线
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  # 将图像从 BGR 转换回 RGB 以供显示
            
        _, frame = cv2.imencode('.jpeg', frame)  # 将处理后的帧编码为 JPEG 格式
        display_handle.update(Image(data=frame.tobytes()))  # 更新显示的图像
        if stopButton.value==True:  # 检查“停止”按钮是否被按下
            picam2.close()  # 如果是,则关闭摄像头
            display_handle.update(None)  # 清空显示的内容

# 显示“停止”按钮并启动显示函数的线程
display(stopButton)
thread = threading.Thread(target=view, args=(stopButton,))
thread.start()  # 启动线程