mirror of
https://github.com/gosticks/body-pose-animation.git
synced 2025-10-16 11:45:42 +00:00
final preparations
This commit is contained in:
parent
51f220b2ae
commit
316bc2d7e3
32
config.yaml
32
config.yaml
@ -1,5 +1,5 @@
|
|||||||
output:
|
output:
|
||||||
rootDir: "./tests/20-02-21"
|
rootDir: "./presentation"
|
||||||
prefix: ""
|
prefix: ""
|
||||||
smpl:
|
smpl:
|
||||||
modelRootDir: ./models
|
modelRootDir: ./models
|
||||||
@ -9,25 +9,25 @@ smpl:
|
|||||||
useVposerInit: false
|
useVposerInit: false
|
||||||
data:
|
data:
|
||||||
renameFiles: false
|
renameFiles: false
|
||||||
rootDir: ./samples/video02
|
rootDir: ./samples/video01
|
||||||
personId: 0
|
personId: 0
|
||||||
sampleImageFormat: "frame-%%%.png"
|
sampleImageFormat: "input_%%%%%%%%%%%%_rendered.png"
|
||||||
sampleNameFormat: "input2_%%%%%%%%%%%%_keypoints.json"
|
sampleNameFormat: "input_%%%%%%%%%%%%_keypoints.json"
|
||||||
sampleCoords: !!python/tuple [1080, 1080]
|
sampleCoords: !!python/tuple [1080, 1080]
|
||||||
camera:
|
camera:
|
||||||
lr: 0.001
|
lr: 0.001
|
||||||
patience: 10
|
patience: 10
|
||||||
optimizer: Adam
|
optimizer: Adam
|
||||||
orientation:
|
orientation:
|
||||||
lr: 0.01
|
lr: 0.03
|
||||||
optimizer: Adam
|
optimizer: LBFGS
|
||||||
iterations: 100
|
iterations: 5
|
||||||
joint_names: ["hip-left", "hip-right", "shoulder-left", "shoulder-right"] # joints to be used for optimization
|
joint_names: ["hip-left", "hip-right", "shoulder-left", "shoulder-right"] # joints to be used for optimization
|
||||||
pose:
|
pose:
|
||||||
device: cuda
|
device: cuda
|
||||||
lr: 0.01
|
lr: 0.01
|
||||||
optimizer: Adam # currently supported Adam, LBFGS
|
optimizer: Adam # currently supported Adam, LBFGS
|
||||||
iterations: 100
|
iterations: 150
|
||||||
useCameraIntrinsics: true
|
useCameraIntrinsics: true
|
||||||
useOpenPoseConf: true # use openpose confidence to weight L2 distance loss
|
useOpenPoseConf: true # use openpose confidence to weight L2 distance loss
|
||||||
bodyMeanLoss:
|
bodyMeanLoss:
|
||||||
@ -35,21 +35,21 @@ pose:
|
|||||||
weight: 0.1
|
weight: 0.1
|
||||||
bodyPrior:
|
bodyPrior:
|
||||||
enabled: true
|
enabled: true
|
||||||
weight: 0.01
|
weight: 0.1
|
||||||
anglePrior:
|
anglePrior:
|
||||||
enabled: true
|
enabled: true
|
||||||
weight: 0.2
|
weight: 0.05
|
||||||
# optional per joint configurations
|
# optional per joint configurations
|
||||||
angleIdx: [56, 53, 12, 9, 37, 40]
|
angleIdx: [56, 53, 12, 9, 37, 40]
|
||||||
directions: [-1, 1, -1, -1, 1, -1]
|
directions: [1, -1, -1, -1, 1, -1]
|
||||||
# weights per joint
|
# weights per joint
|
||||||
weights: [0.4, 0.4, 0.4, 0.4, 0.2, 0.2]
|
weights: [0.2, 0.2, 0.8, 0.8, 0.0, 0.0]
|
||||||
angleLimitLoss:
|
angleLimitLoss:
|
||||||
enabled: true
|
enabled: true
|
||||||
weight: 0.01
|
weight: 0.01
|
||||||
angleSumLoss:
|
angleSumLoss:
|
||||||
enabled: true
|
enabled: true
|
||||||
weight: 0.01
|
weight: 0.001
|
||||||
intersectLoss:
|
intersectLoss:
|
||||||
enabled: true
|
enabled: true
|
||||||
weight: 0.5
|
weight: 0.5
|
||||||
@ -57,14 +57,14 @@ pose:
|
|||||||
sigma: 0.5
|
sigma: 0.5
|
||||||
changeLoss:
|
changeLoss:
|
||||||
enabled: true
|
enabled: true
|
||||||
weight: 0.1
|
weight: 0.07
|
||||||
confWeights:
|
confWeights:
|
||||||
enabled: false
|
enabled: false
|
||||||
vposerPath: "./vposer_v1_0"
|
vposerPath: "./vposer_v1_0"
|
||||||
temporal:
|
temporal:
|
||||||
enabled: true
|
enabled: true
|
||||||
iterations: 75
|
iterations: 50
|
||||||
lr: 0.01
|
lr: 0.03
|
||||||
preview:
|
preview:
|
||||||
enable: true,
|
enable: true,
|
||||||
keypoins:
|
keypoins:
|
||||||
|
|||||||
81
config_loss_off.yaml
Normal file
81
config_loss_off.yaml
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
output:
|
||||||
|
rootDir: "./tests/final-03"
|
||||||
|
prefix: ""
|
||||||
|
smpl:
|
||||||
|
modelRootDir: ./models
|
||||||
|
type: smplx # possible options smplx and smpl
|
||||||
|
gender: MALE # possible options MALE, FEMALE, NEUTRAL
|
||||||
|
ext: npz
|
||||||
|
useVposerInit: false
|
||||||
|
data:
|
||||||
|
renameFiles: false
|
||||||
|
rootDir: ./samples/video01
|
||||||
|
personId: 0
|
||||||
|
sampleImageFormat: "input_%%%%%%%%%%%%_rendered.png"
|
||||||
|
sampleNameFormat: "input_%%%%%%%%%%%%_keypoints.json"
|
||||||
|
sampleCoords: !!python/tuple [1080, 1080]
|
||||||
|
camera:
|
||||||
|
lr: 0.001
|
||||||
|
patience: 10
|
||||||
|
optimizer: Adam
|
||||||
|
orientation:
|
||||||
|
lr: 0.03
|
||||||
|
optimizer: LBFGS
|
||||||
|
iterations: 5
|
||||||
|
joint_names: ["hip-left", "hip-right", "shoulder-left", "shoulder-right"] # joints to be used for optimization
|
||||||
|
pose:
|
||||||
|
device: cuda
|
||||||
|
lr: 0.01
|
||||||
|
optimizer: Adam # currently supported Adam, LBFGS
|
||||||
|
iterations: 200
|
||||||
|
useCameraIntrinsics: true
|
||||||
|
useOpenPoseConf: false # use openpose confidence to weight L2 distance loss
|
||||||
|
bodyMeanLoss:
|
||||||
|
enabled: false
|
||||||
|
weight: 0.1
|
||||||
|
bodyPrior:
|
||||||
|
enabled: false
|
||||||
|
weight: 0.01
|
||||||
|
anglePrior:
|
||||||
|
enabled: false
|
||||||
|
weight: 0.2
|
||||||
|
# optional per joint configurations
|
||||||
|
angleIdx: [56, 53, 12, 9, 37, 40]
|
||||||
|
directions: [-1, 1, -1, -1, 1, -1]
|
||||||
|
# weights per joint
|
||||||
|
weights: [0.4, 0.4, 0.4, 0.4, 0.2, 0.2]
|
||||||
|
angleLimitLoss:
|
||||||
|
enabled: false
|
||||||
|
weight: 0.01
|
||||||
|
angleSumLoss:
|
||||||
|
enabled: false
|
||||||
|
weight: 0.001
|
||||||
|
intersectLoss:
|
||||||
|
enabled: false
|
||||||
|
weight: 0.5
|
||||||
|
maxCollisions: 8
|
||||||
|
sigma: 0.5
|
||||||
|
changeLoss:
|
||||||
|
enabled: true
|
||||||
|
weight: 0.2
|
||||||
|
confWeights:
|
||||||
|
enabled: false
|
||||||
|
vposerPath: "./vposer_v1_0"
|
||||||
|
temporal:
|
||||||
|
enabled: true
|
||||||
|
iterations: 30
|
||||||
|
lr: 0.01
|
||||||
|
preview:
|
||||||
|
enable: true,
|
||||||
|
keypoins:
|
||||||
|
enable: true,
|
||||||
|
radius: 0.01
|
||||||
|
color: 1.0, 0.0, 1.0, 1.0
|
||||||
|
keypoint_torso:
|
||||||
|
enable: true,
|
||||||
|
radius: 0.01
|
||||||
|
color: 1.0, 0.0, 1.0, 1.0
|
||||||
|
joints:
|
||||||
|
enable: true
|
||||||
|
radius: 0.01
|
||||||
|
color: 0.0, 0.7, 0.0, 1.0
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
from utils.video import make_video, make_video_with_pip
|
||||||
from utils.graphs import render_loss_graph
|
from utils.graphs import render_loss_graph
|
||||||
from train import optimize_sample
|
from train import optimize_sample
|
||||||
|
|
||||||
@ -9,19 +10,28 @@ from dataset import SMPLyDataset
|
|||||||
# load and select sample
|
# load and select sample
|
||||||
config = load_config()
|
config = load_config()
|
||||||
dataset = SMPLyDataset.from_config(config=config)
|
dataset = SMPLyDataset.from_config(config=config)
|
||||||
sample_index = 55
|
sample_index = 150
|
||||||
|
save_to_video = True
|
||||||
|
|
||||||
|
|
||||||
if os.getenv('SAMPLE_INDEX') is not None:
|
if os.getenv('SAMPLE_INDEX') is not None:
|
||||||
sample_index = int(os.getenv('SAMPLE_INDEX'))
|
sample_index = int(os.getenv('SAMPLE_INDEX'))
|
||||||
|
|
||||||
|
|
||||||
# train for pose
|
# train for pose
|
||||||
pose, camera_transformation, loss_history, step_imgs, loss_components = optimize_sample(
|
pose, camera_transformation, loss_history, step_imgs, loss_components = optimize_sample(
|
||||||
sample_index,
|
sample_index,
|
||||||
dataset,
|
dataset,
|
||||||
config,
|
config,
|
||||||
interactive=True
|
interactive=not save_to_video,
|
||||||
|
offscreen=save_to_video
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if save_to_video:
|
||||||
|
img_path = dataset.get_image_path(sample_index)
|
||||||
|
make_video_with_pip(step_imgs, pip_image_path=img_path,
|
||||||
|
video_name="example_fit")
|
||||||
|
|
||||||
|
|
||||||
filename = get_output_path_from_conf(config) + ".png"
|
filename = get_output_path_from_conf(config) + ".png"
|
||||||
render_loss_graph(
|
render_loss_graph(
|
||||||
|
|||||||
@ -8,7 +8,7 @@ from renderer import *
|
|||||||
from utils.general import rename_files, get_new_filename
|
from utils.general import rename_files, get_new_filename
|
||||||
|
|
||||||
START_IDX = 1 # starting index of the frame to optimize for
|
START_IDX = 1 # starting index of the frame to optimize for
|
||||||
FINISH_IDX = 200 # choose a big number to optimize for all frames in samples directory
|
FINISH_IDX = 60 # choose a big number to optimize for all frames in samples directory
|
||||||
# if False, only run already saved animation without optimization
|
# if False, only run already saved animation without optimization
|
||||||
RUN_OPTIMIZATION = True
|
RUN_OPTIMIZATION = True
|
||||||
|
|
||||||
|
|||||||
51
example_fit_temporal.py
Normal file
51
example_fit_temporal.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import os
|
||||||
|
from utils.video import make_video_with_pip
|
||||||
|
from utils.graphs import render_loss_graph
|
||||||
|
from train import optimize_sample
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from utils.general import get_output_path_from_conf, load_config
|
||||||
|
from dataset import SMPLyDataset
|
||||||
|
|
||||||
|
# load and select sample
|
||||||
|
config = load_config()
|
||||||
|
dataset = SMPLyDataset.from_config(config=config)
|
||||||
|
sample_index = 55
|
||||||
|
save_to_video = True
|
||||||
|
|
||||||
|
if os.getenv('SAMPLE_INDEX') is not None:
|
||||||
|
sample_index = int(os.getenv('SAMPLE_INDEX'))
|
||||||
|
|
||||||
|
# train for pose
|
||||||
|
best_pose, camera_transformation, loss_history, step_imgs, loss_components = optimize_sample(
|
||||||
|
sample_index - 1,
|
||||||
|
dataset,
|
||||||
|
config,
|
||||||
|
interactive=False
|
||||||
|
)
|
||||||
|
|
||||||
|
config['pose']['lr'] = config['pose']['temporal']['lr']
|
||||||
|
config['pose']['iterations'] = config['pose']['temporal']['iterations']
|
||||||
|
|
||||||
|
# reuse model to train new sample
|
||||||
|
pose_temp, camera_transformation, loss_history, step_imgs, loss_components = optimize_sample(
|
||||||
|
sample_index,
|
||||||
|
dataset,
|
||||||
|
config,
|
||||||
|
interactive=False,
|
||||||
|
offscreen=True,
|
||||||
|
initial_pose=best_pose.body_pose.detach().clone().cpu(),
|
||||||
|
initial_orient=best_pose.global_orient.detach().clone().cpu()
|
||||||
|
)
|
||||||
|
|
||||||
|
if save_to_video:
|
||||||
|
img_path = dataset.get_image_path(sample_index)
|
||||||
|
make_video_with_pip(step_imgs, pip_image_path=img_path,
|
||||||
|
video_name="example_fit_temporal")
|
||||||
|
|
||||||
|
filename = get_output_path_from_conf(config) + ".png"
|
||||||
|
render_loss_graph(
|
||||||
|
loss_history=loss_history,
|
||||||
|
loss_components=loss_components,
|
||||||
|
save=True,
|
||||||
|
filename=filename)
|
||||||
@ -12,8 +12,8 @@ from utils.general import *
|
|||||||
from renderer import *
|
from renderer import *
|
||||||
from utils.general import rename_files, get_new_filename
|
from utils.general import rename_files, get_new_filename
|
||||||
|
|
||||||
START_IDX = 00 # starting index of the frame to optimize for
|
START_IDX = 140 # starting index of the frame to optimize for
|
||||||
FINISH_IDX = 20 # choose a big number to optimize for all frames in samples
|
FINISH_IDX = 300 # choose a big number to optimize for all frames in samples
|
||||||
|
|
||||||
device = torch.device('cpu')
|
device = torch.device('cpu')
|
||||||
dtype = torch.float32
|
dtype = torch.float32
|
||||||
@ -31,7 +31,7 @@ def run_test(config):
|
|||||||
FINISH_IDX,
|
FINISH_IDX,
|
||||||
verbose=False,
|
verbose=False,
|
||||||
offscreen=False,
|
offscreen=False,
|
||||||
save_to_file=False,
|
save_to_file=True,
|
||||||
interpolate=False
|
interpolate=False
|
||||||
)
|
)
|
||||||
video_name = getfilename_from_conf(
|
video_name = getfilename_from_conf(
|
||||||
@ -49,24 +49,28 @@ def run_test(config):
|
|||||||
|
|
||||||
save_to_video(
|
save_to_video(
|
||||||
model_outs, video_name, config,
|
model_outs, video_name, config,
|
||||||
|
start_frame_offset=START_IDX,
|
||||||
dataset=dataset, interpolation_target=60
|
dataset=dataset, interpolation_target=60
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def run_pose_tests(config):
|
def run_pose_tests(config):
|
||||||
priors_types = ['bodyPrior', 'anglePrior', 'angleSumLoss', 'temporal']
|
priors_types = ['bodyPrior', 'anglePrior',
|
||||||
|
'angleSumLoss', 'temporal', 'intersectLoss', 'changeLoss']
|
||||||
l = [False, True]
|
l = [False, True]
|
||||||
permutations = [list(i)
|
permutations = [list(i)
|
||||||
for i in itertools.product(l, repeat=len(priors_types))]
|
for i in itertools.product(l, repeat=len(priors_types))]
|
||||||
|
|
||||||
lr_steps = [0.01, 0.02, 0.03, 0.04, 0.05,
|
lr_steps = [0.01]
|
||||||
0.07, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5]
|
total_runs = len(permutations) * len(lr_steps)
|
||||||
|
run_num = 1
|
||||||
for lr in lr_steps:
|
for lr in lr_steps:
|
||||||
print("running test with lr:", lr)
|
print("running test with lr:", lr)
|
||||||
config['pose']['lr'] = lr
|
config['pose']['lr'] = lr
|
||||||
|
|
||||||
for p in permutations:
|
for p in permutations:
|
||||||
print("running test:", config['pose']['optimizer'])
|
print("running test ", "(" + str(run_num) + "/" + str(total_runs) + "):",
|
||||||
|
config['pose']['optimizer'])
|
||||||
# iterate over all permutations and update config
|
# iterate over all permutations and update config
|
||||||
for i, v in enumerate(p):
|
for i, v in enumerate(p):
|
||||||
config['pose'][priors_types[i]]['enabled'] = v
|
config['pose'][priors_types[i]]['enabled'] = v
|
||||||
@ -79,7 +83,7 @@ print("training: Adam")
|
|||||||
# run tests for adam
|
# run tests for adam
|
||||||
run_pose_tests(config)
|
run_pose_tests(config)
|
||||||
|
|
||||||
print("training: LBFGS")
|
# print("training: LBFGS")
|
||||||
# try the same with lbfgs
|
# try the same with lbfgs
|
||||||
config = load_config("./config.lbfgs.temporal.yaml")
|
# config = load_config("./config.lbfgs.temporal.yaml")
|
||||||
run_pose_tests(config)
|
# run_pose_tests(config)
|
||||||
@ -8,8 +8,8 @@ from utils.general import *
|
|||||||
from renderer import *
|
from renderer import *
|
||||||
from utils.general import rename_files, get_new_filename
|
from utils.general import rename_files, get_new_filename
|
||||||
|
|
||||||
START_IDX = 1 # starting index of the frame to optimize for
|
START_IDX = 150 # starting index of the frame to optimize for
|
||||||
FINISH_IDX = None # choose a big number to optimize for all frames in samples directory
|
FINISH_IDX = 300 # choose a big number to optimize for all frames in samples directory
|
||||||
|
|
||||||
result_image = []
|
result_image = []
|
||||||
idx = START_IDX
|
idx = START_IDX
|
||||||
@ -24,13 +24,14 @@ model_outs, filename = create_animation(
|
|||||||
START_IDX,
|
START_IDX,
|
||||||
FINISH_IDX,
|
FINISH_IDX,
|
||||||
verbose=False,
|
verbose=False,
|
||||||
offscreen=True,
|
offscreen=False,
|
||||||
save_to_file=False,
|
save_to_file=False,
|
||||||
interpolate=False
|
interpolate=False
|
||||||
)
|
)
|
||||||
|
|
||||||
video_name = getfilename_from_conf(
|
video_name = get_output_path_from_conf(
|
||||||
config) + "-" + str(START_IDX) + "-" + str(FINISH_IDX)
|
config) + "-" + str(START_IDX) + "-" + str(FINISH_IDX)
|
||||||
|
|
||||||
save_to_video(model_outs, video_name, config,
|
save_to_video(model_outs, video_name, config,
|
||||||
dataset=dataset, interpolation_target=60)
|
start_frame_offset=START_IDX,
|
||||||
|
dataset=dataset)
|
||||||
|
|||||||
20
train.py
20
train.py
@ -18,12 +18,12 @@ from utils.video import interpolate_poses
|
|||||||
from camera_estimation import TorchCameraEstimate
|
from camera_estimation import TorchCameraEstimate
|
||||||
|
|
||||||
|
|
||||||
def optimize_sample(sample_index, dataset, config, device=torch.device('cpu'), dtype=torch.float32, interactive=True, offscreen=False, verbose=True, initial_pose=None):
|
def optimize_sample(sample_index, dataset, config, device=torch.device('cpu'), dtype=torch.float32, interactive=True, offscreen=False, verbose=True, initial_pose=None, initial_orient=None):
|
||||||
# prepare data and SMPL model
|
# prepare data and SMPL model
|
||||||
model = SMPLyModel.model_from_conf(config)
|
model = SMPLyModel.model_from_conf(config)
|
||||||
init_keypoints, init_joints, keypoints, conf, est_scale, r, img_path = setup_training(
|
init_keypoints, init_joints, keypoints, conf, est_scale, r, img_path = setup_training(
|
||||||
model=model,
|
model=model,
|
||||||
renderer=interactive,
|
renderer=(interactive or offscreen),
|
||||||
dataset=dataset,
|
dataset=dataset,
|
||||||
sample_index=sample_index,
|
sample_index=sample_index,
|
||||||
offscreen=offscreen
|
offscreen=offscreen
|
||||||
@ -69,9 +69,10 @@ def optimize_sample(sample_index, dataset, config, device=torch.device('cpu'), d
|
|||||||
|
|
||||||
params = defaultdict(
|
params = defaultdict(
|
||||||
body_pose=initial_pose,
|
body_pose=initial_pose,
|
||||||
|
global_orient=initial_orient
|
||||||
)
|
)
|
||||||
|
with torch.no_grad():
|
||||||
model(**params)
|
model(**params)
|
||||||
|
|
||||||
# apply transform to scene
|
# apply transform to scene
|
||||||
if r is not None:
|
if r is not None:
|
||||||
@ -88,6 +89,11 @@ def optimize_sample(sample_index, dataset, config, device=torch.device('cpu'), d
|
|||||||
render_steps=(offscreen or interactive)
|
render_steps=(offscreen or interactive)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# FIXME: there seems to some form of projection issue and hence the orientation is missestimating the angle
|
||||||
|
# with torch.no_grad():
|
||||||
|
# .to(device=device, dtype=dtype)
|
||||||
|
# model.global_orient[0][1] = -model.global_orient[0][1]
|
||||||
|
|
||||||
# train for pose
|
# train for pose
|
||||||
best_out, loss_history, step_imgs, loss_components = train_pose_with_conf(
|
best_out, loss_history, step_imgs, loss_components = train_pose_with_conf(
|
||||||
config=config,
|
config=config,
|
||||||
@ -118,6 +124,7 @@ def create_animation(dataset, config, start_idx=0, end_idx=None, offscreen=False
|
|||||||
end_idx = len(dataset) - 1
|
end_idx = len(dataset) - 1
|
||||||
|
|
||||||
initial_pose = None
|
initial_pose = None
|
||||||
|
initial_orient = None
|
||||||
|
|
||||||
for idx in trange(end_idx - start_idx, desc='Optimizing'):
|
for idx in trange(end_idx - start_idx, desc='Optimizing'):
|
||||||
idx = start_idx + idx
|
idx = start_idx + idx
|
||||||
@ -133,8 +140,8 @@ def create_animation(dataset, config, start_idx=0, end_idx=None, offscreen=False
|
|||||||
verbose=verbose,
|
verbose=verbose,
|
||||||
offscreen=offscreen,
|
offscreen=offscreen,
|
||||||
interactive=verbose,
|
interactive=verbose,
|
||||||
initial_pose=initial_pose
|
initial_pose=initial_pose,
|
||||||
)
|
initial_orient=initial_orient)
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print("Optimization of", idx, "frames finished")
|
print("Optimization of", idx, "frames finished")
|
||||||
@ -152,6 +159,7 @@ def create_animation(dataset, config, start_idx=0, end_idx=None, offscreen=False
|
|||||||
|
|
||||||
if use_temporal_data:
|
if use_temporal_data:
|
||||||
initial_pose = best_out.body_pose.detach().clone().cpu() # .to(device=device)
|
initial_pose = best_out.body_pose.detach().clone().cpu() # .to(device=device)
|
||||||
|
initial_orient = best_out.global_orient.detach().clone().cpu()
|
||||||
|
|
||||||
if interpolate:
|
if interpolate:
|
||||||
model_outs = interpolate_poses(model_outs)
|
model_outs = interpolate_poses(model_outs)
|
||||||
|
|||||||
@ -176,4 +176,4 @@ def train_orient_with_conf(
|
|||||||
use_progress_bar=use_progress_bar,
|
use_progress_bar=use_progress_bar,
|
||||||
)
|
)
|
||||||
|
|
||||||
return best_output.global_orient
|
return best_output.global_orient.detach().clone().cpu()
|
||||||
|
|||||||
@ -48,7 +48,8 @@ def save_to_video(
|
|||||||
config: object,
|
config: object,
|
||||||
fps=30,
|
fps=30,
|
||||||
include_thumbnail=True,
|
include_thumbnail=True,
|
||||||
thumbnail_size=0.25,
|
thumbnail_size=0.2,
|
||||||
|
start_frame_offset=0,
|
||||||
dataset: SMPLyDataset = None,
|
dataset: SMPLyDataset = None,
|
||||||
interpolation_target=None
|
interpolation_target=None
|
||||||
):
|
):
|
||||||
@ -76,9 +77,14 @@ def save_to_video(
|
|||||||
inter_ratio = int(interpolation_target / fps)
|
inter_ratio = int(interpolation_target / fps)
|
||||||
num_intermediate = inter_ratio - 1
|
num_intermediate = inter_ratio - 1
|
||||||
sample_output = interpolate_poses(sample_output, num_intermediate)
|
sample_output = interpolate_poses(sample_output, num_intermediate)
|
||||||
|
else:
|
||||||
|
sample_output = [
|
||||||
|
(
|
||||||
|
out.vertices.detach().cpu().numpy()[0],
|
||||||
|
cam
|
||||||
|
) for out, cam in sample_output]
|
||||||
frames = []
|
frames = []
|
||||||
print("[export] rendering animation frames...")
|
print("[export] rendering animation frames...", sample_output[0][0].shape)
|
||||||
|
|
||||||
# just use the first transform
|
# just use the first transform
|
||||||
cam_transform = sample_output[0][1]
|
cam_transform = sample_output[0][1]
|
||||||
@ -87,7 +93,7 @@ def save_to_video(
|
|||||||
r.render_model_geometry(
|
r.render_model_geometry(
|
||||||
faces=model_anim.faces,
|
faces=model_anim.faces,
|
||||||
vertices=vertices,
|
vertices=vertices,
|
||||||
pose=cam_transform,
|
pose=cam_trans # cam_transform,
|
||||||
)
|
)
|
||||||
frames.append(r.get_snapshot())
|
frames.append(r.get_snapshot())
|
||||||
|
|
||||||
@ -98,6 +104,8 @@ def save_to_video(
|
|||||||
def post_process_frame(img, idx: int):
|
def post_process_frame(img, idx: int):
|
||||||
if not include_thumbnail:
|
if not include_thumbnail:
|
||||||
return img
|
return img
|
||||||
|
# account for start from frames not zero
|
||||||
|
idx = start_frame_offset + idx
|
||||||
frame_idx = idx
|
frame_idx = idx
|
||||||
if interpolation_target is not None:
|
if interpolation_target is not None:
|
||||||
# account for possible interpolation
|
# account for possible interpolation
|
||||||
@ -122,6 +130,30 @@ def save_to_video(
|
|||||||
post_process_frame=post_process_frame)
|
post_process_frame=post_process_frame)
|
||||||
|
|
||||||
|
|
||||||
|
def make_video_with_pip(frames, pip_image_path, video_name: str, fps=30, ext: str = "mp4", image_size=0.2):
|
||||||
|
"""renders a video with a pip frame in the corner
|
||||||
|
"""
|
||||||
|
|
||||||
|
def post_process_frame(img, idx: int):
|
||||||
|
overlay = cv2.imread(pip_image_path)
|
||||||
|
|
||||||
|
if overlay is None:
|
||||||
|
print("[error] image could not be ", pip_image_path)
|
||||||
|
return img
|
||||||
|
|
||||||
|
overlay = cv2.resize(
|
||||||
|
overlay,
|
||||||
|
dsize=(
|
||||||
|
int(overlay.shape[1] * image_size),
|
||||||
|
int(overlay.shape[0] * image_size)
|
||||||
|
))
|
||||||
|
img[0:overlay.shape[0], 0:overlay.shape[1]] = overlay
|
||||||
|
return img
|
||||||
|
|
||||||
|
make_video(frames, video_name, fps,
|
||||||
|
post_process_frame=post_process_frame)
|
||||||
|
|
||||||
|
|
||||||
def interpolate_poses(poses, num_intermediate=5):
|
def interpolate_poses(poses, num_intermediate=5):
|
||||||
"""
|
"""
|
||||||
Interpolate vertices and cameras between pairs of frames by adding intermediate results
|
Interpolate vertices and cameras between pairs of frames by adding intermediate results
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user