基于开源二兄弟MediaPipe+Rerun实现人体姿势跟踪可视化

概述

本文中,我们将探索一个利用开源框架MediaPipe的功能以二维和三维方式跟踪人体姿势的使用情形。使这一探索更有趣味的是由开源可视化工具Rerun提供的可视化展示,该工具能够提供人类动作姿势的整体视图。

您将一步步跟随作者使用MediaPipe在2D和3D环境中跟踪人体姿势,并探索工具Rerun的可视化功能。

人体姿势跟踪

人体姿势跟踪是计算机视觉中的一项任务,其重点是识别关键的身体位置、分析姿势和对动作进行分类。这项技术的核心是一个预先训练的机器学习模型,用于评估视觉输入,并在图像坐标和3D世界坐标中识别身体上的地标。该技术的应用场景包括但不限于人机交互、运动分析、游戏、虚拟现实、增强现实、健康等领域。

有一个完美的模型固然很好,但不幸的是,目前的模型仍然不完美。尽管数据集可能存储了多种体型数据,但人体在个体之间是有所不同的。每个人身体的独特性都带来了挑战,尤其是对于那些手臂和腿部尺寸不标准的人来说,这可能会导致使用这项技术时精度较低。在考虑将这项技术集成到系统中时,承认不准确的可能性至关重要。希望科学界正在进行的努力将为开发更强大的模型铺平道路。

除了缺乏准确性之外,使用这项技术还需要考虑伦理和法律因素。例如,如果个人未经同意,在公共场所拍摄人体姿势可能会侵犯隐私权。在现实世界中实施这项技术之前,考虑到任何道德和法律问题都是至关重要的。

先决条件和初始设置

首先,安装所需的库:

# 安装所需的Python包
pip install mediapipe
pip install numpy
pip install opencv-python<4.6
pip install requests>=2.31,<3
pip install rerun-sdk

# 也可以直接使用配置文件requirements.txt
pip install -r examples/python/human_pose_tracking/requirements.txt

使用MediaPipe跟踪人体姿势

谷歌提供的姿势地标检测指南中的图像(参考文献1)

谷歌提供的姿势地标检测指南中的图像

对于希望集成计算机视觉和机器学习的设备ML解决方案的开发人员来说,基于Python语言的MediaPipe框架正是一个方便的工具。

在下面的代码中,MediaPipe姿态标志检测被用于检测图像中人体的标志。该模型可以将身体姿势标志检测为图像坐标和3D世界坐标。一旦成功运行ML模型,就可以使用图像坐标和3D世界坐标来可视化输出。

import mediapipe as mp
import numpy as np
from typing import Any
import numpy.typing as npt
import cv2


"""

从Mediapipe姿势结果集中读取二维地标位置。

Args:
 results (Any): Mediapipe Pose results.
 image_width (int): Width of the input image.
 image_height (int): Height of the input image.

 Returns:
 np.array | None: Array of 2D landmark positions or None if no landmarks are detected.
"""
def read_landmark_positions_2d(
 results: Any,
 image_width: int,
 image_height: int,
) -> npt.NDArray[np.float32] | None:
 if results.pose_landmarks is None:
 return None
 else:
 # 提取标准化的地标位置并将其缩放为图像尺寸
 normalized_landmarks = [results.pose_landmarks.landmark[lm] for lm in mp.solutions.pose.PoseLandmark]
 return np.array([(image_width * lm.x, image_height * lm.y) for lm in normalized_landmarks])


"""

从Mediapipe Pose结果集中读取三维地标位置。

Args:
 results (Any): Mediapipe Pose results.

 Returns:
 np.array | None: Array of 3D landmark positions or None if no landmarks are detected.
"""
def read_landmark_positions_3d(
 results: Any,
) -> npt.NDArray[np.float32] | None:
 if results.pose_landmarks is None:
 return None
 else:
 # 提取三维地标位置
 landmarks = [results.pose_world_landmarks.landmark[lm] for lm in mp.solutions.pose.PoseLandmark]
 return np.array([(lm.x, lm.y, lm.z) for lm in landmarks])


"""

跟踪并分析输入图像中的姿势。

Args:
 image_path (str): Path to the input image.
"""
def track_pose(image_path: str) -> None:
 # 读取图像,将颜色转换为RGB格式
 image = cv2.imread(image_path)
 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

 # 创建Pose模型实例
 pose_detector = mp.solutions.pose.Pose(static_image_mode=True)

 # 处理图像以获得姿势标志
 results = pose_detector.process(image)
 h, w, _ = image.shape

 # 读取二维和三维地标位置
 landmark_positions_2d = read_landmark_positions_2d(results, w, h)
 landmark_positions_3d = read_landmark_positions_3d(results)

使用Rerun可视化MediaPipe的输出

Rerun图像浏览器(图像来自于Rerun官方文档,参考资料2)

Rerun图像浏览器

Rerun可作为多模态数据的可视化工具。通过Rerun图像浏览器,您可以构建布局、自定义可视化以及与数据交互。本节的其余部分将详细介绍如何使用Rerun SDK在Rerun图像浏览器中记录和显示数据。

姿势标志模型(谷歌通过姿势标志检测指南拍摄的图像,参考资料1)

姿势标志模型

在二维和三维点中,指定点之间的连接至关重要。定义这些连接会自动渲染它们之间的线。使用MediaPipe提供的信息,可以从pose_connections集合获取姿势点连接,然后使用Annotation Context将它们设置为关键点连接。

rr.log(
 "/",
 rr.AnnotationContext(
 rr.ClassDescription(
 info=rr.AnnotationInfo(id=0, label="Person"),
 keypoint_annotatinotallow=[rr.AnnotationInfo(id=lm.value, label=lm.name) for lm in mp_pose.PoseLandmark],
 keypoint_cnotallow=mp_pose.POSE_CONNECTIONS,
 )
 ),
 timeless=True,
 )

图像坐标——二维位置

将人的姿势可视化为2D点(作者本人提供的图像)

将人的姿势可视化为2D点

在视频中以可视化方式观察身体姿势的标志似乎是一个不错的选择。要实现这一点,您需要仔细遵循Rerun文档中有关Entities和Components的相关介绍。其中,“实体路径层次结构(The Entity Path Hierarchy)”页面描述了如何在同一实体上记录多个组件。例如,您可以创建“video”实体,并包括视频的“video/rgb”组件和身体姿势的“video/pose”组件。不过,如果你打算把它用于视频设计中的话,你需要认真掌握时间线的概念。每个帧都可以与适当的数据相关联。

以下是一个可以将视频上的2D点可视化的函数:

def track_pose_2d(video_path: str) -> None:
 mp_pose = mp.solutions.pose 

 with closing(VideoSource(video_path)) as video_source, mp_pose.Pose() as pose:
 for idx, bgr_frame in enumerate(video_source.stream_bgr()):
 if max_frame_count is not None and idx >= max_frame_count:
 break

 rgb = cv2.cvtColor(bgr_frame.data, cv2.COLOR_BGR2RGB)

 # 将帧与数据关联
 rr.set_time_seconds("time", bgr_frame.time)
 rr.set_time_sequence("frame_idx", bgr_frame.idx)

 # 呈现视频
 rr.log("video/rgb", rr.Image(rgb).compress(jpeg_quality=75))

 # 获取预测结果
 results = pose.process(rgb)
 h, w, _ = rgb.shape

 # 把2D点记录到'video'实体中
 landmark_positions_2d = read_landmark_positions_2d(results, w, h)
 if landmark_positions_2d is not None:
 rr.log(
 "video/pose/points",
 rr.Points2D(landmark_positions_2d, class_ids=0, keypoint_ids=mp_pose.PoseLandmark),
 )

三维世界坐标——三维点

将人的姿势可视化为3D点(作者本人提供的图像)

将人的姿势可视化为3D点

当你有三维点的时候,为什么要选择二维点呢?创建一个新实体,将其命名为“Person”,并输出有关这些三维点的数据。这就行了!这样就可以创建人体姿势的三维演示。

以下是操作方法:

def track_pose_3d(video_path: str, *, segment: bool, max_frame_count: int | None) -> None:
 mp_pose = mp.solutions.pose 

 rr.log("person", rr.ViewCoordinates.RIGHT_HAND_Y_DOWN, timeless=True)

 with closing(VideoSource(video_path)) as video_source, mp_pose.Pose() as pose:
 for idx, bgr_frame in enumerate(video_source.stream_bgr()):
 if max_frame_count is not None and idx >= max_frame_count:
 break

 rgb = cv2.cvtColor(bgr_frame.data, cv2.COLOR_BGR2RGB)

 # 把帧与数据关联起来
 rr.set_time_seconds("time", bgr_frame.time)
 rr.set_time_sequence("frame_idx", bgr_frame.idx)

 # 呈现视频
 rr.log("video/rgb", rr.Image(rgb).compress(jpeg_quality=75))

 # 取得预测结果
 results = pose.process(rgb)
 h, w, _ = rgb.shape

 # 对于3D呈现的新的实例"Person"
 landmark_positions_3d = read_landmark_positions_3d(results)
 if landmark_positions_3d is not None:
 rr.log(
 "person/pose/points",
 rr.Points3D(landmark_positions_3d, class_ids=0, keypoint_ids=mp_pose.PoseLandmark),
 )

源代码探索

本文重点介绍了“人体姿势跟踪”示例的主要部分。

对于那些喜欢动手的人来说,这个例子的完整源代码可以在GitHub(https://github.com/rerun-io/rerun/blob/latest/examples/python/human_pose_tracking/main.py)上找到。您可以随意探索、修改和理解其中实现的内部工作原理。

提示和建议

1.压缩图像以提高效率

您可以通过压缩记录的图像来提高整个过程的速度:

rr.log(
 "video", 
 rr.Image(img).compress(jpeg_quality=75)
)
2.限制内存使用

如果你记录的数据超过了RAM的容量,它就会开始丢弃旧数据。默认限制是系统RAM的75%。如果你想增加这个限制,可以使用命令行参数——内存限制。有关内存限制的更多信息,请参阅Rerun的“如何限制内存使用”页面信息。

3.根据您的需求定制视觉效果

自定义Rerun查看器(作者本人提供的图像)

自定义Rerun查看器

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

上位机图像处理和嵌入式模块部署(f103 mcu定时器配置)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在mcu开发过程当中&#xff0c;有一种开发模式用的比较多&#xff0c;那就是中断while&#xff08;1&#xff09;。这里面的中断&#xff0c;又是以…

电机控制系列模块解析(22)—— 零矢量刹车

一、零矢量刹车 基本概念 逆变器通常采用三相桥式结构&#xff0c;包含六个功率开关元件&#xff08;如IGBT或MOSFET&#xff09;&#xff0c;分为上桥臂和下桥臂。每个桥臂由两个反并联的开关元件组成&#xff0c;上桥臂和下桥臂对应于电机三相绕组的正负端。正常工作时&…

利用EAS自动生成数据模型和sql脚本

EAS适用于敏捷开发中小系统,这节主要讲解EAS对应的模型和数据库脚本输出应用。 在这个应用程序中,用户可自定义实体模型和枚举模型,只要选择相应的实体或者枚举进行右击添加即可。 解决方案参数设定,在解决方案的设定中可设置项目名称、通用语言,命名空间和输出位置。 连…

Ollama| 搭建本地大模型,最简单的方法!效果直逼GPT

很多人想在本地电脑上搭建一个大模型聊天机器人。总是觉得离自己有点远&#xff0c;尤其是对ai没有了解的童鞋。那么今天我要和你推荐ollama&#xff0c;无论你是否懂开发&#xff0c;哪怕是零基础&#xff0c;只需十分钟&#xff0c;Ollama工具就可以帮助我们在本地电脑上搭建…

智能合作:多AI协同助力传统工作流

背景介绍 红杉资本2024 AI AGENT大会上吴恩达再次介绍了AI四大设计模式即&#xff1a; 反思&#xff08;Reflection)&#xff1b;工具使用&#xff08;Tool use&#xff09;&#xff1b;规划&#xff08;Planning)&#xff1b;多智能体协作(Multi-agent collaboration)&#…

centos下安装kibana7.12.1版本并进行相关配置

1、下载与es版本对应的安装包 wget https://artifacts.elastic.co/downloads/kibana/kibana-7.12.1-linux-x86_64.tar.gz 2、解压压缩包 tar -zxvf kibana-7.12.1-linux-x86_64.tar.gz 3、进入到config目录下修改kibana.yml cd /home/soft/kibana-7.12.1-linux-x86_64/config v…

Excel查找匹配函数(VLOOKUP):功能与应用解析

文章目录 概述VLOOKUP函数语法查询并返回单列结果查找并返回多列结果MATCH函数VLOOKUPMATCH 从右向左逆向查找&#xff1a;INDEX函数INDEXMATCH 函数匹配方式查找匹配注意事项函数名称错误: #NAME?值错误&#xff1a;#VALUE!引用错误&#xff1a;#REF!找不到数据&#xff1a;#…

C++学习/复习4--与类相关的概念/默认成员函数/运算符重载/Date类实现案例

一、类和对象 1.本章概要 2.C中的结构体(struct与class) 升级为类 &#xff08;1&#xff09;类及成员函数的两种定义方式 声明与定义分离 &#xff08;2&#xff09;权限 注意1&#xff1a;struct/class在权限上的区别 &#xff08;3&#xff09;封装 &#xff08;4&#x…

告诉老板,AI大模型应该这样部署!

导语 随着大语言模型创新的快速步伐&#xff0c;企业正在积极探索用例并将其第一个生成式人工智能应用程序部署到生产中。 随着今年LLM或LLMOps的部署正式开始&#xff0c;企业根据自己的人才、工具和资本投资结合了四种类型的LLM部署方法。请记住&#xff0c;随着新的 LLM 优…

[数据结构] -- 双向循环链表

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文(平均质量分82)&#…

Java实现图书系统

首先实现一个图书管理系统,我们要知道有哪些元素? 1.用户分成为管理员和普通用户 2.书:书架 书 3.操作的是: 书架 目录 第一步:建包 第二步:搭建框架 首先:完成book中的方法 其次:完成BookList 然后:完成管理员界面和普通用户界面 最后:Main 第三步:细分方法 1.退…

十二、shell编程之awk

12.1 什么是awk 虽然sed编辑器是非常方便自动修改文本文件的工具&#xff0c;但其也有自身的限制。通常你需要一个用来处理文件中的数据的更高级工具&#xff0c;它能提供一个类编程环境来修改和重新组织文件中的数据。这正是awk能够做到的。 awk程序是Unix中的原始awk程序的…

JVM(三)

在上一篇中&#xff0c;介绍了JVM组件中的类加载器&#xff0c;以及相关的双亲委派机制。这一篇主要介绍运行时的数据区域 JVM架构图&#xff1a; JDK1.8后的内存结构&#xff1a; (图片来源&#xff1a;https://github.com/Seazean/JavaNote) 而在运行时数据区域中&#…

Redis第18讲——Redis和Redission实现延迟消息

即使不是做电商业务的同学&#xff0c;也一定知道订单超时关闭这种业务场景&#xff0c;这个场景大致就是用户下单后&#xff0c;如果在一定时间内未支付&#xff08;比如15分钟、半小时&#xff09;&#xff0c;那么系统就会把这笔订单给关闭掉。这个功能实现的方式有很多种&a…

Windows远程连接命令?

Windows操作系统提供了多种远程连接命令&#xff0c;使用户可以通过网络连接到远程计算机&#xff0c;并在远程操作系统上执行操作。远程连接命令可方便实现远程工作、故障排查和系统维护等任务。本文将介绍几种常见的Windows远程连接命令及其基本使用方法。 远程连接命令 Win…

面向对象编程的奥秘:封装与继承

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、封装的魅力 封装的应用 封装示例 二、继承的力量 继承的应用 继承示例 三、总结 一…

OpenWrt U盘安装使用 详细教程 x86/64平台 软路由实测 系列一

1 官方稳定 版:OpenWrt 23.05 OpenWrt Downloads #根据实际情况选择 PC支持uefi,选择版本&#xff1a;https://downloads.openwrt.org/releases/23.05.3/targets/x86/64/openwrt-23.05.3-x86-64-generic-ext4-combined-efi.img.gz 2 rufus 制作U盘启动 3 制作好的U盘,接入主…

Maven多环境打包配置

一、启动时指定环境配置文件 在启动springboot应用的jar包时&#xff0c;我们可以指定配置文件&#xff0c;通常把配置文件上传到linux服务器对应jar包的同级目录&#xff0c;或者统一的配置文件存放目录 java -jar your-app.jar --spring.config.location/opt/softs/applicat…

新能源汽车的电驱热管理

前言 新能源汽车的电驱热管理是指维持电动汽车电池、电机和电控系统在适宜的工作温度范围内&#xff0c;保障车辆高效、安全、稳定运行的技术方案。随着新能源汽车的快速发展和普及&#xff0c;电驱热管理技术也日益成为关注焦点。本文将从电池、电机和电控系统三个方面介绍新…

Linux--线程的认识(一)

线程的概念 线程&#xff08;Thread&#xff09;是操作系统中进行程序执行的最小单位&#xff0c;也是程序调度和分派的基本单位。它通常被包含在进程之中&#xff0c;是进程中的实际运作单位。一个线程指的是进程中一个单一顺序的控制流&#xff0c;一个进程中可以并发多个线…