mirror of
https://github.com/wassname/pyrobolearn.git
synced 2026-10-29 13:30:12 +08:00
add dataset parsers
This commit is contained in:
1 parent
2598e973ab
commit
477c258cd7
20 files changed
+14147
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,54 @@
|
||||
## 3D datasets
|
||||
|
||||
This repo contains a brief description of 3D datasets that I could find online. It also contains the Python code to load, parse, and plot some of these datasets.
|
||||
|
||||
|
||||
### List of datasets
|
||||
|
||||
Here is a non-exhaustive list of datasets that could be used:
|
||||
|
||||
* [**TUM Kitchen**: "The TUM Kitchen Data Set of Everyday Manipulation Activities for Motion Tracking and Action Recognition", 2009](https://ias.in.tum.de/dokuwiki/software/kitchen-activity-data)
|
||||
* scenarios: "everyday manipulation activities in a natural kitchen environment"
|
||||
* labeled segmented data: 51 DOF articulated human model, 3D joint positions, videos and labels
|
||||
* [**CMU-MMAC**: "Guide to the Carnegie Mellon University Multimodal Activity database", 2009](http://kitchen.cs.cmu.edu/)
|
||||
* scenarios: human activity of subjects performing the tasks involved in cooking and food preparation
|
||||
* [**HumanEva**: "HumanEva: Synchronized Video and Motion Capture Dataset and Baseline Algorithm for Evaluation of Articulated Human Motion", 2010](http://humaneva.is.tue.mpg.de/)
|
||||
* 6 scenarios: walking, jogging, gesturing, throwing and catching a ball, boxing, combo (=walking+jogging+balancing)
|
||||
* nb of subjects: 4
|
||||
* data: 2D and 3D pose estimation
|
||||
* [**MPII Cooking**: "A database for fine grained activity detection of cooking activities", 2012](https://www.mpi-inf.mpg.de/departments/computer-vision-and-multimodal-computing/research/human-activity-recognition/mpii-cooking-activities-dataset/)
|
||||
<img src="figures/MPIICooking-comparison-datasets.png" alt="Datasets" style="width: 400px;"/>
|
||||
* nb of subjects: 12
|
||||
* 65 fine-grained cooking activities: background activity, change temperature, cut apart, cut dice, cut in, cut off ends, cut out inside, cut slices, cut stripes, dry, fill water from tap, grate, lid: put on, lid: remove, mix, move from X to Y, open egg, open tin, open/close cupboard, open/close drawer, open/close fridge, open/close oven, package X, peel, plug in/out, pour, pull out, puree, put in bowl, put in pan/pot, put on bread/dough, put on cutting-board, put on plate, read, remove from package, rip open, scratch off, screw close, screw open, shake, smell, spice, spread, squeeze, stamp, stir, strew, take & put in cupboard, take & put in drawer, take & put in fridge, take & put in oven, take & put in spice holder, take ingredient apart, take out from cupboard, take out from drawer, take out from fridge, take out from oven, take out from spice holder, taste, throw in garbage, unroll dough, wash hands, wash objects, whisk, wipe clean
|
||||
* labeled and segmented data: 2D body joint positions
|
||||
* [**J-HMDB**: "Joint-annotated Human Motion Data Base", 2013](http://jhmdb.is.tue.mpg.de/)
|
||||
<img src="figures/JHMDB-comparison-datasets.png" alt="Datasets" style="width: 400px;"/>
|
||||
* 21 scenarios: brush hair, catch, clap, climb stairs, golf, jump, kick ball, pick, pour, pull-up, push, run, shoot
|
||||
ball, shoot bow, shoot gun, sit, stand, swing baseball, throw, walk, wave
|
||||
* labeled and segmented data: 36-55 clips per action class with each clip containing 15-40 frames + 2D joint positions. 10 body parts connected by 13 joints (shoulder, elbow, wrist, hip, knee, ankle, neck) and two landmarks (face and belly).
|
||||
* [**Human 3.6M**: "Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments", 2014](http://vision.imar.ro/human3.6m/description.php)
|
||||
* 3.6 million 3D human poses and corresponding images
|
||||
* nb of subjects: 11
|
||||
* 15 scenarios: direction, discussion, eating, activitie while seated, greeting, taking photo, posing, making purchases, smoking, waiting, walking, sitting on chair, talking on the phone, walking dog, walking together
|
||||
* data: 3D joint positions and joint angles
|
||||
* [**UTD-MHAD**: "UTD-MHAD: A Multimodal Dataset for Human Action Recognition utilizing a Depth Camera and a Wearable Inertial Sensor", 2015](http://www.utdallas.edu/~kehtar/UTD-MHAD.html)
|
||||
* nb of subjects: 8
|
||||
* 27 different actions: (1) right arm swipe to the left, (2) right arm swipe to the right, (3) right hand wave, (4) two hand front clap, (5) right arm throw, (6) cross arms in the chest, (7) basketball shoot, (8) right hand draw x, (9) right hand draw circle (clockwise), (10) right hand draw circle (counter clockwise), (11) draw triangle, (12) bowling (right hand), (13) front boxing, (14) baseball swing from right, (15) tennis right hand forehand swing, (16) arm curl (two arms), (17) tennis serve, (18) two hand push, (19) right hand knock on door, (20) right hand catch an object, (21) right hand pick up and throw, (22) jogging in place, (23) walking in place, (24) sit to stand, (25) stand to sit, (26) forward lunge (left foot forward), (27) squat (two arms stretch out).
|
||||
* labeled and segmented data: 861 data sequences, 3D skeleton joint positions
|
||||
* [**G3D**: "G3D: A Gaming Action Dataset and Real Time Action Recognition Evaluation Framework", 2012](http://dipersec.king.ac.uk/G3D/index.html)
|
||||
* nb of subjects: 10
|
||||
* 20 gaming actions: punch right, punch left, kick right, kick left, defend, golf swing, tennis swing forehand, tennis swing backhand, tennis serve, throw bowling ball, aim and fire gun, walk, run, jump, climb, crouch, steer a car, wave, flap and clap
|
||||
* data: 3D joint positions
|
||||
* [**CMU-Datasets**](mocap.cs.cmu.edu/search.php)
|
||||
* dataset: very diverse, contains data such as sport activities (soccer, dancing, etc), everyday movements/activities, locomotion (walk/run, jump, etc), interaction with environment and other agents, human subjects imitating animal behaviors (such as snake, dog, chicken, etc), stretching, finegrained movements, and so on.
|
||||
* data: 3D joint positions and videos.
|
||||
* Others: MSRC-12 Kinect Gesture Datase, MPI HDM05 Motion Capture Database, MSR Action3D Database, VGG Human Pose Estimation datasets, etc.
|
||||
|
||||
|
||||
|
||||
### Python Code
|
||||
|
||||
The python code to load, parse, and plot (using animations) has been implemented for the following datasets:
|
||||
|
||||
* UTD-MHAD: see `utd-mhad.ipynb`
|
||||
* CMU-Datasets: see `cmu.ipynb`
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,338 @@
|
||||
# AST/ASF file generated using VICON BodyLanguage
|
||||
# -----------------------------------------------
|
||||
:version 1.10
|
||||
:name VICON
|
||||
:units
|
||||
mass 1.0
|
||||
length 0.45
|
||||
angle deg
|
||||
:documentation
|
||||
.ast/.asf automatically generated from VICON data using
|
||||
VICON BodyBuilder and BodyLanguage model FoxedUp or BRILLIANT.MOD
|
||||
:root
|
||||
order TX TY TZ RX RY RZ
|
||||
axis XYZ
|
||||
position 0 0 0
|
||||
orientation 0 0 0
|
||||
:bonedata
|
||||
begin
|
||||
id 1
|
||||
name lhipjoint
|
||||
direction 0.655637 -0.713449 0.247245
|
||||
length 2.52691
|
||||
axis 0 0 0 XYZ
|
||||
end
|
||||
begin
|
||||
id 2
|
||||
name lfemur
|
||||
direction 0.34202 -0.939693 0
|
||||
length 7.59371
|
||||
axis 0 0 20 XYZ
|
||||
dof rx ry rz
|
||||
limits (-160.0 20.0)
|
||||
(-70.0 70.0)
|
||||
(-60.0 70.0)
|
||||
end
|
||||
begin
|
||||
id 3
|
||||
name ltibia
|
||||
direction 0.34202 -0.939693 0
|
||||
length 7.28717
|
||||
axis 0 0 20 XYZ
|
||||
dof rx
|
||||
limits (-10.0 170.0)
|
||||
end
|
||||
begin
|
||||
id 4
|
||||
name lfoot
|
||||
direction 0.0886837 -0.243657 0.965798
|
||||
length 2.2218
|
||||
axis -90 7.62852e-016 20 XYZ
|
||||
dof rx rz
|
||||
limits (-45.0 90.0)
|
||||
(-70.0 20.0)
|
||||
end
|
||||
begin
|
||||
id 5
|
||||
name ltoes
|
||||
direction 1.53547e-011 -4.22004e-011 1
|
||||
length 1.11249
|
||||
axis -90 7.62852e-016 20 XYZ
|
||||
dof rx
|
||||
limits (-90.0 20.0)
|
||||
end
|
||||
begin
|
||||
id 6
|
||||
name rhipjoint
|
||||
direction -0.645062 -0.722004 0.250209
|
||||
length 2.49697
|
||||
axis 0 0 0 XYZ
|
||||
end
|
||||
begin
|
||||
id 7
|
||||
name rfemur
|
||||
direction -0.34202 -0.939693 0
|
||||
length 7.58734
|
||||
axis 0 0 -20 XYZ
|
||||
dof rx ry rz
|
||||
limits (-160.0 20.0)
|
||||
(-70.0 70.0)
|
||||
(-70.0 60.0)
|
||||
end
|
||||
begin
|
||||
id 8
|
||||
name rtibia
|
||||
direction -0.34202 -0.939693 0
|
||||
length 7.21538
|
||||
axis 0 0 -20 XYZ
|
||||
dof rx
|
||||
limits (-10.0 170.0)
|
||||
end
|
||||
begin
|
||||
id 9
|
||||
name rfoot
|
||||
direction -0.102907 -0.282735 0.953662
|
||||
length 2.23735
|
||||
axis -90 -7.62852e-016 -20 XYZ
|
||||
dof rx rz
|
||||
limits (-45.0 90.0)
|
||||
(-20.0 70.0)
|
||||
end
|
||||
begin
|
||||
id 10
|
||||
name rtoes
|
||||
direction -1.5354e-011 -4.21751e-011 1
|
||||
length 1.11569
|
||||
axis -90 -7.62852e-016 -20 XYZ
|
||||
dof rx
|
||||
limits (-90.0 20.0)
|
||||
end
|
||||
begin
|
||||
id 11
|
||||
name lowerback
|
||||
direction 0.00952301 0.997604 -0.0685217
|
||||
length 2.05943
|
||||
axis 0 0 0 XYZ
|
||||
dof rx ry rz
|
||||
limits (-20.0 45.0)
|
||||
(-30.0 30.0)
|
||||
(-30.0 30.0)
|
||||
end
|
||||
begin
|
||||
id 12
|
||||
name upperback
|
||||
direction 0.00494399 0.999577 -0.0286701
|
||||
length 2.06523
|
||||
axis 0 0 0 XYZ
|
||||
dof rx ry rz
|
||||
limits (-20.0 45.0)
|
||||
(-30.0 30.0)
|
||||
(-30.0 30.0)
|
||||
end
|
||||
begin
|
||||
id 13
|
||||
name thorax
|
||||
direction 0.000729686 0.999992 0.00388603
|
||||
length 2.06807
|
||||
axis 0 0 0 XYZ
|
||||
dof rx ry rz
|
||||
limits (-20.0 45.0)
|
||||
(-30.0 30.0)
|
||||
(-30.0 30.0)
|
||||
end
|
||||
begin
|
||||
id 14
|
||||
name lowerneck
|
||||
direction 0.00452882 0.995459 0.0950816
|
||||
length 1.57426
|
||||
axis 0 0 0 XYZ
|
||||
dof rx ry rz
|
||||
limits (-20.0 45.0)
|
||||
(-30.0 30.0)
|
||||
(-30.0 30.0)
|
||||
end
|
||||
begin
|
||||
id 15
|
||||
name upperneck
|
||||
direction 0.021922 0.997711 -0.0639762
|
||||
length 1.56399
|
||||
axis 0 0 0 XYZ
|
||||
dof rx ry rz
|
||||
limits (-20.0 45.0)
|
||||
(-30.0 30.0)
|
||||
(-30.0 30.0)
|
||||
end
|
||||
begin
|
||||
id 16
|
||||
name head
|
||||
direction 0.008024 0.999444 -0.0323691
|
||||
length 1.6265
|
||||
axis 0 0 0 XYZ
|
||||
dof rx ry rz
|
||||
limits (-20.0 45.0)
|
||||
(-30.0 30.0)
|
||||
(-30.0 30.0)
|
||||
end
|
||||
begin
|
||||
id 17
|
||||
name lclavicle
|
||||
direction 0.967826 0.247107 -0.0474446
|
||||
length 3.6598
|
||||
axis 0 0 0 XYZ
|
||||
dof ry rz
|
||||
limits (-20.0 10.0)
|
||||
(0.0 20.0)
|
||||
end
|
||||
begin
|
||||
id 18
|
||||
name lhumerus
|
||||
direction 1 -4.48971e-011 -2.90544e-027
|
||||
length 4.86513
|
||||
axis 180 -30 -90 XYZ
|
||||
dof rx ry rz
|
||||
limits (-60.0 90.0)
|
||||
(-90.0 90.0)
|
||||
(-90.0 90.0)
|
||||
end
|
||||
begin
|
||||
id 19
|
||||
name lradius
|
||||
direction 1 -4.48958e-011 1.79638e-026
|
||||
length 3.35554
|
||||
axis 180 -30 -90 XYZ
|
||||
dof rx
|
||||
limits (-10.0 170.0)
|
||||
end
|
||||
begin
|
||||
id 20
|
||||
name lwrist
|
||||
direction 1 -4.48952e-011 3.34345e-026
|
||||
length 1.67777
|
||||
axis -2.22354e-014 90 90 XYZ
|
||||
dof ry
|
||||
limits (-180.0 0.0)
|
||||
end
|
||||
begin
|
||||
id 21
|
||||
name lhand
|
||||
direction 1 -4.49055e-011 6.6869e-026
|
||||
length 0.661175
|
||||
axis -4.26681e-014 90 90 XYZ
|
||||
dof rx rz
|
||||
limits (-90.0 90.0)
|
||||
(-45.0 45.0)
|
||||
end
|
||||
begin
|
||||
id 22
|
||||
name lfingers
|
||||
direction 1 -4.48731e-011 1.33738e-025
|
||||
length 0.533057
|
||||
axis -8.53362e-014 90 90 XYZ
|
||||
dof rx
|
||||
limits (0.0 90.0)
|
||||
end
|
||||
begin
|
||||
id 23
|
||||
name lthumb
|
||||
direction 0.707107 -6.35005e-011 0.707107
|
||||
length 0.765366
|
||||
axis -90 45 2.85299e-015 XYZ
|
||||
dof rx rz
|
||||
limits (-45.0 45.0)
|
||||
(-45.0 45.0)
|
||||
end
|
||||
begin
|
||||
id 24
|
||||
name rclavicle
|
||||
direction -0.973174 0.211421 -0.0907389
|
||||
length 3.59444
|
||||
axis 0 0 0 XYZ
|
||||
dof ry rz
|
||||
limits (-10.0 20.0)
|
||||
(-20.0 0.0)
|
||||
end
|
||||
begin
|
||||
id 25
|
||||
name rhumerus
|
||||
direction -1 -4.48964e-011 1.56311e-027
|
||||
length 5.02649
|
||||
axis 180 30 90 XYZ
|
||||
dof rx ry rz
|
||||
limits (-90.0 60.0)
|
||||
(-90.0 90.0)
|
||||
(-90.0 90.0)
|
||||
end
|
||||
begin
|
||||
id 26
|
||||
name rradius
|
||||
direction -1 -4.48948e-011 2.01724e-026
|
||||
length 3.36431
|
||||
axis 180 30 90 XYZ
|
||||
dof rx
|
||||
limits (-10.0 170.0)
|
||||
end
|
||||
begin
|
||||
id 27
|
||||
name rwrist
|
||||
direction -1 -4.49008e-011 3.34345e-026
|
||||
length 1.68216
|
||||
axis -2.22354e-014 -90 -90 XYZ
|
||||
dof ry
|
||||
limits (-180.0 0.0)
|
||||
end
|
||||
begin
|
||||
id 28
|
||||
name rhand
|
||||
direction -1 -4.49013e-011 6.6869e-026
|
||||
length 0.730406
|
||||
axis -4.26681e-014 -90 -90 XYZ
|
||||
dof rx rz
|
||||
limits (-90.0 90.0)
|
||||
(-45.0 45.0)
|
||||
end
|
||||
begin
|
||||
id 29
|
||||
name rfingers
|
||||
direction -1 -4.48867e-011 1.33738e-025
|
||||
length 0.588872
|
||||
axis -8.53362e-014 -90 -90 XYZ
|
||||
dof rx
|
||||
limits (0.0 90.0)
|
||||
end
|
||||
begin
|
||||
id 30
|
||||
name rthumb
|
||||
direction -0.707107 -6.34907e-011 0.707107
|
||||
length 0.845506
|
||||
axis -90 -45 -2.85299e-015 XYZ
|
||||
dof rx rz
|
||||
limits (-45.0 45.0)
|
||||
(-45.0 45.0)
|
||||
end
|
||||
:hierarchy
|
||||
begin
|
||||
root lhipjoint rhipjoint lowerback
|
||||
lhipjoint lfemur
|
||||
lfemur ltibia
|
||||
ltibia lfoot
|
||||
lfoot ltoes
|
||||
rhipjoint rfemur
|
||||
rfemur rtibia
|
||||
rtibia rfoot
|
||||
rfoot rtoes
|
||||
lowerback upperback
|
||||
upperback thorax
|
||||
thorax lowerneck lclavicle rclavicle
|
||||
lowerneck upperneck
|
||||
upperneck head
|
||||
lclavicle lhumerus
|
||||
lhumerus lradius
|
||||
lradius lwrist
|
||||
lwrist lhand lthumb
|
||||
lhand lfingers
|
||||
rclavicle rhumerus
|
||||
rhumerus rradius
|
||||
rradius rwrist
|
||||
rwrist rhand rthumb
|
||||
rhand rfingers
|
||||
end
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,3 @@
|
||||
# CMU Dataset
|
||||
|
||||
* webpage (link to download the dataset): mocap.cs.cmu.edu/search.php
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
Subject #2 (various expressions and human behaviors)
|
||||
|
||||
02_01 02_01.tvd 02_01.c3d 02_01.amc 02_01.avi walk
|
||||
02_02 02_02.tvd 02_02.c3d 02_02.amc 02_02.mpg 02_02.avi walk
|
||||
02_03 02_03.tvd 02_03.c3d 02_03.amc 02_03.mpg 02_03.avi run/jog
|
||||
02_04 02_04.tvd 02_04.c3d 02_04.amc 02_04.mpg 02_04.avi jump, balance
|
||||
02_05 02_05.tvd 02_05.c3d 02_05.amc 02_05.mpg 02_05.avi punch/strike
|
||||
02_06 02_06.tvd 02_06.c3d 02_06.amc 02_06.mpg 02_06.avi bend over, scoop up, rise, lift arm
|
||||
02_07 02_07.tvd 02_07.c3d 02_07.amc 02_07.mpg 02_07.avi swordplay
|
||||
02_08 02_08.tvd 02_08.c3d 02_08.amc 02_08.mpg 02_08.avi swordplay
|
||||
02_09 02_09.tvd 02_09.c3d 02_09.amc 02_09.mpg 02_09.avi swordplay
|
||||
02_10 02_10.tvd 02_10.c3d 02_10.amc 02_10.mpg 02_10.avi wash self
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
The skeleton joint order in UTD-MAD dataset:
|
||||
|
||||
1. head;
|
||||
2. shoulder_center;
|
||||
3. spine;
|
||||
4. hip_center;
|
||||
5. left_shoulder;
|
||||
6. left_elbow;
|
||||
7. left_wrist;
|
||||
8. left_hand;
|
||||
9. right_shoulder;
|
||||
10. right_elbow;
|
||||
11. right_wrist;
|
||||
12. right_hand;
|
||||
13. left_hip;
|
||||
14. left_knee;
|
||||
15. left_ankle;
|
||||
16. left_foot;
|
||||
17. right_hip;
|
||||
18. right_knee;
|
||||
19. right_ankle;
|
||||
20. right_foot;
|
||||
|
||||
Each skeleton data is a 20 x 3 x num_frame matrix. Each row of a skeleton frame corresponds to three spatial coordinates of a joint.
|
||||
@@ -0,0 +1,3 @@
|
||||
# UTD-MHAD Dataset
|
||||
|
||||
* webpage (link to download the dataset): http://www.utdallas.edu/~kehtar/UTD-MHAD.html
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 108 KiB |
@@ -0,0 +1,230 @@
|
||||
import numpy as np
|
||||
from scipy.interpolate import CubicSpline
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
class MocapParser(object):
|
||||
|
||||
def __init__(self, filename):
|
||||
"""
|
||||
Parser for motion capture. By default, if the data is described in Cartesian space, the x-axis should
|
||||
be pointing in front of the human, the y-axis on his/her left, and z-axis upward.
|
||||
:param filename:
|
||||
"""
|
||||
self.filename = filename
|
||||
self.num_samples = 0
|
||||
self.joint_names = []
|
||||
self.link_names = []
|
||||
self.marker_names = []
|
||||
|
||||
self.data = self.loadFile(filename)
|
||||
|
||||
|
||||
def loadFile(self, filename):
|
||||
raise NotImplementedError("loadFile is not implemented.")
|
||||
|
||||
def interpolate(self, data, method='cubic', axis=-1)
|
||||
"""
|
||||
Interpolate the Mocap data such that it is between 0 and 1, along the given axis.
|
||||
|
||||
:param data: mocap data
|
||||
:param method: 'linear', 'cubic', 'hermite' interpolation
|
||||
:param axis: The axis on which to interpolate. The length should be equal to the number of samples in the
|
||||
mocap data
|
||||
:return: Interpolator - function that given the time [0,1] will give the corresponding data
|
||||
"""
|
||||
self.num_samples = data.shape[axis]
|
||||
x = np.linspace(0., 1., self.num_samples)
|
||||
interpolator = CubicSpline(x, self.data, axis=axis)
|
||||
return interpolator
|
||||
|
||||
def getMarkerName(self, marker_idx=None):
|
||||
if marker_idx is None:
|
||||
return self.getMarkerNames()
|
||||
else:
|
||||
return self.marker_names[marker_idx]
|
||||
|
||||
def getMarkerNames(self):
|
||||
return self.marker_names
|
||||
|
||||
def getJointName(self, joint_idx=None):
|
||||
if joint_idx is None:
|
||||
return self.getJointNames()
|
||||
else:
|
||||
return self.joint_names[joint_idx]
|
||||
|
||||
def getJointNames(self):
|
||||
return self.joint_names
|
||||
|
||||
def getLinkName(self, link_idx=None):
|
||||
if link_idx is None:
|
||||
return self.getLinkNames()
|
||||
else:
|
||||
return self.link_names[link_idx]
|
||||
|
||||
def getLinkNames(self):
|
||||
return self.link_names
|
||||
|
||||
def getMarkerPosition(self, marker_idx=None):
|
||||
if marker_idx is None:
|
||||
return self.getMarkerPositions()
|
||||
else:
|
||||
pass
|
||||
|
||||
def getMarkerPositions(self):
|
||||
pass
|
||||
|
||||
def getJointPosition(self, joint_idx=None):
|
||||
if joint_idx is None:
|
||||
return self.getJointPositions()
|
||||
else:
|
||||
pass
|
||||
|
||||
def getJointPositions(self):
|
||||
pass
|
||||
|
||||
def getJointVelocity(self, joint_idx=None):
|
||||
if joint_idx is None:
|
||||
return self.getJointVelocities()
|
||||
else:
|
||||
pass
|
||||
|
||||
def getJointVelocities(self):
|
||||
pass
|
||||
|
||||
def getLinkPosition(self, link_idx=None):
|
||||
if link_idx is None:
|
||||
return self.getLinkPositions()
|
||||
else:
|
||||
pass
|
||||
|
||||
def getLinkPositions(self):
|
||||
pass
|
||||
|
||||
def getLinkVelocity(self, link_idx=None):
|
||||
if link_idx is None:
|
||||
return self.getLinkVelocities()
|
||||
else:
|
||||
pass
|
||||
|
||||
def getLinkVelocities(self):
|
||||
pass
|
||||
|
||||
def getLinkOrientation(self, link_idx=None):
|
||||
if link_idx is None:
|
||||
return self.getLinkOrientations()
|
||||
else:
|
||||
pass
|
||||
|
||||
def getLinkOrientations(self):
|
||||
pass
|
||||
|
||||
def getLinkAngularVelocity(self, link_idx=None):
|
||||
if link_idx is None:
|
||||
return self.getLinkAngularVelocities()
|
||||
else:
|
||||
pass
|
||||
|
||||
def getLinkAngularVelocities(self):
|
||||
pass
|
||||
|
||||
|
||||
## Plotting ##
|
||||
def plot3d(self, ax=None):
|
||||
pass
|
||||
|
||||
def plotJointProfile(self, ax=None, joint_idx=None, pos=True, vel=True, acc=True):
|
||||
pass
|
||||
|
||||
def plotLinkProfile(self, ax=None, link_idx=None, pos=True, vel=True, acc=True, wrt='world'):
|
||||
pass
|
||||
|
||||
def plotMarkerProfile(self, ax=None, link_idx=None, pos=True, vel=True, acc=True, wrt='world'):
|
||||
pass
|
||||
|
||||
def animate3d(self, ax=None, title=None):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
from amcparser.skeleton import Skeleton
|
||||
from amcparser.motion import SkelMotion
|
||||
|
||||
class CMUMocapParser(MocapParser):
|
||||
|
||||
def __init__(self, skeleton_filename, motion_filename, skeleton_scale=1.0):
|
||||
super(CMUMocapParser, self).__init__(motion_filename)
|
||||
self.joint_names = ['head', 'upperneck', 'lowerneck', 'upperback', 'thorax', 'lowerback', 'root', # Spine
|
||||
'rclavicle', 'rhumerus', 'rradius', 'rwrist', 'rhand', 'rthumb', 'rfingers', # Right arm
|
||||
'lclavicle', 'lhumerus', 'lradius', 'lwrist', 'lhand', 'lthumb', 'lfingers', # Left arm
|
||||
'rhipjoint', 'rfemur', 'rtibia', 'rfoot', 'rtoes', # Right leg
|
||||
'lhipjoint', 'lfemur', 'ltibia', 'lfoot', 'ltoes'] # Left leg
|
||||
self.link_names = self.joint_names
|
||||
self.marker_names = self.joint_names
|
||||
self.base_name = 'root'
|
||||
|
||||
# Load skeleton
|
||||
self.skeleton = Skeleton(skeleton_filename, scale=skeleton_scale)
|
||||
|
||||
def loadFile(self, filename, framerate=120.):
|
||||
self.skeleton_motion = SkelMotion(self.skeleton, filename, (1./framerate))
|
||||
# compute trajectories
|
||||
#self.data = self.skeleton_motion.traverse(bone, start, end)
|
||||
self.data = self.skeleton_motion.traverse(None, 0, -1)
|
||||
# make sure that given axis
|
||||
|
||||
def animate3d(self, ax=None, title=None):
|
||||
if ax is None:
|
||||
fig = plt.figure()
|
||||
ax = fig.gca(projection='3d')
|
||||
|
||||
# Rescaling such that the skeleton it is in the right proportion and at the middle
|
||||
xmin, xmax = X[..., 2].min(), X[..., 2].max()
|
||||
ymin, ymax = X[..., 0].min(), X[..., 0].max()
|
||||
zmin, zmax = X[..., 1].min(), X[..., 1].max()
|
||||
x_len, y_len, z_len = (xmax - xmin), (ymax - ymin), (zmax - zmin)
|
||||
max_len = max([x_len, y_len, z_len])
|
||||
xmin, xmax = xmin + (x_len - max_len) / 2., xmin + (x_len + max_len) / 2.
|
||||
ymin, ymax = ymin + (y_len - max_len) / 2., ymin + (y_len + max_len) / 2.
|
||||
zmin, zmax = zmin + (z_len - max_len) / 2., zmin + (z_len + max_len) / 2.
|
||||
|
||||
# Plot trajectories
|
||||
x, y, z = skel.bones['rhand'].xyz_data.T
|
||||
T = len(x)
|
||||
|
||||
def init():
|
||||
ax.set_title('movement')
|
||||
ax.set_xlabel('x')
|
||||
ax.set_xlim(xmin, xmax)
|
||||
ax.set_ylabel('y')
|
||||
ax.set_ylim(ymin, ymax)
|
||||
ax.set_zlabel('z')
|
||||
ax.set_zlim(zmin, zmax)
|
||||
# ax.scatter(x[0], y[0], z[0], marker='o')
|
||||
return fig,
|
||||
|
||||
def animate(i):
|
||||
# ax.view_init(elev=10., azim=i)
|
||||
ax.scatter(x[i], y[i], z[i], marker='o')
|
||||
return fig,
|
||||
|
||||
def animate_skeleton(i):
|
||||
ax.clear()
|
||||
init()
|
||||
# ax.scatter(X[:,2,i], X[:,0,i], X[:,1,i], marker='o', c='b')
|
||||
for d in [X_TO, X_RA, X_LA, X_RL, X_LL]:
|
||||
ax.plot(d[:, i, 2], d[:, i, 0], d[:, i, 1], marker='o', c='b')
|
||||
return [fig] # fig,
|
||||
|
||||
# Animate
|
||||
# anim = animation.FuncAnimation(fig, animate, init_func=init,
|
||||
# frames=T, interval=20, blit=True)
|
||||
anim = animation.FuncAnimation(fig, animate_skeleton, init_func=init,
|
||||
frames=T, interval=20, blit=False)
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
# Test
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
@@ -0,0 +1,967 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### [UTD-MHAD: \"UTD-MHAD: A Multimodal Dataset for Human Action Recognition utilizing a Depth Camera and a Wearable Inertial Sensor\", 2015](http://www.utdallas.edu/~kehtar/UTD-MHAD.html)\n",
|
||||
"\n",
|
||||
"* nb of subjects: 8\n",
|
||||
"* 27 different actions: (1) right arm swipe to the left, (2) right arm swipe to the right, (3) right hand wave, (4) two hand front clap, (5) right arm throw, (6) cross arms in the chest, (7) basketball shoot, (8) right hand draw x, (9) right hand draw circle (clockwise), (10) right hand draw circle (counter clockwise), (11) draw triangle, (12) bowling (right hand), (13) front boxing, (14) baseball swing from right, (15) tennis right hand forehand swing, (16) arm curl (two arms), (17) tennis serve, (18) two hand push, (19) right hand knock on door, (20) right hand catch an object, (21) right hand pick up and throw, (22) jogging in place, (23) walking in place, (24) sit to stand, (25) stand to sit, (26) forward lunge (left foot forward), (27) squat (two arms stretch out).\n",
|
||||
"* labeled and segmented data: 861 data sequences, 3D skeleton joint positions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import scipy.io as sio\n",
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from mpl_toolkits.mplot3d import Axes3D\n",
|
||||
"import matplotlib.animation as animation\n",
|
||||
"import glob\n",
|
||||
"import re\n",
|
||||
"\n",
|
||||
"from IPython.display import HTML\n",
|
||||
"\n",
|
||||
"#%matplotlib inline\n",
|
||||
"%matplotlib notebook"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"PATH = 'data/UTD/*.mat'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Nb of demos: 861\n",
|
||||
"Min T: 41\n",
|
||||
"Max T: 125\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Definition of some variables\n",
|
||||
"id_to_jnt = ['head', 'shoulder_center', 'spine', 'hip_center', 'left_shoulder', 'left_elbow', 'left_wrist',\n",
|
||||
" 'left_hand', 'right_shoulder', 'right_elbow', 'right_wrist', 'right_hand', 'left_hip', 'left_knee',\n",
|
||||
" 'left_ankle', 'left_foot', 'right_hip', 'right_knee', 'right_ankle', 'right_foot']\n",
|
||||
"jnt_to_id = {name: idx for idx,name in enumerate(id_to_jnt)}\n",
|
||||
"id_to_action = ['Swipe left', 'Swipe right', 'Wave', 'Clap', 'Throw', 'Arm cross', 'Basketball shoot', \n",
|
||||
" 'Draw X', 'Draw circle (clockwise)', 'Draw circle (counter clockwise)',\n",
|
||||
" 'Draw triangle', 'Bowling', 'Boxing', 'Baseball swing', 'Tennis swing',\n",
|
||||
" 'Arm curl', 'Tennis serve', 'Push', 'Knock', 'Catch', 'Pickup and throw',\n",
|
||||
" 'Jog', 'Walk', 'Sit to stand', 'Stand to sit', 'Lunge', 'Squat']\n",
|
||||
"action_to_id = {name: idx for idx,name in enumerate(id_to_action)}\n",
|
||||
"Nj = len(id_to_jnt) # 20\n",
|
||||
"\n",
|
||||
"# Load all the data\n",
|
||||
"files = glob.glob(PATH)\n",
|
||||
"data = [sio.loadmat(f)['d_skel'] for f in files] # list of shape Njx3xT\n",
|
||||
"N = len(data)\n",
|
||||
"print(\"Nb of demos: %d\" % len(data))\n",
|
||||
"Ts = np.array([d.shape[2] for d in data])\n",
|
||||
"print(\"Min T: %d\" % np.min(Ts))\n",
|
||||
"print(\"Max T: %d\" % np.max(Ts))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/javascript": [
|
||||
"/* Put everything inside the global mpl namespace */\n",
|
||||
"window.mpl = {};\n",
|
||||
"\n",
|
||||
"mpl.get_websocket_type = function() {\n",
|
||||
" if (typeof(WebSocket) !== 'undefined') {\n",
|
||||
" return WebSocket;\n",
|
||||
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
||||
" return MozWebSocket;\n",
|
||||
" } else {\n",
|
||||
" alert('Your browser does not have WebSocket support.' +\n",
|
||||
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
||||
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
||||
" 'have to enable WebSockets in about:config.');\n",
|
||||
" };\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
||||
" this.id = figure_id;\n",
|
||||
"\n",
|
||||
" this.ws = websocket;\n",
|
||||
"\n",
|
||||
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
||||
"\n",
|
||||
" if (!this.supports_binary) {\n",
|
||||
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
||||
" if (warnings) {\n",
|
||||
" warnings.style.display = 'block';\n",
|
||||
" warnings.textContent = (\n",
|
||||
" \"This browser does not support binary websocket messages. \" +\n",
|
||||
" \"Performance may be slow.\");\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" this.imageObj = new Image();\n",
|
||||
"\n",
|
||||
" this.context = undefined;\n",
|
||||
" this.message = undefined;\n",
|
||||
" this.canvas = undefined;\n",
|
||||
" this.rubberband_canvas = undefined;\n",
|
||||
" this.rubberband_context = undefined;\n",
|
||||
" this.format_dropdown = undefined;\n",
|
||||
"\n",
|
||||
" this.image_mode = 'full';\n",
|
||||
"\n",
|
||||
" this.root = $('<div/>');\n",
|
||||
" this._root_extra_style(this.root)\n",
|
||||
" this.root.attr('style', 'display: inline-block');\n",
|
||||
"\n",
|
||||
" $(parent_element).append(this.root);\n",
|
||||
"\n",
|
||||
" this._init_header(this);\n",
|
||||
" this._init_canvas(this);\n",
|
||||
" this._init_toolbar(this);\n",
|
||||
"\n",
|
||||
" var fig = this;\n",
|
||||
"\n",
|
||||
" this.waiting = false;\n",
|
||||
"\n",
|
||||
" this.ws.onopen = function () {\n",
|
||||
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
||||
" fig.send_message(\"send_image_mode\", {});\n",
|
||||
" fig.send_message(\"refresh\", {});\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" this.imageObj.onload = function() {\n",
|
||||
" if (fig.image_mode == 'full') {\n",
|
||||
" // Full images could contain transparency (where diff images\n",
|
||||
" // almost always do), so we need to clear the canvas so that\n",
|
||||
" // there is no ghosting.\n",
|
||||
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||||
" }\n",
|
||||
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
||||
" };\n",
|
||||
"\n",
|
||||
" this.imageObj.onunload = function() {\n",
|
||||
" this.ws.close();\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
||||
"\n",
|
||||
" this.ondownload = ondownload;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._init_header = function() {\n",
|
||||
" var titlebar = $(\n",
|
||||
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
||||
" 'ui-helper-clearfix\"/>');\n",
|
||||
" var titletext = $(\n",
|
||||
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
||||
" 'text-align: center; padding: 3px;\"/>');\n",
|
||||
" titlebar.append(titletext)\n",
|
||||
" this.root.append(titlebar);\n",
|
||||
" this.header = titletext[0];\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._init_canvas = function() {\n",
|
||||
" var fig = this;\n",
|
||||
"\n",
|
||||
" var canvas_div = $('<div/>');\n",
|
||||
"\n",
|
||||
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
||||
"\n",
|
||||
" function canvas_keyboard_event(event) {\n",
|
||||
" return fig.key_event(event, event['data']);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
||||
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
||||
" this.canvas_div = canvas_div\n",
|
||||
" this._canvas_extra_style(canvas_div)\n",
|
||||
" this.root.append(canvas_div);\n",
|
||||
"\n",
|
||||
" var canvas = $('<canvas/>');\n",
|
||||
" canvas.addClass('mpl-canvas');\n",
|
||||
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
||||
"\n",
|
||||
" this.canvas = canvas[0];\n",
|
||||
" this.context = canvas[0].getContext(\"2d\");\n",
|
||||
"\n",
|
||||
" var rubberband = $('<canvas/>');\n",
|
||||
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
||||
"\n",
|
||||
" var pass_mouse_events = true;\n",
|
||||
"\n",
|
||||
" canvas_div.resizable({\n",
|
||||
" start: function(event, ui) {\n",
|
||||
" pass_mouse_events = false;\n",
|
||||
" },\n",
|
||||
" resize: function(event, ui) {\n",
|
||||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||||
" },\n",
|
||||
" stop: function(event, ui) {\n",
|
||||
" pass_mouse_events = true;\n",
|
||||
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
||||
" },\n",
|
||||
" });\n",
|
||||
"\n",
|
||||
" function mouse_event_fn(event) {\n",
|
||||
" if (pass_mouse_events)\n",
|
||||
" return fig.mouse_event(event, event['data']);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
||||
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
||||
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
||||
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
||||
"\n",
|
||||
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
||||
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
||||
"\n",
|
||||
" canvas_div.on(\"wheel\", function (event) {\n",
|
||||
" event = event.originalEvent;\n",
|
||||
" event['data'] = 'scroll'\n",
|
||||
" if (event.deltaY < 0) {\n",
|
||||
" event.step = 1;\n",
|
||||
" } else {\n",
|
||||
" event.step = -1;\n",
|
||||
" }\n",
|
||||
" mouse_event_fn(event);\n",
|
||||
" });\n",
|
||||
"\n",
|
||||
" canvas_div.append(canvas);\n",
|
||||
" canvas_div.append(rubberband);\n",
|
||||
"\n",
|
||||
" this.rubberband = rubberband;\n",
|
||||
" this.rubberband_canvas = rubberband[0];\n",
|
||||
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
||||
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
||||
"\n",
|
||||
" this._resize_canvas = function(width, height) {\n",
|
||||
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
||||
" // canvas in synch.\n",
|
||||
" canvas_div.css('width', width)\n",
|
||||
" canvas_div.css('height', height)\n",
|
||||
"\n",
|
||||
" canvas.attr('width', width);\n",
|
||||
" canvas.attr('height', height);\n",
|
||||
"\n",
|
||||
" rubberband.attr('width', width);\n",
|
||||
" rubberband.attr('height', height);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
||||
" // upon first draw.\n",
|
||||
" this._resize_canvas(600, 600);\n",
|
||||
"\n",
|
||||
" // Disable right mouse context menu.\n",
|
||||
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
||||
" return false;\n",
|
||||
" });\n",
|
||||
"\n",
|
||||
" function set_focus () {\n",
|
||||
" canvas.focus();\n",
|
||||
" canvas_div.focus();\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" window.setTimeout(set_focus, 100);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||||
" var fig = this;\n",
|
||||
"\n",
|
||||
" var nav_element = $('<div/>')\n",
|
||||
" nav_element.attr('style', 'width: 100%');\n",
|
||||
" this.root.append(nav_element);\n",
|
||||
"\n",
|
||||
" // Define a callback function for later on.\n",
|
||||
" function toolbar_event(event) {\n",
|
||||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||||
" }\n",
|
||||
" function toolbar_mouse_event(event) {\n",
|
||||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
||||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||||
"\n",
|
||||
" if (!name) {\n",
|
||||
" // put a spacer in here.\n",
|
||||
" continue;\n",
|
||||
" }\n",
|
||||
" var button = $('<button/>');\n",
|
||||
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
||||
" 'ui-button-icon-only');\n",
|
||||
" button.attr('role', 'button');\n",
|
||||
" button.attr('aria-disabled', 'false');\n",
|
||||
" button.click(method_name, toolbar_event);\n",
|
||||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||||
"\n",
|
||||
" var icon_img = $('<span/>');\n",
|
||||
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
||||
" icon_img.addClass(image);\n",
|
||||
" icon_img.addClass('ui-corner-all');\n",
|
||||
"\n",
|
||||
" var tooltip_span = $('<span/>');\n",
|
||||
" tooltip_span.addClass('ui-button-text');\n",
|
||||
" tooltip_span.html(tooltip);\n",
|
||||
"\n",
|
||||
" button.append(icon_img);\n",
|
||||
" button.append(tooltip_span);\n",
|
||||
"\n",
|
||||
" nav_element.append(button);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" var fmt_picker_span = $('<span/>');\n",
|
||||
"\n",
|
||||
" var fmt_picker = $('<select/>');\n",
|
||||
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
||||
" fmt_picker_span.append(fmt_picker);\n",
|
||||
" nav_element.append(fmt_picker_span);\n",
|
||||
" this.format_dropdown = fmt_picker[0];\n",
|
||||
"\n",
|
||||
" for (var ind in mpl.extensions) {\n",
|
||||
" var fmt = mpl.extensions[ind];\n",
|
||||
" var option = $(\n",
|
||||
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
||||
" fmt_picker.append(option)\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" // Add hover states to the ui-buttons\n",
|
||||
" $( \".ui-button\" ).hover(\n",
|
||||
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
||||
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
||||
" );\n",
|
||||
"\n",
|
||||
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
||||
" nav_element.append(status_bar);\n",
|
||||
" this.message = status_bar[0];\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
||||
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
||||
" // which will in turn request a refresh of the image.\n",
|
||||
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
||||
" properties['type'] = type;\n",
|
||||
" properties['figure_id'] = this.id;\n",
|
||||
" this.ws.send(JSON.stringify(properties));\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.send_draw_message = function() {\n",
|
||||
" if (!this.waiting) {\n",
|
||||
" this.waiting = true;\n",
|
||||
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||||
" var format_dropdown = fig.format_dropdown;\n",
|
||||
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
||||
" fig.ondownload(fig, format);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
||||
" var size = msg['size'];\n",
|
||||
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
||||
" fig._resize_canvas(size[0], size[1]);\n",
|
||||
" fig.send_message(\"refresh\", {});\n",
|
||||
" };\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
||||
" var x0 = msg['x0'];\n",
|
||||
" var y0 = fig.canvas.height - msg['y0'];\n",
|
||||
" var x1 = msg['x1'];\n",
|
||||
" var y1 = fig.canvas.height - msg['y1'];\n",
|
||||
" x0 = Math.floor(x0) + 0.5;\n",
|
||||
" y0 = Math.floor(y0) + 0.5;\n",
|
||||
" x1 = Math.floor(x1) + 0.5;\n",
|
||||
" y1 = Math.floor(y1) + 0.5;\n",
|
||||
" var min_x = Math.min(x0, x1);\n",
|
||||
" var min_y = Math.min(y0, y1);\n",
|
||||
" var width = Math.abs(x1 - x0);\n",
|
||||
" var height = Math.abs(y1 - y0);\n",
|
||||
"\n",
|
||||
" fig.rubberband_context.clearRect(\n",
|
||||
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
||||
"\n",
|
||||
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
||||
" // Updates the figure title.\n",
|
||||
" fig.header.textContent = msg['label'];\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
||||
" var cursor = msg['cursor'];\n",
|
||||
" switch(cursor)\n",
|
||||
" {\n",
|
||||
" case 0:\n",
|
||||
" cursor = 'pointer';\n",
|
||||
" break;\n",
|
||||
" case 1:\n",
|
||||
" cursor = 'default';\n",
|
||||
" break;\n",
|
||||
" case 2:\n",
|
||||
" cursor = 'crosshair';\n",
|
||||
" break;\n",
|
||||
" case 3:\n",
|
||||
" cursor = 'move';\n",
|
||||
" break;\n",
|
||||
" }\n",
|
||||
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
||||
" fig.message.textContent = msg['message'];\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
||||
" // Request the server to send over a new figure.\n",
|
||||
" fig.send_draw_message();\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
||||
" fig.image_mode = msg['mode'];\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||||
" // Called whenever the canvas gets updated.\n",
|
||||
" this.send_message(\"ack\", {});\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"// A function to construct a web socket function for onmessage handling.\n",
|
||||
"// Called in the figure constructor.\n",
|
||||
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
||||
" return function socket_on_message(evt) {\n",
|
||||
" if (evt.data instanceof Blob) {\n",
|
||||
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
||||
" * transferred with MIME type text/plain:\" errors on\n",
|
||||
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
||||
" * to be part of the websocket stream */\n",
|
||||
" evt.data.type = \"image/png\";\n",
|
||||
"\n",
|
||||
" /* Free the memory for the previous frames */\n",
|
||||
" if (fig.imageObj.src) {\n",
|
||||
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
||||
" fig.imageObj.src);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
||||
" evt.data);\n",
|
||||
" fig.updated_canvas_event();\n",
|
||||
" fig.waiting = false;\n",
|
||||
" return;\n",
|
||||
" }\n",
|
||||
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
||||
" fig.imageObj.src = evt.data;\n",
|
||||
" fig.updated_canvas_event();\n",
|
||||
" fig.waiting = false;\n",
|
||||
" return;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" var msg = JSON.parse(evt.data);\n",
|
||||
" var msg_type = msg['type'];\n",
|
||||
"\n",
|
||||
" // Call the \"handle_{type}\" callback, which takes\n",
|
||||
" // the figure and JSON message as its only arguments.\n",
|
||||
" try {\n",
|
||||
" var callback = fig[\"handle_\" + msg_type];\n",
|
||||
" } catch (e) {\n",
|
||||
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
||||
" return;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" if (callback) {\n",
|
||||
" try {\n",
|
||||
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
||||
" callback(fig, msg);\n",
|
||||
" } catch (e) {\n",
|
||||
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
" };\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
||||
"mpl.findpos = function(e) {\n",
|
||||
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
||||
" var targ;\n",
|
||||
" if (!e)\n",
|
||||
" e = window.event;\n",
|
||||
" if (e.target)\n",
|
||||
" targ = e.target;\n",
|
||||
" else if (e.srcElement)\n",
|
||||
" targ = e.srcElement;\n",
|
||||
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
||||
" targ = targ.parentNode;\n",
|
||||
"\n",
|
||||
" // jQuery normalizes the pageX and pageY\n",
|
||||
" // pageX,Y are the mouse positions relative to the document\n",
|
||||
" // offset() returns the position of the element relative to the document\n",
|
||||
" var x = e.pageX - $(targ).offset().left;\n",
|
||||
" var y = e.pageY - $(targ).offset().top;\n",
|
||||
"\n",
|
||||
" return {\"x\": x, \"y\": y};\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"/*\n",
|
||||
" * return a copy of an object with only non-object keys\n",
|
||||
" * we need this to avoid circular references\n",
|
||||
" * http://stackoverflow.com/a/24161582/3208463\n",
|
||||
" */\n",
|
||||
"function simpleKeys (original) {\n",
|
||||
" return Object.keys(original).reduce(function (obj, key) {\n",
|
||||
" if (typeof original[key] !== 'object')\n",
|
||||
" obj[key] = original[key]\n",
|
||||
" return obj;\n",
|
||||
" }, {});\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
||||
" var canvas_pos = mpl.findpos(event)\n",
|
||||
"\n",
|
||||
" if (name === 'button_press')\n",
|
||||
" {\n",
|
||||
" this.canvas.focus();\n",
|
||||
" this.canvas_div.focus();\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" var x = canvas_pos.x;\n",
|
||||
" var y = canvas_pos.y;\n",
|
||||
"\n",
|
||||
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
||||
" step: event.step,\n",
|
||||
" guiEvent: simpleKeys(event)});\n",
|
||||
"\n",
|
||||
" /* This prevents the web browser from automatically changing to\n",
|
||||
" * the text insertion cursor when the button is pressed. We want\n",
|
||||
" * to control all of the cursor setting manually through the\n",
|
||||
" * 'cursor' event from matplotlib */\n",
|
||||
" event.preventDefault();\n",
|
||||
" return false;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||||
" // Handle any extra behaviour associated with a key event\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
||||
"\n",
|
||||
" // Prevent repeat events\n",
|
||||
" if (name == 'key_press')\n",
|
||||
" {\n",
|
||||
" if (event.which === this._key)\n",
|
||||
" return;\n",
|
||||
" else\n",
|
||||
" this._key = event.which;\n",
|
||||
" }\n",
|
||||
" if (name == 'key_release')\n",
|
||||
" this._key = null;\n",
|
||||
"\n",
|
||||
" var value = '';\n",
|
||||
" if (event.ctrlKey && event.which != 17)\n",
|
||||
" value += \"ctrl+\";\n",
|
||||
" if (event.altKey && event.which != 18)\n",
|
||||
" value += \"alt+\";\n",
|
||||
" if (event.shiftKey && event.which != 16)\n",
|
||||
" value += \"shift+\";\n",
|
||||
"\n",
|
||||
" value += 'k';\n",
|
||||
" value += event.which.toString();\n",
|
||||
"\n",
|
||||
" this._key_event_extra(event, name);\n",
|
||||
"\n",
|
||||
" this.send_message(name, {key: value,\n",
|
||||
" guiEvent: simpleKeys(event)});\n",
|
||||
" return false;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
||||
" if (name == 'download') {\n",
|
||||
" this.handle_save(this, null);\n",
|
||||
" } else {\n",
|
||||
" this.send_message(\"toolbar_button\", {name: name});\n",
|
||||
" }\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
||||
" this.message.textContent = tooltip;\n",
|
||||
"};\n",
|
||||
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
||||
"\n",
|
||||
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
||||
"\n",
|
||||
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
||||
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
||||
" // object with the appropriate methods. Currently this is a non binary\n",
|
||||
" // socket, so there is still some room for performance tuning.\n",
|
||||
" var ws = {};\n",
|
||||
"\n",
|
||||
" ws.close = function() {\n",
|
||||
" comm.close()\n",
|
||||
" };\n",
|
||||
" ws.send = function(m) {\n",
|
||||
" //console.log('sending', m);\n",
|
||||
" comm.send(m);\n",
|
||||
" };\n",
|
||||
" // Register the callback with on_msg.\n",
|
||||
" comm.on_msg(function(msg) {\n",
|
||||
" //console.log('receiving', msg['content']['data'], msg);\n",
|
||||
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
||||
" ws.onmessage(msg['content']['data'])\n",
|
||||
" });\n",
|
||||
" return ws;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
||||
" // This is the function which gets called when the mpl process\n",
|
||||
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
||||
"\n",
|
||||
" var id = msg.content.data.id;\n",
|
||||
" // Get hold of the div created by the display call when the Comm\n",
|
||||
" // socket was opened in Python.\n",
|
||||
" var element = $(\"#\" + id);\n",
|
||||
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
||||
"\n",
|
||||
" function ondownload(figure, format) {\n",
|
||||
" window.open(figure.imageObj.src);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" var fig = new mpl.figure(id, ws_proxy,\n",
|
||||
" ondownload,\n",
|
||||
" element.get(0));\n",
|
||||
"\n",
|
||||
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
||||
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
||||
" ws_proxy.onopen();\n",
|
||||
"\n",
|
||||
" fig.parent_element = element.get(0);\n",
|
||||
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
||||
" if (!fig.cell_info) {\n",
|
||||
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
||||
" return;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" var output_index = fig.cell_info[2]\n",
|
||||
" var cell = fig.cell_info[0];\n",
|
||||
"\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
||||
" fig.root.unbind('remove')\n",
|
||||
"\n",
|
||||
" // Update the output cell to use the data from the current canvas.\n",
|
||||
" fig.push_to_output();\n",
|
||||
" var dataURL = fig.canvas.toDataURL();\n",
|
||||
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
||||
" // the notebook keyboard shortcuts fail.\n",
|
||||
" IPython.keyboard_manager.enable()\n",
|
||||
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
||||
" fig.close_ws(fig, msg);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
||||
" fig.send_message('closing', msg);\n",
|
||||
" // fig.ws.close()\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
||||
" // Turn the data on the canvas into data in the output cell.\n",
|
||||
" var dataURL = this.canvas.toDataURL();\n",
|
||||
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
||||
" // Tell IPython that the notebook contents must change.\n",
|
||||
" IPython.notebook.set_dirty(true);\n",
|
||||
" this.send_message(\"ack\", {});\n",
|
||||
" var fig = this;\n",
|
||||
" // Wait a second, then push the new image to the DOM so\n",
|
||||
" // that it is saved nicely (might be nice to debounce this).\n",
|
||||
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._init_toolbar = function() {\n",
|
||||
" var fig = this;\n",
|
||||
"\n",
|
||||
" var nav_element = $('<div/>')\n",
|
||||
" nav_element.attr('style', 'width: 100%');\n",
|
||||
" this.root.append(nav_element);\n",
|
||||
"\n",
|
||||
" // Define a callback function for later on.\n",
|
||||
" function toolbar_event(event) {\n",
|
||||
" return fig.toolbar_button_onclick(event['data']);\n",
|
||||
" }\n",
|
||||
" function toolbar_mouse_event(event) {\n",
|
||||
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
||||
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
||||
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
||||
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
||||
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
||||
"\n",
|
||||
" if (!name) { continue; };\n",
|
||||
"\n",
|
||||
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
||||
" button.click(method_name, toolbar_event);\n",
|
||||
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
||||
" nav_element.append(button);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" // Add the status bar.\n",
|
||||
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
||||
" nav_element.append(status_bar);\n",
|
||||
" this.message = status_bar[0];\n",
|
||||
"\n",
|
||||
" // Add the close button to the window.\n",
|
||||
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
||||
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
||||
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
||||
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
||||
" buttongrp.append(button);\n",
|
||||
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
||||
" titlebar.prepend(buttongrp);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
||||
" var fig = this\n",
|
||||
" el.on(\"remove\", function(){\n",
|
||||
"\tfig.close_ws(fig, {});\n",
|
||||
" });\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
||||
" // this is important to make the div 'focusable\n",
|
||||
" el.attr('tabindex', 0)\n",
|
||||
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
||||
" // off when our div gets focus\n",
|
||||
"\n",
|
||||
" // location in version 3\n",
|
||||
" if (IPython.notebook.keyboard_manager) {\n",
|
||||
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
||||
" }\n",
|
||||
" else {\n",
|
||||
" // location in version 2\n",
|
||||
" IPython.keyboard_manager.register_events(el);\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
||||
" var manager = IPython.notebook.keyboard_manager;\n",
|
||||
" if (!manager)\n",
|
||||
" manager = IPython.keyboard_manager;\n",
|
||||
"\n",
|
||||
" // Check for shift+enter\n",
|
||||
" if (event.shiftKey && event.which == 13) {\n",
|
||||
" this.canvas_div.blur();\n",
|
||||
" event.shiftKey = false;\n",
|
||||
" // Send a \"J\" for go to next cell\n",
|
||||
" event.which = 74;\n",
|
||||
" event.keyCode = 74;\n",
|
||||
" manager.command_mode();\n",
|
||||
" manager.handle_keydown(event);\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
||||
" fig.ondownload(fig, null);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"mpl.find_output_cell = function(html_output) {\n",
|
||||
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
||||
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
||||
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
||||
" // our purposes (turning an active figure into a static one), is too late.\n",
|
||||
" var cells = IPython.notebook.get_cells();\n",
|
||||
" var ncells = cells.length;\n",
|
||||
" for (var i=0; i<ncells; i++) {\n",
|
||||
" var cell = cells[i];\n",
|
||||
" if (cell.cell_type === 'code'){\n",
|
||||
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
||||
" var data = cell.output_area.outputs[j];\n",
|
||||
" if (data.data) {\n",
|
||||
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
||||
" data = data.data;\n",
|
||||
" }\n",
|
||||
" if (data['text/html'] == html_output) {\n",
|
||||
" return [cell, data, j];\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"// Register the function which deals with the matplotlib target/channel.\n",
|
||||
"// The kernel may be null if the page has been refreshed.\n",
|
||||
"if (IPython.notebook.kernel != null) {\n",
|
||||
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
||||
"}\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Javascript object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<img src=\"data:image/png;base64,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 truncated
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Select a sequence\n",
|
||||
"idx = np.random.randint(0, N)\n",
|
||||
"X = np.copy(data[idx])\n",
|
||||
"T = X.shape[2]\n",
|
||||
"title_idx = int(re.findall(r'a[0-9]+', files[idx])[0][1:]) - 1\n",
|
||||
"\n",
|
||||
"# Get trajectory of one end-effector (x,y,z)\n",
|
||||
"#x,y,z = X[jnt_to_id['right_wrist']] # left_arm\n",
|
||||
"#x,y,z = z,x,y\n",
|
||||
"#T = len(x)\n",
|
||||
"\n",
|
||||
"# Rescaling such that the skeleton it is in the right proportion and at the middle\n",
|
||||
"xmin, xmax = X[:,2].min(), X[:,2].max()\n",
|
||||
"ymin, ymax = X[:,0].min(), X[:,0].max()\n",
|
||||
"zmin, zmax = X[:,1].min(), X[:,1].max()\n",
|
||||
"x_len, y_len, z_len = (xmax - xmin), (ymax - ymin), (zmax - zmin)\n",
|
||||
"max_len = max([x_len, y_len, z_len])\n",
|
||||
"xmin, xmax = xmin + (x_len - max_len)/2., xmin + (x_len + max_len)/2.\n",
|
||||
"ymin, ymax = ymin + (y_len - max_len)/2., ymin + (y_len + max_len)/2.\n",
|
||||
"zmin, zmax = zmin + (z_len - max_len)/2., zmin + (z_len + max_len)/2.\n",
|
||||
"\n",
|
||||
"# Plot trajectory\n",
|
||||
"fig = plt.figure()\n",
|
||||
"ax = fig.gca(projection='3d')\n",
|
||||
"\n",
|
||||
"def init():\n",
|
||||
" ax.set_title(id_to_action[title_idx])\n",
|
||||
" ax.set_xlabel('x')\n",
|
||||
" #ax.set_xlim(xmin, xmax)\n",
|
||||
" ax.set_xlim(-xmax, -xmin)\n",
|
||||
" ax.set_ylabel('y')\n",
|
||||
" ax.set_ylim(ymin, ymax)\n",
|
||||
" ax.set_zlabel('z')\n",
|
||||
" ax.set_zlim(zmin, zmax)\n",
|
||||
" #ax.scatter(x[0], y[0], z[0], marker='o')\n",
|
||||
" return fig,\n",
|
||||
"\n",
|
||||
"def animate(i):\n",
|
||||
" #ax.view_init(elev=10., azim=i)\n",
|
||||
" ax.scatter(-x[i], y[i], z[i], marker='o')\n",
|
||||
" return fig,\n",
|
||||
" \n",
|
||||
"def animate_skeleton(i):\n",
|
||||
" ax.clear()\n",
|
||||
" init()\n",
|
||||
" #ax.scatter(X[:,2,i], X[:,0,i], X[:,1,i], marker='o', c='b')\n",
|
||||
" for j in range(0,20,4):\n",
|
||||
" ax.plot(-X[j:j+4,2,i], X[j:j+4,0,i], X[j:j+4,1,i], marker='o', c='b')\n",
|
||||
" return fig,\n",
|
||||
" \n",
|
||||
"\n",
|
||||
"# Animate\n",
|
||||
"#anim = animation.FuncAnimation(fig, animate, init_func=init,\n",
|
||||
"# frames=T, interval=20, blit=True)\n",
|
||||
"anim = animation.FuncAnimation(fig, animate_skeleton, init_func=init,\n",
|
||||
" frames=T, interval=20, blit=True)\n",
|
||||
"\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# create video with HTML\n",
|
||||
"#HTML(anim.to_html5_video())"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 2",
|
||||
"language": "python",
|
||||
"name": "python2"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# HWRT Database of Handwritten symbols
|
||||
|
||||
* webpage: www.martin-thoma.de/write-math/data/
|
||||
* link to download the dataset: i13pc106.ira.uka.de/~mthoma/hwrt/2015-01-28-data.tar
|
||||
@@ -0,0 +1,7 @@
|
||||
# IAM Online Handwriting Database
|
||||
|
||||
* webpage: www.fki.inf.unibe.ch/databases/iam-on-line-handwriting-database
|
||||
* link to download the dataset: http://www.fki.inf.unibe.ch/databases/iam-on-line-handwriting-database/download-the-iam-on-line-handwriting-database
|
||||
|
||||
Note that you need to register in order to download the datasets.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# ICDAR2013 - Handwriting Stroke Recovery from Offline Data (Kaggle)
|
||||
|
||||
* webpage: https://www.kaggle.com/c/icdar2013-stroke-recovery-from-offline-data
|
||||
* link to download the dataset: https://www.kaggle.com/c/icdar2013-stroke-recovery-from-offline-data/data
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
## Online Handwritten Datasets
|
||||
|
||||
This repo contains the python code to load, parse and plot online handwritten characters.
|
||||
|
||||
In this folder, I focus on the following datasets:
|
||||
|
||||
1. Character Trajectories Data Set (2,858): https://archive.ics.uci.edu/ml/datasets/Character+Trajectories
|
||||
2. UJI Pen Characters (V2) Data Set (11,640): archive.ics.uci.edu/ml/datasets/UJI+Pen+Characters+(Version+2)
|
||||
3. HWRT Database of Handwritten symbols: www.martin-thoma.de/write-math/data/
|
||||
4. ICDAR2013 - Handwriting Stroke Recovery from Offline Data (Kaggle): https://www.kaggle.com/c/icdar2013-stroke-recovery-from-offline-data
|
||||
5. IAM Online Handwriting Database: www.fki.inf.unibe.ch/databases/iam-on-line-handwriting-database
|
||||
|
||||
|
||||
There are of course other datasets (mostly offline) that could be used such as:
|
||||
|
||||
* MNIST dataset (Offline)
|
||||
* NIST Handprinted Forms and Characters Database (Offline)
|
||||
* The IRESTE On/Off Dual Handwriting Database (75€): www.irccyn.ec-nantes.fr/~viardgau/IRONOFF/ICDAR99.htm
|
||||
* UCI online datasets:
|
||||
* Online Handwritten Assamese Characters Dataset (8,235): archive.ics.uci.edu/ml/datasets/Online+Handwritten+Assamese+Characters+Dataset
|
||||
* Pen-Based Recognition of Handwritten Digits Dataset (10,992): archive.ics.uci.edu/ml/datasets/Pen-Based+Recognition+of+Handwritten+Digits
|
||||
* CASIA online and offline chinese handwriting Databases: www.nlpr.ia.ac.cn/databases/handwriting/Online_database.html
|
||||
* CEDAR Handwriting (Offline)
|
||||
|
||||
|
||||
## How to use it?
|
||||
|
||||
The whole python code to load and parse the different datasets is inside the jupyter notebook `handwritten-data.ipynb`. To open the jupyter notebook, you will first need to install jupyter. For each dataset, I plotted 25 random samples to give you a general feeling about the dataset. You will need to download the dataset that you which to use (and put it in the corresponding folder if you do not wish to modify the python code).
|
||||
|
||||
|
||||
## FAQs
|
||||
|
||||
* What is the meaning of 'online'? Online in this case means that you also have the trajectories (x,y), while offline would mean that you only have pictures of handwritten characters/words/sentences.
|
||||
|
||||
* Do I need to cite the dataset that I am using? Yes, you should cite the corresponding paper which can usually be found on the website where you downloaded the dataset.
|
||||
|
||||
* For what can I use these datasets? Mostly for demonstration / supervised learning. You could, for instance, use one of the following models to learn the trajectories: Gaussian Processes, Gaussian Mixture Models, Hidden Markov Models, (Deep) Neural Networks, Dynamic Movement Primitives, etc.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Character Trajectories Data Set
|
||||
|
||||
* webpage: https://archive.ics.uci.edu/ml/datasets/Character+Trajectories
|
||||
* link to download the dataset: https://archive.ics.uci.edu/ml/machine-learning-databases/character-trajectories/
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# UJI Pen Characters (V2) Data Set
|
||||
|
||||
* webpage: archive.ics.uci.edu/ml/datasets/UJI+Pen+Characters+(Version+2)
|
||||
* link to download the dataset: http://archive.ics.uci.edu/ml/machine-learning-databases/uji-penchars/version2/
|
||||
@@ -0,0 +1,388 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Online Handwritten Datasets\n",
|
||||
"\n",
|
||||
"### Table of Contents\n",
|
||||
"\n",
|
||||
"1. [UCI - Character Trajectories Data Set](#uci-character)\n",
|
||||
"2. [UCI - UJI Pen Characters (V2) Data Set](#uci-ujipen)\n",
|
||||
"3. [HWRT Database of Handwritten symbols](#hwrt)\n",
|
||||
"4. [ICDAR2013 - Handwriting Stroke Recovery from Offline Data (Kaggle)](#kaggle)\n",
|
||||
"5. [IAM Online Handwriting Database](#IAMonline)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import pandas as pd\n",
|
||||
"import scipy.io\n",
|
||||
"from scipy import misc\n",
|
||||
"from ast import literal_eval\n",
|
||||
"\n",
|
||||
"%matplotlib inline"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## [UCI - Character Trajectories Data Set](https://archive.ics.uci.edu/ml/datasets/Character+Trajectories ) <a id='uci-character'></a>\n",
|
||||
"\n",
|
||||
"* Size: 2,858\n",
|
||||
"* Short description: single stroke trajectories sampled at 200Hz."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7ff3bdecd590>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"uci_char_path = 'UCI-Character-Trajectories/mixoutALL_shifted.mat'\n",
|
||||
"\n",
|
||||
"# Load the data\n",
|
||||
"uci_char = scipy.io.loadmat(uci_char_path)\n",
|
||||
"#print(uci_char.keys()) # ['mixout', '__version__', '__header__', 'consts', '__globals__']\n",
|
||||
"N = uci_char['mixout'].shape[1]\n",
|
||||
"uci_char = uci_char['mixout'][0]\n",
|
||||
"\n",
|
||||
"# Get a list of (x,y) for each data\n",
|
||||
"data = []\n",
|
||||
"for ex in uci_char:\n",
|
||||
" x = [ex[0,i] for i,force_value in enumerate(ex[2]) if force_value != 0.0]\n",
|
||||
" y = [ex[1,i] for i,force_value in enumerate(ex[2]) if force_value != 0.0]\n",
|
||||
" data.append(np.array([x,y]))\n",
|
||||
"\n",
|
||||
"# Choose randomly 25 characters and plot them\n",
|
||||
"idx = np.random.choice(N, 25, replace=False)\n",
|
||||
"data = [data[i] for i in idx]\n",
|
||||
"plt.figure(figsize=(8,8))\n",
|
||||
"for i,d in enumerate(data):\n",
|
||||
" plt.subplot(5,5,i+1)\n",
|
||||
" plt.axis('off')\n",
|
||||
" plt.plot(d[0], d[1])\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## [UCI - UJI Pen Characters (V2) Data Set](archive.ics.uci.edu/ml/datasets/UJI+Pen+Characters+(Version+2)) <a id='uci-ujipen'></a>\n",
|
||||
"\n",
|
||||
"* Size: 11,640 (Single stroke = 5,973)\n",
|
||||
"* Short description: Single and multi-stroke characters and digits"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7ff3bab85b90>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ujipen_path = 'UCI-Ujipen-Chars2/ujipenchars2.txt'\n",
|
||||
"\n",
|
||||
"# Load and parse the data\n",
|
||||
"num_stroke = 0\n",
|
||||
"data = []\n",
|
||||
"with open(ujipen_path, 'rb') as f:\n",
|
||||
" for line in f.readlines():\n",
|
||||
" line = line.strip() # remove extra space before and after the sentence\n",
|
||||
" if not line.startswith('//'): # Not a comment\n",
|
||||
" if line.startswith('NUMSTROKES'): # check the nb of strokes\n",
|
||||
" num_stroke = int(line[-1])\n",
|
||||
" elif line.startswith('POINTS') and num_stroke == 1: # only keep single stroke characters\n",
|
||||
" hash_idx = line.find('#')\n",
|
||||
" coord = map(int, line[hash_idx+2:].split())\n",
|
||||
" x = coord[::2]\n",
|
||||
" y = coord[1::2]\n",
|
||||
" data.append(np.array([x,y]))\n",
|
||||
"\n",
|
||||
"#print(len(data))\n",
|
||||
"\n",
|
||||
"# Choose randomly 25 characters and plot them\n",
|
||||
"idx = np.random.choice(len(data), 25, replace=False)\n",
|
||||
"data = [data[i] for i in idx]\n",
|
||||
"plt.figure(figsize=(8,8))\n",
|
||||
"for i,d in enumerate(data):\n",
|
||||
" plt.subplot(5,5,i+1)\n",
|
||||
" plt.axis('off')\n",
|
||||
" plt.plot(d[0], d[1][::-1]) # note that the y coordinates goes from 'up' to 'bottom'\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## [HWRT Database of Handwritten symbols](www.martin-thoma.de/write-math/data/) <a id='hwrt'></a>\n",
|
||||
"\n",
|
||||
"* Size: 151,160 (training data), 17,075 (test data)\n",
|
||||
"* Short description: \"on-line data of handwritten symbols such as all alphanumeric characters, arrows, greek characters and mathematical symbols like the integral symbol\"\n",
|
||||
"* Note: this dataset contains single and multiple strokes characters."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7ff3bbd75f10>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"hwrt_path = 'HWRT/train-data.csv'\n",
|
||||
"#hwrt_path = 'HWRT/test-data.csv'\n",
|
||||
"\n",
|
||||
"# Read the csv file. WARNING: do not load the whole file!\n",
|
||||
"# Header: symbol_id; user_id; data; user_agent\n",
|
||||
"data = pd.read_csv(hwrt_path, sep=';', quotechar=\"'\", index_col=False, skiprows=0, nrows=2000)\n",
|
||||
"# transform the string '[[{},{}]]' into a list of list of dict\n",
|
||||
"data.data = data.data.apply(literal_eval)\n",
|
||||
"\n",
|
||||
"# Get a list of (x,y) for each data\n",
|
||||
"xy = []\n",
|
||||
"for i,ex in enumerate(data['data']):\n",
|
||||
" if len(ex) == 1: # single stroke\n",
|
||||
" x = [dic['x'] for dic in ex[0]]\n",
|
||||
" y = [dic['y'] for dic in ex[0]]\n",
|
||||
" xy.append([x,y])\n",
|
||||
"\n",
|
||||
"# Choose randomly 25 characters and plot them\n",
|
||||
"idx = np.random.choice(len(xy), 25, replace=False)\n",
|
||||
"xy = [xy[i] for i in idx]\n",
|
||||
"plt.figure(figsize=(8,8))\n",
|
||||
"for i,d in enumerate(xy):\n",
|
||||
" plt.subplot(5,5,i+1)\n",
|
||||
" plt.axis('off')\n",
|
||||
" plt.plot(d[0], d[1][::-1])\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## [ICDAR2013 - Handwriting Stroke Recovery from Offline Data (Kaggle)](https://www.kaggle.com/c/icdar2013-stroke-recovery-from-offline-data) <a id='kaggle'></a>\n",
|
||||
"\n",
|
||||
"* Size: 1,081 (training: 605, test: 476)\n",
|
||||
"* Short description: \"the data consists of 1,081 (arabic) signatures of 200 writers\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7ff3bac78790>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7ff3b2673d90>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"icdar_traj_path = 'ICDAR2013/train.csv' # normalized data (0,1)\n",
|
||||
"#icdar_traj_path = 'ICDAR2013/unnormalized_data.csv' # unnormalized data\n",
|
||||
"icdar_img_path = 'ICDAR2013/images-handwritten/'\n",
|
||||
"\n",
|
||||
"# Read the csv file. WARNING: do not load the whole file!\n",
|
||||
"# Header: train_id, signature_id, writer_id, occurence_id, time, x, y\n",
|
||||
"data = pd.read_csv(icdar_traj_path, sep=',') #, skiprows=0, nrows=2000)\n",
|
||||
"#print(data.dtypes)\n",
|
||||
"\n",
|
||||
"# Get a list of (x,y) for each data\n",
|
||||
"N = data['signature_id'].max()\n",
|
||||
"xy = []\n",
|
||||
"for i in range(N):\n",
|
||||
" d = data.loc[data['signature_id'] == i+1]\n",
|
||||
" xy.append(np.array([d['x'].values, d['y'].values]))\n",
|
||||
"\n",
|
||||
"# Choose randomly 25 characters and plot them\n",
|
||||
"idx = np.random.choice(len(xy), 25, replace=False)\n",
|
||||
"idx = np.array(range(25))\n",
|
||||
"xy = [xy[i] for i in idx]\n",
|
||||
"plt.figure(figsize=(8,8))\n",
|
||||
"for i,d in enumerate(xy):\n",
|
||||
" plt.subplot(5,5,i+1)\n",
|
||||
" plt.axis('off')\n",
|
||||
" plt.plot(d[0], 1.-d[1]) # note that we need to inverse the y\n",
|
||||
"plt.show()\n",
|
||||
"\n",
|
||||
"# Plot the corresponding images\n",
|
||||
"imgs = [misc.imread(icdar_img_path+'{:04d}.jpg'.format(i+1)) for i in idx]\n",
|
||||
"plt.figure(figsize=(8,8))\n",
|
||||
"for i,img in enumerate(imgs):\n",
|
||||
" plt.subplot(5,5,i+1)\n",
|
||||
" plt.axis('off')\n",
|
||||
" plt.imshow(img)\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## [IAM Online Handwriting Database](www.fki.inf.unibe.ch/databases/iam-on-line-handwriting-database) <a id='IAMonline'></a>\n",
|
||||
"\n",
|
||||
"* Size: 1,712 forms, 12,195 imgs/strokeset/sub-sentences/sequences.\n",
|
||||
"* Short description: \" The IAM On-Line Handwriting Database (IAM-OnDB) contains forms of handwritten English text acquired on a whiteboard.\" It contains the images of the various forms and the corresponding trajectories/strokes. \n",
|
||||
"* Note: You will need to register on the website in order to download the dataset. It is free!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.figure.Figure at 0x7ff3b260bc90>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import xml.etree.ElementTree as ET\n",
|
||||
"from glob import glob\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"iam_imgs_dirpath = 'IAM-Online/lineImages/'\n",
|
||||
"iam_strokes_dirpath = 'IAM-Online/lineStrokes/'\n",
|
||||
"#iam_strokes_dirpath = 'IAM-Online/lineStrokes/a01/a01-000/a01-000u-01.xml'\n",
|
||||
"\n",
|
||||
"# Get all the paths\n",
|
||||
"trajs = sorted(glob(iam_strokes_dirpath+'*/*/*.xml'))[:1000] # take only the first 1000\n",
|
||||
"imgs = sorted(glob(iam_imgs_dirpath+'*/*/*.tif'))[:1000]\n",
|
||||
"N = len(trajs)\n",
|
||||
"\n",
|
||||
"# Load all the xml files, and extract all the strokes\n",
|
||||
"strokes = []\n",
|
||||
"for i,traj in enumerate(trajs):\n",
|
||||
" tree = ET.parse(traj)\n",
|
||||
" # Get the data\n",
|
||||
" xy = []\n",
|
||||
" for stroke in tree.iter(tag='Stroke'):\n",
|
||||
" x = [int(point.attrib['x']) for point in stroke]\n",
|
||||
" y = [int(point.attrib['y']) for point in stroke]\n",
|
||||
" xy.append(np.array([x,y]))\n",
|
||||
" strokes.append(xy)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Randomly choose a strokeset, and then randomly choose 25 strokes and plot them\n",
|
||||
"idx = np.random.choice(N, 1)[0]\n",
|
||||
"strokes = strokes[idx]\n",
|
||||
"N_stroke = len(strokes)\n",
|
||||
"size = N_stroke if N_stroke < 25 else 25\n",
|
||||
"idx = np.random.choice(N_stroke, size, replace=False)\n",
|
||||
"xy = [strokes[i] for i in idx]\n",
|
||||
"plt.figure(figsize=(10,10))\n",
|
||||
"for i,d in enumerate(xy):\n",
|
||||
" if i==25: break\n",
|
||||
" plt.subplot(5,5,i+1)\n",
|
||||
" plt.plot(d[0], d[1].max()-d[1])\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 2",
|
||||
"language": "python",
|
||||
"name": "python2"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
Reference in new issue
Block a user