目錄
演示效果:
演示代碼:
保存為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":continuetrans = - 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()