matplotlib.animation 3d姿态动画

news2024/10/4 13:16:42

目录

演示效果:

演示代码:

保存为gif


演示效果:

演示代码:

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

# 定义人体关键点之间的连接关系
connections = [
    (0, 1),  # 头部到颈部
    (1, 2), (2, 3), (3, 4),  # 右臂
    (1, 5), (5, 6), (6, 7),  # 左臂
    (1, 8),  # 颈部到身体中心
    (8, 9), (9, 10), (10, 11),  # 右腿
    (8, 12), (12, 13), (13, 14),  # 左腿
    (11, 15),  # 右脚到右脚尖
    (14, 16),  # 左脚到左脚尖
]


map_boneInfo = {
# 骨骼名称       父骨骼名称        子骨骼名称    序号       初始位置
"BoneRoot":   ["RootNode",     "",          0,        np.array([  0,  0,0])],
"Hip":        ["BoneRoot",     "",          1,        np.array([  0, 80,0])],
"r_hip":      ["Hip",          "r_knee",    2,        np.array([-10, 80,0])],
"r_knee":     ["r_hip",        "r_foot",    3,        np.array([-10, 40,0])],
"r_foot":     ["r_knee",       "",          4,        np.array([-10,  0,0])],
"l_hip":      ["Hip",          "l_knee",    5,        np.array([ 10, 80,0])],
"l_knee":     ["l_hip",        "l_foot",    6,        np.array([ 10, 40,0])],
"l_foot":     ["l_knee",       "",          7,        np.array([ 10,  0,0])],
"spine":      ["Hip",          "thorax",    8,        np.array([  0,110,0])],
"thorax":     ["spine",        "",          9,        np.array([  0,140,0])],
"neck":       ["thorax",       "head",     10,        np.array([  0,150,0])],
"head":       ["neck",         "",         11,        np.array([  0,160,0])],
"l_shoulder": ["thorax",       "l_elbow",  12,        np.array([ 15,140,0])],
"l_elbow":    ["l_shoulder",   "l_wrist",  13,        np.array([ 50,140,0])],
"l_wrist":    ["l_elbow",      "",         14,        np.array([ 85,140,0])],
"r_shoulder": ["thorax",       "r_elbow",  15,        np.array([-15,140,0])],
"r_elbow":    ["r_shoulder",   "r_wrist",  16,        np.array([-50,140,0])],
"r_wrist":    ["r_elbow",      "",         17,        np.array([-85,140,0])],
}

init_poses=[]

map_initTRS = {}
map_initTRS["BoneRoot"] = np.array([[0,0,0],[0,0,0],[1,1,1]],dtype=float)
for index,i in enumerate(map_boneInfo.keys()):
    if i == "BoneRoot":
        continue
    trans = - map_boneInfo[i][3] + map_boneInfo[map_boneInfo[i][0]][3]

    init_poses.append(map_boneInfo[i][3]/60.0)
    rotate = [0,0,0]
    scale = [1,1,1]
    map_initTRS[i] = np.array([trans, rotate, scale], dtype=float)


# 更新姿态以模拟行走动作
def update_pose(frame, pose, lines):
    # 在x轴上前进,并在y轴上轻微左右摆动以模拟行走的平衡动作
    pose[:, 0] += 0.01  # 向前移动
    pose[:, 1] =pose[:, 1]+ np.sin(frame / 10.0) * 0.02  # 左右摆动
    # 更新线段以连接关键点
    for line, (i, j) in zip(lines, connections):
        line.set_data([pose[i, 0], pose[j, 0]], [pose[i, 1], pose[j, 1]])
        line.set_3d_properties([pose[i, 2], pose[j, 2]])
    return lines

# 创建动画
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 设置坐标轴的显示范围
ax.set_xlim((0, 5))
ax.set_ylim((-1, 1))
ax.set_zlim((0, 3))

def init_pose():
    pose = np.zeros((17, 3))  # 17个关键点,每个有x, y, z坐标

    # 设置头部和颈部位置
    pose[0, 2], pose[1, 2] = 1.8, 1.6  # z轴上的高度

    # 设置右臂位置(水平伸展)
    pose[2, :] = [0, -0.3, 1.5]  # 右肩
    pose[3, :] = [0, -0.7, 1.5]  # 右肘
    pose[4, :] = [0, -1.0, 1.5]  # 右手

    # 设置左臂位置(水平伸展)
    pose[5, :] = [0, 0.3, 1.5]  # 左肩
    pose[6, :] = [0, 0.7, 1.5]  # 左肘
    pose[7, :] = [0, 1.0, 1.5]  # 左手

    # 设置躯干中心位置
    pose[8, 2] = 1.2  # z轴上的高度

    # 设置腿部位置(站立)
    pose[9, :] = [0, -0.2, 1.0]  # 右髋
    pose[10, :] = [0, -0.2, 0.2]  # 右膝
    pose[11, :] = [0, -0.2, -0.5]  # 右脚

    pose[12, :] = [0, 0.2, 1.0]  # 左髋
    pose[13, :] = [0, 0.2, 0.2]  # 左膝
    pose[14, :] = [0, 0.2, -0.5]  # 左脚

    # 脚尖位置(在T姿势中通常不需要特别调整)
    pose[15, :] = [0, -0.2, -1]  # 右脚尖
    pose[16, :] = [0, 0.2, -1]  # 左脚尖

    return pose

# pose = np.asarray(init_poses).astype(np.float32)
pose = init_pose()
lines = [ax.plot([pose[s, 0], pose[e, 0]], [pose[s, 1], pose[e, 1]], [pose[s, 2], pose[e, 2]])[0] for s, e in connections]

ani = FuncAnimation(fig, update_pose, frames=np.arange(0, 200), fargs=(pose, lines), interval=50)

plt.show()

保存为gif

ani.save('1111.gif', writer='pillow', fps=60)

writergif = animation.PillowWriter(fps=30)
ani.save('2222.gif', writer = writergif)
plt.show()

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

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

相关文章

Vue3 五天速成

文章目录 day 11. 创建vue3工程3. 响应式数据4. 计算属性 day 25. watch 监视6. watchEffect7. 标签的ref属性 day 38. 回顾TS中的接口_泛型_自定义类型9. props的使用10. 生命周期11. 自定义Hooks12. 路由 基本切换效果13. 路由 两个注意点14. 路由 路由器的工作模式15. 路由 …

鸿蒙 Stage模型-AbilityStage、Context、Want

前提:基于官网3.1/4.0文档。参考官网文档 基于Android开发体系来进行比较和思考。(或有偏颇,自行斟酌) 一、 AbilityStage 1.概念 AbilityStage是一个Module级别的组件容器,应用的HAP在首次加载时会创建一个AbilitySt…

步进电机驱动器接法

实物 参数 共阳极: 使能给高电平有效 共阴极: 使能给低电平有效 整体接线 参考内容 B站UP范辉

Google Play上架:2024年五月份政策自查之敏感信息访问权限和 API(适用于上架被拒和因AI扫荡被下架或封号)

本文根据谷歌上架政策协议截止日期归纳而出,提供上架遇到问题的开发者们,感谢支持,如有不足,欢迎补充。 关于敏感信息访问权限和 API的相关政策 政策公布日期政策相关内容相关补充内容政策截止日期 政策公布日期 公布日期&#x…

【QT】窗口的大小标题图标设置

窗口的大小标题图标设置 添加一个新的类 创建完成&#xff0c;根据上一节最后的在总结&#xff0c;做个测试&#xff1a; #include "mybutton.h" #include <QDebug>//打印&#xff0c;标准输出 MyButton::MyButton(QWidget *parent) : QPushButton(parent) { …

INFINI Labs 产品更新 | Easysearch 1.7.1发布

INFINI Labs 产品又更新啦~&#xff0c;包括 Console&#xff0c;Gateway&#xff0c;Agent 1.23.0 和 Easysearch 1.7.1。此次版本重点修复历史遗留 Bug 、网友们提的一些需求等。以下是本次更新的详细说明。 INFINI Console v1.23.0 INFINI Console 是一款非常轻量级的多集…

ATFX汇市:油价回落之际加元币值走弱,USDCAD有望刷新年内新高

ATFX汇市&#xff1a;加元是商品货币&#xff0c;币值受到国际油价和精炼石油出口的显著影响。2022年3月份&#xff0c;国际油价达到130美元的峰值水平&#xff0c;随后开启回落走势&#xff0c;时至今日&#xff0c;最新报价在80美元下方&#xff0c;累计跌幅近40%。疲弱的油价…

根据用户名称实现单点登录

一、参数格式 二、后端实现 Controller层 public class IAccessTokenLoginController extends BaseController {Autowiredprivate ISysUserService sysUserService;Autowiredprivate ISingleTokenServiceImpl tokenService;/*** 登录方法** return 结果*/PostMapping("/l…

小家电压力锅WIFI模块供电AC-DC电源芯片特点与SM6035解析

WIFI模块供电的是一种将AC-DC电源芯片交流电转换为直流电的芯片&#xff0c;通常用于为WIFI模块提供电源。这种芯片具有高效、紧凑和可靠等特点&#xff0c;能够满足各种应用场景的需求。 其中&#xff0c;离线开关电源芯片是一种常见的AC-DCLED电源芯片&#xff0c;它通常包括…

JimuReport积木报表 v1.7.1 版本发布,低代码报表工具

项目介绍 一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完成报…

JavaScript基础知识(三)

JavaScript基础知识&#xff08;三&#xff09; 一、事件1. 事件绑定2.事件流2.1 事件捕获与事件冒泡 3.事件对象扩展3.1 阻止事件冒泡3.2 事件默认行为 4.事件委托5.事件类型5.1 鼠标事件5.2 键盘事件5.3 触屏事件 二、计时器方法1. setInterval 与 clearInterval2. setTimeou…

吴恩达机器学习笔记:第5周-9 神经网络的学习1(Neural Networks: Learning)

目录 9.1 代价函数9.2 反向传播算法9.3 反向传播算法的直观理解 9.1 代价函数 首先引入一些便于稍后讨论的新标记方法&#xff1a; 假设神经网络的训练样本有&#x1d45a;个&#xff0c;每个包含一组输入&#x1d465;和一组输出信号&#x1d466;&#xff0c;&#x1d43f;…

【数据存储】大端存储||小端存储(超详细解析,小白一看就懂!!!)

目录 一、前言 二、什么是低地址、高地址 &#xff1f; 三、什么是数据的高位和低位 &#xff1f; 四、什么是大小端存储&#xff1f; &#x1f349; 小端存储详解 &#x1f352; 大端存储详解 五、为什么会有大小端存储&#xff1f; &#x1f34d;大端存储的优点 &#…

保护模式笔记九 中断门和IDT(中断描述符表)

段选择子&#xff1a; 先直观认识一下GDT和段选择子在逻辑地址转换为线性地址中的作用&#xff0c;例如&#xff1a; 给出逻辑地址&#xff1a;21h:12345678h&#xff0c;需要将其转换为线性地址 a. 选择子SEL21h0000000000100 0 01b&#xff0c;他代表的意思是&#xff1a…

H3C 路由过滤路由引入实验

H3C 路由过滤&路由引入实验 实验拓扑 ​​ 实验需求 按照图示配置 IP 地址&#xff0c;R1&#xff0c;R3&#xff0c;R4 上使用 loopback 口模拟业务网段R1 和 R2 运行 RIPv2&#xff0c;R2&#xff0c;R3 和 R4 运行 OSPF&#xff0c;各自协议内部互通在 RIP 和 OSPF …

OpenAI划时代大模型——文本生成视频模型Sora作品欣赏(十五)

Sora介绍 Sora是一个能以文本描述生成视频的人工智能模型&#xff0c;由美国人工智能研究机构OpenAI开发。 Sora这一名称源于日文“空”&#xff08;そら sora&#xff09;&#xff0c;即天空之意&#xff0c;以示其无限的创造潜力。其背后的技术是在OpenAI的文本到图像生成模…

Gemma模型一些细节讲解

Gemma模型报告中提到的几个点进行代码细节解读一下&#xff1a; &#xff08;1&#xff09;Embedding层共享参数 &#xff08;2&#xff09;输入输出层均进行RMSNorm Embedding层共享参数 共享embedding的权重给最后的llm_head层。是词嵌入层的共享&#xff0c;与旋转位置编码…

低密度奇偶校验码LDPC(七)——SPA和积译码算法的简化

往期博文 低密度奇偶校验码LDPC&#xff08;一&#xff09;——概述_什么是gallager构造-CSDN博客 低密度奇偶校验码LDPC&#xff08;二&#xff09;——LDPC编码方法-CSDN博客 低密度奇偶校验码LDPC&#xff08;三&#xff09;——QC-LDPC码概述-CSDN博客 低密度奇偶校验码…

CNAN知识图谱辅助推荐系统

CNAN知识图谱辅助推荐系统 文章介绍了一个基于KG的推荐系统模型&#xff0c;代码也已开源&#xff0c;可以看出主要follow了KGNN-LS 。算法流程大致如下&#xff1a; 1. 算法介绍 算法除去attention机制外&#xff0c;主要的思想在于&#xff1a;user由交互过的item来表示、i…

前端小案例——登录界面(正则验证, 附源码)

一、前言 实现功能&#xff1a; 提供用户名和密码输入框。当用户提交表单时&#xff0c;阻止默认提交行为。使用正则表达式验证用户输入的内容&#xff0c;判断输入的是有效的邮箱地址还是身份证号码。根据验证结果&#xff0c;在输入框下方显示相应的提示信息。 实现逻辑&a…