├── .gitignore ├── MANIFEST.in ├── README.md ├── examples └── test.py ├── pyLasaDataset ├── __init__.py ├── dataset.py └── utilities.py ├── requirements.txt └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled python modules. 2 | *.pyc 3 | 4 | # *.pkl 5 | 6 | # Setuptools distribution folder. 7 | /dist/ 8 | 9 | # Python egg metadata, regenerated from source files by setuptools. 10 | /*.egg-info 11 | 12 | /build/ 13 | 14 | pyLasaDataset/resources/* 15 | 16 | /__pycache__/ 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include MANIFEST.in 2 | include README 3 | include setup.py 4 | recursive-include pyLasaDataset/resources/LASAHandwritingDataset/DataSet *.mat 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyLasaDataset [![PyPI](https://img.shields.io/pypi/v/pylasadataset?color=blue)](https://pypi.org/project/pylasadataset/) 2 | 3 | [LASA Handwriting dataset](https://bitbucket.org/khansari/lasahandwritingdataset) loader and other tools for Python 2 and Python 3. 4 | 5 | ## Installation 6 | 7 | ### Via pip 8 | 9 | `python3 -m pip install pylasadataset` 10 | 11 | Or 12 | 13 | `python3 -m pip install git+https://github.com/justagist/pylasadataset` 14 | 15 | 16 | ### Manual Install 17 | 18 | - Dependencies: `apt install python-tk`; `pip install numpy scipy matplotlib`. 19 | - Run `python setup.py install`. 20 | 21 | ## Usage 22 | 23 | ```python 24 | 25 | import pyLasaDataset as lasa 26 | 27 | # DataSet object has all the LASA handwriting data files 28 | # as attributes, eg: 29 | angle_data = lasa.DataSet.Angle 30 | sine_data = lasa.DataSet.Sine 31 | 32 | 33 | # Each Data object has attributes dt and demos (For documentation, 34 | # refer original dataset repo: 35 | # https://bitbucket.org/khansari/lasahandwritingdataset/src/master/Readme.txt) 36 | dt = angle_data.dt 37 | demos = angle_data.demos # list of 7 Demo objects, each corresponding to a 38 | # repetition of the pattern 39 | 40 | 41 | # Each Demo object in demos list will have attributes pos, t, vel, acc 42 | # corresponding to the original .mat format described in 43 | # https://bitbucket.org/khansari/lasahandwritingdataset/src/master/Readme.txt 44 | demo_0 = demos[0] 45 | pos = demo_0.pos # np.ndarray, shape: (2,2000) 46 | vel = demo_0.vel # np.ndarray, shape: (2,2000) 47 | acc = demo_0.acc # np.ndarray, shape: (2,2000) 48 | t = demo_0.t # np.ndarray, shape: (1,2000) 49 | 50 | 51 | # To visualise the data (2D position and velocity) use the plot_model utility 52 | lasa.utilities.plot_model(lasa.DataSet.BendedLine) # give any of the available 53 | # pattern data as argument 54 | 55 | ``` 56 | -------------------------------------------------------------------------------- /examples/test.py: -------------------------------------------------------------------------------- 1 | 2 | import pyLasaDataset as lasa 3 | 4 | # DataSet object has all the LASA handwriting data files 5 | # as attributes, eg: 6 | angle_data = lasa.DataSet.Angle 7 | sine_data = lasa.DataSet.Sine 8 | 9 | 10 | # Each Data object has attributes dt and demos (For documentation, 11 | # refer original dataset repo: 12 | # https://bitbucket.org/khansari/lasahandwritingdataset/src/master/Readme.txt) 13 | dt = angle_data.dt 14 | demos = angle_data.demos # list of 7 Demo objects, each corresponding to a 15 | # repetition of the pattern 16 | 17 | 18 | # Each Demo object in demos list will have attributes pos, t, vel, acc 19 | # corresponding to the original .mat format described in 20 | # https://bitbucket.org/khansari/lasahandwritingdataset/src/master/Readme.txt 21 | demo_0 = demos[0] 22 | pos = demo_0.pos # np.ndarray, shape: (2,2000) 23 | vel = demo_0.vel # np.ndarray, shape: (2,2000) 24 | acc = demo_0.acc # np.ndarray, shape: (2,2000) 25 | t = demo_0.t # np.ndarray, shape: (1,2000) 26 | 27 | 28 | # To visualise the model use the plot_model utility 29 | lasa.utilities.plot_model(lasa.DataSet.BendedLine) # give any of the available 30 | # pattern data as argument 31 | -------------------------------------------------------------------------------- /pyLasaDataset/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .dataset import DataSet 3 | from . import utilities -------------------------------------------------------------------------------- /pyLasaDataset/dataset.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | from scipy.io import loadmat 4 | 5 | DATASET_PATH_ = os.path.dirname(os.path.abspath(__file__)) + "/resources/LASAHandwritingDataset/DataSet" 6 | 7 | NAMES_ = [f[:-4] for f in os.listdir(DATASET_PATH_) if f[-4:] == ".mat"] 8 | 9 | if os.path.isdir(DATASET_PATH_): 10 | print ("Using LASA DataSet from {}".format(DATASET_PATH_)) 11 | else: 12 | raise IOError("Could not find LASA Dataset in path: {}".format(DATASET_PATH_)) 13 | 14 | class _Demo(object): 15 | """ 16 | Each demo object has attributes: 17 | 18 | pos : 2D cartesian position data. shape: (2,1000) 19 | t : corresponding time for each data point. shape: (1,1000) 20 | vel : 2D cartesian velocity data for motion. shape: (2,1000) 21 | acc : 2D cartesian acceleration data for motion. shape: (2,1000) 22 | 23 | """ 24 | def __init__(self, demo): 25 | 26 | 27 | typelist = str(np.asarray(demo[0][0].dtype)) 28 | typelist = typelist[1:-2].split(', ') 29 | idx = 0 30 | for att in typelist: 31 | if "'O'" in att: 32 | continue 33 | else: 34 | setattr(self, att[2:-1], demo[0][0][idx]) 35 | idx+=1 36 | 37 | assert idx == 5, "Reading data for demo failed" 38 | 39 | class _Data(object): 40 | """ 41 | Data object for each pattern has the following two attributes: 42 | 43 | dt : the average time steps across all demonstrations for this pattern 44 | demos : array of _Demo objects (len: 7) corresponding the trials for this pattern 45 | 46 | """ 47 | def __init__(self, matdata, name): 48 | self.name = name 49 | self.dt = matdata['dt'][0][0] 50 | self.demos = [_Demo(d) for d in matdata['demos'][0]] 51 | 52 | assert len(self.demos) == 7, "ERROR: Data for matdata could not be read properly." 53 | 54 | def __repr__(self): 55 | return str({'dt':self.dt, 'demos':self.demos}) 56 | 57 | @classmethod 58 | def get_data(cls, name): 59 | return cls(loadmat("{}/{}.mat".format(DATASET_PATH_,name)), name) 60 | 61 | 62 | class _PyLasaDataSet(object): 63 | 64 | def __getattr__(self, name): 65 | if name in NAMES_: 66 | return _Data.get_data(name) 67 | else: 68 | raise AttributeError("DataSet has no data named '{}'".format(name)) 69 | 70 | 71 | DataSet = _PyLasaDataSet() 72 | 73 | if __name__ == '__main__': 74 | a = DataSet.Angle 75 | b = DataSet.BendedLine 76 | -------------------------------------------------------------------------------- /pyLasaDataset/utilities.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def plot_model(data): 4 | 5 | import matplotlib.pyplot as plt 6 | 7 | pos_data = [d.pos for d in data.demos] 8 | speed_data = [np.sqrt(np.sum(d.vel**2,0)) for d in data.demos] 9 | 10 | # plt.plot(speed_data[0]) 11 | # plt.show() 12 | # plt.figure() 13 | fig = plt.figure() 14 | 15 | fig.suptitle(data.name, fontsize=16) 16 | 17 | f1_ax1 = plt.subplot(2,1,1) 18 | f1_ax1.set_title("Position Trajectory") 19 | 20 | f1_ax2 = plt.subplot(2,1,2) 21 | f1_ax2.set_title("Speed Profile") 22 | 23 | for i, vals in enumerate(pos_data): 24 | lines = f1_ax1.plot(vals[0,:], vals[1,:],'b') 25 | start = f1_ax1.scatter(vals[0,0], vals[1,0], c = 'k', marker = 'x') 26 | target = f1_ax1.scatter(vals[0,-1], vals[1,-1], c = 'k', marker = '*') 27 | f1_ax2.plot(speed_data[i],'b') 28 | 29 | start.set_label("Starting Points") 30 | target.set_label("Target") 31 | 32 | f1_ax1.set_xlabel("x (mm)") 33 | f1_ax1.set_ylabel("y (mm)") 34 | 35 | f1_ax2.set_xlabel("time (s)") 36 | f1_ax2.set_ylabel("speed (mm/s)") 37 | f1_ax1.legend() 38 | plt.axis('tight') 39 | plt.show() 40 | 41 | 42 | 43 | if __name__ == '__main__': 44 | import pyLasaDataset as lasa 45 | 46 | plot_model(lasa.DataSet.Angle) 47 | 48 | 49 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | scipy 3 | matplotlib -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # from setup_reqs import use_setuptools 2 | # use_setuptools() 3 | import os, subprocess 4 | from setuptools import setup, find_packages 5 | from distutils.core import setup 6 | 7 | def read(fname): 8 | return open(os.path.join(os.path.dirname(__file__), fname)).read() 9 | 10 | def clone_repo(): 11 | 12 | process = subprocess.Popen(['git', 'clone', 'https://bitbucket.org/khansari/lasahandwritingdataset.git', 'pyLasaDataset/resources/LASAHandwritingDataset'], 13 | stdout=subprocess.PIPE, 14 | universal_newlines=True) 15 | 16 | while True: 17 | output = process.stdout.readline() 18 | print(output.strip()) 19 | return_code = process.poll() 20 | if return_code is not None: 21 | print('RETURN CODE', return_code) 22 | # Process has finished, read rest of the output 23 | for output in process.stdout.readlines(): 24 | print(output.strip()) 25 | break 26 | 27 | clone_repo() 28 | 29 | setup( 30 | name = "pyLasaDataset", 31 | version = "0.1.1", 32 | author = "Saif Sidhik", 33 | author_email = "mail@saifsidhik.page", 34 | description = ("LASA Handwriting dataset loader and other tools for Python."), 35 | long_description_content_type="text/markdown", 36 | long_description=read("README.md"), 37 | license = "Public Domain", 38 | keywords = "handwriting dataset, python", 39 | url = "https://github.com/justagist/pyLasaDataset", 40 | project_urls = { 41 | "Bug Tracker": "https://github.com/justagist/pylasadataset/issues", 42 | "Documentation": "https://github.com/justagist/pyLasaDataset/blob/master/README.md", 43 | "Source Code": "https://github.com/justagist/pylasadataset", 44 | }, 45 | classifiers=[ 46 | "License :: Public Domain", 47 | "Topic :: Software Development :: Libraries :: Python Modules", 48 | ], 49 | packages=find_packages(), 50 | install_requires=[ 51 | 'scipy', 'numpy', 'matplotlib' 52 | ], 53 | include_package_data=True, 54 | ) 55 | --------------------------------------------------------------------------------