KINECAL 1.0.2
(47,326 bytes)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Nov 15 12:53:26 2019
@author: 55129822
"""
'''
consider tracked?
'''
import numpy as np
import pandas as pd
import os
from scipy import signal
from scipy import stats
from scipy.spatial.transform import Rotation as R
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
import matplotlib.transforms as transforms
import matplotlib.image as mpl_image
from PIL import Image as pil_image
from mpl_toolkits.mplot3d import Axes3D
import os
import sys
from tqdm import tqdm
from enum import Enum
import re
from sway_utils import metrics as sm
import csv
from sklearn import preprocessing
import scipy.misc
#%%
class SkeletonJoints(Enum):
SPINEBASE = 0
SPINEMID = 1
NECK = 2
HEAD = 3
SHOULDERLEFT = 4
ELBOWLEFT = 5
WRISTLEFT = 6
HANDLEFT = 7
SHOULDERRIGHT = 8
ELBOWRIGHT = 9
WRISTRIGHT = 10
HANDRIGHT = 11
HIPLEFT = 12
KNEELEFT = 13
ANKLELEFT = 14
FOOTLEFT = 15
HIPRIGHT = 16
KNEERIGHT = 17
ANKLERIGHT = 18
FOOTRIGHT = 19
SPINESHOULDER = 20
HANDTIPLEFT = 21
THUMBLEFT = 22
HANDTIPRIGHT = 23
THUMBRIGHT = 24
COM = 25
#HEELLEFT = 26
#HEELRIGHT = 27
class SkeletonJoints_no_hands(Enum):
SPINEBASE = 0
SPINEMID = 1
NECK = 2
#HEAD = 3
SHOULDERLEFT = 4
ELBOWLEFT = 5
WRISTLEFT = 6
#HANDLEFT = 7
SHOULDERRIGHT = 8
ELBOWRIGHT = 9
WRISTRIGHT = 10
#HANDRIGHT = 11
HIPLEFT = 12
KNEELEFT = 13
ANKLELEFT = 14
#FOOTLEFT = 15
HIPRIGHT = 16
KNEERIGHT = 17
ANKLERIGHT = 18
#FOOTRIGHT = 19
SPINESHOULDER = 20
#HANDTIPLEFT = 21
#THUMBLEFT = 22
#HANDTIPRIGHT = 23
#THUMBRIGHT = 24
COM = 25
#HEELLEFT = 26
#HEELRIGHT = 27
class HierarchicalSkeletonJoints(Enum):
COM = 25
HEAD = 3
NECK = 2
SPINESHOULDER = 20
SPINEMID = 1
SPINEBASE = 0
SHOULDERLEFT = 4
SHOULDERRIGHT = 8
ELBOWLEFT = 5
ELBOWRIGHT = 9
WRISTLEFT = 6
WRISTRIGHT = 10
HIPLEFT = 12
HIPRIGHT = 16
KNEELEFT = 13
KNEERIGHT = 17
ANKLELEFT = 14
ANKLERIGHT = 18
FOOTLEFT = 15
FOOTRIGHT = 19
HANDLEFT = 7
HANDTIPLEFT = 21
THUMBLEFT = 22
HANDRIGHT = 11
HANDTIPRIGHT = 23
THUMBRIGHT = 24
class SkeletonJointAngles(Enum):
BODY_COM_ANGLE = 1
BODY_LEAN_ANGLE = 2
KNEELEFT_ANGLE = 3
KNEERIGHT_ANGLE = 4
HIPLEFT_ANGLE = 5
HIPRIGHT_ANGLE = 6
ELBOWLEFT_ANGLE = 7
ELBOWLRIGHT_ANGLE = 8
ARMPITLEFT_ANGLE = 9
ARMPITROIGHT_ANGLE = 10
ANKLELEFT_ANGLE = 11
ANKLELRIGHT_ANGLE = 12
class BodySegments(Enum):
#Torso
HEAD_NECK = [SkeletonJoints.HEAD.value, SkeletonJoints.NECK.value]
NECK_SPINESHOULDER = [SkeletonJoints.NECK.value, SkeletonJoints.SPINESHOULDER.value]
SPINESHOULDER_SPINEMID = [SkeletonJoints.SPINESHOULDER.value, SkeletonJoints.SPINEMID.value]
SPINEMID_SPINEBASE = [SkeletonJoints.SPINEMID.value, SkeletonJoints.SPINEBASE.value]
#Left arm
SPINESHOULDER_SHOULDERLEFT = [SkeletonJoints.SPINESHOULDER.value, SkeletonJoints.SHOULDERLEFT.value]
SHOULDERLEFT_ELBOWLEFT = [SkeletonJoints.SHOULDERLEFT.value, SkeletonJoints.ELBOWLEFT.value]
ELBOWLEFT_WRISTLEFT = [SkeletonJoints.ELBOWLEFT.value, SkeletonJoints.WRISTLEFT.value]
WRISTLEFT_HANDLEFT = [SkeletonJoints.WRISTLEFT.value, SkeletonJoints.HANDLEFT.value]
HANDLEFT_THUMPLEFT = [SkeletonJoints.HANDLEFT.value, SkeletonJoints.THUMBLEFT.value]
HANDLEFT_HANDTIPLEFT = [SkeletonJoints.HANDLEFT.value, SkeletonJoints.HANDTIPLEFT.value]
#Right arm
SPINESHOULDER_SHOULDERRIGHT = [SkeletonJoints.SPINESHOULDER.value, SkeletonJoints.SHOULDERRIGHT.value]
SHOULDERRIGHT_ELBOWRIGHT = [SkeletonJoints.SHOULDERRIGHT.value, SkeletonJoints.ELBOWRIGHT.value]
ELBOWRIGHT_WRISTRIGHT = [SkeletonJoints.ELBOWRIGHT.value, SkeletonJoints.WRISTRIGHT.value]
WRISTRIGHT_HANDRIGHT = [SkeletonJoints.WRISTRIGHT.value, SkeletonJoints.HANDRIGHT.value]
HANDRIGHT_THUMPRIGHT = [SkeletonJoints.HANDRIGHT.value, SkeletonJoints.THUMBRIGHT.value]
HANDRIGHT_HANDTIPRIGHT = [SkeletonJoints.HANDRIGHT.value, SkeletonJoints.HANDTIPRIGHT.value]
#Left leg
SPINEBASE_HIPLEFT = [SkeletonJoints.SPINEBASE.value, SkeletonJoints.HIPLEFT.value]
HIPLEFT_KNEELEFT = [SkeletonJoints.HIPLEFT.value, SkeletonJoints.KNEELEFT.value]
KNEELEFT_ANKLELEFT = [SkeletonJoints.KNEELEFT.value, SkeletonJoints.ANKLELEFT.value]
ANKLELEFT_FOOTLEFT = [SkeletonJoints.ANKLELEFT.value, SkeletonJoints.FOOTLEFT.value]
#Right leg
SPINEBASE_HIPRIGHT = [SkeletonJoints.SPINEBASE.value, SkeletonJoints.HIPRIGHT.value]
HIPRIGHT_KNEERIGHT = [SkeletonJoints.HIPRIGHT.value, SkeletonJoints.KNEERIGHT.value]
KNEERIGHT_ANKLERIGHT = [SkeletonJoints.KNEERIGHT.value, SkeletonJoints.ANKLERIGHT.value]
ANKLERIGHT_FOOTRIGHT = [SkeletonJoints.ANKLERIGHT.value, SkeletonJoints.FOOTRIGHT.value]
HEAD_SPINE_BASE = [SkeletonJoints.HEAD.value, SkeletonJoints.SPINEBASE.value]
SHOULDERKEFT_WRISTLEFT = [SkeletonJoints.SHOULDERLEFT.value, SkeletonJoints.WRISTLEFT.value]
HIPLEFT_ANKLELEFT = [SkeletonJoints.HIPLEFT.value, SkeletonJoints.ANKLELEFT.value]
class HierarchyForBodySegments(Enum):
HEAD = 3
NECK = 2
SPINESHOULDER = 20
SPINEMID = 1
SPINEBASE = 0
SHOULDERLEFT = 4
SHOULDERRIGHT = 8
ELBOWLEFT = 5
ELBOWRIGHT = 9
WRISTLEFT = 6
WRISTRIGHT = 10
HIPLEFT = 12
HIPRIGHT = 16
KNEELEFT = 13
KNEERIGHT = 17
ANKLELEFT = 14
ANKLERIGHT = 18
FOOTLEFT = 15
FOOTRIGHT = 19
HANDLEFT = 7
HANDTIPLEFT = 21
THUMBLEFT = 22
HANDRIGHT = 11
HANDTIPRIGHT = 23
THUMBRIGHT = 24
class BodyParts(Enum):
TORSO = [SkeletonJoints.HEAD,
SkeletonJoints.NECK,
SkeletonJoints.SPINESHOULDER,
SkeletonJoints.SPINEMID,
SkeletonJoints.SPINEBASE]
ARM_LEFT = [SkeletonJoints.SHOULDERLEFT,
SkeletonJoints.ELBOWLEFT,
SkeletonJoints.WRISTLEFT,
SkeletonJoints.HANDLEFT,
SkeletonJoints.THUMBLEFT,
SkeletonJoints.HANDTIPLEFT]
ARM_RIGHT = [SkeletonJoints.SHOULDERRIGHT,
SkeletonJoints.ELBOWRIGHT,
SkeletonJoints.WRISTRIGHT,
SkeletonJoints.HANDRIGHT,
SkeletonJoints.THUMBRIGHT,
SkeletonJoints.HANDTIPRIGHT]
LEG_LEFT = [SkeletonJoints.HIPLEFT,
SkeletonJoints.KNEELEFT,
SkeletonJoints.ANKLELEFT,
SkeletonJoints.FOOTLEFT]
LEG_RIGHT = [SkeletonJoints.HIPRIGHT,
SkeletonJoints.KNEERIGHT,
SkeletonJoints.ANKLERIGHT,
SkeletonJoints.FOOTRIGHT]
class BodySections(Enum):
TORSO = BodyParts.TORSO
ARMS = [BodyParts.ARM_LEFT, BodyParts.ARM_RIGHT]
LEGS = [BodyParts.LEG_LEFT, BodyParts.LEG_RIGHT]
class ScaleBodyParts(Enum):
TORSO = ['HEAD',
'NECK',
'SPINESHOULDER',
'SPINEMID',
'SPINEBASE']
ARMS = ['SHOULDERLEFT',
'EBOWLEFT',
'WRISTLEFT',
'HANDLEFT',
'THUMBLEFT',
'HANDTIPLEFT',
'SHOULDERRIGHT',
'ELBOWRIGHT',
'WRISTRIGHT',
'HANDRIGHT',
'THUMBRIGHT',
'HANDTIPRIGHT']
LEGS = ['HIPLEFT',
'KNEELEFT',
'ANKLELEFT',
'FOOTLEFT',
'HIPRIGHT',
'KNEERIGHT',
'ANKLERIGHT',
'FOOTRIGHT']
class WalkedSkelAngles(Enum):
'''
inspired by:
A. Vakanski, H. P. Jun, D. Paul, and R. Baker,
“A data set of human body movements for physical rehabilitation exercises,”
Data, vol. 3, no. 1, 2018.
NB no head tip and no tip
'''
#Torso
SPINEBASE_SPINEMID = [SkeletonJoints.SPINEBASE.value, SkeletonJoints.SPINEMID.value]
SPINEMID_SPINESHOULDER = [SkeletonJoints.SPINEMID.value, SkeletonJoints.SPINESHOULDER.value]
SPINESHOULDER_NECK = [SkeletonJoints.SPINESHOULDER.value, SkeletonJoints.NECK.value]
NECK_HEAD = [SkeletonJoints.NECK.value, SkeletonJoints.HEAD.value]
#Left upper
SPINESHOULDER_SHOULDERLEFT = [SkeletonJoints.SPINESHOULDER.value, SkeletonJoints.SHOULDERLEFT.value]
SHOULDERLEFT_ELBOWLEFT = [SkeletonJoints.SHOULDERLEFT.value, SkeletonJoints.ELBOWLEFT.value]
ELBOWLEFT_WRISTLEFT = [SkeletonJoints.ELBOWLEFT.value, SkeletonJoints.WRISTLEFT.value]
WRISTLEFT_HANDLEFT = [SkeletonJoints.WRISTLEFT.value, SkeletonJoints.HANDLEFT.value]
#Right upper
SPINESHOULDER_SHOULDERRIGHT = [SkeletonJoints.SPINESHOULDER.value, SkeletonJoints.SHOULDERRIGHT.value]
SHOULDERRIGHT_ELBOWRIGHT = [SkeletonJoints.SHOULDERRIGHT.value, SkeletonJoints.ELBOWRIGHT.value]
ELBOWRIGHT_WRISTRIGHT = [SkeletonJoints.ELBOWRIGHT.value, SkeletonJoints.WRISTRIGHT.value]
WRISTRIGHT_HANDRIGHT = [SkeletonJoints.WRISTRIGHT.value, SkeletonJoints.HANDRIGHT.value]
#Left lower
SPINEBASE_HIPLEFT = [SkeletonJoints.SPINEBASE.value, SkeletonJoints.HIPLEFT.value]
HIPLEFT_KNEELEFT = [SkeletonJoints.HIPLEFT.value, SkeletonJoints.KNEELEFT.value]
KNEELEFT_ANKLELEFT = [SkeletonJoints.KNEELEFT.value, SkeletonJoints.ANKLELEFT.value]
ANKLELEFT_FOOTLEFT = [SkeletonJoints.ANKLELEFT.value, SkeletonJoints.FOOTLEFT.value]
#Right lower
SPINEBASE_HIPRIGHT = [SkeletonJoints.SPINEBASE.value, SkeletonJoints.HIPRIGHT.value]
HIPRIGHT_KNEERIGHT = [SkeletonJoints.HIPRIGHT.value, SkeletonJoints.KNEERIGHT.value]
KNEERIGHT_ANKLERIGHT = [SkeletonJoints.KNEERIGHT.value, SkeletonJoints.ANKLERIGHT.value]
ANKLERIGHT_FOOTRIGHT = [SkeletonJoints.ANKLERIGHT.value, SkeletonJoints.FOOTRIGHT.value]
class WalkedSkelAnglesIn3s(Enum):
'''
Walk skeleton and get angles
'''
#Torso
SPINEMID_a = [SkeletonJoints.SPINEBASE.value,
SkeletonJoints.SPINEMID.value,
SkeletonJoints.SPINESHOULDER.value]
SPINESHOULDER_a = [SkeletonJoints.SPINEMID.value,
SkeletonJoints.SPINESHOULDER.value,
SkeletonJoints.NECK.value]
NECK_a = [SkeletonJoints.SPINESHOULDER.value,
SkeletonJoints.NECK.value,
SkeletonJoints.HEAD.value]
#Upper body
ARMPITLEFT_a = [SkeletonJoints.SPINESHOULDER.value,
SkeletonJoints.SHOULDERLEFT.value,
SkeletonJoints.ELBOWLEFT.value]
ELBOWLEFT_a = [SkeletonJoints.SHOULDERLEFT.value,
SkeletonJoints.ELBOWLEFT.value,
SkeletonJoints.WRISTLEFT.value]
ARMPITRIGHT_a = [SkeletonJoints.SPINESHOULDER.value,
SkeletonJoints.SHOULDERRIGHT.value,
SkeletonJoints.ELBOWRIGHT.value]
ELBOWRIGHT_a = [SkeletonJoints.SHOULDERLEFT.value,
SkeletonJoints.ELBOWRIGHT.value,
SkeletonJoints.WRISTRIGHT.value]
#Lower body
HIPLEFT_a = [SkeletonJoints.SPINEBASE.value,
SkeletonJoints.HIPLEFT.value,
SkeletonJoints.KNEELEFT.value]
KNEELEFT_a = [SkeletonJoints.HIPLEFT.value,
SkeletonJoints.KNEELEFT.value,
SkeletonJoints.ANKLELEFT.value]
HIPRIGHT_a = [SkeletonJoints.SPINEBASE.value,
SkeletonJoints.HIPRIGHT.value,
SkeletonJoints.KNEERIGHT.value]
KNEERIGHT_a = [SkeletonJoints.HIPLEFT.value,
SkeletonJoints.KNEERIGHT.value,
SkeletonJoints.ANKLERIGHT.value]
class RefernceTorsoJoints_HEAD(Enum):
HEAD = SkeletonJoints.HEAD.value
SHOULDERLEFT = SkeletonJoints.SHOULDERLEFT.value
SHOULDERRIGHT = SkeletonJoints.SHOULDERRIGHT.value
HIPLEFT = SkeletonJoints.HIPLEFT.value
HIPRIGHT = SkeletonJoints.HIPRIGHT.value
class RefernceTorsoJoints_NECK(Enum):
NECK = SkeletonJoints.NECK.value
SHOULDERLEFT = SkeletonJoints.SHOULDERLEFT.value
SHOULDERRIGHT = SkeletonJoints.SHOULDERRIGHT.value
HIPLEFT = SkeletonJoints.HIPLEFT.value
HIPRIGHT = SkeletonJoints.HIPRIGHT.value
class RefernceTorsoJoints_COM(Enum):
COM = SkeletonJoints.COM.value
X = 0
Y = 1
Z = 2
#%%
'''
General utilities
'''
def walkFileSystem(filePath):
root = []
dirs = []
files = []
for root, dirs, files in os.walk(filePath):
break
d = ''
for d in dirs:
if 'remov' in d.lower():
dirs.remove(d)
d = ''
for d in dirs:
if 'up-and-go' in d.lower():
dirs.remove(d)
d = ''
for d in dirs:
if '3m' in d.lower():
dirs.remove(d)
d = ''
for d in dirs:
if 'toe' in d.lower():
dirs.remove(d)
d = ''
for d in dirs:
if 'dual' in d.lower():
dirs.remove(d)
return root, dirs, files
#%%
class KinectRecording:
'''
Class that represents a single kinect recording
'''
_root_path = ''
_skel_root_path = ''
_skel_file_root = ''
_dataset_prefix = ''
_movement = ''
_part_id = 0
_labels = []
_ref_spine_base = [] #spine base of first skel frame
_ref_skel_frame = [] #whole of first skel frame
_frame_count = -1
_load_from_cache = False
_cached_stacked_raw_XYZ_file_path = ''
_cached_skeletons_path = ''
_skel_scale = []
_torso_scale = 0
#_ref_neck_length = 0.15
_scale_skeletons = False
''''
Values from files
skeletons: list of pandas DataFrames, representing
text files from kinect:
[features, SkeletonJoints] tipically, [6,26]
fetures : Indes, Tracked, X, Y, Z, px_X, px_Y
'''
skeletons = []
raw_XYZ_values = []
''''
stacked XYZ values are flattend versions of the raw and filteterd
kinect recordings
[XYZ, SkeletonJoints, #frames] typically,[3, 26, 600]
'''
stacked_raw_XYZ_values = []
stacked_filtered_XYZ_values = []
''''
stacked angle values represent the key angles of the
filtered XYZ values
[fetures, #frames] typically,[3, 600]
featurs: COM_angle, knee_angle, hip_angle_side, hip_angle_front,
lean_angle
'''
stacked_raw_angle_values = []
stacked_filtered_angle_vlaues = []
'''
get sway metrics from file
'''
sway_metrics = []
'''
calulate and store
local inter-joint coordination pattern (IJCP)
'''
IJCP_Dist = []
IJCP_Velo = []
'''
Calulate and store smc features
'''
smc_features = []
'''
calulate and store Walling Skel Angles
'''
walked_skel_angles = []
'''
Calulate and sotre Cosine Distance and Normalised Magnitude from
Q. Ke, S. An, M. Bennamoun, F. Sohel, and F. Boussaid, “SkeletonNet:
Mining Deep Part Features for 3-D Action Recognition,”
IEEE Signal Process. Lett., vol. 24, no. 6, pp. 731–735, Jun. 2017.
'''
cosine_distance = []
normalised_magnitude = []
def __init__(self, skel_root_path, dataset_prefix, movement, part_id, labels=[], scale_skeletons=False):
self._root_path = str.replace(skel_root_path, '/skel', '')
self._root_path = str.replace(self._root_path, '\skel', '')
self._dataset_prefix = dataset_prefix
self._skel_root_path = skel_root_path
self._movement = movement
self._part_id = part_id
self._labels = labels
self._scale_skeletons = scale_skeletons
self.load_skeletons(skel_root_path)
self.load_sway_metrics()
def load_sway_metrics(self):
sway_metric_path = os.path.join(self._root_path, 'sway_metrics.csv')
if os.path.exists(sway_metric_path):
self.sway_metrics = pd.read_csv(sway_metric_path)
def save_stacked_raw_XYZ(self):
if not os.path.exists(self._cached_stacked_raw_XYZ_file_path):
np.save(self._cached_stacked_raw_XYZ_file_path, self.stacked_raw_XYZ_values)
def save_skeletons(self):
if not os.path.exists(self._cached_skeletons_path):
#np.save(self._cached_skeletons_path, self.skeletons)
pd.concat(self.skeletons).to_csv(self._cached_skeletons_path)
def load_skeletons(self, skel_root_path):
#If chahed file exists, load
#Load scaled or none-scaled versions
if self._scale_skeletons:
cached_stacked_raw_XYZ_file_name = (self._dataset_prefix +
str(self._part_id) + '_' +
'cached_stacked_raw_XYZ_scaled_' +
#'cached_stacked_ankle_raw_XYZ_scaled_' +
self._movement + '.npy')
cached_skeletons_file_name = (self._dataset_prefix +
str(self._part_id) + '_' +
'cached_skeletons_scaled_' +
#'cached_skeletons_ankle_scaled_' +
self._movement + '.csv')
else:
cached_stacked_raw_XYZ_file_name = (self._dataset_prefix +
str(self._part_id) + '_' +
'cached_stacked_raw_XYZ_' +
self._movement + '.npy')
cached_skeletons_file_name = (self._dataset_prefix +
str(self._part_id) + '_' +
'cached_skeletons' +
self._movement + '.csv')
self._cached_stacked_raw_XYZ_file_path = os.path.join(self._root_path,
cached_stacked_raw_XYZ_file_name)
self._cached_skeletons_path = os.path.join(self._root_path,
cached_skeletons_file_name)
if os.path.exists(self._cached_stacked_raw_XYZ_file_path):
self.stacked_raw_XYZ_values = np.load(self._cached_stacked_raw_XYZ_file_path)
self._load_from_cache = True
#print('loading:', self._cached_stacked_raw_XYZ_file_path, '\n')
if os.path.exists(self._cached_skeletons_path):
self.skeletons = pd.read_csv(self._cached_skeletons_path)
#self._load_from_cache = True
#print('loading:', self._cached_skeletons_path, '\n')
#else calulate stuff
else:
root, dirs, skel_files = walkFileSystem(skel_root_path)
skel_files.sort()
if len(skel_files) == 0:
print('Skel files for:', self._cached_stacked_raw_XYZ_file_path)
for skelfile in tqdm(skel_files):
#for skelfile in skel_files:
skel_file_path = os.path.join(root, skelfile)
_skel_frame, _raw_XYZ = self._load_skel_file(skel_file_path)
'''skels are now normailesed and com added '''
self.skeletons.append(_skel_frame)
self.raw_XYZ_values.append(_raw_XYZ)
#dont include first frame, having a skel base of 0,0,0 can cause problems
if self._frame_count > 0:
if len(self.stacked_raw_XYZ_values) == 0:
self.stacked_raw_XYZ_values = _raw_XYZ
else:
self.stacked_raw_XYZ_values = np.dstack([self.stacked_raw_XYZ_values, _raw_XYZ])
#Save
self.save_stacked_raw_XYZ()
self.save_skeletons()
#now calulate features
self.stacked_filtered_XYZ_values = self.filter_joint_sequences(self.stacked_raw_XYZ_values)
return
def filter_joint_sequences(self, noisy_raw_XYZ, N=2, fc=10, fs=30):
stacked_filtered_XYZ_values = []
filtered_X = []
filtered_Z = []
filtered_Z = []
for joint in SkeletonJoints:
joint_number = joint.value
#or 'WRIST' in joint.name
if 'HAND' in joint.name or 'THUMB' in joint.name or 'FOOT' in joint.name or 'ANKLE' in joint.name:
_N=2
_fc=15
_fs=fs
else:
_N=N
_fc=fc
_fs=fs
X, Y, Z = sm.filter_signal(noisy_raw_XYZ[0, joint_number, :],
noisy_raw_XYZ[1, joint_number, :],
noisy_raw_XYZ[2, joint_number, :],
N=_N, fc=_fc, fs=_fs)
if len(filtered_X) == 0:
filtered_X = X
filtered_Y = Y
filtered_Z = Z
else:
filtered_X = np.dstack([filtered_X, X])
filtered_Y = np.dstack([filtered_Y, Y])
filtered_Z = np.dstack([filtered_Z, Z])
filtered_X = np.transpose(filtered_X)
filtered_Y = np.transpose(filtered_Y)
filtered_Z = np.transpose(filtered_Z)
stacked_filtered_XYZ_values = np.stack([filtered_X[:,:,0], filtered_Y[:,:,0], filtered_Z[:,:,0]])
return stacked_filtered_XYZ_values
def calulate_CD_and_NM(self, rebuild=False, save_pngs=False):
scaled = ''
if self._scale_skeletons:
scaled = 'scaled_'
joint_set = 'no_hands_'
ref_set = 'CoM_'
cached_CD_file_name = os.path.join(self._root_path,
(self._dataset_prefix +
str(self._part_id) + '_' +
scaled +
joint_set +
ref_set +
'CD_' +
self._movement + '.npy'))
cached_NM_file_name = os.path.join(self._root_path,
(self._dataset_prefix +
str(self._part_id) + '_' +
scaled +
joint_set +
ref_set +
'NM_' +
self._movement + '.npy'))
cd_cache_file_exists = os.path.exists(cached_CD_file_name)
nm_cache_file_exists = os.path.exists(cached_NM_file_name)
if not cd_cache_file_exists or not nm_cache_file_exists or rebuild:
cosine_distance = []
normalised_magnitude = []
for skel_idx in tqdm(range(np.shape(self.stacked_filtered_XYZ_values)[2])):
skel = self.stacked_filtered_XYZ_values[:,:,skel_idx]
cd_row = []
nm_row = []
col_names = []
for ref_joint in RefernceTorsoJoints_COM: #RefernceTorsoJoints_HEAD RefernceTorsoJoints_NECK RefernceTorsoJoints_COM
for skel_joint in SkeletonJoints_no_hands: #SkeletonJoints
cd = sm.cosine_distance_between_joints(skel[:, ref_joint.value],
skel[:, skel_joint.value])
col_names.append(ref_joint.name + '_' + skel_joint.name)
# cd_csv_rows.append({'ref_joint': ref_joint.name,
# 'skel_joint': skel_joint.name,
# 'cd': cd})
cd_row.append(cd)
nm = sm.normalised_magnitude_between_joints(skel[:, skel_joint.value],
skel[:, ref_joint.value])
# nm_csv_rows.append({'ref_joint': ref_joint.name,
# 'skel_joint': skel_joint.name,
# 'nm': nm})
nm_row.append(nm)
cosine_distance.append(cd_row)
normalised_magnitude.append(nm_row)
self.cosine_distance = cosine_distance
self.normalised_magnitude = normalised_magnitude
#save
np.save(cached_CD_file_name, self.cosine_distance)
np.save(cached_NM_file_name, self.normalised_magnitude)
# for col in SkeletonJoints_no_hands:
# col_names.append(col.name)
pd.DataFrame(self.cosine_distance, columns=col_names).to_csv(cached_CD_file_name.replace('.npy', '.csv'))
pd.DataFrame(self.normalised_magnitude, columns=col_names).to_csv(cached_NM_file_name.replace('.npy', '.csv'))
else:
self.cosine_distance = np.load(cached_CD_file_name)
print('loading:', cached_CD_file_name, '\n')
self.normalised_magnitude = np.load(cached_NM_file_name)
print('loading:', cached_NM_file_name, '\n')
if save_pngs:
str_part_id = str(self._part_id)
plt.figure()
plt.plot(kinect_recording.cosine_distance)
plt.title('Cosign distance ' + scaled + ' ' + str_part_id)
plt.savefig(os.path.join(self._root_path,('CD_' + scaled +
ref_set + joint_set +
str_part_id)))
plt.close()
plt.figure()
plt.plot(kinect_recording.normalised_magnitude)
plt.title('Normalised magnitude ' + scaled + ' ' + str_part_id)
plt.savefig(os.path.join(self._root_path,('NM_' + scaled +
ref_set + joint_set +
str_part_id)))
plt.close()
img = pd.DataFrame(self.cosine_distance).values
#min_max_scaler = preprocessing.MinMaxScaler()
img_scaled = ((img - img.min()) * (1/(img.max()
- img.min()) * 255)).astype('uint8')
img_3ch = np.dstack([img_scaled, img_scaled, img_scaled])
img_3ch_to_save = pil_image.fromarray(img_3ch, mode='RGB')
img_3ch_to_save.save(cached_NM_file_name.replace('.npy', '.png'))
def normalise_skeleton(self, skel_frame):
if len(self._ref_spine_base) == 0:
self._ref_spine_base = skel_frame.iloc[SkeletonJoints.SPINEBASE.value][['X', 'Y', 'Z']].tolist()
self._ref_skel_frame = skel_frame
normalised_skel_frame = pd.DataFrame.copy(skel_frame,deep=False)
# x = 0
# y = 1
# z = 2
for i, joint in enumerate(SkeletonJoints): #HierarchyForBodySegments
joint_name = joint.name
joint_number = joint.value
normalised_skel_frame.iloc[joint_number, normalised_skel_frame.columns.get_loc('X')] = (skel_frame.iloc[joint_number]['X'] - self._ref_spine_base[X])
normalised_skel_frame.iloc[joint_number, normalised_skel_frame.columns.get_loc('Y')] = (skel_frame.iloc[joint_number]['Y'] - self._ref_spine_base[Y])
normalised_skel_frame.iloc[joint_number, normalised_skel_frame.columns.get_loc('Z')] = (skel_frame.iloc[joint_number]['Z'] - self._ref_spine_base[Z])
if self._scale_skeletons:
skel_scale = self.get_scale_for_joint(skel_frame, joint_name)
normalised_skel_frame.iloc[joint_number, normalised_skel_frame.columns.get_loc('X')] = (normalised_skel_frame.iloc[joint_number]['X'] * skel_scale)
normalised_skel_frame.iloc[joint_number, normalised_skel_frame.columns.get_loc('Y')] = (normalised_skel_frame.iloc[joint_number]['Y'] * skel_scale)
normalised_skel_frame.iloc[joint_number, normalised_skel_frame.columns.get_loc('Z')] = (normalised_skel_frame.iloc[joint_number]['Z'] * skel_scale)
if joint_number == 24:
break
self._frame_count +=1
return normalised_skel_frame
def _load_skel_file(self, skel_file_path):
""" debug skelfile """
#print(skel_file_path)
#replace with array of skeletons
columns = ['Joint', 'Tracked', 'X', 'Y', 'Z', 'px_X', 'px_Y']
skel_frame = pd.read_csv(skel_file_path, delimiter=' ', header=None, nrows=25, names=columns, index_col=0)
''' Normalise '''
skel_frame = self.normalise_skeleton(skel_frame)
#Add CoM
tmp_CoM = self.calulate_CoM_position(skel_frame)
tmp_CoM_row = {'Tracked':'Tracked',
'X':tmp_CoM[0],
'Y':tmp_CoM[1],
'Z':tmp_CoM[2],
'px_X':0,
'px_Y':0}
df_CoM_row = pd.DataFrame(tmp_CoM_row, index=['CoM'])
skel_frame = skel_frame.append(df_CoM_row)
X = skel_frame['X']
Y = skel_frame['Y']
Z = skel_frame['Z']
raw_XYZ = np.stack([X.values, Y.values, Z.values])
return skel_frame, raw_XYZ
def calulate_CoM_position(self, skel_frame):
# _X = 2
# _Y = 3
# _Z = 4
spine_base = np.stack([skel_frame['X'][SkeletonJoints.SPINEMID.value], skel_frame['Y'][SkeletonJoints.SPINEMID.value], skel_frame['Z'][SkeletonJoints.SPINEMID.value]])
hip_left = np.stack([skel_frame['X'][SkeletonJoints.HIPLEFT.value], skel_frame['Y'][SkeletonJoints.HIPLEFT.value], skel_frame['Z'][SkeletonJoints.HIPLEFT.value]])
hip_right = np.stack([skel_frame['X'][SkeletonJoints.HIPRIGHT.value], skel_frame['Y'][SkeletonJoints.HIPRIGHT.value], skel_frame['Z'][SkeletonJoints.HIPRIGHT.value]])
x_mean = np.mean([spine_base[0],hip_left[0],hip_right[0]])
y_mean = np.mean([spine_base[1],hip_left[1],hip_right[1]])
z_mean = np.mean([spine_base[2],hip_left[2],hip_right[2]])
CoM = np.stack([x_mean,y_mean,z_mean])
#com = spine_base
return CoM.tolist()
def calulate_skeleton_angles_from_stacked_XYZ_values(self, stacked_filtered_XYZ_values):
angles_list = []
#X = 0
#Y = 1
#Z = 2
tmp_foot_left_joint = np.stack([np.mean(stacked_filtered_XYZ_values[X][SkeletonJoints.FOOTLEFT.value]),
np.mean(stacked_filtered_XYZ_values[Y][SkeletonJoints.FOOTLEFT.value]),
np.mean(stacked_filtered_XYZ_values[Z][SkeletonJoints.FOOTLEFT.value])])
tmp_foot_left_joint = np.stack([np.mean(stacked_filtered_XYZ_values[X][SkeletonJoints.FOOTRIGHT.value]),
np.mean(stacked_filtered_XYZ_values[Y][SkeletonJoints.FOOTRIGHT.value]),
np.mean(stacked_filtered_XYZ_values[Z][SkeletonJoints.FOOTRIGHT.value])])
tmp_foot_mean_joint = sm.mean_twin_joint_pos(tmp_foot_left_joint,
tmp_foot_left_joint)
tmp_ground_plane = np.stack([np.mean(stacked_filtered_XYZ_values[X][SkeletonJoints.COM.value]),
tmp_foot_mean_joint[1],
np.mean(stacked_filtered_XYZ_values[Z][SkeletonJoints.COM.value])])
for i in np.ndindex(stacked_filtered_XYZ_values.shape[2]):
tmp_shoulder_left_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.SHOULDERLEFT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.SHOULDERLEFT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.SHOULDERLEFT.value][i]])
tmp_shoulder_right_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.SHOULDERRIGHT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.SHOULDERRIGHT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.SHOULDERRIGHT.value][i]])
tmp_spine_shoulder_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.SPINESHOULDER.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.SPINESHOULDER.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.SPINESHOULDER.value][i]])
tmp_com_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.COM.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.COM.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.COM.value][i]])
tmp_elbow_left_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.ELBOWLEFT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.ELBOWLEFT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.ELBOWLEFT.value][i]])
tmp_elbow_right_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.ELBOWRIGHT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.ELBOWRIGHT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.ELBOWRIGHT.value][i]])
tmp_wrist_left_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.WRISTLEFT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.WRISTLEFT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.WRISTLEFT.value][i]])
tmp_wrist_right_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.WRISTRIGHT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.WRISTRIGHT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.WRISTRIGHT.value][i]])
tmp_hip_left_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.HIPLEFT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.HIPLEFT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.HIPLEFT.value][i]])
tmp_hip_right_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.HIPRIGHT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.HIPRIGHT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.HIPRIGHT.value][i]])
tmp_knee_left_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.KNEELEFT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.KNEELEFT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.KNEELEFT.value][i]])
tmp_knee_right_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.KNEERIGHT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.KNEERIGHT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.KNEERIGHT.value][i]])
tmp_ankle_left_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.ANKLELEFT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.ANKLELEFT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.ANKLELEFT.value][i]])
tmp_ankle_right_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.ANKLERIGHT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.ANKLERIGHT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.ANKLERIGHT.value][i]])
tmp_heel_left_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.ANKLELEFT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.FOOTLEFT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.ANKLELEFT.value][i]])
tmp_heel_right_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.ANKLERIGHT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.FOOTRIGHT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.ANKLERIGHT.value][i]])
tmp_heel_mean_joint = sm.mean_twin_joint_pos(tmp_heel_left_joint, tmp_heel_right_joint)
tmp_ankle_left_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.ANKLELEFT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.ANKLELEFT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.ANKLELEFT.value][i]])
tmp_ankle_right_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.ANKLERIGHT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.ANKLERIGHT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.ANKLERIGHT.value][i]])
tmp_foot_left_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.FOOTLEFT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.FOOTLEFT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.FOOTLEFT.value][i]])
tmp_foot_right_joint = np.stack([stacked_filtered_XYZ_values[X][SkeletonJoints.FOOTRIGHT.value][i],
stacked_filtered_XYZ_values[Y][SkeletonJoints.FOOTRIGHT.value][i],
stacked_filtered_XYZ_values[Z][SkeletonJoints.FOOTRIGHT.value][i]])
body_com_angle = sm.get_angle_between_three_joints(tmp_com_joint,
tmp_heel_mean_joint,
tmp_ground_plane)
body_lean_angle = sm.get_angle_between_three_joints(tmp_spine_shoulder_joint,
tmp_heel_mean_joint,
tmp_ground_plane)
knee_angle_left = sm.get_angle_between_three_joints(tmp_hip_left_joint,
tmp_knee_left_joint,
tmp_ankle_left_joint)
knee_angle_right = sm.get_angle_between_three_joints(tmp_hip_right_joint,
tmp_knee_right_joint,
tmp_ankle_right_joint)
hip_angle_left = sm.get_angle_between_three_joints(tmp_shoulder_left_joint,
tmp_hip_left_joint,
tmp_knee_left_joint)
hip_angle_right = sm.get_angle_between_three_joints(tmp_shoulder_right_joint,
tmp_hip_right_joint,
tmp_knee_right_joint)
elbow_angle_left = sm.get_angle_between_three_joints(tmp_shoulder_left_joint,
tmp_elbow_left_joint,
tmp_wrist_left_joint)
elbow_angle_right = sm.get_angle_between_three_joints(tmp_shoulder_right_joint,
tmp_elbow_right_joint,
tmp_wrist_right_joint)
armpit_angle_left = sm.get_angle_between_three_joints(tmp_hip_left_joint,
tmp_shoulder_left_joint,
tmp_elbow_left_joint)
armpit_angle_right = sm.get_angle_between_three_joints(tmp_hip_right_joint,
tmp_shoulder_right_joint,
tmp_elbow_right_joint)
ankle_angle_left = sm.get_angle_between_three_joints(tmp_foot_left_joint,
tmp_heel_left_joint,
tmp_knee_left_joint)
ankle_angle_right = sm.get_angle_between_three_joints(tmp_foot_right_joint,
tmp_heel_right_joint,
tmp_knee_right_joint)
'''
BODY_COM_ANGLE = 1
BODY_LEAN_ANGLE = 2
KNEELEFT_ANGLE = 3
KNEERIGHT_ANGLE = 4
HIPLEFT_ANGLE = 5
HIPRIGHT_ANGLE = 6
ELBOWLEFT_ANGLE = 7
ELBOWLEFT_ANGLE = 8
ARMPITLEFT_ANGLE = 9
ARMPITLEFT_ANGLE = 10
ANKLELEFT_ANGLE = 11
ANKLELRIGHT_ANGLE = 12
'''
angles_row = np.hstack([self._part_id,
body_com_angle,
body_lean_angle,
knee_angle_left,
knee_angle_right,
hip_angle_left,
hip_angle_right,
elbow_angle_left,
elbow_angle_right,
armpit_angle_left,
armpit_angle_right,
ankle_angle_left,
ankle_angle_right])
if len(self._labels) != 0:
arr_labels = np.array(self._labels)[0]
self.load_sway_metrics()
angles_row = np.concatenate((angles_row, np.array(self.sway_metrics.iloc[0,10:]), arr_labels))
angles_list.append(angles_row)
return np.array(angles_list)
def calculate_walked_skel_angles(self):
columns = []
for combination in WalkedSkelAnglesIn3s:
#for combination in WalkedSkelAngles:
columns = np.hstack([columns, (combination.name + '_SP')])
columns = np.hstack([columns, (combination.name + '_FP')])
columns = np.hstack([columns, (combination.name + '_TP')])
skel_walked_angels = []
X = 0
Y = 1
Z = 2
for i in range(self.stacked_filtered_XYZ_values.shape[2]):
skel_angles_row = np.array([])
for combination in WalkedSkelAnglesIn3s:
#for combination in WalkedSkelAngles:
j1 = np.stack([1 * self.stacked_filtered_XYZ_values[X][combination.value[0]][i],
1 * self.stacked_filtered_XYZ_values[Y][combination.value[0]][i],
1 * self.stacked_filtered_XYZ_values[Z][combination.value[0]][i]])
j2 = np.stack([1 * self.stacked_filtered_XYZ_values[X][combination.value[1]][i],
1 * self.stacked_filtered_XYZ_values[Y][combination.value[1]][i],
1 * self.stacked_filtered_XYZ_values[Z][combination.value[1]][i]])
j3 = np.stack([1 * self.stacked_filtered_XYZ_values[X][combination.value[2]][i],
1 * self.stacked_filtered_XYZ_values[Y][combination.value[2]][i],
1 * self.stacked_filtered_XYZ_values[Z][combination.value[2]][i]])
euler_angle_3d = sm.get_3d_angle_between_three_joints(j1, j2, j3, deg=True)
if len(skel_angles_row) == 0:
skel_angles_row = euler_angle_3d
else:
skel_angles_row = np.hstack([skel_angles_row, euler_angle_3d])
skel_walked_angels.append(skel_angles_row)
pd_skel_walked_angels = pd.DataFrame(skel_walked_angels, columns=columns)
self.walked_skel_angles = pd_skel_walked_angels