mediapipe实现实时动作检测【python版本】

前言

MediaPipe为直播和流媒体提供跨平台、可定制的机器学习(MachineLearning) 解决方案。利用mediapipe和python可以实现以下功能:

  1. MediaPipe Face Detection 人脸检测
  2. MediaPipe Face Mesh 人脸三维关键点(468个)检测
  3. MediaPipe Hands 手部关键点检测
  4. MediaPipe Holistic 人体识别
  5. MediaPipe Objectron 物体识别
  6. MediaPipe Pose 人体动作姿态识别
  7. MediaPipe Selfie Segmentation 自拍分割

本文代码运行环境:win10,python3.7,pycharm,mediapipe 0.8.10,
涉及到的Python库为:opencv-python,mediapipe,matplotlib

安装opencv-python

在python中使用pip install指令安装库很简单,由于包比较大所以使用豆瓣源安装

pip install opencv-python -i https://pypi.douban.com/simple/

调用opencv相关函数时导入的包为:

import cv2 as cv

对于使用pycharm导入cv2之后没有代码提示的问题,可以参考此文章
解决Opencv / cv2没有代码提示的问题

安装mediapipe

pip install mediapipe -i https://pypi.douban.com/simple/

可能遇到的错误

  1. 包的版本问题
    在这里插入图片描述
    报错是因为protobuf这个包的版本太高了导致不兼容,卸载重装低版本的就行
 pip uninstall protobuf
pip install protobuf==3.19.0
  1. 第一次运行mediapipe代码可能需要下载模型
    第一次运行mediapipe 代码的时候 有时候会下载模型,但是有时候因为网络问题,可能下载不下来,报错:
Downloading model to D:\anaconda\envs\virtual_mediapipe\lib\site-packages\mediapipe/modules/pose_landmark/pose_landmark_heavy.tflite

TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连 接尝试失败。
[ WARN:0] global C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-_xlv4eex\opencv\modules\videoio\src\cap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback

可以去github或gitee上下载对应的包
https://github.com/google/mediapipe/tree/master/mediapipe/modules/pose_landmark
https://gitee.com/mirrors/mediapipe/tree/master/mediapipe/modules/pose_landmark
输出信息中写了 他会把需要的包下载到什么文件夹:

Downloading model to D:\anaconda\envs\virtual_mediapipe \lib\sitepackages\mediapipe/modules/pose_landmark/pose_landmark_heavy.tflite
比如这个模型:pose_landmark_heavy.tflite
在这里插入图片描述
把对应文件下载下来后复制粘贴到这个文件夹就解决了
在这里插入图片描述
接下来就可以愉快的使用mediapipe了

补充(2022-9-19):
tflite更改
由于开发者说他们在0.8.11版本以后已经不在把.tflite这样的比较大的二进制文件放在github上存储了,而是让程序从Google Cloud Storage上下载,所以国内一般会报错。考虑到找这这个文件比较麻烦,如果需要这两个文件的同志可以到这里下载:https://wwp.lanzoup.com/iDEQ70byj22j
在这里插入图片描述
如果是运行上述七种功能中的其他几种(比如MediaPipe Face Detection、MediaPipe Face Mesh、MediaPipe Hands等)也遇到类似缺少模型但又因网络问题无法下载的情况,可以前往github上找到开发者之前发布(releases)的mediapipe(比如0.8.10.12及其之前)的版本下载下来,这里面也仍然还保留有所有需要的.tflite文件。链接:https://github.com/google/mediapipe/releases
0.8.10.12
0.8.10.12及其之前的版本达到了266MB,如果github下载慢的话,这里也提供一个123网盘的下载链接:https://www.123pan.com/s/XuubVv-jFmvd.html

先来实现单张图片的人体关键点检测检测

import cv2 as cv
import mediapipe as mp
import matplotlib.pyplot as plt


# 定义可视化图像函数
def look_img(img):
    # opencv读入图像格式为BGR,matplotlib可视化格式为RGB,因此需要将BGR转为RGB
    img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
    plt.imshow(img_rgb)
    plt.show()


# 导入solution
mp_pose = mp.solutions.pose

# 导入绘图函数
mp_drawing = mp.solutions.drawing_utils

# 导入模型
pose = mp_pose.Pose(static_image_mode=True,         # 是静态图片还是连续视频帧
                    model_complexity=2,             # 选择人体姿态关键点检测模型,0性能差但快,2性能好但慢,1介于两者之间
                    smooth_landmarks=True,          # 是否平滑关键点
                    enable_segmentation=True,       # 是否人体抠图
                    min_detection_confidence=0.5,   # 置信度阈值
                    min_tracking_confidence=0.5     # 追踪阈值
                    )

# 读入图像
img = cv.imread('2.png')
# BGR转RGB
img_RGB = cv.cvtColor(img, cv.COLOR_BGR2RGB)
# 将图像输入模型,获取预测结果
results = pose.process(img_RGB)

# 可视化结果
mp_drawing.draw_landmarks(img, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
look_img(img)

# 在三维真实物理坐标系中以米为单位可视化人体关键点
mp_drawing.plot_landmarks(results.pose_world_landmarks, mp_pose.POSE_CONNECTIONS)

原图是这样的
在这里插入图片描述
经过关键点识别之后是这样的
在这里插入图片描述
三维人体图像是这样的,由于第三个维度是预测出来的,所以有时候不是很准确。
在这里插入图片描述

实现视频实时动作检测

会了单张图像检测后,视频检测就非常简单了。
视频就是由连续的一帧一帧图像组成的,摄像头实时获取的视频也不例外,只需要调用cv2(opencv)里的视频捕捉函数一帧一帧读取图像就可以了。

import cv2 as cv
import mediapipe as mp


# 导入solution
mp_pose = mp.solutions.pose
# 导入绘图函数
mp_drawing = mp.solutions.drawing_utils

# 导入模型
pose = mp_pose.Pose(static_image_mode=True,  # 是静态图片还是连续视频帧
                    model_complexity=2,  # 选择人体姿态关键点检测模型,0性能差但快,2性能好但慢,1介于两者之间
                    smooth_landmarks=True,  # 是否平滑关键点
                    enable_segmentation=True,  # 是否人体抠图
                    min_detection_confidence=0.5,  # 置信度阈值
                    min_tracking_confidence=0.5  # 追踪阈值
                    )


# 处理单帧的函数
def process_frame(img):
    img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
    results = pose.process(img_rgb)

    mp_drawing.draw_landmarks(img, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
    return img


# 读取视频帧的函数
def process_cap(cap, gap):
    while cap.isOpened():
        # 读视频帧
        ret, frame = cap.read()
        if ret:  # 判断是否读取成功
            # 如果读取成功则处理该帧
            frame = process_frame(frame)
            # 展示处理后的三通道图像
            cv.imshow('video', frame)
            # 按键盘的esc或者q退出
            if cv.waitKey(gap) in [ord('q'), 27]:
                break
        else:
            # print('error!')
            break

    # 关闭摄像头
    cap.release()
    # 关闭图像窗口
    cv.destroyAllWindows()


# 从摄像头实时检测
def detect_camera():
    # 创建窗口
    cv.namedWindow('video', cv.WINDOW_NORMAL)
    # 调用摄像头获取画面  0是windows系统下默认的摄像头,1是Mac系统
    cap = cv.VideoCapture(0)

    process_cap(cap, 1)


# 从本地导入视频检测
def detect_video(path):
    # 创建窗口
    cv.namedWindow('video', cv.WINDOW_NORMAL)

    # 从本地读取视频
    cap = cv.VideoCapture(path)
    # 获取原视频帧率
    fps = cap.get(cv.CAP_PROP_FPS)
    # 获取原视频窗口大小
    width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
    # print(fps)
    # 视频两帧之间的播放间隔,单位为毫秒
    gap = int(1000 / fps)
    cv.resizeWindow('video',width,height)
    process_cap(cap, gap)


if __name__ == '__main__':
    while True:
        menu = int(input('请选择检测模式:1. 打开摄像头检测\t2. 从本地导入视频检测\t3. 退出\n'))
        if menu == 1:
            detect_camera()
            break
        elif menu == 2:
            path = input('请输入视频路径(例如:D:\\download\\abc.mp4):\n')
            detect_video(path)
            break
        elif menu == 3:
            break
        else:
            print("输入错误,请重新输入!")
            continue

  • 14
    点赞
  • 164
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
### 回答1: PythonOpenCV库和MediaPipe工具包是可以一起使用的,以实现手势识别的功能。 首先,需要在Python中安装OpenCV库和MediaPipe工具包。可以使用pip命令来安装它们: ``` pip install opencv-python pip install mediapipe ``` 安装完成后,就可以开始使用了。 首先,导入必要的库: ```python import cv2 import mediapipe as mp ``` 接下来,创建一个MediaPipe的Hand对象和一个OpenCV的VideoCapture对象,用于读取摄像头输入: ```python mp_hands = mp.solutions.hands hands = mp_hands.Hands() cap = cv2.VideoCapture(0) ``` 然后,使用一个循环来读取摄像头输入并进行手势识别: ```python while True: ret, frame = cap.read() if not ret: break frame_RGB = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results = hands.process(frame_RGB) if results.multi_handedness: for hand_landmarks in results.multi_hand_landmarks: # 在这里可以对hand_landmarks进行处理和识别手势的操作 cv2.imshow('Gesture Recognition', frame) if cv2.waitKey(1) == ord('q'): break ``` 在循环中,首先将读取到的帧转换为RGB格式,然后使用Hands对象的process方法对该帧进行手势识别。得到的结果存储在results变量中。 在对每个检测到的手部进行循环处理时,可以使用hand_landmarks来获取该手的关键点坐标。可以根据这些关键点的位置和运动轨迹来实现手势的识别和分析。 最后,通过cv2.imshow方法显示图像,并使用cv2.waitKey方法等待用户操作。当用户按下"q"键时,循环终止,程序退出。 通过以上步骤,就可以使用PythonOpenCV库和MediaPipe工具包实现手势识别的功能了。当然,实际的手势识别算法和操作需要根据具体需求进行进一步的开发和优化。 ### 回答2: Python OpenCVMediaPipe结合使用可以实现手势识别。首先,我们需要安装必要的库和工具,包括Pythonopencv-pythonmediapipe和其他依赖项。 然后,我们可以使用MediaPipe提供的HandTracking模块来检测手部的关键点。它使用机器学习模型来识别手势,并返回手部关键点的坐标。我们可以通过OpenCV的视频捕捉模块读取摄像头的实时图像。 接下来,我们通过应用MediaPipe的HandTracking模块获取手部关键点的坐标,并使用OpenCV将这些坐标绘制到图像上,以便我们可以实时看到手部的位置和动作。 完成这些基本的设置后,我们可以定义特定的手势,例如拇指和食指的指尖接触,作为一个简单的示例。我们可以通过检查特定的关键点之间的距离和角度来识别这种手势。如果关键点之间的距离较小并且角度较小,则我们可以确定手势是拇指和食指的指尖接触。 我们可以使用类似的方法来识别其他手势,比如手掌的张开和闭合,拳头的形成等等。我们可以定义一系列规则和阈值来确定特定手势的识别。 最后,我们可以根据检测到的手势执行特定的操作。例如,当识别到拇指和食指的指尖接触时,我们可以触发相机的快门,实现手势拍照。 总之,PythonOpenCVMediaPipe结合使用可以实现手势识别。我们可以利用MediaPipe的HandTracking模块检测手部关键点,并使用OpenCV实时绘制手势位置。通过定义特定手势的规则,我们可以识别各种手势并执行相应操作。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值