|
import sys |
|
import torch |
|
import torch.nn as nn |
|
import torch.nn.functional as F |
|
from torch.utils.data import Dataset, DataLoader |
|
import numpy as np |
|
import os |
|
import random |
|
import copy |
|
import json |
|
from collections import defaultdict |
|
from lib.utils.utils_data import crop_scale, flip_data, resample, split_clips |
|
|
|
def posetrack2h36m(x): |
|
''' |
|
Input: x (T x V x C) |
|
|
|
PoseTrack keypoints = [ 'nose', |
|
'head_bottom', |
|
'head_top', |
|
'left_ear', |
|
'right_ear', |
|
'left_shoulder', |
|
'right_shoulder', |
|
'left_elbow', |
|
'right_elbow', |
|
'left_wrist', |
|
'right_wrist', |
|
'left_hip', |
|
'right_hip', |
|
'left_knee', |
|
'right_knee', |
|
'left_ankle', |
|
'right_ankle'] |
|
H36M: |
|
0: 'root', |
|
1: 'rhip', |
|
2: 'rkne', |
|
3: 'rank', |
|
4: 'lhip', |
|
5: 'lkne', |
|
6: 'lank', |
|
7: 'belly', |
|
8: 'neck', |
|
9: 'nose', |
|
10: 'head', |
|
11: 'lsho', |
|
12: 'lelb', |
|
13: 'lwri', |
|
14: 'rsho', |
|
15: 'relb', |
|
16: 'rwri' |
|
''' |
|
y = np.zeros(x.shape) |
|
y[:,0,:] = (x[:,11,:] + x[:,12,:]) * 0.5 |
|
y[:,1,:] = x[:,12,:] |
|
y[:,2,:] = x[:,14,:] |
|
y[:,3,:] = x[:,16,:] |
|
y[:,4,:] = x[:,11,:] |
|
y[:,5,:] = x[:,13,:] |
|
y[:,6,:] = x[:,15,:] |
|
y[:,8,:] = x[:,1,:] |
|
y[:,7,:] = (y[:,0,:] + y[:,8,:]) * 0.5 |
|
y[:,9,:] = x[:,0,:] |
|
y[:,10,:] = x[:,2,:] |
|
y[:,11,:] = x[:,5,:] |
|
y[:,12,:] = x[:,7,:] |
|
y[:,13,:] = x[:,9,:] |
|
y[:,14,:] = x[:,6,:] |
|
y[:,15,:] = x[:,8,:] |
|
y[:,16,:] = x[:,10,:] |
|
y[:,0,2] = np.minimum(x[:,11,2], x[:,12,2]) |
|
y[:,7,2] = np.minimum(y[:,0,2], y[:,8,2]) |
|
return y |
|
|
|
|
|
class PoseTrackDataset2D(Dataset): |
|
def __init__(self, flip=True, scale_range=[0.25, 1]): |
|
super(PoseTrackDataset2D, self).__init__() |
|
self.flip = flip |
|
data_root = "data/motion2d/posetrack18_annotations/train/" |
|
file_list = sorted(os.listdir(data_root)) |
|
all_motions = [] |
|
all_motions_filtered = [] |
|
self.scale_range = scale_range |
|
for filename in file_list: |
|
with open(os.path.join(data_root, filename), 'r') as file: |
|
json_dict = json.load(file) |
|
annots = json_dict['annotations'] |
|
imgs = json_dict['images'] |
|
motions = defaultdict(list) |
|
for annot in annots: |
|
tid = annot['track_id'] |
|
pose2d = np.array(annot['keypoints']).reshape(-1,3) |
|
motions[tid].append(pose2d) |
|
all_motions += list(motions.values()) |
|
for motion in all_motions: |
|
if len(motion)<30: |
|
continue |
|
motion = np.array(motion[:30]) |
|
if np.sum(motion[:,:,2]) <= 306: |
|
continue |
|
motion = crop_scale(motion, self.scale_range) |
|
motion = posetrack2h36m(motion) |
|
motion[motion[:,:,2]==0] = 0 |
|
if np.sum(motion[:,0,2]) < 30: |
|
continue |
|
all_motions_filtered.append(motion) |
|
all_motions_filtered = np.array(all_motions_filtered) |
|
self.motions_2d = all_motions_filtered |
|
|
|
def __len__(self): |
|
'Denotes the total number of samples' |
|
return len(self.motions_2d) |
|
|
|
def __getitem__(self, index): |
|
'Generates one sample of data' |
|
motion_2d = torch.FloatTensor(self.motions_2d[index]) |
|
if self.flip and random.random()>0.5: |
|
motion_2d = flip_data(motion_2d) |
|
return motion_2d, motion_2d |
|
|
|
class InstaVDataset2D(Dataset): |
|
def __init__(self, n_frames=81, data_stride=27, flip=True, valid_threshold=0.0, scale_range=[0.25, 1]): |
|
super(InstaVDataset2D, self).__init__() |
|
self.flip = flip |
|
self.scale_range = scale_range |
|
motion_all = np.load('data/motion2d/InstaVariety/motion_all.npy') |
|
id_all = np.load('data/motion2d/InstaVariety/id_all.npy') |
|
split_id = split_clips(id_all, n_frames, data_stride) |
|
motions_2d = motion_all[split_id] |
|
valid_idx = (motions_2d[:,0,0,2] > valid_threshold) |
|
self.motions_2d = motions_2d[valid_idx] |
|
|
|
def __len__(self): |
|
'Denotes the total number of samples' |
|
return len(self.motions_2d) |
|
|
|
def __getitem__(self, index): |
|
'Generates one sample of data' |
|
motion_2d = self.motions_2d[index] |
|
motion_2d = crop_scale(motion_2d, self.scale_range) |
|
motion_2d[motion_2d[:,:,2]==0] = 0 |
|
if self.flip and random.random()>0.5: |
|
motion_2d = flip_data(motion_2d) |
|
motion_2d = torch.FloatTensor(motion_2d) |
|
return motion_2d, motion_2d |
|
|