Mediapipe-姿态估计实例

news2024/9/26 1:22:27

Mediapipe简介

Mediapipe 是由 Google Research 开发的一款开源框架,旨在帮助开发者轻松地构建、测试和部署复杂的多模态、多任务的机器学习模型。它特别擅长于实时处理和分析音频、视频等多媒体数据。以下是 Mediapipe 的一些关键特点和组件:

关键特点

  1. 多平台支持:Mediapipe 支持在多个平台上运行,包括桌面、移动设备和网页。这使得开发者可以轻松地将模型部署到不同的平台上。

  2. 高效的实时处理:Mediapipe 具有高度优化的性能,能够在资源受限的设备上进行实时处理。这使其特别适合于移动设备和嵌入式系统。

  3. 模块化设计:Mediapipe 使用图表(graph)来组织和连接不同的处理模块。这种设计使得开发者可以灵活地组合和复用不同的处理组件。

  4. 丰富的预构建解决方案:Mediapipe 提供了许多预构建的解决方案,如人脸检测、手部追踪、姿态估计等,开发者可以直接使用这些解决方案来快速构建应用。

主要组件

  1. 图表(Graph):Mediapipe 的核心是其图表结构,图表定义了数据流和处理模块的连接方式。每个图表由一系列节点(nodes)和边(edges)组成,节点表示具体的处理模块,边表示数据在节点之间的流动。

  2. 节点(Nodes):节点是图表的基本单元,表示具体的处理操作。Mediapipe 提供了许多内置的节点,如数据输入输出节点、图像处理节点、机器学习推理节点等。

  3. 数据包(Packets):数据包是图表中传输的数据单元,节点之间通过发送和接收数据包来通信。数据包可以包含各种类型的数据,如图像帧、音频信号、检测结果等。

  4. 计算机视觉解决方案:Mediapipe 提供了许多预构建的计算机视觉解决方案,这些解决方案已经高度优化,能够在实时应用中使用。常见的解决方案包括人脸检测、手部追踪、姿态估计、对象检测等。

常见使用场景

  1. 姿态估计(Pose Estimation):Mediapipe 可以实时检测和追踪人体的关键点(如肩膀、肘部、膝盖等),并估计人体的姿态。这对于体育训练、动作捕捉、增强现实等应用非常有用。

  2. 手部追踪(Hand Tracking):Mediapipe 能够检测和追踪手部的关键点,提供手势识别和手部动作分析的能力。这在手势控制、虚拟现实、手写输入等应用中有广泛的应用。

  3. 人脸检测(Face Detection):Mediapipe 提供了高效的人脸检测和关键点追踪功能,可以用于面部识别、表情分析、虚拟化妆等场景。

  4. 对象检测(Object Detection):Mediapipe 还提供了实时的对象检测解决方案,可以用于监控、无人驾驶、智能家居等领域。

示例代码

以下是一个使用 Mediapipe 进行姿态估计的简单示例:

import cv2
import mediapipe as mp

# Initialize mediapipe pose class.
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()

# Initialize mediapipe drawing class, useful for annotation.
mp_drawing = mp.solutions.drawing_utils

# Load the video file or start webcam capture.
cap = cv2.VideoCapture(0)  # Use 0 for webcam, or provide video file path

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    # Convert the BGR image to RGB.
    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # Process the image and detect the pose.
    result = pose.process(image_rgb)

    # Draw the pose annotation on the image.
    if result.pose_landmarks:
        mp_drawing.draw_landmarks(frame, result.pose_landmarks, mp_pose.POSE_CONNECTIONS)

    # Display the frame with pose landmarks.
    cv2.imshow('Pose Estimation', frame)

    # Break the loop if 'q' is pressed.
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

# Release the video capture object and close display window.
cap.release()
cv2.destroyAllWindows()

这段代码使用 Mediapipe 的姿态估计功能,读取视频流并实时绘制人体的关键点。你可以使用摄像头实时捕捉人体姿态,也可以处理预录制的视频文件。

实例1-读取视频流并进行骨骼点绘制:

import cv2
import mediapipe as mp

# Initialize mediapipe pose class.
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()

# Initialize mediapipe drawing class, useful for annotation.
mp_drawing = mp.solutions.drawing_utils

# Load the video file.
cap = cv2.VideoCapture('D:/basketball.mp4')

# Check if the video is opened successfully.
if not cap.isOpened():
    print("Error: Could not open video.")
    exit()

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("Reached the end of the video.")
        break

    # Convert the BGR image to RGB.
    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # Process the image and detect the pose.
    result = pose.process(image_rgb)

    # Draw the pose annotation on the image.
    if result.pose_landmarks:
        mp_drawing.draw_landmarks(frame, result.pose_landmarks, mp_pose.POSE_CONNECTIONS)

    # Display the frame with pose landmarks.
    cv2.imshow('Pose Estimation', frame)

    # Break the loop if 'q' is pressed.
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

# Release the video capture object and close display window.
cap.release()
cv2.destroyAllWindows()

效果如下:
在这里插入图片描述

实例2-读取视频流中姿态估计与3D绘制:

代码如下:

import cv2
import mediapipe as mp
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from matplotlib.animation import FuncAnimation

# Initialize mediapipe pose class.
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()

# Initialize mediapipe drawing class, useful for annotation.
mp_drawing = mp.solutions.drawing_utils

# Load the video file.
cap = cv2.VideoCapture('D:/basketball.mp4')

# Check if the video is opened successfully.
if not cap.isOpened():
    print("Error: Could not open video.")
    exit()

fig = plt.figure(figsize=(10, 5))
ax2d = fig.add_subplot(121)
ax3d = fig.add_subplot(122, projection='3d')

def update(frame_number):
    ret, frame = cap.read()
    if not ret:
        print("Reached the end of the video.")
        return

    # Convert the BGR image to RGB.
    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # Process the image and detect the pose.
    result = pose.process(image_rgb)

    # Clear the previous plots
    ax2d.clear()
    ax3d.clear()

    # Draw the pose annotation on the image.
    if result.pose_landmarks:
        mp_drawing.draw_landmarks(frame, result.pose_landmarks, mp_pose.POSE_CONNECTIONS)

        # Extract the landmark points.
        landmarks = result.pose_landmarks.landmark
        xs = [landmark.x for landmark in landmarks]
        ys = [landmark.y for landmark in landmarks]
        zs = [landmark.z for landmark in landmarks]

        # Plot 2D image
        ax2d.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
        ax2d.set_title('Pose Estimation')
        ax2d.axis('off')

        # Plot 3D landmarks
        ax3d.scatter(xs, ys, zs, c='blue', marker='o')
        ax3d.set_xlim([0, 1])
        ax3d.set_ylim([0, 1])
        ax3d.set_zlim([-1, 1])
        ax3d.set_xlabel('X')
        ax3d.set_ylabel('Y')
        ax3d.set_zlabel('Z')
        ax3d.set_title('3D Pose Landmarks')

ani = FuncAnimation(fig, update, interval=10)

plt.show()

cap.release()
cv2.destroyAllWindows()

效果如下:
在这里插入图片描述
为了将三维骨骼点连接起来,可以使用 mpl_toolkits.mplot3d.art3d.Line3DCollection 来绘制骨骼连接。你需要定义这些连接的点对,并在三维图中使用它们来绘制线条。以下是更新后的代码:

import cv2
import mediapipe as mp
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Line3DCollection
import numpy as np
from matplotlib.animation import FuncAnimation

# Initialize mediapipe pose class.
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()

# Initialize mediapipe drawing class, useful for annotation.
mp_drawing = mp.solutions.drawing_utils

# Load the video file.
cap = cv2.VideoCapture('D:/basketball.mp4')

# Check if the video is opened successfully.
if not cap.isOpened():
    print("Error: Could not open video.")
    exit()

fig = plt.figure(figsize=(10, 5))
ax2d = fig.add_subplot(121)
ax3d = fig.add_subplot(122, projection='3d')

def update(frame_number):
    ret, frame = cap.read()
    if not ret:
        print("Reached the end of the video.")
        return

    # Convert the BGR image to RGB.
    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # Process the image and detect the pose.
    result = pose.process(image_rgb)

    # Clear the previous plots
    ax2d.clear()
    ax3d.clear()

    # Draw the pose annotation on the image.
    if result.pose_landmarks:
        mp_drawing.draw_landmarks(frame, result.pose_landmarks, mp_pose.POSE_CONNECTIONS)

        # Extract the landmark points.
        landmarks = result.pose_landmarks.landmark
        xs = [landmark.x for landmark in landmarks]
        ys = [landmark.y for landmark in landmarks]
        zs = [landmark.z for landmark in landmarks]

        # Define the connections between landmarks
        connections = [
            (0, 1), (1, 2), (2, 3), (3, 7), (0, 4), (4, 5), (5, 6), (6, 8),
            (9, 10), (11, 12), (11, 13), (13, 15), (15, 17), (15, 19), (15, 21),
            (17, 19), (12, 14), (14, 16), (16, 18), (16, 20), (16, 22), (18, 20),
            (11, 23), (12, 24), (23, 24), (23, 25), (24, 26), (25, 27), (26, 28),
            (27, 29), (28, 30), (29, 31), (30, 32)
        ]

        # Create a list of 3D lines
        lines = [[(xs[start], ys[start], zs[start]), (xs[end], ys[end], zs[end])] for start, end in connections]

        # Plot 2D image
        ax2d.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
        ax2d.set_title('Pose Estimation')
        ax2d.axis('off')

        # Plot 3D landmarks and connections
        ax3d.scatter(xs, ys, zs, c='blue', marker='o')
        ax3d.add_collection3d(Line3DCollection(lines, colors='blue', linewidths=2))
        ax3d.set_xlim([0, 1])
        ax3d.set_ylim([0, 1])
        ax3d.set_zlim([-1, 1])
        ax3d.set_xlabel('X')
        ax3d.set_ylabel('Y')
        ax3d.set_zlabel('Z')
        ax3d.set_title('3D Pose Landmarks')

ani = FuncAnimation(fig, update, interval=10)

plt.show()

cap.release()
cv2.destroyAllWindows()

在这个代码中,我们定义了 connections 列表,它包含了骨骼点之间的连接对。然后我们创建了一个 lines 列表,用于存储这些连接的三维线段,并使用 ax3d.add_collection3d(Line3DCollection(lines, colors='blue', linewidths=2)) 方法将这些线段添加到三维图中。

运行这个脚本后,三维图中不仅会显示骨骼点,还会将这些点连起来,形成完整的骨骼结构。
效果如下:
在这里插入图片描述
上面的代码看似三维图的骨骼是倒立的,你可以调整三维图的坐标显示,以使得骨骼结构显示为正常的人体姿态。可以通过设置三维图的坐标轴范围和方向来调整显示效果。以下是修改后的代码,调整了坐标轴的范围和方向,以使骨骼结构正常显示:

import cv2
import mediapipe as mp
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Line3DCollection
import numpy as np
from matplotlib.animation import FuncAnimation

# Initialize mediapipe pose class.
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()

# Initialize mediapipe drawing class, useful for annotation.
mp_drawing = mp.solutions.drawing_utils

# Load the video file.
cap = cv2.VideoCapture('D:/basketball.mp4')

# Check if the video is opened successfully.
if not cap.isOpened():
    print("Error: Could not open video.")
    exit()

fig = plt.figure(figsize=(10, 5))
ax2d = fig.add_subplot(121)
ax3d = fig.add_subplot(122, projection='3d')

def update(frame_number):
    ret, frame = cap.read()
    if not ret:
        print("Reached the end of the video.")
        return

    # Convert the BGR image to RGB.
    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # Process the image and detect the pose.
    result = pose.process(image_rgb)

    # Clear the previous plots
    ax2d.clear()
    ax3d.clear()

    # Draw the pose annotation on the image.
    if result.pose_landmarks:
        mp_drawing.draw_landmarks(frame, result.pose_landmarks, mp_pose.POSE_CONNECTIONS)

        # Extract the landmark points.
        landmarks = result.pose_landmarks.landmark
        xs = [landmark.x for landmark in landmarks]
        ys = [landmark.y for landmark in landmarks]
        zs = [-landmark.z for landmark in landmarks]  # Negate the z-axis for better visualization

        # Define the connections between landmarks
        connections = [
            (0, 1), (1, 2), (2, 3), (3, 7), (0, 4), (4, 5), (5, 6), (6, 8),
            (9, 10), (11, 12), (11, 13), (13, 15), (15, 17), (15, 19), (15, 21),
            (17, 19), (12, 14), (14, 16), (16, 18), (16, 20), (16, 22), (18, 20),
            (11, 23), (12, 24), (23, 24), (23, 25), (24, 26), (25, 27), (26, 28),
            (27, 29), (28, 30), (29, 31), (30, 32)
        ]

        # Create a list of 3D lines
        lines = [[(xs[start], ys[start], zs[start]), (xs[end], ys[end], zs[end])] for start, end in connections]

        # Plot 2D image
        ax2d.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
        ax2d.set_title('Pose Estimation')
        ax2d.axis('off')

        # Plot 3D landmarks and connections
        ax3d.scatter(xs, ys, zs, c='blue', marker='o')
        ax3d.add_collection3d(Line3DCollection(lines, colors='blue', linewidths=2))
        ax3d.set_xlim([0, 1])
        ax3d.set_ylim([1, 0])  # Flip the y-axis for better visualization
        ax3d.set_zlim([1, -1])
        ax3d.set_xlabel('X')
        ax3d.set_ylabel('Y')
        ax3d.set_zlabel('Z')
        ax3d.set_title('3D Pose Landmarks')

ani = FuncAnimation(fig, update, interval=10)

plt.show()

cap.release()
cv2.destroyAllWindows()

在这个代码中:

  1. 通过取反 zs 坐标 (zs = [-landmark.z for landmark in landmarks]),使得骨骼点的 Z 轴方向与预期一致。
  2. 通过设置 ax3d.set_ylim([1, 0]) 来翻转 Y 轴的方向,以便更符合常见的视觉习惯。

运行这个脚本后,三维图中的骨骼结构应会显示为正常的人体姿态。
显示效果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1920310.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Unity2D 2022:UI】制作主菜单

一、创建主菜单游戏场景 1. 在Scenes文件夹中新建一个游戏场景Main Menu 2. 为场景添加背景 (1)创建画布Canvas (2)在Canvas中创建新的空游戏物体Main Menu (3)在Main Menu中新建一个图像游戏物体Backgrou…

Java项目中,常用的SQL语句

常用的命令: 1.数据的增删改查 1.插入数据(进行注册) 语法 1: --第一种: INSERT INTO 表名(列名 1,列名 2, …) ; insert into tablename(member1,member3) valuse(,); --第二种: INSERT INTO 表名 VALUES(值 1,值 …

Linux工具篇:yum

前言: 目录 前言: Linux 软件包管理器 yum yum是什么? 什么是软件包? Linux系统(centos)的生态: 那我的yum是怎么找到对应的软件呢? 关于 rzsz yum查看软件包(安装…

Python task

def wordcount(text):# 将文本分割成单词列表,并转换为小写words text.lower().split()# 初始化一个空字典用于存储单词计数word_counts {}# 遍历单词列表中的每个单词for word in words:# 如果单词在字典中,则计数加1,否则将单词加入字典并…

配置sublime的中的C++编译器(.sublime-build),实现C++20在sublime中的使用,小白教程

一,前期准备 首先我们需要准备一下 C 环境,当然如果你觉得你当前的C环境配置好了,并且C的版本也能完成您日常的使用需求,您可以使用下面两条命令对C的版本进行查询 g -vg --version通过返回的版本简单的判断是否能解决您的需求&…

Delta的最新更新可让iPad用户同时模拟多款游戏

Delta iOS 应用程序发布了一个更新,引入了复古 游戏模拟器重新设计的标识,以及原生 iPad 支持,允许用户同时玩多个 游戏。 据 Delta 开发者 Riley Testut 称,欧盟用户可以立即通过AltStore PAL 下载更新,但其他用户则需…

Tomcat多实例

一、Tomcat多实例 Tomcat多实例是指在同一台服务器上运行多个独立的tomcat实例,每个tomcat实例都具有独立的配置文件、日志文件、应用程序和端口,通过配置不同的端口和文件目录,可以实现同时运行多个独立的Tomcat服务器,每个服务…

成为编程大佬!!----->数据结构与算法(2)——顺序表!!

前言:线性表是数据结构与算法的重中之重,所有具有线性逻辑结构的数据结构,都能称为线性表。这篇文章我们先来讨论线性表中的顺序表,顺序表和线性表都是后续实现栈,树,串和图等等结构的重要基础。 目录 ❀简…

YOLOv10改进 | 主干/Backbone篇 | 轻量级网络ShuffleNetV1(附代码+修改教程)

一、本文内容 本文给大家带来的改进内容是ShuffleNetV1,这是一种为移动设备设计的高效CNN架构。它通过使用点群卷积和通道混洗等操作,减少了计算成本,同时保持了准确性,通过这些技术,ShuffleNet在降低计算复杂度的同时…

yolov8、RTDETR无法使用多个GPU训练

yolov8、RTDETR无法使用多个GPU训练 网上看了好多解决方法: 什么命令行 CUDA_VISIBLE_DEVICES0,1 python train.py 环境变量都不行 最后找到解决方案:在ultralytics/engine/trainer.py 中的第246行 将 self.model DDP(self.model, device_ids[RANK])…

Web 应用程序开发的前沿:2024 年会发生什么??

Web 应用程序开发是发展最快的领域之一,令人印象深刻地改变了网络空间的给定面貌。 随着我们进入 2024 年,许多进步趋势和技术正在出现,它们整合了开发人员和商人探索他们才能的新领域。 这篇博客将介绍有关创建 Web 应用程序的最新趋势的想法…

记一次若依框架和Springboot常见报错的实战漏洞挖掘

目录 前言 本次测实战利用图​ 1.判段系统框架 2.登录页面功能点测试 2.1 弱口令 2.2 webpack泄露信息判断 2.3 未授权接口信息发现 3.进一步测试发现新的若依测试点 3.1 默认弱口令 3.2 历史漏洞 4.访问8080端口发现spring经典爆粗 4.1 druid弱口令 4.2 SwaggerU…

牛顿力学和拉格朗日力学求解atwood machine问题对比

一个半径为 R R R、转动惯量为 I I I 的圆盘。绳子与圆盘无滑动,质量 m 2 m_2 m2​ 的物体在重力 g g g 作用下下坠,带动质量 m 1 m_1 m1​ 的物体上升。求 m 1 m_1 m1​和 m 2 m_2 m2​ 的加速度 a a a。 牛顿力学方法 对质量 m 1 m_1 m1​ 和 …

攻防世界(PHP过滤器过滤)file_include

转换过滤器官方文档:https://www.php.net/manual/zh/filters.convert.php#filters.convert.iconv 这道题因为convert.base64-encode被过滤掉了,所以使用convert.iconv.*过滤器 在激活 iconv 的前提下可以使用 convert.iconv.* 压缩过滤器, 等…

Jmeter多用户登录操作实战

在使用Jmeter性能测试时,首先要解决的问题恐怕就会并发压测和多用登录的问题.今天就一篇文章讲清楚这两个问题的解决方案: 一.多并发压测如何配置线程? (1)同时并发:设置线程组、执行时间、循环次数,这种方式可以控制接口请求的…

Axure-黑马

Axure-黑马 编辑时间2024/7/12 来源:B站黑马程序员 需求其他根据:visio,墨刀 Axure介绍 Axure RP是美国Axure Software Solution给公司出品的一款快速原型大的软件,一般来说使用者会称他为Axure 应用场景 拉投资使用 给项目团…

(自用)高并发实现高效内存管理

高并发下传统方式的弊端 C语言常用的内存操作函数 C下采用new进行内存分配,delete进行内存释放。 弊端一 分配内存需要进入内核态,总分配大小不变的情况下,多次分配较小的内存导致了变态频繁,降低系统效率. 弊端二 弊端三 情形…

LayoutLMv2:视觉丰富文档理解的多模态预训练

文本和布局的预训练由于其有效的模型架构和大规模未标记扫描/数字出生文档的优势,在各种视觉丰富的文档理解任务中被证明是有效的。我们提出了具有新的预训练任务的LayoutLMv2架构,以在单个多模态框架中对文本、布局和图像之间的交互进行建模。具体而言&…

JVM:SpringBoot TomcatEmbeddedWebappClassLoader

文章目录 一、介绍二、SpringBoot中TomcatEmbeddedWebappClassLoader与LaunchedURLClassLoader的关系 一、介绍 TomcatEmbeddedWebappClassLoader 是 Spring Boot 在其内嵌 Tomcat 容器中使用的一个类加载器(ClassLoader)。在 Spring Boot 应用中&#…

【漏洞复现】方正全媒体采编系统——binary.do——SQL注入

声明:本文档或演示材料仅供教育和教学目的使用,任何个人或组织使用本文档中的信息进行非法活动,均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 方正全媒体采编系统(FZMediaEditor)是一…