matplotlib.animation 3d姿态动画

目录

演示效果:

演示代码:

保存为gif


演示效果:

演示代码:

python 复制代码
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

python 复制代码
ani.save('1111.gif', writer='pillow', fps=60)

writergif = animation.PillowWriter(fps=30)
ani.save('2222.gif', writer = writergif)
plt.show()
相关推荐
先生沉默先11 小时前
3dsMax合并FBX的时候相同的节点会被合并(重命名解决),3Ds MAX创建空物体(虚拟对象或者点)
3d·3dsmax
ZPC821012 小时前
Python使用matplotlib绘制图形大全(曲线图、条形图、饼图等)
开发语言·python·matplotlib
Death20014 小时前
Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系
c语言·c++·qt·3d·c#
摇曳的树18 小时前
【3D目标检测】激光雷达和相机联合标定(二)——MATLAB联合标定工具使用
数码相机·目标检测·3d
知来者逆18 小时前
V3D——从单一图像生成 3D 物体
人工智能·计算机视觉·3d·图像生成
唐·柯里昂7981 天前
[3D打印]拓竹切片软件Bambu Studio使用
经验分享·笔记·3d
摇曳的树1 天前
【3D目标检测】激光雷达和相机联合标定(一)——ROS同步解包
数码相机·目标检测·3d
摩尔线程2 天前
使用MTVerseXR SDK实现VR串流
3d·xr·图形渲染·vr·摩尔线程
GIS数据转换器2 天前
城市空间设计对居民生活质量的影响:构建宜居城市的蓝图
大数据·人工智能·3d·gis·生活·智慧城市
qq_15321452643 天前
【2022工业3D异常检测文献】AST: 基于归一化流的双射性产生不对称学生-教师异常检测方法
图像处理·深度学习·神经网络·机器学习·计算机视觉·3d·视觉检测