check flame config

This commit is contained in:
shuaiqing 2023-10-16 19:45:09 +08:00
parent 0fb7de5499
commit 2d8584f643
4 changed files with 70 additions and 32 deletions

View File

@ -1,19 +0,0 @@
<!--
* @Date: 2021-04-13 16:49:12
* @Author: Qing Shuai
* @LastEditors: Qing Shuai
* @LastEditTime: 2021-04-13 16:51:16
* @FilePath: /EasyMocapRelease/apps/calibration/camera_parameters.md
-->
# Camera Parameters Format
For example, if the name of a video is `1.mp4`, then there must exist `K_1`, `dist_1` in `intri.yml`, and `R_1((3, 1), rotation vector of camera)`, `T_1(3, 1)` in `extri.yml`. The file format is following [OpenCV format](https://docs.opencv.org/master/dd/d74/tutorial_file_input_output_with_xml_yml.html).
## Write/Read
See `easymocap/mytools/camera_utils.py`=>`write_camera`, `read_camera` functions.
## Conversion between different format
TODO

View File

@ -3,14 +3,27 @@ import os
from easymocap.config import Config, load_object from easymocap.config import Config, load_object
from tqdm import tqdm from tqdm import tqdm
def process(dataset, model): def process(dataset, model, args):
ret_all = [] ret_all = []
print('[Run] dataset has {} samples'.format(len(dataset))) print('[Run] dataset has {} samples'.format(len(dataset)))
for i in tqdm(range(len(dataset)), desc='[Run]'): if args.num_workers == -1:
data = dataset[i] for i in tqdm(range(len(dataset)), desc='[Run]'):
ret = model.at_step(data, i) data = dataset[i]
ret_all.append(ret) ret = model.at_step(data, i)
ret_all = model.at_final(ret_all) ret_all.append(ret)
else:
import torch
dataloader = torch.utils.data.DataLoader(dataset,
batch_size=1, num_workers=args.num_workers, shuffle=False, collate_fn=lambda x:x, drop_last=False)
index = 0
for data in tqdm(dataloader, desc='[Run]'):
data = data[0]
ret = model.at_step(data, index)
if not args.skip_final:
ret_all.append(ret)
index += 1
if not args.skip_final:
ret_all = model.at_final(ret_all)
def update_data_by_args(cfg_data, args): def update_data_by_args(cfg_data, args):
if args.root is not None: if args.root is not None:
@ -23,7 +36,7 @@ def update_data_by_args(cfg_data, args):
cfg_data.args.ranges = args.ranges cfg_data.args.ranges = args.ranges
if args.cameras is not None: if args.cameras is not None:
cfg_data.args.reader.cameras.root = args.cameras cfg_data.args.reader.cameras.root = args.cameras
if args.skip_vis: if args.skip_vis or args.skip_vis_step:
cfg_data.args.subs_vis = [] cfg_data.args.subs_vis = []
return cfg_data return cfg_data
@ -41,7 +54,7 @@ def update_exp_by_args(cfg_exp, args):
val.skip = True val.skip = True
if args.skip_vis or args.skip_vis_final: if args.skip_vis or args.skip_vis_final:
for key, val in cfg_exp.args.at_final.items(): for key, val in cfg_exp.args.at_final.items():
if key.startswith('vis'): if key.startswith('vis') or key == 'make_video':
val.skip = True val.skip = True
def load_cfg_from_file(cfg, args): def load_cfg_from_file(cfg, args):
@ -74,9 +87,11 @@ def main_entrypoint():
parser.add_argument('--ranges', type=int, default=None, nargs=3) parser.add_argument('--ranges', type=int, default=None, nargs=3)
parser.add_argument('--cameras', type=str, default=None, help='Camera file path') parser.add_argument('--cameras', type=str, default=None, help='Camera file path')
parser.add_argument('--out', type=str, default=None) parser.add_argument('--out', type=str, default=None)
parser.add_argument('--num_workers', type=int, default=-1)
parser.add_argument('--skip_vis', action='store_true') parser.add_argument('--skip_vis', action='store_true')
parser.add_argument('--skip_vis_step', action='store_true') parser.add_argument('--skip_vis_step', action='store_true')
parser.add_argument('--skip_vis_final', action='store_true') parser.add_argument('--skip_vis_final', action='store_true')
parser.add_argument('--skip_final', action='store_true')
parser.add_argument('--debug', action='store_true') parser.add_argument('--debug', action='store_true')
args = parser.parse_args() args = parser.parse_args()
@ -96,7 +111,7 @@ def main_entrypoint():
print(dataset) print(dataset)
model = load_object(cfg_exp.module, cfg_exp.args) model = load_object(cfg_exp.module, cfg_exp.args)
process(dataset, model) process(dataset, model, args)
if __name__ == '__main__': if __name__ == '__main__':
main_entrypoint() main_entrypoint()

4
config/model/flame.yml Normal file
View File

@ -0,0 +1,4 @@
module: easymocap.bodymodel.smpl.SMPLModel
args:
model_path: data/bodymodels/FLAME2020/FLAME_NEUTRAL.pkl
device: cuda

View File

@ -85,12 +85,13 @@ class SMPLModel(Model):
self.lbs = lbs self.lbs = lbs
self.data = load_model_data(model_path) self.data = load_model_data(model_path)
self.register_any_lbs(self.data) self.register_any_lbs(self.data)
# keypoints regressor # keypoints regressor
if regressor_path is not None and use_joints: if regressor_path is not None and use_joints:
X_regressor = load_regressor(regressor_path) X_regressor = load_regressor(regressor_path)
X_regressor = torch.cat((self.J_regressor, X_regressor), dim=0) X_regressor = torch.cat((self.J_regressor, X_regressor), dim=0)
self.register_any_keypoints(X_regressor) self.register_any_keypoints(X_regressor)
elif regressor_path is None:
self.register_any_keypoints(self.J_regressor)
if not self.use_root_rot: if not self.use_root_rot:
self.NUM_POSES -= 3 # remove first 3 dims self.NUM_POSES -= 3 # remove first 3 dims
self.to(self.device) self.to(self.device)
@ -169,7 +170,9 @@ class SMPLModel(Model):
def forward(self, return_verts=True, return_tensor=True, def forward(self, return_verts=True, return_tensor=True,
return_smpl_joints=False, return_smpl_joints=False,
only_shape=False, pose2rot=True, **params): only_shape=False, pose2rot=True,
v_template=None,
**params):
params = self.check_params(params) params = self.check_params(params)
poses, shapes = params['poses'], params['shapes'] poses, shapes = params['poses'], params['shapes']
poses = self.extend_poses(pose2rot=pose2rot, **params) poses = self.extend_poses(pose2rot=pose2rot, **params)
@ -187,7 +190,8 @@ class SMPLModel(Model):
Rh = batch_rodrigues(Rh) Rh = batch_rodrigues(Rh)
Th = Th.unsqueeze(dim=1) Th = Th.unsqueeze(dim=1)
if return_verts or not self.use_joints: if return_verts or not self.use_joints:
v_template = self.v_template if v_template is None:
v_template = self.v_template
if 'scale' in params.keys(): if 'scale' in params.keys():
v_template = v_template * params['scale'][0] v_template = v_template * params['scale'][0]
vertices, joints, T_joints, T_vertices = self.lbs(shapes, poses, v_template, vertices, joints, T_joints, T_vertices = self.lbs(shapes, poses, v_template,
@ -199,7 +203,8 @@ class SMPLModel(Model):
vertices = joints vertices = joints
else: else:
# only forward joints # only forward joints
v_template = self.j_v_template if v_template is None:
v_template = self.j_v_template
if 'scale' in params.keys(): if 'scale' in params.keys():
v_template = v_template * params['scale'][0] v_template = v_template * params['scale'][0]
vertices, joints, _, _ = self.lbs(shapes, poses, v_template, vertices, joints, _, _ = self.lbs(shapes, poses, v_template,
@ -236,6 +241,39 @@ class SMPLModel(Model):
return Params.merge(params, **kwargs) return Params.merge(params, **kwargs)
def convert_to_standard_smpl(self, params):
params = self.check_params(params)
poses, shapes = params['poses'], params['shapes']
Th = params['Th']
vertices, joints, _, _ = lbs(shapes, poses, self.v_template,
self.shapedirs, self.posedirs,
self.J_regressor, self.parents,
self.weights, pose2rot=True, dtype=self.dtype, only_shape=True)
# N x 3
j0 = joints[:, 0, :]
Rh = params['Rh']
# N x 3 x 3
rot = batch_rodrigues(Rh)
# change the rotate center
min_xyz, _ = self.v_template.min(dim=0, keepdim=True)
# X' = X + delta_center
delta_center = torch.tensor([0., -min_xyz[0, 1], 0.]).reshape(1, 3).to(j0.device)
# J' = J + delta_center
j0new = j0 + delta_center
# Tnew = T - (R(d - J0) + J0)
Tnew = Th - (torch.einsum('bij,bj->bi', rot, delta_center-j0new) + j0new)
if poses.shape[1] == 69:
poses = torch.cat([Rh, poses], dim=1)
elif poses.shape[1] == 72:
poses[:, :3] = Rh
else:
import ipdb;ipdb.set_trace()
res = dict(poses=poses.detach().cpu().numpy(),
shapes=shapes.detach().cpu().numpy(),
Th=Tnew.detach().cpu().numpy()
)
return res
def convert_from_standard_smpl(self, params): def convert_from_standard_smpl(self, params):
params = self.check_params(params) params = self.check_params(params)
poses, shapes = params['poses'], params['shapes'] poses, shapes = params['poses'], params['shapes']