SCAIL-2 / SCAIL-Pose /pose_draw /reshape_utils.py
fffiloni's picture
Migrated files batch 1
09462dc verified
Raw
History Blame Contribute Delete
19.9 kB
import numpy as np
import random
def pose_offset(offset_x, offset_y, pose, vitposes):
for i in range(len(pose["bodies"]["candidate"])):
bodies = pose["bodies"]
faces = pose["faces"][i]
right_hand = pose["hands"][2 * i]
left_hand = pose["hands"][2 * i + 1]
candidate = bodies["candidate"][i]
subset = bodies["subset"][i]
for face_point in faces:
if face_point[0] == -1 and face_point[1] == -1:
continue
face_point[0] = face_point[0] + offset_x
face_point[1] = face_point[1] + offset_y
for left_hand_point in left_hand:
if left_hand_point[0] == -1 and left_hand_point[1] == -1:
continue
left_hand_point[0] = left_hand_point[0] + offset_x
left_hand_point[1] = left_hand_point[1] + offset_y
for right_hand_point in right_hand:
if right_hand_point[0] == -1 and right_hand_point[1] == -1:
continue
right_hand_point[0] = right_hand_point[0] + offset_x
right_hand_point[1] = right_hand_point[1] + offset_y
assert len(candidate) == len(subset), f"candidate, length: {len(candidate)} and subset, length: {len(subset)} must have the same length"
for idx, body_point in enumerate(candidate):
if subset[idx] == -1:
continue
if body_point[0] == -1 and body_point[1] == -1:
continue
body_point[0] = body_point[0] + offset_x
body_point[1] = body_point[1] + offset_y
if vitposes is not None:
for vitpose in vitposes:
vitpose['keypoints_body'] = vitpose['keypoints_body'] + np.array([offset_x, offset_y, 0])
vitpose['keypoints_left_hand'] = vitpose['keypoints_left_hand'] + np.array([offset_x, offset_y, 0])
vitpose['keypoints_right_hand'] = vitpose['keypoints_right_hand'] + np.array([offset_x, offset_y, 0])
def pose_whole_scale(scale_x, scale_y, pose, vitposes): # 目前仅能用于单人
# 获取最左端的x 最右端的x 最上端的y 最下端的y
min_x = float('inf')
max_x = float('-inf')
min_y = float('inf')
max_y = float('-inf')
if len(pose["bodies"]["candidate"]) > 1:
return
for i in range(len(pose["bodies"]["candidate"])):
bodies = pose["bodies"]
faces = pose["faces"][i]
right_hand = pose["hands"][2 * i]
left_hand = pose["hands"][2 * i + 1]
candidate = bodies["candidate"][i]
subset = bodies["subset"][i]
for face_point in faces:
if face_point[0] == -1 and face_point[1] == -1:
continue
min_x = min(min_x, face_point[0])
max_x = max(max_x, face_point[0])
min_y = min(min_y, face_point[1])
max_y = max(max_y, face_point[1])
for left_hand_point in left_hand:
if left_hand_point[0] == -1 and left_hand_point[1] == -1:
continue
min_x = min(min_x, left_hand_point[0])
max_x = max(max_x, left_hand_point[0])
min_y = min(min_y, left_hand_point[1])
max_y = max(max_y, left_hand_point[1])
for right_hand_point in right_hand:
if right_hand_point[0] == -1 and right_hand_point[1] == -1:
continue
min_x = min(min_x, right_hand_point[0])
max_x = max(max_x, right_hand_point[0])
min_y = min(min_y, right_hand_point[1])
max_y = max(max_y, right_hand_point[1])
assert len(candidate) == len(subset), "candidate and subset must have the same length"
for idx, body_point in enumerate(candidate):
if subset[idx] == -1:
continue
if body_point[0] == -1 and body_point[1] == -1:
continue
min_x = min(min_x, body_point[0])
max_x = max(max_x, body_point[0])
min_y = min(min_y, body_point[1])
max_y = max(max_y, body_point[1])
# 计算缩放比例
# 根据bbox中心进行dilate, 倍数为x_scale, y_scale
bbox_center_x = (min_x + max_x) / 2
bbox_center_y = (min_y + max_y) / 2
for i in range(len(pose["bodies"]["candidate"])):
bodies = pose["bodies"]
candidate = bodies["candidate"][i]
for body_point in candidate:
if body_point[0] == -1 and body_point[1] == -1:
continue
body_point[0] = body_point[0] + (body_point[0] - bbox_center_x) * scale_x # scale越大,越远离中心,变化越大
body_point[1] = body_point[1] + (body_point[1] - bbox_center_y) * scale_y
for face_point in faces:
if face_point[0] == -1 and face_point[1] == -1:
continue
face_point[0] = face_point[0] + (face_point[0] - bbox_center_x) * scale_x
face_point[1] = face_point[1] + (face_point[1] - bbox_center_y) * scale_y
for left_hand_point in left_hand:
if left_hand_point[0] == -1 and left_hand_point[1] == -1:
continue
left_hand_point[0] = left_hand_point[0] + (left_hand_point[0] - bbox_center_x) * scale_x
left_hand_point[1] = left_hand_point[1] + (left_hand_point[1] - bbox_center_y) * scale_y
for right_hand_point in right_hand:
if right_hand_point[0] == -1 and right_hand_point[1] == -1:
continue
right_hand_point[0] = right_hand_point[0] + (right_hand_point[0] - bbox_center_x) * scale_x
right_hand_point[1] = right_hand_point[1] + (right_hand_point[1] - bbox_center_y) * scale_y
if vitposes is not None:
min_x = float('inf')
max_x = float('-inf')
min_y = float('inf')
max_y = float('-inf')
if len(vitposes) > 1:
return
for vitpose in vitposes:
for body_point in vitpose['keypoints_body']:
if body_point[2] < 0.4:
continue
min_x = min(min_x, body_point[0])
max_x = max(max_x, body_point[0])
min_y = min(min_y, body_point[1])
max_y = max(max_y, body_point[1])
for left_hand_point in vitpose['keypoints_left_hand']:
if left_hand_point[2] < 0.4:
continue
min_x = min(min_x, left_hand_point[0])
max_x = max(max_x, left_hand_point[0])
min_y = min(min_y, left_hand_point[1])
max_y = max(max_y, left_hand_point[1])
for right_hand_point in vitpose['keypoints_right_hand']:
if right_hand_point[2] < 0.4:
continue
min_x = min(min_x, right_hand_point[0])
max_x = max(max_x, right_hand_point[0])
min_y = min(min_y, right_hand_point[1])
max_y = max(max_y, right_hand_point[1])
bbox_center_x = (min_x + max_x) / 2
bbox_center_y = (min_y + max_y) / 2
for body_point in vitpose['keypoints_body']:
body_point[0] = body_point[0] + (body_point[0] - bbox_center_x) * scale_x
body_point[1] = body_point[1] + (body_point[1] - bbox_center_y) * scale_y
for left_hand_point in vitpose['keypoints_left_hand']:
left_hand_point[0] = left_hand_point[0] + (left_hand_point[0] - bbox_center_x) * scale_x
left_hand_point[1] = left_hand_point[1] + (left_hand_point[1] - bbox_center_y) * scale_y
for right_hand_point in vitpose['keypoints_right_hand']:
right_hand_point[0] = right_hand_point[0] + (right_hand_point[0] - bbox_center_x) * scale_x
right_hand_point[1] = right_hand_point[1] + (right_hand_point[1] - bbox_center_y) * scale_y
# 如果做多人增强,需要修改逻辑,每个人都有随机性,现在都是做单人增强,增强方法一致
def pose_reshape(alpha, pose, vitposes,
anchor_point, anchor_part, end_point, end_part,
affected_body_points, affected_faces_points, affected_left_hands_points, affected_right_hands_points):
"""
直接修改原始pose中的某些点的位置,通过根据一个不动点和端点之间的向量偏移被影响点的位置。
一次只能有一个anchor_point, 一个end_point,多个affected_points
alpha: 变化比例
anchor_point: 起始点
anchor_part: 起始点所属的身体部分,0代表body candidate, 1代表face, 2代表hand
end_point: 中止点
end_part: 中止点所属的身体部分,0代表body candidate, 1代表face, 2代表hand
"""
for i in range(len(pose["bodies"]["candidate"])):
bodies = pose["bodies"]
# faces = pose["faces"][i:i+1]
faces = pose["faces"][i]
# hands = pose["hands"][2*i:2*i+2]
right_hand = pose["hands"][2 * i]
left_hand = pose["hands"][2 * i + 1]
candidate = bodies["candidate"][i]
# subset = bodies["subset"][i:i+1]
subset = bodies["subset"][i]
assert anchor_part == 0, "anchor part must belong to the body"
anchor_x, anchor_y = candidate[anchor_point]
if subset[anchor_point] == -1:
continue
if end_part == 0:
end_x, end_y = candidate[end_point]
if subset[end_point] == -1:
continue
elif end_part == 1:
end_x, end_y = faces[end_point]
# 不考虑Hands
if end_x == -1 and end_y == -1:
continue
vector_x = end_x - anchor_x
vector_y = end_y - anchor_y
offset_x = vector_x * alpha
offset_y = vector_y * alpha
for affected_body_point in affected_body_points:
if subset[affected_body_point] == -1:
continue
affected_x, affected_y = candidate[affected_body_point]
candidate[affected_body_point] = [affected_x + offset_x, affected_y + offset_y]
for affected_faces_point in affected_faces_points:
affected_x, affected_y = faces[affected_faces_point]
if affected_x == -1 and affected_y == -1:
continue
faces[affected_faces_point] = [affected_x + offset_x, affected_y + offset_y]
for affected_hands_point in affected_left_hands_points:
affected_x, affected_y = left_hand[affected_hands_point]
if affected_x == -1 and affected_y == -1:
continue
left_hand[affected_hands_point] = [affected_x + offset_x, affected_y + offset_y]
for affected_hands_point in affected_right_hands_points:
affected_x, affected_y = right_hand[affected_hands_point]
if affected_x == -1 and affected_y == -1:
continue
right_hand[affected_hands_point] = [affected_x + offset_x, affected_y + offset_y]
if vitposes is not None:
vit_visible_threshold = 0.5
for vitpose in vitposes:
assert anchor_part == 0, "anchor part must belong to the body"
anchor_x, anchor_y, _ = vitpose['keypoints_body'][anchor_point]
if vitpose['keypoints_body'][anchor_point][2] < vit_visible_threshold:
continue
if end_part == 0:
end_x, end_y, _ = vitpose['keypoints_body'][end_point]
if vitpose['keypoints_body'][end_point][2] < vit_visible_threshold:
continue
# 不考虑hands
elif end_part == 1:
continue # ViTPose的脸不动
vector_x = end_x - anchor_x
vector_y = end_y - anchor_y
offset_x = vector_x * alpha
offset_y = vector_y * alpha
for affected_body_point in affected_body_points:
if vitpose['keypoints_body'][affected_body_point][2] < vit_visible_threshold:
continue
vitpose['keypoints_body'][affected_body_point][0] = vitpose['keypoints_body'][affected_body_point][0] + offset_x
vitpose['keypoints_body'][affected_body_point][1] = vitpose['keypoints_body'][affected_body_point][1] + offset_y
# 左右标记相反,需要互换
for affected_left_hand_point in affected_left_hands_points:
if vitpose['keypoints_right_hand'][affected_left_hand_point][2] < vit_visible_threshold:
continue
vitpose['keypoints_right_hand'][affected_left_hand_point][0] = vitpose['keypoints_right_hand'][affected_left_hand_point][0] + offset_x
vitpose['keypoints_right_hand'][affected_left_hand_point][1] = vitpose['keypoints_right_hand'][affected_left_hand_point][1] + offset_y
for affected_right_hand_point in affected_right_hands_points:
if vitpose['keypoints_left_hand'][affected_right_hand_point][2] < vit_visible_threshold:
continue
vitpose['keypoints_left_hand'][affected_right_hand_point][0] = vitpose['keypoints_left_hand'][affected_right_hand_point][0] + offset_x
vitpose['keypoints_left_hand'][affected_right_hand_point][1] = vitpose['keypoints_left_hand'][affected_right_hand_point][1] + offset_y
# reshapePool只负责形变,骨骼偏移、丢弃等得从draw层来做
class reshapePool:
def __init__(self, alpha): # 对每个视频只初始化一次
self.faces_indices = np.arange(0, 68)
self.left_hands_indices = np.arange(0, 21)
self.right_hands_indices = np.arange(0, 21)
self.alpha = alpha # 0.1
self.offset_x = random.uniform(-1/16, 1/16)
self.offset_y = random.uniform(-1/16, 1/16)
self.scale_x = random.uniform(-alpha/2, alpha/2)
self.scale_y = random.uniform(-alpha/2, alpha/2)
self.body_reshape_methods = [
self.extend_body,
self.extend_arm,
self.extend_leg,
self.shrink_body,
self.shrink_arm,
self.shrink_leg,
]
self.scale_reshape_methods = [
self.offset_wholebody,
# self.scale_wholebody,
self.dilate_face,
self.shrink_face,
]
self.selected_methods = random.sample(self.body_reshape_methods, 2) + random.sample(self.scale_reshape_methods, random.choice([0, 1]))
def apply_random_reshapes(self, pose, vitposes=None):
# Apply the two selected reshape methods
for method in self.selected_methods:
method(pose, vitposes)
def offset_wholebody(self, pose, vitposes):
pose_offset(self.offset_x, self.offset_y, pose, vitposes)
def scale_wholebody(self, pose, vitposes):
pose_whole_scale(self.scale_x, self.scale_y, pose, vitposes)
def extend_body(self, pose, vitposes):
pose_reshape(self.alpha, pose, vitposes,
1, 0, 8, 0,
[8, 9, 10], [], [], []
)
pose_reshape(self.alpha, pose, vitposes,
1, 0, 11, 0,
[11, 12, 13], [], [], []
)
def shrink_body(self, pose, vitposes):
pose_reshape(-self.alpha, pose, vitposes,
1, 0, 8, 0,
[8, 9, 10], [], [], []
)
pose_reshape(-self.alpha, pose, vitposes,
1, 0, 11, 0,
[11, 12, 13], [], [], []
)
def extend_arm(self, pose, vitposes):
pose_reshape(self.alpha, pose, vitposes,
2, 0, 3, 0,
[3, 4], [], self.left_hands_indices, []
)
pose_reshape(self.alpha, pose, vitposes,
5, 0, 6, 0,
[6, 7], [], [], self.right_hands_indices
)
pose_reshape(self.alpha, pose, vitposes,
3, 0, 4, 0,
[4], [], self.left_hands_indices, []
)
pose_reshape(self.alpha, pose, vitposes,
6, 0, 7, 0,
[7], [], [], self.right_hands_indices
)
def shrink_arm(self, pose, vitposes):
pose_reshape(-self.alpha, pose, vitposes,
2, 0, 3, 0,
[3, 4], [], self.left_hands_indices, []
)
pose_reshape(-self.alpha, pose, vitposes,
5, 0, 6, 0,
[6, 7], [], [], self.right_hands_indices
)
pose_reshape(-self.alpha, pose, vitposes,
3, 0, 4, 0,
[4], [], self.left_hands_indices, []
)
pose_reshape(-self.alpha, pose, vitposes,
6, 0, 7, 0,
[7], [], [], self.right_hands_indices
)
def extend_leg(self, pose, vitposes):
pose_reshape(self.alpha, pose, vitposes,
8, 0, 9, 0,
[9, 10], [], [], []
)
pose_reshape(self.alpha, pose, vitposes,
11, 0, 12, 0,
[12, 13], [], [], []
)
pose_reshape(self.alpha, pose, vitposes,
9, 0, 10, 0,
[10], [], [], []
)
pose_reshape(self.alpha, pose, vitposes,
12, 0, 13, 0,
[13], [], [], []
)
def shrink_leg(self, pose, vitposes):
pose_reshape(-self.alpha, pose, vitposes,
8, 0, 9, 0,
[9, 10], [], [], []
)
pose_reshape(-self.alpha, pose, vitposes,
11, 0, 12, 0,
[12, 13], [], [], []
)
pose_reshape(-self.alpha, pose, vitposes,
9, 0, 10, 0,
[10], [], [], []
)
pose_reshape(-self.alpha, pose, vitposes,
12, 0, 13, 0,
[13], [], [], []
)
def extend_shoulder(self, pose, vitposes):
pose_reshape(self.alpha, pose, vitposes,
1, 0, 2, 0,
[2, 3, 4], [], self.left_hands_indices, []
)
pose_reshape(self.alpha, pose, vitposes,
1, 0, 5, 0,
[5, 6, 7], [], [], self.right_hands_indices
)
def shrink_shoulder(self, pose, vitposes):
pose_reshape(-self.alpha, pose, vitposes,
1, 0, 2, 0,
[2, 3, 4], [], self.left_hands_indices, []
)
pose_reshape(-self.alpha, pose, vitposes,
1, 0, 5, 0,
[5, 6, 7], [], [], self.right_hands_indices
)
def dilate_face(self, pose, vitposes):
for i in self.faces_indices:
pose_reshape(self.alpha, pose, vitposes,
0, 0, i, 1,
[], [i], [], []
)
for i in [14, 15, 16, 17]:
pose_reshape(self.alpha, pose, vitposes,
0, 0, i, 0,
[i], [], [], []
)
def shrink_face(self, pose, vitposes): # 缩小脸会看不清
for i in self.faces_indices:
pose_reshape(-self.alpha / 2, pose, vitposes,
0, 0, i, 1,
[], [i], [], []
)
for i in [14, 15, 16, 17]:
pose_reshape(-self.alpha / 2, pose, vitposes,
0, 0, i, 0,
[i], [], [], []
)