import pandas as pd import ast import torch import random import numpy as np from torch.nn.utils.rnn import pad_sequence from random import randrange from augmentations import augment_arm_joint_rotate, augment_rotate, augment_shear from normalization.body_normalization import BODY_IDENTIFIERS from augmentations.augment import HAND_IDENTIFIERS def load_dataset(file_location: str): # Load the datset csv file df = pd.read_csv(file_location, encoding="utf-8") df.columns = [item.replace("_left_", "_0_").replace("_right_", "_1_") for item in list(df.columns)] # TEMP labels = df["labels"].to_list() data = [] for row_index, row in df.iterrows(): current_row = np.empty(shape=(len(ast.literal_eval(row["leftEar_X"])), len(BODY_IDENTIFIERS + HAND_IDENTIFIERS), 2) ) for index, identifier in enumerate(BODY_IDENTIFIERS + HAND_IDENTIFIERS): current_row[:, index, 0] = ast.literal_eval(row[identifier + "_X"]) current_row[:, index, 1] = ast.literal_eval(row[identifier + "_Y"]) data.append(current_row) return data, labels def tensor_to_dictionary(landmarks_tensor: torch.Tensor) -> dict: data_array = landmarks_tensor.numpy() output = {} for landmark_index, identifier in enumerate(BODY_IDENTIFIERS + HAND_IDENTIFIERS): output[identifier] = data_array[:, landmark_index] return output def dictionary_to_tensor(landmarks_dict: dict) -> torch.Tensor: output = np.empty(shape=(len(landmarks_dict["leftEar"]), len(BODY_IDENTIFIERS + HAND_IDENTIFIERS), 2)) for landmark_index, identifier in enumerate(BODY_IDENTIFIERS + HAND_IDENTIFIERS): output[:, landmark_index, 0] = [frame[0] for frame in landmarks_dict[identifier]] output[:, landmark_index, 1] = [frame[1] for frame in landmarks_dict[identifier]] return torch.from_numpy(output) def random_augmentation(augmentations, augmentations_prob, depth_map): if augmentations and random.random() < augmentations_prob: selected_aug = randrange(4) if selected_aug == 0: depth_map = augment_arm_joint_rotate(depth_map, 0.3, (-4, 4)) elif selected_aug == 1: depth_map = augment_shear(depth_map, "perspective", (0, 0.1)) elif selected_aug == 2: depth_map = augment_shear(depth_map, "squeeze", (0, 0.15)) elif selected_aug == 3: depth_map = augment_rotate(depth_map, (-13, 13)) return depth_map def collate_fn_triplet_padd(batch): ''' Padds batch of variable length note: it converts things ToTensor manually here since the ToTensor transform assume it takes in images rather than arbitrary tensors. ''' # batch: list of length batch_size, each element contains ouput of dataset # MASKING anchor_lengths = [element[0].shape[0] for element in batch] max_anchor_l = max(anchor_lengths) positive_lengths = [element[1].shape[0] for element in batch] max_positive_l = max(positive_lengths) negative_lengths = [element[2].shape[0] for element in batch] max_negative_l = max(negative_lengths) anchor_mask = [[False] * anchor_lengths[n] + [True] * (max_anchor_l - anchor_lengths[n]) for n in range(len(batch))] positive_mask = [[False] * positive_lengths[n] + [True] * (max_positive_l - positive_lengths[n]) for n in range(len(batch))] negative_mask = [[False] * negative_lengths[n] + [True] * (max_negative_l - negative_lengths[n]) for n in range(len(batch))] # PADDING anchor_batch = [element[0] for element in batch] positive_batch = [element[1] for element in batch] negative_batch = [element[2] for element in batch] anchor_batch = pad_sequence(anchor_batch, batch_first=True) positive_batch = pad_sequence(positive_batch, batch_first=True) negative_batch = pad_sequence(negative_batch, batch_first=True) return anchor_batch, positive_batch, negative_batch, \ torch.Tensor(anchor_mask), torch.Tensor(positive_mask), torch.Tensor(negative_mask) def collate_fn_padd(batch): ''' Padds batch of variable length note: it converts things ToTensor manually here since the ToTensor transform assume it takes in images rather than arbitrary tensors. ''' # batch: list of length batch_size, each element contains ouput of dataset # MASKING anchor_lengths = [element[0].shape[0] for element in batch] max_anchor_l = max(anchor_lengths) anchor_mask = [[False] * anchor_lengths[n] + [True] * (max_anchor_l - anchor_lengths[n]) for n in range(len(batch))] # PADDING anchor_batch = [element[0] for element in batch] anchor_batch = pad_sequence(anchor_batch, batch_first=True) labels = torch.Tensor([element[1] for element in batch]) return anchor_batch, labels, torch.Tensor(anchor_mask)