我安装库的版本号供参考:aiohappyeyeballs 2.4.4
aiohttp 3.11.9
aiosignal 1.3.1
antlr4-python3-runtime 4.9.3
anyio 4.6.2.post1
argon2-cffi 23.1.0
argon2-cffi-bindings 21.2.0
arrow 1.3.0
asttokens 3.0.0
async-lru 2.0.4
async-timeout 5.0.1
attrs 24.2.0
autocommand 2.2.2
av 13.0.0
babel 2.16.0
backports.tarfile 1.2.0
beautifulsoup4 4.12.3
black 24.10.0
bleach 6.2.0
certifi 2024.8.30
cffi 1.17.1
chardet 5.2.0
charset-normalizer 3.4.0
cheroot 10.0.1
CherryPy 18.10.0
chumpy 0.70
click 8.1.7
colorlog 6.9.0
comm 0.2.2
contourpy 1.3.1
cycler 0.12.1
Cython 3.0.11
cython_bbox 0.1.5
debugpy 1.8.9
decorator 5.1.1
defusedxml 0.7.1
docstring_parser 0.16
dpvo 0.0.0 /home/sxxzwbl/GVHMR/GVHMR/third-party/DPVO
einops 0.8.0
embreex 2.17.7.post5
exceptiongroup 1.2.2
executing 2.1.0
fastjsonschema 2.21.1
ffmpeg-python 0.2.0
filelock 3.16.1
fonttools 4.55.1
fqdn 1.5.1
frozenlist 1.5.0
fsspec 2024.10.0
future 1.0.0
fvcore 0.1.5.post20221221
gvhmr 1.0.0 /home/sxxzwbl/GVHMR/GVHMR
h11 0.14.0
httpcore 1.0.7
httpx 0.28.0
huggingface-hub 0.26.3
hydra-colorlog 1.2.0
hydra-core 1.3.0
hydra_zen 0.13.0
idna 3.10
imageio 2.34.1
iniconfig 2.0.0
iopath 0.1.10
ipdb 0.13.13
ipykernel 6.29.5
ipython 8.30.0
ipywidgets 8.1.5
isoduration 20.11.0
jaraco.collections 5.1.0
jaraco.context 6.0.1
jaraco.functools 4.1.0
jaraco.text 4.0.0
jedi 0.19.2
Jinja2 3.1.4
joblib 1.4.2
json5 0.10.0
jsonpointer 3.0.0
jsonschema 4.23.0
jsonschema-specifications 2024.10.1
jupyter 1.1.1
jupyter_client 8.6.3
jupyter-console 6.6.3
jupyter_core 5.7.2
jupyter-events 0.10.0
jupyter-lsp 2.2.5
jupyter_server 2.14.2
jupyter_server_terminals 0.5.3
jupyterlab 4.2.6
jupyterlab_pygments 0.3.0
jupyterlab_server 2.27.3
jupyterlab_widgets 3.0.13
kiwisolver 1.4.7
lapx 0.5.11.post1
lazy_loader 0.4
lightning 2.3.0
lightning-utilities 0.11.9
llvmlite 0.43.0
loguru 0.7.3
lxml 5.3.0
manifold3d 3.0.0
mapbox_earcut 1.0.2
markdown-it-py 3.0.0
MarkupSafe 3.0.2
matplotlib 3.9.3
matplotlib-inline 0.1.7
mdurl 0.1.2
mistune 3.0.2
more-itertools 10.5.0
mpmath 1.3.0
msgspec 0.18.6
multidict 6.1.0
mypy-extensions 1.0.0
nbclient 0.10.1
nbconvert 7.16.4
nbformat 5.10.4
nest-asyncio 1.6.0
networkx 3.4.2
nodeenv 1.9.1
notebook 7.2.2
notebook_shim 0.2.4
numba 0.60.0
numpy 1.23.5
nvidia-cublas-cu12 12.1.3.1
nvidia-cuda-cupti-cu12 12.1.105
nvidia-cuda-nvrtc-cu12 12.1.105
nvidia-cuda-runtime-cu12 12.1.105
nvidia-cudnn-cu12 8.9.2.26
nvidia-cufft-cu12 11.0.2.54
nvidia-curand-cu12 10.3.2.106
nvidia-cusolver-cu12 11.4.5.107
nvidia-cusparse-cu12 12.1.0.106
nvidia-nccl-cu12 2.20.5
nvidia-nvjitlink-cu12 12.6.85
nvidia-nvtx-cu12 12.1.105
omegaconf 2.3.0
opencv-python 4.10.0.84
overrides 7.7.0
packaging 24.2
pandas 2.2.3
pandocfilters 1.5.1
parso 0.8.4
pathspec 0.12.1
pexpect 4.9.0
pillow 11.0.0
pip 24.2
platformdirs 4.3.6
pluggy 1.5.0
plyfile 1.1
portalocker 3.0.0
portend 3.2.0
prometheus_client 0.21.1
prompt_toolkit 3.0.48
propcache 0.2.1
protobuf 5.29.0
psutil 6.1.0
ptyprocess 0.7.0
pure_eval 0.2.3
py-cpuinfo 9.0.0
pycollada 0.8
pycparser 2.22
Pygments 2.18.0
pyliblzfse 0.4.1
pyparsing 3.2.0
pypose 0.6.9
pytest 8.3.4
python-dateutil 2.9.0.post0
python-json-logger 2.0.7
pytorch-lightning 2.4.0
pytorch3d 0.7.6
pytz 2024.2
PyYAML 6.0.2
pyzmq 26.2.0
referencing 0.35.1
requests 2.32.3
rfc3339-validator 0.1.4
rfc3986-validator 0.1.1
rich 13.9.4
rpds-py 0.22.1
Rtree 1.3.0
safetensors 0.4.5
scikit-image 0.24.0
scipy 1.14.1
seaborn 0.13.2
Send2Trash 1.8.3
setuptools 75.1.0
shapely 2.0.6
shtab 1.7.1
six 1.16.0
smplx 0.1.28
sniffio 1.3.1
soupsieve 2.6
stack-data 0.6.3
svg.path 6.3
sympy 1.13.3
tabulate 0.9.0
tempora 5.7.0
tensorboardX 2.6.2.2
termcolor 2.5.0
terminado 0.18.1
tifffile 2024.9.20
timm 0.9.12
tinycss2 1.4.0
tomli 2.2.1
torch 2.3.0+cu121
torch_scatter 2.1.2+pt23cu121
torchmetrics 1.6.0
torchvision 0.18.0+cu121
tornado 6.4.2
tqdm 4.67.1
traitlets 5.14.3
transforms3d 0.4.2
trimesh 4.5.3
triton 2.3.0
typeguard 4.4.1
types-python-dateutil 2.9.0.20241003
typing_extensions 4.12.2
tyro 0.9.2
tzdata 2024.2
ultralytics 8.2.42
ultralytics-thop 2.0.12
uri-template 1.3.0
urllib3 2.2.3
vhacdx 0.0.8.post1
viser 0.2.19
wcwidth 0.2.13
webcolors 24.11.1
webencodings 0.5.1
websocket-client 1.8.0
websockets 14.1
wheel 0.44.0
widgetsnbextension 4.0.13
wis3d 1.0.1
xatlas 0.0.9
xxhash 3.5.0
yacs 0.1.8
yarl 1.18.3
yourdfpy 0.0.56
zc.lockfile 3.0.post1
import bpy
import os
import math
import numpy as np
from mathutils import Matrix, Vector, Quaternion, Euler
import json
import pickle
#### Change the variables here
###############################
smpl_model = r"/home/sxxzwbl/GVHMR/GVHMR/inputs/checkpoints/body_models/smpl/basicModel_f_lbs_10_207_0_v1.0.2.fbx" #写入自己的路径
file = r'/home/sxxzwbl/GVHMR/GVHMR/outputs/hmr4d_results.pt_person-1.pkl' #写入自己的路径
high_from_floor = 1.5 #离地高度自定义
##############################
with open(file, 'rb') as handle:
results = pickle.load(handle)
# 保存 betas 数据为文本文件
def save_betas_to_file(betas, file_path):
with open(file_path, 'w') as f:
for value in betas:
f.write(f"{value}\n")
# 获取 betas 数据并保存
betas = results['smpl_params_global']['betas']
output_file_path = os.path.splitext(file)[0] + '_betas.txt'
save_betas_to_file(betas, output_file_path)
print(f"betas 数据已保存到 {output_file_path}")
part_match_custom_less2 = {'root': 'root', 'bone_00': 'Pelvis', 'bone_01': 'L_Hip', 'bone_02': 'R_Hip',
'bone_03': 'Spine1', 'bone_04': 'L_Knee', 'bone_05': 'R_Knee', 'bone_06': 'Spine2',
'bone_07': 'L_Ankle', 'bone_08': 'R_Ankle', 'bone_09': 'Spine3', 'bone_10': 'L_Foot',
'bone_11': 'R_Foot', 'bone_12': 'Neck', 'bone_13': 'L_Collar', 'bone_14': 'R_Collar',
'bone_15': 'Head', 'bone_16': 'L_Shoulder', 'bone_17': 'R_Shoulder', 'bone_18': 'L_Elbow',
'bone_19': 'R_Elbow', 'bone_20': 'L_Wrist', 'bone_21': 'R_Wrist',
'bone_22': 'L_Hand', 'bone_23': 'R_Hand',
}
### INICIO --- Inseri para utilizar no WHAM
def Rodrigues(rotvec):
theta = np.linalg.norm(rotvec)
r = (rotvec/theta).reshape(3, 1) if theta > 0. else rotvec
cost = np.cos(theta)
mat = np.asarray([[0, -r[2], r[1]],
[r[2], 0, -r[0]],
[-r[1], r[0], 0]],dtype=object) #adicionei "",dtype=object" por que estava dando erro
return(cost*np.eye(3) + (1-cost)*r.dot(r.T) + np.sin(theta)*mat)
def rodrigues2bshapes(pose):
rod_rots = np.asarray(pose).reshape(22, 3)
mat_rots = [Rodrigues(rod_rot) for rod_rot in rod_rots]
bshapes = np.concatenate([(mat_rot - np.eye(3)).ravel()
for mat_rot in mat_rots[1:]])
return(mat_rots, bshapes)
############
def get_global_pose(global_pose, arm_ob, frame=None):
arm_ob.pose.bones['f_avg_root'].rotation_quaternion.w = 0.0
arm_ob.pose.bones['f_avg_root'].rotation_quaternion.x = -1.0
bone = arm_ob.pose.bones['f_avg_Pelvis']
# if frame is not None:
# bone.keyframe_insert('rotation_quaternion', frame=frame)
root_orig = arm_ob.pose.bones['f_avg_root'].rotation_quaternion
mw_orig = arm_ob.matrix_world.to_quaternion()
pelvis_quat = Matrix(global_pose[0]).to_quaternion()
bone.rotation_quaternion = pelvis_quat
bone.keyframe_insert('rotation_quaternion', frame=frame)
pelvis_applyied = arm_ob.pose.bones['f_avg_Pelvis'].rotation_quaternion
bpy.context.view_layer.update()
rot_world_orig = root_orig @ pelvis_applyied @ mw_orig #pegar a rotacao em relacao ao mundo
return rot_world_orig
###############
# apply trans pose and shape to character
# def apply_trans_pose_shape(trans, body_pose, shape, ob, arm_ob, obname, scene, cam_ob, frame=None):
def apply_trans_pose_shape(trans, body_pose, arm_ob, obname, frame=None):
# transform pose into rotation matrices (for pose) and pose blendshapes
# if self.option in [2,3]: #para WHAM ou slahmr
# mrots, bsh = rodrigues2bshapes(body_pose)
# else: #para 4d humans
# mrots = body_pose
mrots, bsh = rodrigues2bshapes(body_pose)
# mrots = body_pose
part_bones = part_match_custom_less2
# trans = Vector((trans[0],trans[1]-2.2,trans[2]))
trans = Vector((trans[0],trans[1]-high_from_floor,trans[2]))
# print('frame in apply pose:', frame)
arm_ob.pose.bones['f_avg_Pelvis'].location = trans
arm_ob.pose.bones['f_avg_Pelvis'].keyframe_insert('location', frame=frame)
arm_ob.pose.bones['f_avg_root'].rotation_quaternion.w = 0.0
arm_ob.pose.bones['f_avg_root'].rotation_quaternion.x = -1.0
for ibone, mrot in enumerate(mrots):
if ibone < 22: #incui essa parte por que no modelo que eu to usando nao tem bone para a mao
bone = arm_ob.pose.bones['f_avg_'+part_bones['bone_%02d' % ibone]]
bone.rotation_quaternion = Matrix(mrot).to_quaternion()
if frame is not None:
bone.keyframe_insert('rotation_quaternion', frame=frame)
import os
def init_scene(scene, params, gender='female', angle=0):
# path_fbx = os.path.join(path_code,smpl_model)
# smpl_model = r"D:\AI_Stuff\GVHMR\basicModel_m_lbs_10_207_0_v1.0.2.fbx"
path_fbx = smpl_model
bpy.ops.import_scene.fbx(filepath=path_fbx, axis_forward='-Y', axis_up='-Z', global_scale=100)#, automatic_bone_orientation=True)
# arm_obj = bpy.context.selected_objects[0]
arm_ob = bpy.context.selected_objects[0]
obj_gender = 'f'
obname = '%s_avg' % obj_gender
ob = bpy.data.objects[obname]
# arm_obj = 'Armature'
# bpy.context.scene.source = arm_obj
print('success load')
# ob.data.use_auto_smooth = False # autosmooth creates artifacts
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_all(action='DESELECT')
cam_ob = ''
# ob.data.shape_keys.animation_data_clear()
# arm_ob = bpy.data.objects[arm_obj]
# arm_ob = context.scene.source
arm_ob.animation_data_clear()
return(ob, obname, arm_ob, cam_ob)
# qtd_frames = len(results[character]['pose'])
params = []
object_name = 'f_avg'
obj_gender = 'm'
scene = bpy.data.scenes['Scene']
ob, obname, arm_ob, cam_ob= init_scene(scene, params, obj_gender)
qtd_frames = len(results['smpl_params_global']['transl'])
print('qtd frames: ',qtd_frames)
# shape = results[character]['betas'].tolist()
for fframe in range(0,qtd_frames):
bpy.context.scene.frame_set(fframe)
#print('data',data)
# trans = [0.0, 0.0, 1.521]
trans = results['smpl_params_global']['transl'][fframe]
# shape = data[1]['smpl'][character]['betas']
#
global_orient = results['smpl_params_global']['global_orient'][fframe]
# pelvis = fixed_pelvis_quat[fframe]
# global_orient = np.array(Quaternion(pelvis).to_matrix()).reshape(1,3,3)
#
##o trtamento abaixo nao deu certo
# rotation_x = Matrix.Rotation(math.radians(180.0),3,'X') #rodar ao redor de X
# rotation_y = Matrix.Rotation(math.radians(90.0),3,'Y') #rodar ao redor de X
# global_orient = global_orient @ rotation_x @rotation_y
#
body_pose = results['smpl_params_global']['body_pose'][fframe]
body_pose_fim = body_pose.reshape(int(len(body_pose)/3), 3)
final_body_pose = np.vstack([global_orient, body_pose_fim])
# apply_trans_pose_shape(Vector(trans), final_body_pose, shape, obj,arm_ob, obname, scene, cam_ob, fframe)
#
#
apply_trans_pose_shape(Vector(trans), final_body_pose, arm_ob, obname, fframe)
bpy.context.view_layer.update()
arm_ob.pose.bones['f_avg_root'].rotation_quaternion.w = 1.0
arm_ob.pose.bones['f_avg_root'].rotation_quaternion.x = 0.0
arm_ob.pose.bones['f_avg_root'].rotation_quaternion.y = 0.0
arm_ob.pose.bones['f_avg_root'].rotation_quaternion.z = 0.0
arm_ob.pose.bones['f_avg_Pelvis'].constraints.new('COPY_LOCATION')
# arm_ob.pose.bones["f_avg_Pelvis"].constraints["Copy Location"].target = armature_ref
arm_ob.pose.bones["f_avg_Pelvis"].constraints[0].target = arm_ob
arm_ob.pose.bones["f_avg_Pelvis"].constraints[0].subtarget = "f_avg_Pelvis"
# arm_ob.pose.bones["f_avg_Pelvis"].constraints["Copy Location"].subtarget = "f_avg_Pelvis"
arm_ob.pose.bones['f_avg_Pelvis'].constraints.new('COPY_ROTATION')
# arm_ob.pose.bones["f_avg_Pelvis"].constraints["Copy Rotation"].target = armature_ref
arm_ob.pose.bones["f_avg_Pelvis"].constraints[1].target = arm_ob
# arm_ob.pose.bones["f_avg_Pelvis"].constraints["Copy Rotation"].subtarget = "f_avg_Pelvis"
arm_ob.pose.bones["f_avg_Pelvis"].constraints[1].subtarget = "f_avg_Pelvis"
import bpy
import os
import re
# 定义 .pkl 文件所在的文件夹路径(你可以在这里修改路径)
pkl_folder = "/home/sxxzwbl/GVHMR/GVHMR/outputs/pkl_blender/"
# 获取指定文件夹下所有 .pkl 文件的列表
pkl_files = [f for f in os.listdir(pkl_folder) if f.endswith('.pkl')]
# 检查 .pkl 文件的数量
if len(pkl_files) == 0:
raise FileNotFoundError(f"在文件夹 '{pkl_folder}' 中未找到任何 .pkl 文件。")
elif len(pkl_files) > 1:
raise ValueError(f"在文件夹 '{pkl_folder}' 中找到多个 .pkl 文件。脚本只支持处理一个 .pkl 文件。")
# 由于只存在一个 .pkl 文件,获取该文件的名称
pkl_filename = pkl_files[0]
# 构建对应的 .txt 文件的完整路径
txt_filename = os.path.splitext(pkl_filename)[0] + "_betas.txt" # 替换文件扩展名为 .txt
txt_path = os.path.join(pkl_folder, txt_filename)
# 检查 .txt 文件是否存在
if not os.path.exists(txt_path):
raise FileNotFoundError(f"未找到与 '{pkl_filename}' 同名的 '{txt_filename}' 文件。")
# 读取 .txt 文件内容
with open(txt_path, 'r') as file:
content = file.read()
# 使用正则表达式提取所有浮点数
numbers = re.findall(r'[-+]?\d*\.\d+|\d+', content)
# 将提取的字符串转换为浮点数,并取相反数
betas = [-float(num) for num in numbers]
# 打印读取到的数值(可选)
print(f"从 '{txt_filename}' 读取到的数值(取相反数后):", betas)
# 检查是否读取到足够的数值
if len(betas) < 10:
raise ValueError(f"文件 '{txt_filename}' 中没有足够的数值来填充形态键。")
# 截取前10个数值
betas = betas[:10]
# 遍历所有选中的对象
for obj in bpy.context.selected_objects:
if obj.type == 'MESH' and obj.data.shape_keys:
shape_keys = obj.data.shape_keys.key_blocks
# 获取对象的名称
obj_name = obj.name
# 构建 .pkl 文件的完整路径
pkl_path = os.path.join(pkl_folder, pkl_filename)
# 构建对应的 .txt 文件的完整路径
txt_path = os.path.join(pkl_folder, txt_filename)
# 读取 .txt 文件内容(如果需要再次使用)
with open(txt_path, 'r') as file:
content = file.read()
# 使用正则表达式提取所有浮点数
numbers = re.findall(r'[-+]?\d*\.\d+|\d+', content)
# 将提取的字符串转换为浮点数,并取相反数
betas = [-float(num) for num in numbers]
# 打印读取到的数值(可选)
print(f"从 '{txt_filename}' 读取到的数值(取相反数后):", betas)
# 检查是否读取到足够的数值
if len(betas) < 10:
print(f"文件 '{txt_filename}' 中没有足够的数值来填充形态键。")
continue # 跳过当前对象,继续下一个
# 截取前10个数值
betas = betas[:10]
# 遍历指定范围内的形态键 (从shape000到shape009)
for i in range(10):
key_name = f"Shape{i:03d}" # 生成形态键名称,如"Shape000", "Shape001", ..., "Shape009"
# 检查是否存在指定名称的形态键
if key_name in shape_keys:
shape_key = shape_keys[key_name]
# 设置范围下限和上限
shape_key.slider_min = -3.0
shape_key.slider_max = 3.0
# 设置当前值
shape_key.value = betas[i]
# 打印结果(可选)
print(f"对象 '{obj.name}' 的形态键 '{key_name}' 的值已设置为 {shape_key.value},范围设置为 [-3, 3]")
else:
print(f"对象 '{obj.name}' 中未找到形态键 '{key_name}'")