Mediapipe绘制实时3d铰接骨架图——Mediapipe实时姿态估计

一、前言

大约两年前,基于自己的理解我曾写了几篇关于Mediapipe的文章,似乎帮助到了一些人。这两年,忙于比赛、实习、毕业、工作和考研。上篇文章已经是一年多前发的了。这段时间收到很多私信和评论,请原谅无法一一回复了。我将尝试在这篇文章里回答一些大家经常问到的问题。

二、绘制3d铰接骨架

我曾在之前的文章里讲过,可以使用Mediapipe推理得到的3d坐标绘制到3d画布上,使用的函数就是:mp.solutions.drawing_utils.plot_landmarks(),不过只能导出2d图,没法拖动交互,实现效果如下:
在这里插入图片描述
这个函数是官方自己封装的,我们可以利用matplotlib自行实现实时绘制3d铰接骨架图的需求,效果如下:

实时姿态估计


由于画在了3d画布上,这时候就能拖动画布,以不同角度查看实时的人体姿态。大家可以自行尝试。

三、关于Mediapipe的3d坐标

  1. mediapipe可以推理得到3d坐标,但这个3d坐标并不是真实的3d坐标。这些坐标描述了一个以人体臀部为中心的人体外接圆,是虚拟的坐标。这一点可以从其官方描述得知。
    在这里插入图片描述

  2. 在对每一帧图像做处理时,如果要获取某个keypoint(人体某个关节)在图像上的坐标时,可以这样转换:

results = pose.process(img)
X_ = results.pose_landmarks.landmark[mp_pose.PoseLandmark.NOSE].x * img_width
Y_ = results.pose_landmarks.landmark[mp_pose.PoseLandmark.NOSE].y * img_height

四、关于姿态估计的进一步学习

  1. 如果想获取实际的3d坐标,可以用相机标定,这里涉及的知识更多。Google搜索‘camera calibration’可以学习到更多。
  2. 其他好用的人体姿态估计模型,有mmpose、alphapose、openpose等。个人比较喜欢mmpose,从数据标注到模型训练都比较成熟。
  3. 曾经有人问过,如果要做动物姿态估计,那么毫不犹豫请用DeepLabCut,同样在数据标注和模型训练及导出上,非常成熟易用。

五、所有代码

要结束程序,请按ESC,或者ctrl+c

import cv2
import matplotlib.pyplot as plt
import mediapipe as mp
import time
import numpy as np

mp_pose = mp.solutions.pose
mp_drawing = mp.solutions.drawing_utils 
mp_drawing_styles = mp.solutions.drawing_styles

colorclass = plt.cm.ScalarMappable(cmap='jet')
colors = colorclass.to_rgba(np.linspace(0, 1, int(33)))
colormap = (colors[:, 0:3])

def draw3d(plt, ax, world_landmarks, connnection=mp_pose.POSE_CONNECTIONS):
    ax.clear()
    ax.set_xlim3d(-1, 1)
    ax.set_ylim3d(-1, 1)
    ax.set_zlim3d(-1, 1)

    landmarks = []
    for index, landmark in enumerate(world_landmarks.landmark):
        landmarks.append([landmark.x, landmark.z, landmark.y*(-1)])
    landmarks = np.array(landmarks)

    ax.scatter(landmarks[:, 0], landmarks[:, 1], landmarks[:, 2], c=np.array(colormap), s=50)
    for _c in connnection:
        ax.plot([landmarks[_c[0], 0], landmarks[_c[1], 0]],
                [landmarks[_c[0], 1], landmarks[_c[1], 1]],
                [landmarks[_c[0], 2], landmarks[_c[1], 2]], 'k')

    plt.pause(0.001)

#端口号一般是0,除非你还有其他摄像头
#使用本地视频推理,复制其文件路径代替端口号即可
cap = cv2.VideoCapture(0)
with mp_pose.Pose(
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5, 
    model_complexity = 1) as pose:
  fig = plt.figure()
  ax = fig.add_subplot(111, projection="3d")

  while cap.isOpened():
    success, image = cap.read()
    if not success:
        print("Ignoring empty camera frame.")
        # If loading a video, use 'break' instead of 'continue'.
        continue
    
    # To improve performance, optionally mark the image as not writeable to
    # pass by reference.
    start = time.time()
    image.flags.writeable = False
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = pose.process(image)
    
    # Draw the pose annotation on the image.
    image.flags.writeable = True
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    
    mp_drawing.draw_landmarks(
        image,
        results.pose_landmarks,
        mp_pose.POSE_CONNECTIONS,
        landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style())
    
    end = time.time()
    fps = 1 / (end - start)
    fps = "%.2f fps" % fps
    #实时显示帧数
    image = cv2.flip(image, 1)
    cv2.putText(image, "FPS {0}".format(fps), (100, 50),
                cv2.FONT_HERSHEY_SIMPLEX, 0.75, (255, 255, 255),3)   
    
    cv2.imshow('MediaPipe Pose', image)
    if cv2.waitKey(5) & 0xFF == 27:
        break
    if results.pose_world_landmarks:
        draw3d(plt, ax, results.pose_world_landmarks)

cap.release()

六、写在最后

如果有任何问题,欢迎在评论区讨论、赐教。

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

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

相关文章

HarmonyOS 实践之应用状态变量共享

平时在开发的过程中,我们会在应用中共享数据,在不同的页面间共享信息。虽然常用的共享信息,也可以通过不同页面中组件间信息共享的方式,但有时使用应用级别的状态管理会让开发工作变得简单。 根据不同的使用场景,ArkTS…

HarmonyOS 组件通用属性之通用事件 文档参数讲解(触摸事件)

好 本文 我们来说说触摸事件 字面意思也非常好理解 就是我们手机手指触摸物体触发 我们先在编辑器组件介绍中 找到这个东西的基本用法 Button("跳转").onTouch((event: TouchEvent) > {})最明显的就是 event 的类型变了 点击事件的是 ClickEvent 而这里是 Touc…

14 2023.12.31 --------release--------misc--------

呵呵 一部分 misc 存在草稿箱好久了 而且 也并没有那么重要, 直接放出去吧 今年的 专业技能方面的收获主要是一些方面 linux 方面, 这部分内容主要是集中在上半年 90 telnet 连接上对方服务之后 立即 “Connection closed by foreign host.“ 89 重写 /proc/sys/vm/nr_pd…

【LMM 002】大型语言和视觉助手 LLaVA-1.5

论文标题:Improved Baselines with Visual Instruction Tuning 论文作者:Haotian Liu, Chunyuan Li, Yuheng Li, Yong Jae Lee 作者单位:University of Wisconsin-Madison, Microsoft Research, Columbia University 论文原文:htt…

win/linux 环境查看动态库包含的函数

我们打包了动态库,还要查看是否包含一些函数,需要导出这些函数 在win 环境下可以使用 .def 格式的文件进行操作 ######################################################### 跳过这一步,回到主题,在两个系统平台如何查看动态库包…

LanceDB:在对抗数据复杂性战役中,您可信赖的坐骑

LanceDB 建立在 Lance(一种开源列式数据格式)之上,具有一些有趣的功能,使其对 AI/ML 具有吸引力。例如,LanceDB 支持显式和隐式矢量化,能够处理各种数据类型。LanceDB 与 PyTorch 和 TensorFlow 等领先的 M…

图文证明 等价无穷小替换

等价无穷小替换 定义 等价无穷小是无穷小之间的一种关系,指的是:在同一自变量的趋向过程中,若两个无穷小之比的极限为1,则称这两个无穷小是等价的。无穷小等价关系刻画的是两个无穷小趋向于零的速度是相等的。 设当 x → x 0 时…

第5课 使用openCV捕获摄像头并实现预览功能

这节课我们开始利用ffmpeg和opencv来实现一个rtmp推流端。推流端的最基本功能其实就两个:预览画面并将画面和声音合并后推送到rtmp服务器。 一、FFmpeg API 推流的一般过程 1.引入ffmpeg库:在代码中引入ffmpeg库,以便使用其提供的功能。 2.捕获摄像头…

条款14:在资源管理类中小心拷贝行为

你可能会发现,有时候需要创建自己的资源管理类。例如,假设你正在使用一个C API来操作互斥对象,互斥类型提供了lock和unlock函数: void lock(Mutex* pm); // 锁住pm指向的互斥量 void unlock(Mutex* pm); // 互斥量解锁 class Lock { publi…

【LMM 003】生物医学领域的垂直类大型多模态模型 LLaVA-Med

论文标题:LLaVA-Med: Training a Large Language-and-Vision Assistant for Biomedicine in One Day 论文作者:Chunyuan Li∗, Cliff Wong∗, Sheng Zhang∗, Naoto Usuyama, Haotian Liu, Jianwei Yang Tristan Naumann, Hoifung Poon, Jianfeng Gao 作…

2001-2021年各省高速公路里程数据

2001-2021年全国及各省高速公路里程数据 1、时间:2001-2021年 2、指标:高速公路里程 3、范围:全国及30个省市 (不含西藏) 4、来源:各省NJ、省TJGB、第三产业TJNJ (无缺失) 5、指…

Bytebase:统一数据库 CI/CD 解决方案 | 开源日报 No.128

bytebase/bytebase Stars: 7.9k License: NOASSERTION Bytebase 是一个数据库 CI/CD 解决方案,为开发人员和 DBA 提供统一的工具来管理不同数据库系统的开发生命周期。其主要功能包括标准化操作流程、SQL 代码审查、GitOps 集成以及数据访问控制等。关键特性和核心…

【JWT】JWT实战应用

学习参考:BV1gk4y177DS ------------------------------------------------------------------------------------------------------- # 一、前置知识点 - Java Web - Spring/SpringMVC/SpringBoot - Spring Security # 二、JWT介绍 ## 2.1 概念 官网:https://jwt.i…

带大家做一个,易上手的家常蒜酱鲍鱼

超市有个福利鲍鱼 就买回来弄一下 搞一个整个的蒜 蒜去皮切末 三四个干辣椒切小末 切一点葱花混进去 鲍鱼去壳 去内脏&牙齿 将鲍鱼切块 因为鲍鱼是正经不好入味的东西 起锅烧油 下入 葱蒜干辣椒 翻炒出味 然后倒入鲍鱼进行翻炒 翻炒均匀后 倒入 一勺生抽 半勺老抽 …

Python pycharm编辑器修改代码字体

在pycharm编辑器下修改代码字体,可以按照以下步骤: 点开上图所示的菜单, 再点击File->Settings,进入设置页面。 我们找到Editor下的Font并点选,然后我们就可以在右侧修改字体相关配置了。 这里建议使用等宽字体&…

27 UVM queue

uvm_queue类构建一个动态队列,该队列将按需分配并通过引用传递。 uvm_queue类声明: class uvm_queue #( type T int ) extends uvm_object 1 uvm_queue class hierarchy 2 uvm_queue class Methods 3 UVM Queue Example 在下面的示例中,…

Excel中部分sheet页隐藏并设置访问密码

1、新建sheet1 2、新建sheet2 3、隐藏sheet2 4、保护工作簿、输密码 5、密码二次确认 6、隐藏的sheet2已经查看不了 7、想要查看时,按图示输入原密码即可 8、查看sheet2内容

理解SQL中not in 与null值的真实含义

A not in B的原理是拿A表值与B表值做是否不等的比较, 也就是a ! b. 在sql中, null是缺失未知值而不是空值。 当你判断任意值a ! null时, 官方说, “You cannot use arithmetic comparison operators such as , <, or <> to test for NULL”, 任何与null值的对比都将返…

微服务(11)

目录 51.pod的重启策略是什么&#xff1f; 52.描述一下pod的生命周期有哪些状态&#xff1f; 53.创建一个pod的流程是什么&#xff1f; 54.删除一个Pod会发生什么事情&#xff1f; 55.k8s的Service是什么&#xff1f; 51.pod的重启策略是什么&#xff1f; 可以通过命令kub…

光伏逆变器MPPT的作用、原理及算法

MPPT是逆变器非常核心的技术&#xff0c;MPPT电压在进行光伏电站设计时一项非常关键的参数。 一、什么是MPPT&#xff1f; &#xff08;单块光伏组件的I-V、P-V曲线&#xff09; 上图中&#xff0c;光伏组件的输出电压和电流遵循I-V曲线(绿色)、P-V曲线(蓝色)&#xff0c;如果…