Date | Number of Motions | Number of Segmentations | Size | Download |
---|---|---|---|---|
Jan. 1, 2024 Latest | 3916 | 160 | 676.8 MB | 2024-01-01.zip |
Oct. 1, 2023 | 3916 | 160 | 676.8 MB | 2023-10-01.zip |
July 1, 2023 | 3916 | 160 | 676.8 MB | 2023-07-01.zip |
April 1, 2023 | 3916 | 160 | 676.8 MB | 2023-04-01.zip |
Jan. 1, 2023 | 3916 | 160 | 676.8 MB | 2023-01-01.zip |
Oct. 1, 2022 | 3916 | 160 | 676.8 MB | 2022-10-01.zip |
July 1, 2022 | 3916 | 160 | 676.8 MB | 2022-07-01.zip |
April 1, 2022 | 3916 | 160 | 676.8 MB | 2022-04-01.zip |
Jan. 1, 2022 | 3916 | 160 | 676.8 MB | 2022-01-01.zip |
Oct. 1, 2021 | 3916 | 160 | 676.8 MB | 2021-10-01.zip |
July 1, 2021 | 3916 | 160 | 676.8 MB | 2021-07-01.zip |
April 1, 2021 | 3916 | 160 | 676.8 MB | 2021-04-01.zip |
Jan. 1, 2021 | 3916 | 160 | 676.8 MB | 2021-01-01.zip |
July 1, 2020 | 3916 | 160 | 676.8 MB | 2020-07-01.zip |
April 1, 2020 | 3917 | 160 | 676.8 MB | 2020-04-01.zip |
Jan. 1, 2020 | 3917 | 160 | 676.8 MB | 2020-01-01.zip |
Oct. 1, 2019 | 3917 | 160 | 676.8 MB | 2019-10-01.zip |
July 1, 2019 | 3917 | 160 | 676.8 MB | 2019-07-01.zip |
April 1, 2019 | 3917 | 160 | 676.8 MB | 2019-04-01.zip |
Jan. 1, 2019 | 3917 | 160 | 676.8 MB | 2019-01-01.zip |
Oct. 1, 2018 | 3917 | 160 | 676.8 MB | 2018-10-01.zip |
July 1, 2018 | 3917 | 160 | 676.8 MB | 2018-07-01.zip |
March 5, 2018 | 3918 | 53 | 677.4 MB | 2018-03-05.zip |
@misc{seehausen2018msegtool, title={KIT Motion-Segmentation Dataset}, author={Cedric Seehausen and Mirko Wächter and Christian Mandery and Tamim Asfour}, year={2018}, url={https://motion-segmentation.humanoids.kit.edu/} }
The content of the extracted Dataset looks like this:
dbfileid_segmentationid_segmentation.xml dbfileid_othersegmentatinid_segmentation.xml ... dbfileid_meta.json dbfileid_mmm.xml otherdbfileid_segmentationid_segmentation.xml otherdbfileid_othersegmentatinid_segmentation.xml ... otherdbfileid_meta.json otherdbfileid_mmm.xml ...
Each file is prefixed with the Motion Database file-id followed by its type. Please notice that the IDs are not necessarily consecutive. However, each ID is unique and for each ID, there is always one Metadata file, one MMM file and an unknown number of segmentation files, which are also identified by an unique id. The format and contents of the available files are explained below.
<id>_mmm.xml
)The motions are available as XML files that represent the motion using the Master Motor Map (MMM) framework. We recommend that you always use this file when working with the motion data since it abstracts from the concrete motion capture system in use and allows you to use new data sources in the future without effort. An comprehensive documentation of the data format is available on the MMM website. Please refer to this documentation for details. We also provide a simple Python example (see below) that parses the most important parts of the XML file without any third-party dependencies.
<?xml version='1.0'?>
<MMM>
<Motion name='subject_id_4'>
<Model>
<File>mmm.xml</File>
</Model>
<ModelProcessorConfig type='Winter'>
<Height>1.82</Height>
<Mass>100</Mass>
</ModelProcessorConfig>
<JointOrder>
<Joint name='BLNx_joint'/>
<Joint name='BLNy_joint'/>
<Joint name='BLNz_joint'/>
<Joint name='BPx_joint'/>
<Joint name='BPy_joint'/>
<Joint name='BPz_joint'/>
<Joint name='BTx_joint'/>
<Joint name='BTy_joint'/>
<Joint name='BTz_joint'/>
<Joint name='BUNx_joint'/>
<Joint name='BUNy_joint'/>
<Joint name='BUNz_joint'/>
<Joint name='LAx_joint'/>
<Joint name='LAy_joint'/>
<Joint name='LAz_joint'/>
<Joint name='LEx_joint'/>
<Joint name='LEz_joint'/>
<Joint name='LHx_joint'/>
<Joint name='LHy_joint'/>
<Joint name='LHz_joint'/>
<Joint name='LKx_joint'/>
<Joint name='LSx_joint'/>
<Joint name='LSy_joint'/>
<Joint name='LSz_joint'/>
<Joint name='LWx_joint'/>
<Joint name='LWy_joint'/>
<Joint name='LFx_joint'/>
<Joint name='LMrot_joint'/>
<Joint name='RAx_joint'/>
<Joint name='RAy_joint'/>
<Joint name='RAz_joint'/>
<Joint name='REx_joint'/>
<Joint name='REz_joint'/>
<Joint name='RHx_joint'/>
<Joint name='RHy_joint'/>
<Joint name='RHz_joint'/>
<Joint name='RKx_joint'/>
<Joint name='RSx_joint'/>
<Joint name='RSy_joint'/>
<Joint name='RSz_joint'/>
<Joint name='RWx_joint'/>
<Joint name='RWy_joint'/>
<Joint name='RFx_joint'/>
<Joint name='RMrot_joint'/>
</JointOrder>
<MotionFrames>
<MotionFrame>
<Timestep>0</Timestep>
<RootPosition>1142.97 -252.854 973.526</RootPosition>
<RootRotation>-0.0735726 -0.0238353 1.64312</RootRotation>
<JointPosition>-0.612953 0.0476239 0.212333 0.161793 0.0028466 0.0190509 -0.0479624 -0.0228922 -0.0694337 0.387513 -0.0018089 0.135106 0.158669 -0.324085 -0.165832 0.35672 -0.0738947 0.103075 0.0545089 0.135437 -0.221003 -0.154341 0.179823 -0.279305 0.0844597 -0.254741 -0.122429 0.224831 0.0616969 0.324959 -0.483339 0.308075 0.857774 0.00596291 0.0430199 0.373412 -0.021832 -0.11818 -0.083582 -0.152354 0.120838 0.373251 -0.0313812 -0.261799 </JointPosition>
<JointVelocity>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 </JointVelocity>
<JointAcceleration>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 </JointAcceleration>
</MotionFrame>
<MotionFrame>
<Timestep>0.01</Timestep>
<RootPosition>1142.89 -252.863 973.795</RootPosition>
<RootRotation>-0.0752048 -0.0231932 1.64472</RootRotation>
<JointPosition>-0.651594 -0.142824 0.211258 0.17367 0.000509898 0.0173047 -0.0596829 -0.0227031 -0.0701363 0.471133 0.261797 0.116722 0.155988 -0.323779 -0.172119 0.356309 -0.0834862 0.106037 0.0545055 0.139367 -0.222049 -0.151358 0.178517 -0.269665 0.0925315 -0.257984 -0.113151 0.221422 0.0603637 0.326164 -0.478189 0.309305 0.879796 0.00786525 0.0430097 0.363636 -0.0238971 -0.115228 -0.0827109 -0.163222 0.134703 0.373612 -0.021385 -0.261799 </JointPosition>
<JointVelocity>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 </JointVelocity>
<JointAcceleration>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 </JointAcceleration>
</MotionFrame>
<!-- More <MotionFrame> elements follow -->
</MotionFrames>
</Motion>
<!-- If there are Objects in the Motion there is another <Motion> Tag -->
<!-- The Motion->Model->File attribute contains the curresponding Database object -->
<Motion name='subject_id_4'>
<Model>
<File>object_<object_id>.xml</File> <!-- <object_id> is replaced with the file id of the object -->
</Model>
<MotionFrames>
<MotionFrame>
<Timestep>0</Timestep>
<RootPosition>1142.97 -252.854 973.526</RootPosition>
<RootRotation>-0.0735726 -0.0238353 1.64312</RootRotation>
</MotionFrame>
<MotionFrame>
<Timestep>0.01</Timestep>
<RootPosition>1142.89 -252.863 973.795</RootPosition>
<RootRotation>-0.0752048 -0.0231932 1.64472</RootRotation>
</MotionFrame>
<!-- More <MotionFrame> elements follow -->
</MotionFrames>
</Motion>
</MMM>
<id>_<number>_segmentations.xml
)Segmentations are available as XML files. One motion can have many segmentations.
<?xml version='1.0' encoding='utf8'?>
<segmentation id="62306" db_id="1322"> <!-- db_id = id in Motion Database (not Unique), id = file id of the Motion (Unique)-->
<segment name="Standing">
<start_frame>0</start_frame>
<end_frame>54</end_frame>
<segment name="Standing">
<start_frame>0</start_frame>
<end_frame>54</end_frame>
<segment name="Standing">
<start_frame>0</start_frame>
<end_frame>54</end_frame>
</segment>
</segment>
</segment>
<segment name="Jumping">
<start_frame>54</start_frame>
<end_frame>202</end_frame>
<segment name="Propulsion Phase">
<start_frame>54</start_frame>
<end_frame>106</end_frame>
<segment name="Propulsion Phase">
<start_frame>54</start_frame>
<end_frame>106</end_frame>
</segment>
</segment>
<segment name="Flying">
<start_frame>106</start_frame>
<end_frame>140</end_frame>
<segment name="Flying Up">
<start_frame>106</start_frame>
<end_frame>129</end_frame>
</segment>
<segment name="Flying Down">
<start_frame>129</start_frame>
<end_frame>140</end_frame>
</segment>
</segment>
<segment name="Landing">
<start_frame>140</start_frame>
<end_frame>202</end_frame>
<segment name="Landing">
<start_frame>140</start_frame>
<end_frame>202</end_frame>
</segment>
</segment>
</segment>
<segment name="Standing">
<start_frame>202</start_frame>
<end_frame>445</end_frame>
<segment name="Standing">
<start_frame>202</start_frame>
<end_frame>445</end_frame>
<segment name="Standing">
<start_frame>202</start_frame>
<end_frame>445</end_frame>
</segment>
</segment>
</segment>
<segment name="Walking">
<start_frame>445</start_frame>
<end_frame>649</end_frame>
<segment name="Right Step">
<start_frame>445</start_frame>
<end_frame>507</end_frame>
<segment name="Lift Right Foot">
<start_frame>445</start_frame>
<end_frame>492</end_frame>
</segment>
<segment name="Place Right Foot">
<start_frame>492</start_frame>
<end_frame>507</end_frame>
</segment>
</segment>
<segment name="Left Step">
<start_frame>507</start_frame>
<end_frame>544</end_frame>
<segment name="Lift Left Foot">
<start_frame>507</start_frame>
<end_frame>525</end_frame>
</segment>
<segment name="Place Left Foot">
<start_frame>525</start_frame>
<end_frame>544</end_frame>
</segment>
</segment>
<segment name="Right Step">
<start_frame>544</start_frame>
<end_frame>590</end_frame>
<segment name="Lift Right Foot">
<start_frame>544</start_frame>
<end_frame>566</end_frame>
</segment>
<segment name="Place Right Foot">
<start_frame>566</start_frame>
<end_frame>590</end_frame>
</segment>
</segment>
<segment name="Left Step">
<start_frame>590</start_frame>
<end_frame>649</end_frame>
<segment name="Lift Left Foot">
<start_frame>590</start_frame>
<end_frame>611</end_frame>
</segment>
<segment name="Place Left Foot">
<start_frame>611</start_frame>
<end_frame>649</end_frame>
</segment>
</segment>
</segment>
<segment name="Standing">
<start_frame>649</start_frame>
<end_frame>989</end_frame>
<segment name="Standing">
<start_frame>649</start_frame>
<end_frame>989</end_frame>
<segment name="Standing">
<start_frame>649</start_frame>
<end_frame>989</end_frame>
</segment>
</segment>
</segment>
</segmentation>
The Segmentations get rated by the proposed algorithm out of "A Framework for Evaluating Motion Segmentation Algorithms".
Segmentations that could be outliers get noted in the Metafile as well as the most likely best segmentation. These values are only for orientation and are not forced to be right.
Also, there is a mean_similarity noted. This is the average deviation between segmentations of the Motion file. The lower this value is, the better. Values over 2000 should be considered as a warning since this means that the Segmentations of the Motion file are not similar at all.
<id>_meta.json
)The metadata for each entry is provided as a simple JSON dictionary. It links each entry to the Motion Segmentation Tool and the source database of the motion. This information is useful if you need to look up additional data from the database, e.g. the subject's height or weight. This allows you to find and filter out outliers.
{
"motion_segmentation_tool":{
"id":3966,
"segmentation_ids":[
5524,
5528,
5723,
6853,
7321
],
"mean_similarity": 1026.214564
"best_segmentation": 5723 //if there are to few segmentations for that motion this is "None"
"outlier": [ //Lists marked outliers
5528,
6853
]
},
"source":{
"mirror_database":{
"identifier":"kit",
"motion_file_id":53570,
"motion_id":1149
},
"institution":{
"identifier":"cmu",
"name":"Carnegie Mellon University"
},
"database":{
"identifier":"cmu",
"motion_file_id":38,
"motion_id":127
}
},
"nb_segmentations": 5
}
Notice that the mirror_database
entry is not always available.
You can use the Ice interface of the KIT Whole-Body Human Motion Database to obtain additional information on each motion. The Ice interface can be used with a wide variety of different programming and scripting languages. You can use the motion_id
entry from the metadata dictionary to obtain the corresponding ID for each motion. Additional information, as well as the necessary Ice interface specification, is available here.
We provide a simple example that illustrates how the entire dataset can be loaded using Python. The only dependency that we use is numpy
.
import argparse
import os
import json
import xml.etree.cElementTree as ET
import logging
import numpy as np
def parse_motions(path):
xml_tree = ET.parse(path)
xml_root = xml_tree.getroot()
xml_motions = xml_root.findall('Motion')
motions = []
if len(xml_motions) > 1:
logging.warn('more than one tag in file "%s", only parsing the first one', path)
motions.append(_parse_motion(xml_motions[0], path))
return motions
def _parse_motion(xml_motion, path):
xml_joint_order = xml_motion.find('JointOrder')
if xml_joint_order is None:
return [], []
joint_names = []
joint_indexes = []
for idx, xml_joint in enumerate(xml_joint_order.findall('Joint')):
name = xml_joint.get('name')
if name is None:
return [], []
joint_indexes.append(idx)
joint_names.append(name)
frames = []
xml_frames = xml_motion.find('MotionFrames')
if xml_frames is None:
return [], []
for xml_frame in xml_frames.findall('MotionFrame'):
frames.append(_parse_frame(xml_frame, joint_indexes))
return joint_names, frames
def _parse_frame(xml_frame, joint_indexes):
n_joints = len(joint_indexes)
xml_joint_pos = xml_frame.find('JointPosition')
if xml_joint_pos is None:
raise RuntimeError(' not found')
joint_pos = _parse_list(xml_joint_pos, n_joints, joint_indexes)
return joint_pos
def _parse_list(xml_elem, length, indexes=None):
if indexes is None:
indexes = range(length)
elems = [float(x) for idx, x in enumerate(xml_elem.text.rstrip().split(' ')) if idx in indexes]
if len(elems) != length:
raise RuntimeError('invalid number of elements')
return elems
def main(args):
input_path = args.input
print('Scanning files ...')
files = [f for f in os.listdir(input_path) if os.path.isfile(os.path.join(input_path, f)) and f[0] != '.']
fileids = list(set([os.path.splitext(f)[0].split('_')[0] for f in files]))
print('done, {} potential motions and their segmentations found'.format(len(fileids)))
print('')
# Parse all files.
print('Processing data in "{}" ...'.format(input_path))
all_ids = []
all_motions = []
all_segmentations = []
all_metadata = []
reference_joint_names = None
for idx, basename in enumerate(fileids):
print(' {}/{} ...'.format(idx + 1, len(fileids))),
# Load motion.
mmm_path = os.path.join(input_path, basename + '_mmm.xml')
assert os.path.exists(mmm_path)
joint_names, frames = parse_motions(mmm_path)[0]
if reference_joint_names is None:
reference_joint_names = joint_names[:]
elif reference_joint_names != joint_names:
print('skipping, invalid joint_names {}'.format(joint_names))
continue
# Load segmentation.
segmentation_names = list(set([os.path.splitext(f)[0].split('_')[1] for f in files if len(os.path.splitext(f)[0].split('_')) == 3 and basename == os.path.splitext(f)[0].split('_')[0]]))
print segmentation_names
for segId, segmentation_name in enumerate(segmentation_names):
segmentation_path = os.path.join(input_path, basename
+ "_" + segmentation_name
+ '_segmentation.xml')
assert os.path.exists(segmentation_path)
xml_tree = ET.parse(segmentation_path)
segmentation = xml_tree.getroot()
all_segmentations.append(segmentation)
# Load metadata.
meta_path = os.path.join(input_path, basename + '_meta.json')
assert os.path.exists(meta_path)
with open(meta_path, 'r') as f:
meta = json.load(f)
all_ids.append(int(basename))
all_motions.append(np.array(frames, dtype='float32'))
all_metadata.append(meta)
print('done')
assert len(all_motions) == len(all_segmentations)
assert len(all_motions) == len(all_ids)
print('done, successfully processed {} motions and their segmentations'.format(len(all_motions)))
print('')
# At this point, you can do anything you want with the motion and segmentation data.
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='')
parser.add_argument('input', type=str)
main(parser.parse_args())
Notice that this only parses the joint values of the MMM file. You can also use the MMM framework to do much more with the data. Please refer to the MMM documentation for details.