SCAIL-2 / SCAIL-Pose /NLFPoseExtract /reshape_utils_3d.py
fffiloni's picture
Migrated files batch 1
09462dc verified
Raw
History Blame Contribute Delete
13.9 kB
import numpy as np
import random
from NLFPoseExtract.nlf_draw import intrinsic_matrix_from_field_of_view, process_data_to_COCO_format, p3d_to_p2d
import torch
# reshapePool只负责形变,骨骼偏移、丢弃等得从draw层来做
class reshapePool3d:
def __init__(self, reshape_type, height, width): # 对每个视频只初始化一次
self.reshape_type = reshape_type
self.height = height
self.width = width
self.shoulder_alpha = 0
self.upper_arm_alpha = 0
self.forearm_alpha = 0
self.body_alpha = 0
self.thigh_alpha = 0
self.calf_alpha = 0
self.face_alpha = random.choices([-0.4, -0.2, 0, 0.2, 0.4], weights=[0.2, 0.15, 0.3, 0.15, 0.2], k=1)[0]
self.body_reshape_methods = [
self.reshape_body,
self.reshape_arm,
self.reshape_leg,
self.reshape_shoulder,
]
self.face_reshape_methods = [
self.reshape_face,
]
self.body_offset_selected_methods = []
options = ["normal_human", "dwarf", "slender", "elf", "random_long_arm_long_leg", "king-kong"]
if self.reshape_type == "low":
weights = [0.8, 0, 0, 0.1, 0.1, 0]
self.body_offset_selected_methods = []
if self.reshape_type == "normal":
weights = [0.4, 0.1, 0.1, 0.1, 0.2, 0.1]
elif self.reshape_type == "high":
weights = [0.3, 0.2, 0.1, 0.1, 0.2, 0.1]
elif self.reshape_type == "dongman":
weights = [0.1, 0.2, 0.2, 0.2, 0.2, 0.1]
self.face_alpha = random.choices([-0.4, -0.2, 0.4], weights=[0.4, 0.2, 0.4], k=1)[0]
choice = random.choices(options, weights=weights, k=1)[0]
self.aug_init(choice)
def pose_reshape_2d_for_face(self, alpha, candidate, face, subset, body_anchor_point, body_affected_points):
anchor_x, anchor_y = candidate[body_anchor_point]
if subset[body_anchor_point] == -1:
return
for face_point_idx in range(len(face)):
face_point_x, face_point_y = face[face_point_idx]
if face_point_x == -1 or face_point_y == -1:
continue
vector_x = face_point_x - anchor_x
vector_y = face_point_y - anchor_y
offset_x = vector_x * alpha
offset_y = vector_y * alpha
face[face_point_idx] = [face_point_x + offset_x, face_point_y + offset_y]
for body_affected_point_idx in body_affected_points:
body_point_x, body_point_y = candidate[body_affected_point_idx]
if subset[body_affected_point_idx] == -1 or body_point_x == -1 or body_point_y == -1:
continue
vector_x = body_point_x - anchor_x
vector_y = body_point_y - anchor_y
offset_x = vector_x * alpha
offset_y = vector_y * alpha
candidate[body_affected_point_idx] = [body_point_x + offset_x, body_point_y + offset_y]
def pose_reshape_3d(self, alpha, smpl_joints, candidate, subset, left_hand, right_hand, face,
anchor_point, end_point,
affected_body_points):
"""
# joints3d: n, 24, 3
alpha: 变化比例
anchor_point: 起始点
anchor_part: 起始点所属的身体部分,0代表body candidate, 1代表face, 2代表hand
end_point: 中止点
"""
if torch.sum(smpl_joints[anchor_point]) == 0:
right_hand[:] = -1
left_hand[:] = -1
face[:] = -1
subset[:] = -1
return
anchor_x, anchor_y, anchor_z = smpl_joints[anchor_point]
end_x, end_y, end_z = smpl_joints[end_point]
vector_x = end_x - anchor_x
vector_y = end_y - anchor_y
vector_z = end_z - anchor_z
offset_x = (vector_x * alpha).item()
offset_y = (vector_y * alpha).item()
offset_z = (vector_z * alpha).item()
map_to_2d = {}
map_to_2d[4] = 11
map_to_2d[7] = 12
map_to_2d[10] = 13
map_to_2d[5] = 8
map_to_2d[8] = 9
map_to_2d[11] = 10
map_to_2d[20] = 6
map_to_2d[22] = 7
map_to_2d[21] = 3
map_to_2d[23] = 4
map_to_2d[18] = 5
map_to_2d[19] = 2
for affected_body_point in affected_body_points:
if torch.sum(smpl_joints[affected_body_point]) == 0:
continue
new_smpl_joint = smpl_joints[affected_body_point] + torch.tensor([offset_x, offset_y, offset_z]).to(smpl_joints.device)
new_smpl_joint_2d_offset = p3d_to_p2d(new_smpl_joint.reshape(1,1,3).cpu().numpy(), self.height, self.width)[0][0] - p3d_to_p2d(smpl_joints[affected_body_point].reshape(1,1,3).cpu().numpy(), self.height, self.width)[0][0]
new_smpl_joint_2d_offset = np.array([new_smpl_joint_2d_offset[0] / self.width, new_smpl_joint_2d_offset[1] / self.height])
smpl_joints[affected_body_point] = new_smpl_joint
if affected_body_point in map_to_2d.keys():
affected_candidate_point_idx = map_to_2d[affected_body_point]
if subset[affected_candidate_point_idx] != -1 and candidate[affected_candidate_point_idx][0] != -1 and candidate[affected_candidate_point_idx][1] != -1:
candidate[affected_candidate_point_idx] = candidate[affected_candidate_point_idx] + new_smpl_joint_2d_offset # 2d的也移动这么多
if affected_candidate_point_idx == 4: # dwpose 右手 (反的
left_hand[:] = left_hand + new_smpl_joint_2d_offset
if affected_candidate_point_idx == 7: # dwpose 左手 (反的
right_hand[:] = right_hand + new_smpl_joint_2d_offset
def aug_init(self, body_type):
print(f"augmentation: using body_type: {body_type}")
self.shoulder_alpha = 0
self.upper_arm_alpha = 0
self.forearm_alpha = 0
self.body_alpha = 0
self.thigh_alpha = 0
self.calf_alpha = 0
if body_type == "normal_human":
self.body_reshape_selected_methods = []
elif body_type == "dwarf": # body不动
self.upper_arm_alpha = random.uniform(-0.3, -0.2)
self.forearm_alpha = self.upper_arm_alpha
self.shoulder_alpha = -0.2
self.thigh_alpha = random.uniform(-0.3, -0.2)
self.calf_alpha = self.thigh_alpha
self.body_reshape_selected_methods = [self.reshape_shoulder, self.reshape_arm, self.reshape_leg]
self.face_alpha = 0.2
elif body_type == "slender":
self.upper_arm_alpha = 0.3
self.forearm_alpha = 0.2
self.shoulder_alpha = 0.2
self.thigh_alpha = 0.1
self.calf_alpha = 0.1
self.body_reshape_selected_methods = [self.reshape_shoulder, self.reshape_arm, self.reshape_leg]
self.face_alpha = -0.2
elif body_type == "elf":
self.body_alpha = random.uniform(-0.2, 0.2)
self.shoulder_alpha = 0.1
self.upper_arm_alpha = 0.1
self.forearm_alpha = 0.1
self.thigh_alpha = 0.25
self.calf_alpha = 0.25
self.body_reshape_selected_methods = [self.reshape_body, self.reshape_shoulder, self.reshape_arm, self.reshape_leg]
self.face_alpha = 0
elif body_type == "king-kong":
self.body_alpha = 0.1
self.thigh_alpha = -0.25
self.calf_alpha = -0.25
self.upper_arm_alpha = 0.2
self.forearm_alpha = 0.2
self.shoulder_alpha = 0.3
self.body_reshape_selected_methods = [self.reshape_body, self.reshape_shoulder, self.reshape_arm, self.reshape_leg]
self.face_alpha = 0
elif body_type == "random_long_arm_long_leg":
self.upper_arm_alpha = random.uniform(-0.2, 0.2)
self.forearm_alpha = random.uniform(-0.2, 0.2)
self.thigh_alpha = random.uniform(-0.2, 0.2)
self.calf_alpha = random.uniform(-0.2, 0.2)
self.body_alpha = random.uniform(-0.1, 0.1)
self.body_reshape_selected_methods = [self.reshape_body, self.reshape_arm, self.reshape_leg]
elif body_type == "test_case_1":
self.upper_arm_alpha = -0.4
self.forearm_alpha = -0.4
self.shoulder_alpha = -0.3
self.thigh_alpha = 0.2
self.calf_alpha = 0.2
self.body_alpha = 0.1
self.face_alpha = 0.4
self.body_reshape_selected_methods = [self.reshape_body, self.reshape_shoulder, self.reshape_arm, self.reshape_leg]
elif body_type == "test_case_2":
self.upper_arm_alpha = 0.4
self.forearm_alpha = 0.4
self.shoulder_alpha = 0.3
self.thigh_alpha = -0.2
self.calf_alpha = -0.25
self.body_alpha = -0.2
self.face_alpha = -0.2
self.body_reshape_selected_methods = [self.reshape_body, self.reshape_shoulder, self.reshape_arm, self.reshape_leg]
elif body_type == "test_case_3":
self.upper_arm_alpha = 0.2
self.forearm_alpha = 0.2
self.shoulder_alpha = 0.2
self.thigh_alpha = 0.4
self.calf_alpha = 0.4
self.body_alpha = 0.3
self.face_alpha = 0.15
self.body_reshape_selected_methods = [self.reshape_body, self.reshape_shoulder, self.reshape_arm, self.reshape_leg]
elif body_type == "normal_human_test":
self.body_reshape_selected_methods = []
self.face_alpha = 0
def apply_random_reshapes(self, smpl_joints_list, candidate, left_hand, right_hand, face, subset):
# Apply the two selected reshape methods
for method in self.body_reshape_selected_methods:
method(smpl_joints_list, candidate, subset, left_hand, right_hand, face)
for method in self.body_offset_selected_methods:
method(smpl_joints_list, candidate, left_hand, right_hand, face)
for method in self.face_reshape_methods:
method(candidate, face, subset)
def reshape_body(self, smpl_joints_list, candidate, subset, left_hand, right_hand, face):
self.pose_reshape_3d(self.body_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
12, 1,
[1, 4, 7, 10]
)
self.pose_reshape_3d(self.body_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
12, 2,
[2, 5, 8, 11]
)
def reshape_arm(self, smpl_joints_list, candidate, subset, left_hand, right_hand, face):
self.pose_reshape_3d(self.upper_arm_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
16, 18,
[18, 20, 22]
)
self.pose_reshape_3d(self.upper_arm_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
17, 19,
[19, 21, 23]
)
self.pose_reshape_3d(self.forearm_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
18, 20,
[20, 22]
)
self.pose_reshape_3d(self.forearm_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
19, 21,
[21, 23]
)
def reshape_leg(self, smpl_joints_list, candidate, subset, left_hand, right_hand, face):
self.pose_reshape_3d(self.thigh_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
1, 4,
[4, 7, 10]
)
self.pose_reshape_3d(self.thigh_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
2, 5,
[5, 8, 11]
)
self.pose_reshape_3d(self.calf_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
4, 7,
[7, 10]
)
self.pose_reshape_3d(self.calf_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
5, 8,
[8, 11]
)
def reshape_shoulder(self, smpl_joints_list, candidate, subset, left_hand, right_hand, face):
self.pose_reshape_3d(self.shoulder_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
12, 16,
[16, 18, 20, 22]
)
self.pose_reshape_3d(self.shoulder_alpha, smpl_joints_list, candidate, subset, left_hand, right_hand, face,
12, 17,
[17, 19, 21, 23]
)
# def offset_3d_all(self, smpl_joints_list, candidate, left_hand, right_hand, face):
# smpl_joints_list = smpl_joints_list + torch.tensor([self.offset_3d_x, self.offset_3d_y, self.offset_3d_z]).to(smpl_joints_list.device)
# offset_2d = p3d_to_p2d(np.array([[[self.offset_3d_x, self.offset_3d_y, self.offset_3d_z]]]), self.height, self.width)[0][0]
# candidate = candidate + np.array([offset_2d[0], offset_2d[1]])
# left_hand = left_hand + np.array([offset_2d[0], offset_2d[1]])
# right_hand = right_hand + np.array([offset_2d[0], offset_2d[1]])
# face = face + np.array([offset_2d[0], offset_2d[1]])
def reshape_face(self, candidate, face, subset):
self.pose_reshape_2d_for_face(alpha=self.face_alpha, candidate=candidate, face=face, subset=subset,
body_anchor_point=0, body_affected_points=[14, 15, 16, 17])