32 스켈레톤 데이터를 랜덤으로 샘플링하는 기능
34 sample (dict): 데이터, 여러 프레임의 스켈레톤 좌표와 스코어 값이 저장된 'keypoint', 'keypoint_score'를 포함하여야함
35 'image_feature'가 존재하면 'image_feature'도 함께 샘플링함
36 clip_len (int): 샘플링 수량
37 return (dict): 샘플링된 데이터
40 num_frames = sample[
'keypoint'].shape[1]
41 if num_frames < clip_len:
42 start = np.random.randint(0, num_frames)
43 inds = np.arange(start, start + clip_len)
44 elif clip_len <= num_frames < 2 * clip_len:
45 basic = np.arange(clip_len)
46 inds = np.random.choice(
47 clip_len + 1, num_frames - clip_len, replace=
False)
48 offset = np.zeros(clip_len + 1, dtype=np.int32)
50 offset = np.cumsum(offset)
51 inds = basic + offset[:-1]
54 [i * num_frames // clip_len
for i
in range(clip_len + 1)])
57 offset = np.random.randint(bsize)
60 sample[
'keypoint'] = sample[
'keypoint'][:, inds].astype(np.float32)
61 sample[
'keypoint_score'] = sample[
'keypoint_score'][:, inds].astype(np.float32)
62 if 'image_feature' in sample:
63 sample[
'image_feature'] = sample[
'image_feature'][:, inds]
69 모든 스켈레톤을 포함하는 영역을 계산하고 좌상단의 좌표가 (0, 0)이 되도록 스켈레톤 좌표를 shifting함
70 스켈레톤 좌표의 전체 영역의 크기(높이, 너비)는 'kp_hw'에 저장됨
72 sample (dict): 데이터, 스켈레톤 좌표가 저장된 'keypoint'를 포함함
73 return (dict): shifting함된 스켈레톤 좌표와 영역의 크기가 포함된 데이터
75 keypoint = sample[
'keypoint']
77 kp_x = keypoint[..., 0]
78 kp_y = keypoint[..., 1]
88 center = ((max_x + min_x) / 2, (max_y + min_y) / 2)
89 half_width = (max_x - min_x) / 2 * (1 + padding)
90 half_height = (max_y - min_y) / 2 * (1 + padding)
93 max_val = max(half_width, half_height)
98 min_x, max_x = center[0] - half_width, center[0] + half_width
99 min_y, max_y = center[1] - half_height, center[1] + half_height
102 min_x, min_y = int(min_x), int(min_y)
103 max_x, max_y = int(max_x), int(max_y)
110 sample[
'kp_hw'] = (max_y - min_y, max_x - min_x)
116 스켈레톤 좌표를 일정 비율만큼 이동 시키는 기능
118 sample (dict): 데이터, 스켈레톤 좌표가 저장된 'keypoint'를 포함함
119 shift_ratio (float): 좌표 이동 비율
120 return (dict): 좌표가 이동된 스켈레톤을 포함하는 데이터
123 keypoint = sample[
'keypoint']
125 x1 = keypoint[:, 0, :, 0].min()
126 x2 = keypoint[:, 0, :, 0].max()
127 y1 = keypoint[:, 0, :, 1].min()
128 y2 = keypoint[:, 0, :, 1].max()
131 w_range = (x2-x1)*shift_ratio
132 h_range = (y2-y1)*shift_ratio
135 dx = random.uniform(-w_range, w_range)
136 dy = random.uniform(-h_range, h_range)
139 sample[
'keypoint'][:, :, :, 0] += dx
140 sample[
'keypoint'][:, :, :, 1] += dy
169 kp_hw (tuple): 스켈레톤을 모두 포함하는 박스의 영역 크기
170 area_range (tuple): 자르는 영역 크기의 범위, 원본 대비 비율
171 aspect_ratio_range (tuple): aspect_ratio(가로 세로 비율) 범위
172 max_attempts (int): 랜덤 생성 최대 반복횟수, 10번안에 파라미터를 만족하는 영역이 생성되지 않으면 고정된 영역을 반환함
173 return (float, float, float, float): left, top, right, bottom
181 min_ar, max_ar = aspect_ratio_range
182 aspect_ratios = np.exp( np.random.uniform(np.log(min_ar), np.log(max_ar), size=max_attempts) )
183 target_areas = np.random.uniform(*area_range, size=max_attempts) * area
186 candidate_crop_w = np.round(np.sqrt(target_areas * aspect_ratios)).astype(np.int32)
187 candidate_crop_h = np.round(np.sqrt(target_areas / aspect_ratios)).astype(np.int32)
190 for i
in range(max_attempts):
191 crop_w = candidate_crop_w[i]
192 crop_h = candidate_crop_h[i]
195 if crop_h <= h
and crop_w <= w:
196 x_offset = random.randint(0, w - crop_w)
197 y_offset = random.randint(0, h - crop_h)
198 return x_offset, y_offset, x_offset + crop_w, y_offset + crop_h
201 crop_size = min(h, w)
202 x_offset = (w - crop_size) // 2
203 y_offset = (h - crop_size) // 2
204 return x_offset, y_offset, x_offset + crop_size, y_offset + crop_size
208 키포인트를 랜덤으로 자르는 기능, 랜덤으로 영역을 생성하고 자름
210 sample (dict): 데이터, 스켈레톤 좌표가 저장된 'keypoint'와 스켈레톤 영역의 크기가 저장된 'kp_hw'를 포함함
211 area_range (tuple): 자르는 영역 크기의 범위, 원본 대비 비율
212 aspect_ratio_range (tuple): aspect_ratio(가로 세로 비율) 범위
213 return (dict): 잘린 키포인트가 포함된 데이터
216 keypoint = sample[
'keypoint']
217 h, w = sample[
'kp_hw']
220 left, top, right, bottom =
get_crop_bbox( (h, w), area_range, aspect_ratio_range)
221 new_h, new_w = bottom - top, right - left
222 crop_bbox = np.array([left, top, right, bottom])
225 sample[
'keypoint'] = keypoint - crop_bbox[:2]
226 sample[
'kp_hw'] = (new_h, new_w)
234 sample (dict): 데이터, 여러 프레임의 스켈레톤 좌표와 스코어 값이 저장된 'keypoint', 'keypoint_score'와 스켈레톤 영역의 크기가 저장된 'kp_hw'를 포함함
235 flip_ratio (float): 좌우 반전 할 확률
236 return (dict): 일정 확률로 좌우 반전이된 스켈레톤을 포함하는 데이터
240 flip = np.random.rand() < flip_ratio
244 left_kp = [1, 3, 5, 7, 9, 11, 13, 15]
245 right_kp = [2, 4, 6, 8, 10, 12, 14, 16]
247 h, w = sample[
'kp_hw']
248 keypoint = sample[
'keypoint']
249 keypoint_score = sample[
'keypoint_score']
251 keypoint[..., 0] = w - keypoint[..., 0]
254 new_order = list(range(keypoint.shape[2]))
255 for left, right
in zip(left_kp, right_kp):
256 new_order[left] = right
257 new_order[right] = left
258 keypoint = keypoint[:, :, new_order]
259 keypoint_score = keypoint_score[:, :, new_order]
261 sample[
'keypoint'] = keypoint
262 sample[
'keypoint_score'] = keypoint_score
269 하나의 스켈레톤에 대한 히트맵을 생성하는 기능, 여러명의 사람일 수 있음
271 pose_heatmap (np.array): 1종 스켈레톤의 히트맵, shape (H, W)
272 centers (np.array): 1-종의 스켈레톤 좌표(ex-손목, 코 등), shape (num_person, 2)
273 max_values (np.array): 1-종의 스켈레톤 스코어, shape (num_person)
278 img_h, img_w = pose_heatmap.shape
279 for center, max_value
in zip(centers, max_values):
285 mu_x, mu_y = center[0], center[1]
286 st_x = max(int(mu_x - 3 * sigma), 0)
287 ed_x = min(int(mu_x + 3 * sigma) + 1, img_w)
288 st_y = max(int(mu_y - 3 * sigma), 0)
289 ed_y = min(int(mu_y + 3 * sigma) + 1, img_h)
290 x = np.arange(st_x, ed_x, 1, np.float32)
291 y = np.arange(st_y, ed_y, 1, np.float32)
294 if not (len(x)
and len(y)):
299 patch = np.exp(-((x - mu_x)**2 + (y - mu_y)**2) / 2 / sigma**2)
300 patch = patch * max_value
303 pose_heatmap[st_y:ed_y, st_x:ed_x] = \
304 np.maximum(pose_heatmap[st_y:ed_y, st_x:ed_x], patch)
320 스켈레톤 좌표를 사용해서 히트맵을 생성하는 기능
322 sample (dict): 데이터, 여러 프레임의 스켈레톤 좌표와 스코어 값이 저장된 'keypoint', 'keypoint_score'와 스켈레톤 영역의 크기가 저장된 'kp_hw'를 포함함
323 return (dict): 스켈레톤을 기반으로한 히트맵이 포함된 데이터, 히트맵의 키는 'pose_heatmap'임
325 keypoint = sample[
'keypoint']
326 keypoint_score = sample[
'keypoint_score']
328 h, w = sample[
'kp_hw']
329 num_frame = keypoint.shape[1]
330 num_c = keypoint.shape[2]
333 pose_heatmap = np.zeros([num_frame, num_c, h, w], dtype=np.float32)
334 for i
in range(num_frame):
337 kpscores = keypoint_score[:, i]
344 pose_heatmap = np.transpose(pose_heatmap, (1, 0, 2, 3))
345 sample[
'pose_heatmap'] = pose_heatmap