Package: llamass
llamassLLAMASS is Loader for the AMASS datasetMotivationI'm writing this to use in a project working with pose data to train models on theAMASS dataset. I wanted to be able to install it in colab notebooks and elsewhere easily. Hopefully it's also useful for other people but be aware this is research code so not necessarily reliable.BadgesInstallLicense AgreementBefore using the AMASS dataset I'm expected to sign up to the license agreeementhere. This package doesn't require any other code from MPI but visualization of pose data does, see below.Install with pipRequirements are handled by pip during the install but in a new environment I would installpytorchfirst to configure cuda as required for the system.pip install llamassFor VisualizationThere are demos for plotting available in theamass repoand in thesmplx repo. I wrote a library based on these to plot without having to think about thebetas,dmplsetc. It's calledgaitplotliband it can be installed from github:pip install git+https://github.com/gngdb/gaitplotlib.gitHow to useDownloading the dataTheAMASS websiteprovides links to download the various parts of the AMASS dataset. Each is provided as a.tar.bz2and I had to download them from the website by hand. Save all of these in a folder somehwere.Unpacking the dataAfter installingllamass, it provides a console script to unpack thetar.bz2files downloaded from theAMASSwebsite:fast_amass_unpack -n 4 --verify <dir with .tar.bz2 files> <dir to save unpacked data>This will unpack the data in parallel in 4 jobs and provides a progress bar. The--verifyflag willmd5sumthe directory the files are unpacked to and check it against what I found when I unpacked it. It'll also avoid unpacking tar files that have already been unpacked by looking for saved.hashfiles in the target directory. It's slower but more reliable and recovers from incomplete unpacking.Alternatively, this can be access in the library using thellamass.core.unpack_body_modelsfunction:importllamass.corellamass.core.unpack_body_models("sample_data/",unpacked_directory,4)sample_data/sample.tar.bz2 extracting to /tmp/tmp06iwsfhuDownload MetadataI've processed the files to find out how many frames are in each numpy archive unpacked whenfast_amass_unpackis run. By default, the first time theAMASSDataset object is asked for it'slenit will look for a file containing this information in the specified AMASS directory. If it doesn't find it, it will recompute it and that can take 5 minutes.Save 5 minutes by downloading it from this repository:wget https://github.com/gngdb/llamass/raw/master/npz_file_lens.json.gz -P <dir to save unpacked data>Train/val/test Splitdetails of script for splits goes hereUsing the dataOnce the data is unpacked it can be loaded by a PyTorch DataLoader directly using thellamass.core.AMASSDataset class.overlapping: whether the clips of frames taken from each file should be allowed to overlapclip_length: how long should clips from each file be?transform: a transformation function apply to all fieldsIt is anIterableDatasetso itcannot be shuffled by the DataLoader. Ifshuffle=Truethe DataLoader will hit an error. However, theAMASSclass itself implements shuffling and it can be enabled usingshuffle=Trueat initialisation.Also, in order to use more than one worker it is necessary to use the providedworker_init_fnin the DataLoader. This can also be accessed by usingllamass.core.IterableLoaderin place ofDataLoader, and this is safer because usingDataLoaderwithoutworker_init_fnwill yield duplicate data when workers load from the same files.importtorchfromtorch.utils.dataimportDataLoaderamass=llamass.core.AMASS(unpacked_directory,overlapping=False,clip_length=1,transform=torch.tensor,shuffle=False,seed=0,)# these are equivalentamassloader=DataLoader(amass,batch_size=4,num_workers=2,worker_init_fn=llamass.core.worker_init_fn)amassloader=llamass.core.IterableLoader(amass,batch_size=4,num_workers=2)fordatainamassloader:forkindata:print(k,data[k].size())breakposes torch.Size([4, 1, 156])
dmpls torch.Size([4, 1, 8])
trans torch.Size([4, 1, 3])
betas torch.Size([4, 1, 16])
gender torch.Size([4, 1])Visualise Posesposes=next(iter(llamass.core.IterableLoader(amass,batch_size=200,num_workers=2)))poses=poses['poses'].squeeze()# gaitplotlibimportnumpyasnpimportgaitplotlib.coreimportmatplotlib.pyplotaspltplt.style.use('ggplot')params=gaitplotlib.core.plottable(poses.numpy())defplot_pose(pose_index,save_to=None):fig,axes=plt.subplots(1,3,figsize=(10,6))ford,axinenumerate(axes):dims_to_plot=[iforiinrange(3)ifi!=d]joints,skeleton=params[pose_index]["joints"],params.skeletonj=joints[:,dims_to_plot]ax.scatter(*j.T,color="r",s=0.2)forboneinskeleton:a=j[bone[0]]b=j[bone[1]]x,y=list(zip(a,b))ax.plot(x,y,color="r",alpha=0.5)ax.axes.xaxis.set_ticklabels([])ax.axes.yaxis.set_ticklabels([])ax.set_aspect('equal',adjustable='box')ifsave_toisnotNone:plt.tight_layout()plt.savefig(save_to)plt.close()else:plt.show()plot_pose(0)# gaitplotlibfrompathlibimportPathimportmediapyasmediaanimloc=Path(unpacked_directory)/'anim'animloc.mkdir(exist_ok=True)defget_frame(i,frameloc=animloc/'frame.jpeg'):plot_pose(i,save_to=frameloc)returnmedia.read_image(frameloc)img_arr=get_frame(0)withmedia.VideoWriter(animloc/'anim.gif',codec='gif',shape=img_arr.shape[:2],fps=10)asw:foriinrange(0,params.vertices.shape[0],10):frameloc=animloc/'frame.jpeg'plot_pose(i,save_to=frameloc)img_arr=media.read_image(frameloc)w.add_image(img_arr)video=media.read_video(animloc/'anim.gif')media.show_video(video,codec='gif')To doTo do:Adapt to use fairmotionUse HuMoR's preprocessing and loss functions