mirror of
https://github.com/gosticks/body-pose-animation.git
synced 2025-10-16 11:45:42 +00:00
157 lines
4.8 KiB
Python
157 lines
4.8 KiB
Python
import matplotlib.pyplot as plt
|
|
import torch
|
|
import numpy as np
|
|
import smplx
|
|
import os
|
|
from human_body_prior.body_model.body_model_vposer import BodyModelWithPoser
|
|
from human_body_prior.tools.model_loader import load_vposer
|
|
|
|
|
|
def get_model_path(type, gender, dir):
|
|
return os.path.join(
|
|
dir,
|
|
type,
|
|
type.upper() + "_" +
|
|
gender.upper() + ".npz")
|
|
|
|
|
|
def get_model_path_from_conf(config):
|
|
return get_model_path(
|
|
config['smpl']['type'],
|
|
config['smpl']['gender'],
|
|
config['smpl']['modelRootDir']
|
|
)
|
|
|
|
|
|
class VPoserModel():
|
|
global_vposer = None
|
|
|
|
def __init__(
|
|
self,
|
|
model_type='smpl',
|
|
body_model_path="./models/smplx/SMPLX_MALE.npz",
|
|
vposer_model_path="./vposer_v1_0",
|
|
ext='npz',
|
|
gender='neutral',
|
|
create_body_pose=True,
|
|
plot_joints=True,
|
|
num_betas=10,
|
|
sample_shape=False,
|
|
sample_expression=False,
|
|
num_expression_coeffs=10,
|
|
use_vposer=True
|
|
):
|
|
self.body_model_path = body_model_path
|
|
self.vposer_model_path = vposer_model_path
|
|
self.model_type = model_type
|
|
self.ext = ext
|
|
self.gender = gender
|
|
self.plot_joints = plot_joints
|
|
self.num_betas = num_betas
|
|
self.sample_shape = sample_shape
|
|
self.sample_expression = sample_expression
|
|
self.num_expression_coeffs = num_expression_coeffs
|
|
self.create_body_pose = create_body_pose
|
|
self.use_vposer = use_vposer
|
|
|
|
self.create_model()
|
|
|
|
def create_model(self):
|
|
|
|
self.model = BodyModelWithPoser(
|
|
bm_path=self.body_model_path,
|
|
batch_size=1,
|
|
poser_type="vposer",
|
|
smpl_exp_dir=self.vposer_model_path
|
|
)
|
|
return self.model
|
|
|
|
def get_vposer_latent(self):
|
|
return self.model.poZ_body
|
|
|
|
def get_pose(self):
|
|
return self.model.pose_body
|
|
|
|
def from_conf(config, use_global=True):
|
|
model_path = get_model_path_from_conf(config)
|
|
|
|
if VPoserModel.global_vposer is None:
|
|
VPoserModel.global_vposer = VPoserModel(
|
|
model_type=config['smpl']['type'],
|
|
gender=config['smpl']['gender'],
|
|
vposer_model_path=config['pose']['vposerPath'],
|
|
body_model_path=model_path)
|
|
|
|
return VPoserModel.global_vposer
|
|
|
|
|
|
class SMPLyModel():
|
|
def __init__(
|
|
self,
|
|
model_folder,
|
|
model_type='smplx',
|
|
ext='npz',
|
|
gender='male',
|
|
create_body_pose=True,
|
|
plot_joints=True,
|
|
num_betas=10,
|
|
sample_shape=False,
|
|
sample_expression=True,
|
|
num_expression_coeffs=10,
|
|
use_face_contour=False,
|
|
use_vposer_init=False,
|
|
device=torch.device('cpu')
|
|
):
|
|
self.model_folder = model_folder
|
|
self.model_type = model_type
|
|
self.ext = ext
|
|
self.gender = gender
|
|
self.plot_joints = plot_joints
|
|
self.num_betas = num_betas
|
|
self.sample_shape = sample_shape
|
|
self.sample_expression = sample_expression
|
|
self.num_expression_coeffs = num_expression_coeffs
|
|
self.use_face_contour = use_face_contour
|
|
self.create_body_pose = create_body_pose
|
|
self.use_vposer_init = use_vposer_init
|
|
self.device = device
|
|
|
|
def create_model(self, initial_pose=None):
|
|
if self.use_vposer_init:
|
|
# sample a valid human shape via vposer
|
|
vp, ps = load_vposer("./vposer_v1_0")
|
|
vp = vp.to(device=self.device)
|
|
self.vp = vp
|
|
self.vposer_sample = torch.from_numpy(
|
|
np.random.randn(1, 32).astype(np.float32)).to(device=self.device)
|
|
|
|
# sample SMPL body pose from vposer
|
|
initial_pose = self.vp.decode(
|
|
self.vposer_sample, output_type='aa').view(-1, 63)
|
|
|
|
self.model = smplx.create(
|
|
self.model_folder,
|
|
model_type=self.model_type,
|
|
gender=self.gender,
|
|
body_pose=initial_pose,
|
|
use_face_contour=self.use_face_contour,
|
|
create_body_pose=self.create_body_pose,
|
|
num_betas=self.num_betas,
|
|
return_verts=True,
|
|
num_expression_coeffs=self.num_expression_coeffs,
|
|
ext=self.ext)
|
|
return self.model
|
|
|
|
def from_config(config, device=None, dtype=None):
|
|
return SMPLyModel(
|
|
model_folder=config['smpl']['modelRootDir'],
|
|
gender=config['smpl']['gender'],
|
|
model_type=config['smpl']['type'],
|
|
ext=config['smpl']['ext'],
|
|
use_vposer_init=config['smpl']['useVposerInit'],
|
|
device=device
|
|
)
|
|
|
|
def model_from_conf(config, device=None, dtype=None, initial_pose=None):
|
|
return SMPLyModel.from_config(config, device=device, dtype=dtype).create_model(initial_pose=initial_pose)
|