├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── configs
├── VTacO
│ └── VTacO_YCB.yaml
├── VTacOH
│ └── VTacOH_YCB.yaml
├── default.yaml
└── tactile
│ └── tactile_test.yaml
├── manifests
└── Dockerfile
├── media
├── VTacO.png
└── teaser.png
├── requirements.txt
├── src
├── TransformerFusion.py
├── __init__.py
├── checkpoints.py
├── common.py
├── config.py
├── conv_onet
│ ├── __init__.py
│ ├── config.py
│ ├── generation.py
│ ├── inferencing.py
│ ├── models
│ │ ├── __init__.py
│ │ └── decoder.py
│ └── training.py
├── data
│ ├── __init__.py
│ ├── core.py
│ ├── fields.py
│ └── transforms.py
├── encoder
│ ├── __init__.py
│ ├── assets
│ │ ├── anchor
│ │ │ ├── anchor_mapping_path.pkl
│ │ │ ├── anchor_weight.txt
│ │ │ ├── face_vertex_idx.txt
│ │ │ └── merged_vertex_assignment.txt
│ │ ├── closed_hand
│ │ │ └── hand_mesh_close.obj
│ │ ├── fhbhands_fits
│ │ │ ├── Subject_1
│ │ │ │ ├── close_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ └── put_salt
│ │ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ ├── Subject_2
│ │ │ │ ├── close_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 5
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ └── put_salt
│ │ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 6
│ │ │ │ │ └── pkls.pkl
│ │ │ ├── Subject_3
│ │ │ │ ├── close_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ └── put_salt
│ │ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 6
│ │ │ │ │ └── pkls.pkl
│ │ │ ├── Subject_4
│ │ │ │ ├── close_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 5
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 5
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_liquid_soap
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 5
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ └── put_salt
│ │ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ ├── Subject_5
│ │ │ │ ├── close_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_liquid_soap
│ │ │ │ │ ├── 6
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 7
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 8
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 9
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_liquid_soap
│ │ │ │ │ ├── 6
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 7
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 8
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 9
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_juice_bottle
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_liquid_soap
│ │ │ │ │ ├── 6
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 7
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 8
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 9
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_milk
│ │ │ │ │ ├── 1
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 4
│ │ │ │ │ │ └── pkls.pkl
│ │ │ │ └── put_salt
│ │ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ │ └── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ └── Subject_6
│ │ │ │ ├── close_juice_bottle
│ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_liquid_soap
│ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── close_milk
│ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_juice_bottle
│ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_liquid_soap
│ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── open_milk
│ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_juice_bottle
│ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_liquid_soap
│ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── pour_milk
│ │ │ │ ├── 1
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ │ └── pkls.pkl
│ │ │ │ ├── 4
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── 5
│ │ │ │ │ └── pkls.pkl
│ │ │ │ └── put_salt
│ │ │ │ ├── 1
│ │ │ │ └── pkls.pkl
│ │ │ │ ├── 2
│ │ │ │ └── pkls.pkl
│ │ │ │ ├── 3
│ │ │ │ └── pkls.pkl
│ │ │ │ ├── 4
│ │ │ │ └── pkls.pkl
│ │ │ │ ├── 5
│ │ │ │ └── pkls.pkl
│ │ │ │ ├── 6
│ │ │ │ └── pkls.pkl
│ │ │ │ └── 7
│ │ │ │ └── pkls.pkl
│ │ ├── hand_palm_full.txt
│ │ └── mano
│ │ │ ├── LICENSE.txt
│ │ │ ├── MANO_RIGHT.pkl
│ │ │ ├── fhb_skel_centeridx9.pkl
│ │ │ ├── info.txt
│ │ │ └── mano_v1_2
│ │ │ ├── .DS_Store
│ │ │ ├── ._.DS_Store
│ │ │ ├── LICENSE.txt
│ │ │ ├── __init__.py
│ │ │ ├── models
│ │ │ ├── LICENSE.txt
│ │ │ ├── MANO_LEFT.pkl
│ │ │ ├── MANO_RIGHT.pkl
│ │ │ ├── SMPLH_female.pkl
│ │ │ └── info.txt
│ │ │ └── webuser
│ │ │ ├── LICENSE.txt
│ │ │ ├── README.txt
│ │ │ ├── __init__.py
│ │ │ ├── hello_world
│ │ │ ├── MANO___hello_world.py
│ │ │ ├── MANO___render.py
│ │ │ ├── SMPL+H___hello_world.py
│ │ │ └── SMPL+H___render.py
│ │ │ ├── lbs.py
│ │ │ ├── posemapper.py
│ │ │ ├── serialization.py
│ │ │ ├── smpl_handpca_wrapper.py
│ │ │ ├── smpl_handpca_wrapper_HAND_only.py
│ │ │ └── verts.py
│ ├── mano
│ │ ├── __init__.py
│ │ └── webuser
│ │ │ ├── __init__.py
│ │ │ ├── lbs.py
│ │ │ ├── posemapper.py
│ │ │ ├── serialization.py
│ │ │ ├── smpl_handpca_wrapper_HAND_only.py
│ │ │ └── verts.py
│ ├── manolayer.py
│ ├── manopth
│ │ ├── __init__.py
│ │ ├── anchorlayer.py
│ │ ├── anchorutils.py
│ │ ├── argutils.py
│ │ ├── axislayer.py
│ │ ├── demo.py
│ │ ├── manolayer.py
│ │ ├── quatutils.py
│ │ ├── rodrigues_layer.py
│ │ ├── rot6d.py
│ │ ├── rotproj.py
│ │ ├── tensutils.py
│ │ └── upsample_layer.py
│ ├── pointnet.py
│ ├── pointnetpp.py
│ ├── unet.py
│ ├── unet3d.py
│ └── voxels.py
├── inferencing.py
├── layers.py
├── training.py
└── utils
│ ├── __init__.py
│ ├── binvox_rw.py
│ ├── icp.py
│ ├── io.py
│ ├── mesh.py
│ ├── visualize.py
│ └── voxels.py
├── train.py
└── train_depth.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | . filter=lfs diff=lfs merge=lfs -text
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build files
2 | build
3 | *.so
4 | *.o
5 | src/utils/libmcubes/mcubes.cpp
6 | src/utils/libsimplify/simplify_mesh.cpp
7 | src/TransformerFusion.py
8 |
9 | # Python Cache
10 | *.pyc
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Songyou Peng, Michael Niemeyer, Lars Mescheder, Marc Pollefeys, Andreas Geiger
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Visual-Tactile Sensing for In-Hand Object Reconstruction
2 | [**Paper**](https://arxiv.org/pdf/2303.14498.pdf) | [**Project Page**](https://sites.google.com/view/vtaco)
3 |
4 |
5 |

6 |
7 |
8 | This repository contains the implementation of the paper:
9 |
10 | **Visual-Tactile Sensing for In-Hand Object Reconstruction**
11 | Wenqiang Xu*, Zhenjun Yu*, Han Xue, Ruolin Ye, Siqiong Yao, Cewu Lu (* = Equal contribution)
12 | **CVPR 2023**
13 |
14 | If you find our code or paper useful, please consider citing
15 | ```bibtex
16 | @inproceedings{xu2023visual,
17 | title={Visual-Tactile Sensing for In-Hand Object Reconstruction},
18 | author={Xu, Wenqiang and Yu, Zhenjun and Xue, Han and Ye, Ruolin and Yao, Siqiong and Lu, Cewu},
19 | booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
20 | pages={8803--8812},
21 | year={2023}
22 | }
23 |
24 | ```
25 |
26 | ## Get-Started
27 |
28 | The code is only tested on Ubuntu, we will soon test it on Windows system.
29 |
30 | ## With conda and pip
31 |
32 | Install [anaconda](https://www.anaconda.com/) or [miniconda](https://docs.conda.io/en/latest/miniconda.html). Supposing that the name `vtaco` is used for conda environment:
33 |
34 | ```shell
35 | conda create -y -n vtaco python=3.8
36 | conda activate vtaco
37 | ```
38 |
39 | Then, install dependencies with `pip install`
40 |
41 | ```shell
42 | pip install -r requirements.txt
43 | ```
44 |
45 | ## With Docker
46 |
47 | Install Docker under the [instructions](https://docs.docker.com/get-started/). Supposing hat the tag `vtaco-train` is used for docker image:
48 |
49 | ```shell
50 | docker build -t vtaco-train -f ./manifests/Dockerfile .
51 | ```
52 |
53 | To start a develop container, run
54 |
55 | ```shell
56 | docker run --ipc=host --rm -it -p 8888:8888 vtaco-train
57 | ```
58 |
59 | This will launch a jupyterlab server inside the container. The server can be accessed via port `8888`.
60 |
61 | If the Docker installation is configured with Nvidia's GPU support, an additional `--gpus all` flag can be passed
62 |
63 | ```shell
64 | docker run --ipc=host --gpus all --rm -it -p 8888:8888 vtaco-train
65 | ```
66 |
67 | To mount the dataset, add an additional `--volume` mapping.
68 |
69 | ```shell
70 | docker run --ipc=host --gpus all --rm -it -p 8888:8888 --volume :/opt/vtaco/data vtaco-train
71 | ```
72 |
73 | **Note**: The `` should be replaced by actual path on the host system.
74 |
75 | ## Dataset
76 | We are uploading the dataset, which will be available on https://huggingface.co/datasets/robotflow/vtaco/
77 | You can follow the instructions to download the dataset for training and testing dataset for VTacO and VTacOH.
78 |
79 | ## VT-Sim
80 | The VT-Sim has been released [here](https://github.com/jeffsonyu/VT-Sim)
81 |
82 | ## Training
83 | To train the Depth Estimator $U_I(\cdot)$ and the sensor pose estimator, we provide a config file `configs/tactile/tactile_test.yaml`, you can run the following command to train from scratch:
84 | ```
85 | python train_depth.py configs/tactile/tactile_test.yaml
86 | ```
87 |
88 | With the pretrained model of $U_I(\cdot)$ and the sensor pose estimator, examples for training VTacO or VTacOH are as follows:
89 |
90 | ```shell
91 | python train.py configs/VTacO/VTacO_YCB.yaml
92 | python train.py configs/VTacOH/VTacOH_YCB.yaml
93 | ```
94 |
95 | **Note**: you might need to change *path* in *data*, and *model_file* in *encoder_t2d_kwargs* of the config file, to your data path and pretrained model path. This path is `out/tactile/test/model_best.pt` by default.
96 |
97 | All the results will be saved in `out/` folder, including checkpoints, visualization results and logs for tensorboard.
98 |
--------------------------------------------------------------------------------
/configs/VTacO/VTacO_YCB.yaml:
--------------------------------------------------------------------------------
1 | method: vtaco
2 | data:
3 | input_type: pointcloud
4 | classes: null
5 | path: ./data/VTacO_YCB
6 | pointcloud_n: 3000
7 | pointcloud_noise: 0.005
8 | points_subsample: 100000
9 | num_sample: 2048
10 | points_file: points.npz
11 | points_iou_file: points.npz
12 | voxels_file: null
13 | pointcloud_file: pointcloud.npz
14 | points_unpackbits: False
15 |
16 | model:
17 | train_tactile: False
18 | with_img: True
19 | with_contact: False
20 |
21 | encoder: pointnet_local_pool
22 | encoder_kwargs:
23 | hidden_dim: 32
24 | plane_type: 'grid'
25 | grid_resolution: 64
26 | unet3d: True
27 | unet3d_kwargs:
28 | num_levels: 4
29 | f_maps: 32
30 | in_channels: 32
31 | out_channels: 32
32 |
33 | encoder_hand: pointnet_local_pool
34 | encoder_hand_kwargs:
35 | hidden_dim: 32
36 | plane_type: ['xz', 'xy', 'yz']
37 | plane_resolution: 32
38 | unet: True
39 | unet_kwargs:
40 | depth: 4
41 | merge_mode: concat
42 | start_filts: 32
43 |
44 | out_mano: True
45 | out_dim: 51
46 | manolayer_kwargs: &manolayer_k
47 | center_idx: 9
48 | flat_hand_mean: False
49 | ncomps: 45
50 | side: right
51 | mano_root: src/encoder/assets/mano
52 | use_pca: False
53 | root_rot_mode: axisang
54 | joint_rot_mode: axisang
55 | robust_rot: False
56 | return_transf: False
57 | return_full_pose: True
58 |
59 | encoder_img: Resnet18
60 | encoder_img_kwargs:
61 | num_classes: 32
62 |
63 | encoder_t2d: True
64 | encoder_t2d_kwargs:
65 | pretrained: True
66 | model_file: ../../tactile/test/model.pt # NOTE: replace this with actual path
67 |
68 | encoder_img: UNet
69 | encoder_img_kwargs:
70 | num_classes: 1
71 | in_channel: 3
72 | start_filts: 32
73 | depth: 3
74 |
75 | encoder_hand: pointnet_local_pool
76 | encoder_hand_kwargs:
77 | c_dim: 512
78 | hidden_dim: 32
79 | plane_type: ['xz', 'xy', 'yz']
80 | plane_resolution: 64
81 | unet: True
82 | unet_kwargs:
83 | depth: 4
84 | merge_mode: concat
85 | start_flits: 32
86 |
87 | out_mano: True
88 | out_dim: 30
89 | manolayer_kwargs: *manolayer_k
90 |
91 |
92 | decoder: simple_local
93 | decoder_kwargs:
94 | sample_mode: bilinear # bilinear / nearest
95 | hidden_size: 32
96 | c_dim: 32
97 |
98 | training:
99 | out_dir: out/VTacO/YCB
100 | opt: Adam
101 | lr: 0.0001
102 | gpu: 1
103 | batch_size: 3
104 | model_selection_metric: iou
105 | model_selection_mode: maximize
106 | print_every: 100
107 | visualize_every: 10000
108 | validate_every: 1000
109 | checkpoint_every: 2000
110 | backup_every: 10000
111 | n_workers: 8
112 | n_workers_val: 4
113 |
114 | test:
115 | threshold: 0.5
116 | eval_mesh: true
117 | eval_pointcloud: False
118 | # model_file: ../AKB_all/model_best.pt
119 | model_file: model.pt
120 |
121 | generation:
122 | vis_all: True
123 | refine: false
124 | n_x: 128
125 | n_z: 1
126 | alpha: 0.2
127 |
--------------------------------------------------------------------------------
/configs/VTacOH/VTacOH_YCB.yaml:
--------------------------------------------------------------------------------
1 | method: vtaco
2 | data:
3 | input_type: pointcloud
4 | classes: null
5 | path: ./data/VTacO_YCB
6 | pointcloud_n: 3000
7 | pointcloud_noise: 0.005
8 | points_subsample: 100000
9 | num_sample: 2048
10 | points_file: points.npz
11 | points_iou_file: points.npz
12 | voxels_file: null
13 | pointcloud_file: pointcloud.npz
14 | points_unpackbits: False
15 |
16 | model:
17 | train_tactile: False
18 | with_img: True
19 | with_contact: False
20 |
21 | encoder: pointnet_local_pool
22 | encoder_kwargs:
23 | hidden_dim: 32
24 | plane_type: 'grid'
25 | grid_resolution: 64
26 | unet3d: True
27 | unet3d_kwargs:
28 | num_levels: 4
29 | f_maps: 32
30 | in_channels: 32
31 | out_channels: 32
32 |
33 | encoder_hand: pointnet_local_pool
34 | encoder_hand_kwargs:
35 | hidden_dim: 32
36 | plane_type: ['xz', 'xy', 'yz']
37 | plane_resolution: 32
38 | unet: True
39 | unet_kwargs:
40 | depth: 4
41 | merge_mode: concat
42 | start_filts: 32
43 | out_mano: True
44 | out_dim: 51
45 | manolayer_kwargs:
46 | center_idx: 9
47 | flat_hand_mean: False
48 | ncomps: 45
49 | side: right
50 | mano_root: src/encoder/assets/mano
51 | use_pca: False
52 | root_rot_mode: axisang
53 | joint_rot_mode: axisang
54 | robust_rot: False
55 | return_transf: False
56 | return_full_pose: True
57 |
58 | encoder_img: Resnet18
59 | encoder_img_kwargs:
60 | num_classes: 32
61 |
62 | encoder_t2d: False
63 | encoder_t2d_kwargs: False
64 |
65 | decoder: simple_local
66 | decoder_kwargs:
67 | sample_mode: bilinear # bilinear / nearest
68 | hidden_size: 32
69 | c_dim: 32
70 |
71 | training:
72 | out_dir: out/VTacOH/YCB
73 | opt: Adam
74 | lr: 0.0001
75 | gpu: 0
76 | batch_size: 6
77 | model_selection_metric: iou
78 | model_selection_mode: maximize
79 | print_every: 100
80 | visualize_every: 10000
81 | validate_every: 1000
82 | checkpoint_every: 3000
83 | backup_every: 10000
84 | n_workers: 8
85 | n_workers_val: 4
86 | test:
87 | threshold: 0.5
88 | eval_mesh: true
89 | eval_pointcloud: false
90 | # model_file: ../AKB_all/model_best.pt
91 | model_file: model.pt
92 | generation:
93 | vis_all: True
94 | vis_n_outputs: 168
95 | refine: false
96 | n_x: 128
97 | n_z: 1
98 | alpha: 0.2
99 |
--------------------------------------------------------------------------------
/configs/default.yaml:
--------------------------------------------------------------------------------
1 | method: vtaco
2 | data:
3 | dataset: Shapes3D
4 | path: data/ShapeNet
5 | watertight_path: data/watertight
6 | classes: null
7 | input_type: img
8 | train_split: train
9 | val_split: val
10 | test_split: test
11 | dim: 3
12 | points_file: points.npz
13 | points_iou_file: points.npz
14 | multi_files: null
15 | points_subsample: 1024
16 | points_unpackbits: true
17 | model_file: model.off
18 | watertight_file: model_watertight.off
19 | img_folder: img
20 | img_size: 224
21 | img_with_camera: false
22 | img_augment: false
23 | n_views: 24
24 | pointcloud_file: pointcloud.npz
25 | pointcloud_chamfer_file: pointcloud.npz
26 | pointcloud_n: 256
27 | pointcloud_target_n: 1024
28 | pointcloud_noise: 0.05
29 | voxels_file: 'model.binvox'
30 | padding: 0.1
31 | model:
32 | decoder: simple
33 | encoder: resnet18
34 | decoder_kwargs: {}
35 | encoder_kwargs: {}
36 | multi_gpu: false
37 | c_dim: 512
38 | pretrained_path: None
39 | training:
40 | out_dir: out/default
41 | batch_size: 64
42 | print_every: 200
43 | visualize_every: 1000
44 | checkpoint_every: 1000
45 | validate_every: 2000
46 | backup_every: 100000
47 | eval_sample: false
48 | model_selection_metric: loss
49 | model_selection_mode: minimize
50 | n_workers: 4
51 | n_workers_val: 4
52 | test:
53 | threshold: 0.5
54 | eval_mesh: true
55 | eval_pointcloud: true
56 | remove_wall: false
57 | model_file: model_best.pt
58 | generation:
59 | batch_size: 100000
60 | refinement_step: 0
61 | vis_n_outputs: 30
62 | generate_mesh: true
63 | generate_pointcloud: true
64 | generation_dir: generation
65 | use_sampling: false
66 | resolution_0: 32
67 | upsampling_steps: 2
68 | simplify_nfaces: null
69 | copy_groundtruth: false
70 | copy_input: true
71 | latent_number: 4
72 | latent_H: 8
73 | latent_W: 8
74 | latent_ny: 2
75 | latent_nx: 2
76 | latent_repeat: true
77 | sliding_window: False # added for crop generation
78 |
--------------------------------------------------------------------------------
/configs/tactile/tactile_test.yaml:
--------------------------------------------------------------------------------
1 | method: vtaco
2 | data:
3 | input_type: pointcloud
4 | classes: null
5 | path: ./data/VTacO_YCB
6 | pointcloud_n: 3000
7 | pointcloud_noise: 0.005
8 | points_subsample: 100000
9 | num_sample: 2048
10 | points_file: points.npz
11 | points_iou_file: points.npz
12 | voxels_file: null
13 | pointcloud_file: pointcloud.npz
14 | points_unpackbits: False
15 |
16 | model:
17 | train_tactile: True
18 | with_img: True
19 | with_contact: False
20 |
21 | encoder: False
22 |
23 | encoder_hand: pointnet_local_pool
24 | encoder_hand_kwargs:
25 | hidden_dim: 32
26 | plane_type: ['xz', 'xy', 'yz']
27 | plane_resolution: 64
28 | unet: True
29 | unet_kwargs:
30 | depth: 4
31 | merge_mode: concat
32 | start_filts: 32
33 | out_mano: True
34 | out_dim: 30
35 | manolayer_kwargs:
36 | center_idx: 9
37 | flat_hand_mean: False
38 | ncomps: 45
39 | side: right
40 | mano_root: src/encoder/assets/mano
41 | use_pca: False
42 | root_rot_mode: axisang
43 | joint_rot_mode: axisang
44 | robust_rot: False
45 | return_transf: False
46 | return_full_pose: True
47 |
48 | encoder_img: UNet
49 | encoder_img_kwargs:
50 | num_classes: 1
51 | in_channel: 3
52 | start_filts: 32
53 | depth: 3
54 |
55 | encoder_t2d: False
56 | encoder_t2d_kwargs: False
57 |
58 |
59 | decoder: False
60 |
61 |
62 | training:
63 | out_dir: out/tactile/test
64 | opt: Adam
65 | lr: 0.0001
66 | gpu: 0
67 | batch_size: 12
68 | model_selection_metric: loss_depth
69 | model_selection_mode: minimize
70 | print_every: 100
71 | visualize_every: 20000
72 | validate_every: 1000
73 | checkpoint_every: 3000
74 | backup_every: 10000
75 | n_workers: 8
76 | n_workers_val: 4
77 | test:
78 | model_file: model.pt
79 | generation:
80 | vis_all: False
81 | vis_split: 10
82 | vis_n_outputs: 168
83 | refine: false
84 | n_x: 128
85 | n_z: 1
86 | alpha: 0.2
87 |
88 |
--------------------------------------------------------------------------------
/manifests/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nvidia/cuda:11.6.2-base-ubuntu20.04
2 |
3 | ENV DEBIAN_FRONTEND=noninteractive
4 |
5 | # Optional: change mirror
6 | RUN sed -i 's/http:\/\/archive.ubuntu.com/https:\/\/mirror.sjtu.edu.cn/g' /etc/apt/sources.list
7 |
8 | RUN apt-get update && \
9 | apt-get install -y python3.8 python3-pip git vim htop libsm6 libxext6 libxrender-dev libgl1-mesa-glx libglib2.0-dev && \
10 | update-alternatives --install /usr/bin/python python /usr/bin/python3 1 && \
11 | update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 && \
12 | pip install --upgrade pip
13 |
14 | COPY requirements.txt /tmp/requirements.txt
15 |
16 | # Optional: change pip mirror
17 | RUN pip config set global.index-url https://mirror.sjtu.edu.cn/pypi/web/simple
18 |
19 | # Install required packages
20 | RUN pip install -r /tmp/requirements.txt && \
21 | rm /tmp/requirements.txt
22 |
23 | WORKDIR /opt/vtaco
24 | COPY . /opt/vtaco/
25 |
26 | ENV JUPYTER_ALLOW_ROOT=1
27 | ENV SHELL=/bin/bash
28 |
29 | CMD ["jupyter-lab", "--ip=0.0.0.0", "--allow-root" ]
--------------------------------------------------------------------------------
/media/VTacO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/media/VTacO.png
--------------------------------------------------------------------------------
/media/teaser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/media/teaser.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | numpy==1.23.5
2 | cython
3 | trimesh
4 | chumpy
5 | scipy
6 | scikit-image
7 | open3d
8 | matplotlib
9 | pandas
10 | pillow
11 | imageio
12 | opencv-python
13 | plyfile
14 | libigl
15 | rtree
16 | pybullet
17 | tqdm
18 | h5py
19 | pyyaml
20 | tensorboard
21 | tensorboardX
22 | jupyterlab
23 | pykdtree
24 |
25 | --extra-index-url=https://download.pytorch.org/whl/cu116
26 | torch==1.13.0+cu116
27 | torchvision==0.14.0+cu116
28 |
29 | --find-links=https://data.pyg.org/whl/torch-1.13.0+cu116.html
30 | torch_scatter==2.0.9
31 |
32 |
--------------------------------------------------------------------------------
/src/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/__init__.py
--------------------------------------------------------------------------------
/src/checkpoints.py:
--------------------------------------------------------------------------------
1 | import os
2 | import urllib
3 | import torch
4 | from torch.utils import model_zoo
5 | import numpy as np
6 | from plyfile import PlyData, PlyElement
7 |
8 |
9 | class CheckpointIO(object):
10 | ''' CheckpointIO class.
11 |
12 | It handles saving and loading checkpoints.
13 |
14 | Args:
15 | checkpoint_dir (str): path where checkpoints are saved
16 | '''
17 | def __init__(self, checkpoint_dir='./chkpts', **kwargs):
18 | self.module_dict = kwargs
19 | self.checkpoint_dir = checkpoint_dir
20 | if not os.path.exists(checkpoint_dir):
21 | os.makedirs(checkpoint_dir)
22 |
23 | def register_modules(self, **kwargs):
24 | ''' Registers modules in current module dictionary.
25 | '''
26 | self.module_dict.update(kwargs)
27 |
28 | def save(self, filename, **kwargs):
29 | ''' Saves the current module dictionary.
30 |
31 | Args:
32 | filename (str): name of output file
33 | '''
34 | if not os.path.isabs(filename):
35 | filename = os.path.join(self.checkpoint_dir, filename)
36 |
37 | outdict = kwargs
38 | for k, v in self.module_dict.items():
39 | outdict[k] = v.state_dict()
40 | torch.save(outdict, filename)
41 |
42 | def load(self, filename, device):
43 | '''Loads a module dictionary from local file or url.
44 |
45 | Args:
46 | filename (str): name of saved module dictionary
47 | '''
48 | if is_url(filename):
49 | return self.load_url(filename)
50 | else:
51 | return self.load_file(filename, device)
52 |
53 | def load_file(self, filename, device):
54 | '''Loads a module dictionary from file.
55 |
56 | Args:
57 | filename (str): name of saved module dictionary
58 | '''
59 |
60 | if not os.path.isabs(filename):
61 | filename = os.path.join(self.checkpoint_dir, filename)
62 |
63 | if os.path.exists(filename):
64 | print(filename)
65 | print('=> Loading checkpoint from local file...')
66 | state_dict = torch.load(filename, map_location=device)
67 | scalars = self.parse_state_dict(state_dict)
68 | return scalars
69 | else:
70 | raise FileNotFoundError
71 |
72 | def load_url(self, url):
73 | '''Load a module dictionary from url.
74 |
75 | Args:
76 | url (str): url to saved model
77 | '''
78 | print(url)
79 | print('=> Loading checkpoint from url...')
80 | state_dict = model_zoo.load_url(url, progress=True)
81 | scalars = self.parse_state_dict(state_dict)
82 | return scalars
83 |
84 | def parse_state_dict(self, state_dict):
85 | '''Parse state_dict of model and return scalars.
86 |
87 | Args:
88 | state_dict (dict): State dict of model
89 | '''
90 |
91 | for k, v in self.module_dict.items():
92 | if k in state_dict:
93 | v.load_state_dict(state_dict[k])
94 | else:
95 | print('Warning: Could not find %s in checkpoint!' % k)
96 | scalars = {k: v for k, v in state_dict.items()
97 | if k not in self.module_dict}
98 | return scalars
99 |
100 | def is_url(url):
101 | scheme = urllib.parse.urlparse(url).scheme
102 | return scheme in ('http', 'https')
103 |
104 |
105 | def write_ply(save_path, points, text=True):
106 | """
107 | save_path : path to save: '/yy/XX.ply'
108 | pt: point_cloud: size (N,3)
109 | """
110 | points = [(points[i,0], points[i,1], points[i,2]) for i in range(points.shape[0])]
111 | vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'),('z', 'f4')])
112 | el = PlyElement.describe(vertex, 'vertex', comments=['vertices'])
113 | PlyData([el], text=text).write(save_path)
114 |
--------------------------------------------------------------------------------
/src/conv_onet/__init__.py:
--------------------------------------------------------------------------------
1 | from src.conv_onet import (
2 | config, generation, training, models, inferencing
3 | )
4 |
5 | __all__ = [
6 | config, generation, training, models, inferencing
7 | ]
8 |
--------------------------------------------------------------------------------
/src/data/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | from src.data.core import (
3 | Shapes3dDataset, collate_remove_none, worker_init_fn
4 | )
5 | from src.data.fields import (
6 | IndexField, PointsField,
7 | VoxelsField, PatchPointsField, PointCloudField, PatchPointCloudField, PartialPointCloudField,
8 | )
9 | from src.data.transforms import (
10 | PointcloudNoise, SubsamplePointcloud,
11 | SubsamplePoints,
12 | )
13 | __all__ = [
14 | # Core
15 | Shapes3dDataset,
16 | collate_remove_none,
17 | worker_init_fn,
18 | # Fields
19 | IndexField,
20 | PointsField,
21 | VoxelsField,
22 | PointCloudField,
23 | PartialPointCloudField,
24 | PatchPointCloudField,
25 | PatchPointsField,
26 | # Transforms
27 | PointcloudNoise,
28 | SubsamplePointcloud,
29 | SubsamplePoints,
30 | ]
31 |
--------------------------------------------------------------------------------
/src/data/transforms.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 |
4 | # Transforms
5 | class PointcloudNoise(object):
6 | ''' Point cloud noise transformation class.
7 |
8 | It adds noise to point cloud data.
9 |
10 | Args:
11 | stddev (int): standard deviation
12 | '''
13 |
14 | def __init__(self, stddev):
15 | self.stddev = stddev
16 |
17 | def __call__(self, data):
18 | ''' Calls the transformation.
19 |
20 | Args:
21 | data (dictionary): data dictionary
22 | '''
23 | data_out = data.copy()
24 | points = data[None]
25 | noise = self.stddev * np.random.randn(*points.shape)
26 | noise = noise.astype(np.float32)
27 | data_out[None] = points + noise
28 | return data_out
29 |
30 | class SubsamplePointcloud(object):
31 | ''' Point cloud subsampling transformation class.
32 |
33 | It subsamples the point cloud data.
34 |
35 | Args:
36 | N (int): number of points to be subsampled
37 | '''
38 | def __init__(self, N):
39 | self.N = N
40 |
41 | def __call__(self, data):
42 | ''' Calls the transformation.
43 |
44 | Args:
45 | data (dict): data dictionary
46 | '''
47 | data_out = data.copy()
48 | points = data[None]
49 | normals = data['normals']
50 |
51 | indices = np.random.randint(points.shape[0], size=self.N)
52 | data_out[None] = points[indices, :]
53 | data_out['normals'] = normals[indices, :]
54 |
55 | return data_out
56 |
57 |
58 | class SubsamplePoints(object):
59 | ''' Points subsampling transformation class.
60 |
61 | It subsamples the points data.
62 |
63 | Args:
64 | N (int): number of points to be subsampled
65 | '''
66 | def __init__(self, N):
67 | self.N = N
68 |
69 | def __call__(self, data):
70 | ''' Calls the transformation.
71 |
72 | Args:
73 | data (dictionary): data dictionary
74 | '''
75 | points = data[None]
76 | occ = data['occ']
77 | contact = data['contact']
78 |
79 | data_out = data.copy()
80 | if isinstance(self.N, int):
81 | idx = np.random.randint(points.shape[0], size=self.N)
82 | data_out.update({
83 | None: points[idx, :],
84 | 'occ': occ[idx],
85 | 'contact': contact[idx],
86 | })
87 | else:
88 | Nt_out, Nt_in = self.N
89 | occ_binary = (occ >= 0.5)
90 | points0 = points[~occ_binary]
91 | points1 = points[occ_binary]
92 |
93 | idx0 = np.random.randint(points0.shape[0], size=Nt_out)
94 | idx1 = np.random.randint(points1.shape[0], size=Nt_in)
95 |
96 | points0 = points0[idx0, :]
97 | points1 = points1[idx1, :]
98 | points = np.concatenate([points0, points1], axis=0)
99 |
100 | occ0 = np.zeros(Nt_out, dtype=np.float32)
101 | occ1 = np.ones(Nt_in, dtype=np.float32)
102 | occ = np.concatenate([occ0, occ1], axis=0)
103 |
104 | volume = occ_binary.sum() / len(occ_binary)
105 | volume = volume.astype(np.float32)
106 |
107 | data_out.update({
108 | None: points,
109 | 'occ': occ,
110 | 'volume': volume,
111 | })
112 | return data_out
113 |
--------------------------------------------------------------------------------
/src/encoder/__init__.py:
--------------------------------------------------------------------------------
1 | from src.encoder import (
2 | pointnet, voxels, pointnetpp, manolayer
3 | )
4 |
5 | from src.layers import (
6 | Resnet18, Resnet34, Resnet50, UNet
7 | )
8 |
9 | from src.TransformerFusion import TransformerFusion
10 |
11 | encoder_dict = {
12 | 'pointnet_local_pool': pointnet.LocalPoolPointnet,
13 | 'pointnet_crop_local_pool': pointnet.PatchLocalPoolPointnet,
14 | 'pointnet_plus_plus': pointnetpp.PointNetPlusPlus,
15 | 'voxel_simple_local': voxels.LocalVoxelEncoder,
16 | 'Resnet18': Resnet18,
17 | 'Resnet34': Resnet34,
18 | 'Resnet50': Resnet50,
19 | 'UNet': UNet
20 | }
21 |
--------------------------------------------------------------------------------
/src/encoder/assets/anchor/anchor_mapping_path.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/anchor/anchor_mapping_path.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/anchor/anchor_weight.txt:
--------------------------------------------------------------------------------
1 | 9.127206963206775381e-01 5.290459555463346286e-02
2 | 6.318858159375735813e-03 7.851291478708912752e-01
3 | 3.469871281618357173e-02 3.609718760535627347e-01
4 | 8.118042616108084308e-02 3.770357185189284199e-01
5 | 7.139128443441763450e-01 2.156628403142699102e-01
6 | 6.102575923233312105e-01 2.157600674458490797e-01
7 | 6.421338559311650096e-01 7.304322566454510279e-02
8 | 3.614738543950377775e-02 2.080237550804511781e-01
9 | 5.059216725617607380e-02 3.632653449562375236e-01
10 | 8.524558003834914466e-02 7.712450923960123550e-01
11 | 2.816070218830744598e-01 6.995181033281936411e-01
12 | 8.290694629857187081e-02 8.423876955369394848e-01
13 | 3.088925494041749181e-02 8.627622937845070838e-01
14 | 4.662061502695714621e-01 1.663164749933313813e-01
15 | 3.087580856812601193e-01 1.062666663189449912e-01
16 | 3.812775866370716749e-01 5.706766784325894015e-01
17 | 9.170660623549244106e-02 6.172138178673470393e-02
18 | 1.756457029163932234e-03 8.591494990349831662e-01
19 | 1.479803045310174592e-01 4.627880828002478020e-01
20 | 4.020798372721484104e-01 1.135726549121500867e-01
21 | 7.156467813398222910e-01 2.739734324124764031e-01
22 | 3.520095581614726687e-01 2.671365212118718691e-01
23 | 2.015296217041099014e-01 4.821987314170388950e-01
24 | 5.084336460743781316e-01 2.888743199750400392e-01
25 | 3.800210113732255812e-01 1.336270642277738452e-01
26 | 1.967075400063786617e-01 2.087892762379574552e-01
27 | 7.956256664910418830e-02 4.392777616730406121e-01
28 | 8.678066733415505940e-01 1.167114918079196206e-01
29 | 1.755045139809834343e-01 1.383249604991268755e-01
30 | 4.813043598003381995e-01 1.938758920208112080e-01
31 | 9.139261996539482791e-01 1.626103880337713414e-02
32 | 7.221214469731718211e-01 1.541693589407441833e-01
33 |
--------------------------------------------------------------------------------
/src/encoder/assets/anchor/face_vertex_idx.txt:
--------------------------------------------------------------------------------
1 | 4 7 115
2 | 267 125 700
3 | 766 764 768
4 | 739 736 740
5 | 761 759 762
6 | 61 60 63
7 | 113 26 265
8 | 171 194 139
9 | 47 237 238
10 | 353 355 327
11 | 328 330 325
12 | 346 345 347
13 | 147 66 268
14 | 379 386 370
15 | 357 396 397
16 | 437 467 442
17 | 435 440 441
18 | 456 455 459
19 | 71 275 72
20 | 242 241 254
21 | 485 489 496
22 | 469 507 513
23 | 576 577 578
24 | 546 549 552
25 | 569 568 570
26 | 772 102 101
27 | 45 130 131
28 | 596 607 601
29 | 630 625 631
30 | 691 694 693
31 | 663 666 669
32 | 685 686 642
33 |
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/close_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/close_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/open_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/open_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/pour_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/pour_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/put_salt/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/put_salt/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/put_salt/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/put_salt/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/put_salt/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/put_salt/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_1/put_salt/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_1/put_salt/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/close_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/close_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/open_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/open_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/pour_milk/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/6/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_2/put_salt/6/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/close_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/close_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/open_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/open_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/pour_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/pour_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/6/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_3/put_salt/6/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/close_milk/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/open_milk/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/pour_milk/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_4/put_salt/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_liquid_soap/6/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_liquid_soap/6/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_liquid_soap/7/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_liquid_soap/7/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_liquid_soap/8/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_liquid_soap/8/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_liquid_soap/9/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_liquid_soap/9/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/close_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/close_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_liquid_soap/6/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_liquid_soap/6/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_liquid_soap/7/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_liquid_soap/7/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_liquid_soap/8/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_liquid_soap/8/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_liquid_soap/9/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_liquid_soap/9/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/open_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/open_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_liquid_soap/6/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_liquid_soap/6/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_liquid_soap/7/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_liquid_soap/7/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_liquid_soap/8/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_liquid_soap/8/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_liquid_soap/9/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_liquid_soap/9/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/pour_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/pour_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_5/put_salt/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_juice_bottle/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_liquid_soap/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/close_milk/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_juice_bottle/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/open_milk/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_juice_bottle/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_liquid_soap/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_liquid_soap/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_liquid_soap/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_liquid_soap/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_liquid_soap/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_liquid_soap/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_liquid_soap/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_liquid_soap/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/pour_milk/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/1/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/1/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/2/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/2/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/3/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/3/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/4/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/4/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/5/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/5/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/6/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/6/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/7/pkls.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/fhbhands_fits/Subject_6/put_salt/7/pkls.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/hand_palm_full.txt:
--------------------------------------------------------------------------------
1 | 0
2 | 1
3 | 2
4 | 3
5 | 4
6 | 7
7 | 8
8 | 9
9 | 10
10 | 11
11 | 12
12 | 24
13 | 25
14 | 26
15 | 27
16 | 30
17 | 31
18 | 32
19 | 33
20 | 34
21 | 35
22 | 36
23 | 37
24 | 40
25 | 44
26 | 45
27 | 46
28 | 47
29 | 48
30 | 49
31 | 60
32 | 61
33 | 62
34 | 63
35 | 64
36 | 65
37 | 66
38 | 67
39 | 68
40 | 69
41 | 70
42 | 71
43 | 72
44 | 73
45 | 74
46 | 75
47 | 76
48 | 77
49 | 93
50 | 94
51 | 95
52 | 96
53 | 97
54 | 98
55 | 99
56 | 100
57 | 101
58 | 102
59 | 103
60 | 106
61 | 107
62 | 108
63 | 109
64 | 110
65 | 111
66 | 112
67 | 113
68 | 114
69 | 115
70 | 116
71 | 117
72 | 118
73 | 119
74 | 120
75 | 123
76 | 124
77 | 125
78 | 126
79 | 128
80 | 129
81 | 130
82 | 131
83 | 132
84 | 137
85 | 138
86 | 139
87 | 140
88 | 141
89 | 142
90 | 146
91 | 147
92 | 148
93 | 149
94 | 150
95 | 151
96 | 152
97 | 154
98 | 155
99 | 156
100 | 157
101 | 159
102 | 164
103 | 165
104 | 166
105 | 167
106 | 168
107 | 169
108 | 170
109 | 171
110 | 172
111 | 173
112 | 188
113 | 194
114 | 195
115 | 196
116 | 197
117 | 198
118 | 199
119 | 223
120 | 228
121 | 237
122 | 238
123 | 240
124 | 241
125 | 242
126 | 243
127 | 244
128 | 245
129 | 246
130 | 247
131 | 249
132 | 254
133 | 255
134 | 257
135 | 262
136 | 264
137 | 265
138 | 266
139 | 267
140 | 268
141 | 271
142 | 275
143 | 278
144 | 280
145 | 281
146 | 284
147 | 285
148 | 288
149 | 298
150 | 301
151 | 322
152 | 323
153 | 324
154 | 325
155 | 326
156 | 327
157 | 328
158 | 329
159 | 330
160 | 331
161 | 332
162 | 333
163 | 337
164 | 340
165 | 341
166 | 342
167 | 343
168 | 344
169 | 345
170 | 346
171 | 347
172 | 348
173 | 349
174 | 350
175 | 351
176 | 352
177 | 353
178 | 354
179 | 355
180 | 356
181 | 357
182 | 358
183 | 359
184 | 370
185 | 371
186 | 372
187 | 373
188 | 374
189 | 375
190 | 376
191 | 377
192 | 378
193 | 379
194 | 380
195 | 385
196 | 386
197 | 387
198 | 392
199 | 396
200 | 397
201 | 398
202 | 402
203 | 403
204 | 410
205 | 413
206 | 435
207 | 436
208 | 437
209 | 438
210 | 439
211 | 440
212 | 441
213 | 442
214 | 452
215 | 453
216 | 454
217 | 455
218 | 456
219 | 459
220 | 461
221 | 462
222 | 466
223 | 467
224 | 468
225 | 469
226 | 470
227 | 471
228 | 482
229 | 483
230 | 484
231 | 485
232 | 486
233 | 487
234 | 488
235 | 489
236 | 490
237 | 491
238 | 496
239 | 497
240 | 501
241 | 502
242 | 503
243 | 504
244 | 506
245 | 507
246 | 508
247 | 510
248 | 513
249 | 514
250 | 521
251 | 522
252 | 523
253 | 524
254 | 525
255 | 544
256 | 545
257 | 546
258 | 547
259 | 548
260 | 549
261 | 550
262 | 551
263 | 552
264 | 553
265 | 555
266 | 559
267 | 560
268 | 563
269 | 564
270 | 565
271 | 566
272 | 567
273 | 568
274 | 569
275 | 570
276 | 571
277 | 572
278 | 573
279 | 574
280 | 575
281 | 576
282 | 577
283 | 578
284 | 579
285 | 580
286 | 581
287 | 582
288 | 583
289 | 594
290 | 595
291 | 596
292 | 597
293 | 600
294 | 601
295 | 602
296 | 603
297 | 604
298 | 605
299 | 606
300 | 607
301 | 608
302 | 609
303 | 612
304 | 614
305 | 615
306 | 618
307 | 619
308 | 620
309 | 621
310 | 622
311 | 624
312 | 625
313 | 630
314 | 631
315 | 638
316 | 639
317 | 640
318 | 641
319 | 642
320 | 644
321 | 652
322 | 653
323 | 656
324 | 657
325 | 660
326 | 661
327 | 662
328 | 663
329 | 664
330 | 665
331 | 666
332 | 667
333 | 668
334 | 669
335 | 670
336 | 671
337 | 672
338 | 674
339 | 675
340 | 676
341 | 677
342 | 678
343 | 679
344 | 680
345 | 681
346 | 682
347 | 683
348 | 684
349 | 685
350 | 686
351 | 687
352 | 688
353 | 689
354 | 690
355 | 691
356 | 692
357 | 693
358 | 694
359 | 695
360 | 696
361 | 698
362 | 699
363 | 700
364 | 701
365 | 704
366 | 711
367 | 713
368 | 714
369 | 732
370 | 733
371 | 734
372 | 735
373 | 736
374 | 737
375 | 738
376 | 739
377 | 740
378 | 741
379 | 742
380 | 743
381 | 749
382 | 750
383 | 753
384 | 754
385 | 755
386 | 756
387 | 757
388 | 758
389 | 759
390 | 760
391 | 761
392 | 762
393 | 763
394 | 764
395 | 765
396 | 766
397 | 767
398 | 768
399 | 769
400 | 770
401 | 771
402 | 772
403 | 773
404 | 774
405 | 775
406 | 776
407 | 777
408 |
--------------------------------------------------------------------------------
/src/encoder/assets/mano/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Please read carefully the following terms and conditions and any accompanying documentation before you download and/or use the MANO/SMPL+H model, data and software, (the "Model"), including 3D meshes, blend weights, blend shapes, textures, software, scripts, and animations. By downloading and/or using the Model, you acknowledge that you have read these terms and conditions, understand them, and agree to be bound by them. If you do not agree with these terms and conditions, you must not download and/or use the Model.
2 |
3 | Ownership
4 | The Model has been developed at the Max Planck Institute for Intelligent Systems (hereinafter "MPI") and is owned by and proprietary material of the Max-Planck-Gesellschaft zur Foerderung der Wissenschaften e.V. (hereinafter "MPG"; MPI and MPG hereinafter collectively "Max-Planck").
5 |
6 | License Grant
7 | Max-Planck grants you a non-exclusive, non-transferable, free of charge right:
8 |
9 | To download the Model and use it on computers owned, leased or otherwise controlled by you and/or your organisation;
10 | To use the Model for the sole purpose of performing non-commercial scientific research, non-commercial education, or non-commercial artistic projects.
11 | Any other use, in particular any use for commercial purposes, is prohibited. This includes, without limitation, incorporation in a commercial product, use in a commercial service, as training data for a commercial product, for commercial ergonomic analysis (e.g. product design, architectural design, etc.), or production of other artifacts for commercial purposes including, for example, web services, movies, television programs, mobile applications, or video games. The Model may not be used for pornographic purposes or to generate pornographic material whether commercial or not. This license also prohibits the use of the Model to train methods/algorithms/neural networks/etc. for commercial use of any kind. The Model may not be reproduced, modified and/or made available in any form to any third party without Max-Planck's prior written permission. By downloading the Model, you agree not to reverse engineer it.
12 |
13 | Disclaimer of Representations and Warranties
14 | You expressly acknowledge and agree that the Model results from basic research, is provided "AS IS", may contain errors, and that any use of the Model is at your sole risk. MAX-PLANCK MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MODEL, NEITHER EXPRESS NOR IMPLIED, AND THE ABSENCE OF ANY LEGAL OR ACTUAL DEFECTS, WHETHER DISCOVERABLE OR NOT. Specifically, and not to limit the foregoing, Max-Planck makes no representations or warranties (i) regarding the merchantability or fitness for a particular purpose of the Model, (ii) that the use of the Model will not infringe any patents, copyrights or other intellectual property rights of a third party, and (iii) that the use of the Model will not cause any damage of any kind to you or a third party.
15 |
16 | Limitation of Liability
17 | Under no circumstances shall Max-Planck be liable for any incidental, special, indirect or consequential damages arising out of or relating to this license, including but not limited to, any lost profits, business interruption, loss of programs or other data, or all other commercial damages or losses, even if advised of the possibility thereof.
18 |
19 | No Maintenance Services
20 | You understand and agree that Max-Planck is under no obligation to provide either maintenance services, update services, notices of latent defects, or corrections of defects with regard to the Model. Max-Planck nevertheless reserves the right to update, modify, or discontinue the Model at any time.
21 |
22 | Publication with MANO/SMPL+H
23 | You agree to cite the most recent paper describing the model as specified on the download website. This website lists the most up to date bibliographic information on the about page.
24 |
25 | Media projects with MANO/SMPL+H
26 | When using MANO/SMPL+H in a media project please give credit to Max Planck Institute for Intelligent Systems. For example: MANO/SMPL+H was used for character animation courtesy of the Max Planck Institute for Intelligent Systems.
27 |
28 | Commercial licensing opportunities
29 | For commercial use in any field, please contact ps-license@tue.mpg.de.
30 |
31 | Public-Relations
32 | Use for public-relations is possible only after obtaining explicit license, please contact ps-license@tue.mpg.de.
--------------------------------------------------------------------------------
/src/encoder/assets/mano/MANO_RIGHT.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/mano/MANO_RIGHT.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/mano/fhb_skel_centeridx9.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/mano/fhb_skel_centeridx9.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/mano/info.txt:
--------------------------------------------------------------------------------
1 | - MANO is unisex
2 | - MANO comes in 2 versions for left and right hand
3 | - SMPL+H is gender specific
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/mano/mano_v1_2/.DS_Store
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/._.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/mano/mano_v1_2/._.DS_Store
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Please read carefully the following terms and conditions and any accompanying documentation before you download and/or use the MANO/SMPL+H model, data and software, (the "Model"), including 3D meshes, blend weights, blend shapes, textures, software, scripts, and animations. By downloading and/or using the Model, you acknowledge that you have read these terms and conditions, understand them, and agree to be bound by them. If you do not agree with these terms and conditions, you must not download and/or use the Model.
2 |
3 | Ownership
4 | The Model has been developed at the Max Planck Institute for Intelligent Systems (hereinafter "MPI") and is owned by and proprietary material of the Max-Planck-Gesellschaft zur Foerderung der Wissenschaften e.V. (hereinafter "MPG"; MPI and MPG hereinafter collectively "Max-Planck").
5 |
6 | License Grant
7 | Max-Planck grants you a non-exclusive, non-transferable, free of charge right:
8 |
9 | To download the Model and use it on computers owned, leased or otherwise controlled by you and/or your organisation;
10 | To use the Model for the sole purpose of performing non-commercial scientific research, non-commercial education, or non-commercial artistic projects.
11 | Any other use, in particular any use for commercial purposes, is prohibited. This includes, without limitation, incorporation in a commercial product, use in a commercial service, as training data for a commercial product, for commercial ergonomic analysis (e.g. product design, architectural design, etc.), or production of other artifacts for commercial purposes including, for example, web services, movies, television programs, mobile applications, or video games. The Model may not be used for pornographic purposes or to generate pornographic material whether commercial or not. This license also prohibits the use of the Model to train methods/algorithms/neural networks/etc. for commercial use of any kind. The Model may not be reproduced, modified and/or made available in any form to any third party without Max-Planck's prior written permission. By downloading the Model, you agree not to reverse engineer it.
12 |
13 | Disclaimer of Representations and Warranties
14 | You expressly acknowledge and agree that the Model results from basic research, is provided "AS IS", may contain errors, and that any use of the Model is at your sole risk. MAX-PLANCK MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MODEL, NEITHER EXPRESS NOR IMPLIED, AND THE ABSENCE OF ANY LEGAL OR ACTUAL DEFECTS, WHETHER DISCOVERABLE OR NOT. Specifically, and not to limit the foregoing, Max-Planck makes no representations or warranties (i) regarding the merchantability or fitness for a particular purpose of the Model, (ii) that the use of the Model will not infringe any patents, copyrights or other intellectual property rights of a third party, and (iii) that the use of the Model will not cause any damage of any kind to you or a third party.
15 |
16 | Limitation of Liability
17 | Under no circumstances shall Max-Planck be liable for any incidental, special, indirect or consequential damages arising out of or relating to this license, including but not limited to, any lost profits, business interruption, loss of programs or other data, or all other commercial damages or losses, even if advised of the possibility thereof.
18 |
19 | No Maintenance Services
20 | You understand and agree that Max-Planck is under no obligation to provide either maintenance services, update services, notices of latent defects, or corrections of defects with regard to the Model. Max-Planck nevertheless reserves the right to update, modify, or discontinue the Model at any time.
21 |
22 | Publication with MANO/SMPL+H
23 | You agree to cite the most recent paper describing the model as specified on the download website. This website lists the most up to date bibliographic information on the about page.
24 |
25 | Media projects with MANO/SMPL+H
26 | When using MANO/SMPL+H in a media project please give credit to Max Planck Institute for Intelligent Systems. For example: MANO/SMPL+H was used for character animation courtesy of the Max Planck Institute for Intelligent Systems.
27 |
28 | Commercial licensing opportunities
29 | For commercial use in any field, please contact ps-license@tue.mpg.de.
30 |
31 | Public-Relations
32 | Use for public-relations is possible only after obtaining explicit license, please contact ps-license@tue.mpg.de.
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 |
10 | About this file:
11 | ================
12 | This is an initialization file to help python look for submodules in this directory.
13 |
14 | '''
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/models/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Please read carefully the following terms and conditions and any accompanying documentation before you download and/or use the MANO/SMPL+H model, data and software, (the "Model"), including 3D meshes, blend weights, blend shapes, textures, software, scripts, and animations. By downloading and/or using the Model, you acknowledge that you have read these terms and conditions, understand them, and agree to be bound by them. If you do not agree with these terms and conditions, you must not download and/or use the Model.
2 |
3 | Ownership
4 | The Model has been developed at the Max Planck Institute for Intelligent Systems (hereinafter "MPI") and is owned by and proprietary material of the Max-Planck-Gesellschaft zur Foerderung der Wissenschaften e.V. (hereinafter "MPG"; MPI and MPG hereinafter collectively "Max-Planck").
5 |
6 | License Grant
7 | Max-Planck grants you a non-exclusive, non-transferable, free of charge right:
8 |
9 | To download the Model and use it on computers owned, leased or otherwise controlled by you and/or your organisation;
10 | To use the Model for the sole purpose of performing non-commercial scientific research, non-commercial education, or non-commercial artistic projects.
11 | Any other use, in particular any use for commercial purposes, is prohibited. This includes, without limitation, incorporation in a commercial product, use in a commercial service, as training data for a commercial product, for commercial ergonomic analysis (e.g. product design, architectural design, etc.), or production of other artifacts for commercial purposes including, for example, web services, movies, television programs, mobile applications, or video games. The Model may not be used for pornographic purposes or to generate pornographic material whether commercial or not. This license also prohibits the use of the Model to train methods/algorithms/neural networks/etc. for commercial use of any kind. The Model may not be reproduced, modified and/or made available in any form to any third party without Max-Planck's prior written permission. By downloading the Model, you agree not to reverse engineer it.
12 |
13 | Disclaimer of Representations and Warranties
14 | You expressly acknowledge and agree that the Model results from basic research, is provided "AS IS", may contain errors, and that any use of the Model is at your sole risk. MAX-PLANCK MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MODEL, NEITHER EXPRESS NOR IMPLIED, AND THE ABSENCE OF ANY LEGAL OR ACTUAL DEFECTS, WHETHER DISCOVERABLE OR NOT. Specifically, and not to limit the foregoing, Max-Planck makes no representations or warranties (i) regarding the merchantability or fitness for a particular purpose of the Model, (ii) that the use of the Model will not infringe any patents, copyrights or other intellectual property rights of a third party, and (iii) that the use of the Model will not cause any damage of any kind to you or a third party.
15 |
16 | Limitation of Liability
17 | Under no circumstances shall Max-Planck be liable for any incidental, special, indirect or consequential damages arising out of or relating to this license, including but not limited to, any lost profits, business interruption, loss of programs or other data, or all other commercial damages or losses, even if advised of the possibility thereof.
18 |
19 | No Maintenance Services
20 | You understand and agree that Max-Planck is under no obligation to provide either maintenance services, update services, notices of latent defects, or corrections of defects with regard to the Model. Max-Planck nevertheless reserves the right to update, modify, or discontinue the Model at any time.
21 |
22 | Publication with MANO/SMPL+H
23 | You agree to cite the most recent paper describing the model as specified on the download website. This website lists the most up to date bibliographic information on the about page.
24 |
25 | Media projects with MANO/SMPL+H
26 | When using MANO/SMPL+H in a media project please give credit to Max Planck Institute for Intelligent Systems. For example: MANO/SMPL+H was used for character animation courtesy of the Max Planck Institute for Intelligent Systems.
27 |
28 | Commercial licensing opportunities
29 | For commercial use in any field, please contact ps-license@tue.mpg.de.
30 |
31 | Public-Relations
32 | Use for public-relations is possible only after obtaining explicit license, please contact ps-license@tue.mpg.de.
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/models/MANO_LEFT.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/mano/mano_v1_2/models/MANO_LEFT.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/models/MANO_RIGHT.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/assets/mano/mano_v1_2/models/MANO_RIGHT.pkl
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/models/SMPLH_female.pkl:
--------------------------------------------------------------------------------
1 | version https://git-lfs.github.com/spec/v1
2 | oid sha256:b3113724e824cf8f990977f327eaad724c943a56d895b72dc78c6fb647aa0e1e
3 | size 130423021
4 |
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/models/info.txt:
--------------------------------------------------------------------------------
1 | - MANO is unisex
2 | - MANO comes in 2 versions for left and right hand
3 | - SMPL+H is gender specific
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/webuser/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Please read carefully the following terms and conditions and any accompanying documentation before you download and/or use the MANO/SMPL+H model, data and software, (the "Model"), including 3D meshes, blend weights, blend shapes, textures, software, scripts, and animations. By downloading and/or using the Model, you acknowledge that you have read these terms and conditions, understand them, and agree to be bound by them. If you do not agree with these terms and conditions, you must not download and/or use the Model.
2 |
3 | Ownership
4 | The Model has been developed at the Max Planck Institute for Intelligent Systems (hereinafter "MPI") and is owned by and proprietary material of the Max-Planck-Gesellschaft zur Foerderung der Wissenschaften e.V. (hereinafter "MPG"; MPI and MPG hereinafter collectively "Max-Planck").
5 |
6 | License Grant
7 | Max-Planck grants you a non-exclusive, non-transferable, free of charge right:
8 |
9 | To download the Model and use it on computers owned, leased or otherwise controlled by you and/or your organisation;
10 | To use the Model for the sole purpose of performing non-commercial scientific research, non-commercial education, or non-commercial artistic projects.
11 | Any other use, in particular any use for commercial purposes, is prohibited. This includes, without limitation, incorporation in a commercial product, use in a commercial service, as training data for a commercial product, for commercial ergonomic analysis (e.g. product design, architectural design, etc.), or production of other artifacts for commercial purposes including, for example, web services, movies, television programs, mobile applications, or video games. The Model may not be used for pornographic purposes or to generate pornographic material whether commercial or not. This license also prohibits the use of the Model to train methods/algorithms/neural networks/etc. for commercial use of any kind. The Model may not be reproduced, modified and/or made available in any form to any third party without Max-Planck's prior written permission. By downloading the Model, you agree not to reverse engineer it.
12 |
13 | Disclaimer of Representations and Warranties
14 | You expressly acknowledge and agree that the Model results from basic research, is provided "AS IS", may contain errors, and that any use of the Model is at your sole risk. MAX-PLANCK MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MODEL, NEITHER EXPRESS NOR IMPLIED, AND THE ABSENCE OF ANY LEGAL OR ACTUAL DEFECTS, WHETHER DISCOVERABLE OR NOT. Specifically, and not to limit the foregoing, Max-Planck makes no representations or warranties (i) regarding the merchantability or fitness for a particular purpose of the Model, (ii) that the use of the Model will not infringe any patents, copyrights or other intellectual property rights of a third party, and (iii) that the use of the Model will not cause any damage of any kind to you or a third party.
15 |
16 | Limitation of Liability
17 | Under no circumstances shall Max-Planck be liable for any incidental, special, indirect or consequential damages arising out of or relating to this license, including but not limited to, any lost profits, business interruption, loss of programs or other data, or all other commercial damages or losses, even if advised of the possibility thereof.
18 |
19 | No Maintenance Services
20 | You understand and agree that Max-Planck is under no obligation to provide either maintenance services, update services, notices of latent defects, or corrections of defects with regard to the Model. Max-Planck nevertheless reserves the right to update, modify, or discontinue the Model at any time.
21 |
22 | Publication with MANO/SMPL+H
23 | You agree to cite the most recent paper describing the model as specified on the download website. This website lists the most up to date bibliographic information on the about page.
24 |
25 | Media projects with MANO/SMPL+H
26 | When using MANO/SMPL+H in a media project please give credit to Max Planck Institute for Intelligent Systems. For example: MANO/SMPL+H was used for character animation courtesy of the Max Planck Institute for Intelligent Systems.
27 |
28 | Commercial licensing opportunities
29 | For commercial use in any field, please contact ps-license@tue.mpg.de.
30 |
31 | Public-Relations
32 | Use for public-relations is possible only after obtaining explicit license, please contact ps-license@tue.mpg.de.
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/webuser/README.txt:
--------------------------------------------------------------------------------
1 | License:
2 | ========
3 | To learn about MANO and SMPL+H, please visit our website: http://mano.is.tue.mpg.de
4 | You can find the MANO/SMPL+H paper at: http://files.is.tue.mpg.de/dtzionas/MANO/paper/Embodied_Hands_SiggraphAsia2017.pdf
5 |
6 | Visit our downloads page to download data (scans, alignments), model files and python code for MANO (hand-only) and SMPL+H (body+hands):
7 | http://mano.is.tue.mpg.de/downloads
8 |
9 | For comments or questions, please email us at: mano@tue.mpg.de
10 |
11 |
12 | System Requirements:
13 | ====================
14 | Operating system: OSX, Linux
15 |
16 | Python Dependencies:
17 | - Numpy & Scipy [http://www.scipy.org/scipylib/download.html]
18 | - Chumpy [https://github.com/mattloper/chumpy]
19 | - OpenCV [http://opencv.org/downloads.html]
20 |
21 |
22 | Getting Started:
23 | ================
24 |
25 | 1. Extract the Code:
26 | --------------------
27 | Extract the "mano.zip" file to your home directory (or any other location you wish)
28 |
29 |
30 | 2. Set the PYTHONPATH:
31 | ----------------------
32 | We need to update the PYTHONPATH environment variable so that the system knows how to find the MANO/SMPL+H code. Add the following lines to your ~/.bash_profile file (create it if it doesn't exist; Linux users might have ~/.bashrc file instead), replacing ~/mano with the location where you extracted the mano.zip (or with version 1_X: mano_v1_X.zip) file:
33 |
34 | MANO_LOCATION=~/mano_v1_2
35 | export PYTHONPATH=$PYTHONPATH:$MANO_LOCATION
36 |
37 |
38 | Open a new terminal window to check if the python path has been updated by typing the following:
39 | > echo $PYTHONPATH
40 |
41 |
42 | 3. Install the 3D viewer
43 | -------------------------------
44 | - Please follow the installation instruction @ https://github.com/MPI-IS/mesh
45 | - Run 'pip install opendr' (in the same virtual environment)
46 |
47 |
48 | 4. Run the Hello World scripts:
49 | -------------------------------
50 | In the new Terminal window, navigate to the mano/webuser/hello_world directory. You can run the hello world scripts now by typing the following:
51 |
52 | > python MANO___hello_world.py
53 |
54 | OR
55 |
56 | > python MANO___render.py
57 |
58 | OR
59 |
60 | > python SMPL+H___hello_world.py
61 |
62 | OR
63 |
64 | > python SMPL+H___render.py
65 |
66 |
67 | Note:
68 | Both of these scripts will require the dependencies listed above. The scripts are provided as a sample to help you get started.
69 |
70 | Acknowledgements:
71 | The code is based on the release code of http://smpl.is.tue.mpg.de. Therefore, we would like to kindly thank Matthew Loper and Naureen Mahmood.
72 |
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/webuser/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 |
10 | About this file:
11 | ================
12 | This is an initialization file to help python look for submodules in this directory.
13 | '''
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/webuser/hello_world/MANO___hello_world.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 | Acknowledgements:
10 | The code file is based on the release code of http://smpl.is.tue.mpg.de with adaptations.
11 | Therefore, we would like to kindly thank Matthew Loper and Naureen Mahmood.
12 |
13 |
14 | Please Note:
15 | ============
16 | This is a demo version of the script for driving the MANO model with python.
17 | We would be happy to receive comments, help and suggestions on improving this code
18 | and in making it available on more platforms.
19 |
20 |
21 | System Requirements:
22 | ====================
23 | Operating system: OSX, Linux
24 |
25 | Python Dependencies:
26 | - Numpy & Scipy [http://www.scipy.org/scipylib/download.html]
27 | - Chumpy [https://github.com/mattloper/chumpy]
28 |
29 |
30 | About the Script:
31 | =================
32 | This script demonstrates a few basic functions to help users get started with using
33 | the MANO model. The code shows how to:
34 | - Load the MANO model
35 | - Edit pose & shape parameters of the model to create a new body in a new pose
36 | - Save the resulting body as a mesh in .OBJ format
37 |
38 |
39 | Running the Hello World code:
40 | =============================
41 | Inside Terminal, navigate to the mano/webuser/hello_world directory. You can run
42 | the hello world script now by typing the following:
43 | > python MANO___hello_world.py
44 |
45 | '''
46 |
47 | from webuser.smpl_handpca_wrapper_HAND_only import load_model
48 | import numpy as np
49 |
50 | ## Load MANO/SMPL+H model (here we load the righ hand model)
51 | ## Make sure path is correct
52 | m = load_model('../../models/MANO_RIGHT.pkl', ncomps=6, flat_hand_mean=False)
53 |
54 | ## Assign random pose and shape parameters
55 | m.betas[:] = np.random.rand(m.betas.size) * .03
56 | #m.pose[:] = np.random.rand(m.pose.size) * 1.0
57 | m.pose[:3] = [0., 0., 0.]
58 | m.pose[3:] = [-0.42671473, -0.85829819, -0.50662164, +1.97374622, -0.84298473, -1.29958491]
59 | # the first 3 elements correspond to global rotation
60 | # the next ncomps to the hand pose
61 |
62 | ## Write to an .obj file
63 | outmesh_path = './MANO___hello_world___PosedShaped.obj'
64 | with open(outmesh_path, 'w') as fp:
65 | for v in m.r:
66 | fp.write( 'v %f %f %f\n' % ( v[0], v[1], v[2]) )
67 |
68 | for f in m.f+1: # Faces are 1-based, not 0-based in obj files
69 | fp.write( 'f %d %d %d\n' % (f[0], f[1], f[2]) )
70 |
71 | ## Print message
72 | print '..Output mesh saved to: ', outmesh_path
73 |
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/webuser/hello_world/SMPL+H___hello_world.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 | Acknowledgements:
10 | The code file is based on the release code of http://smpl.is.tue.mpg.de with adaptations.
11 | Therefore, we would like to kindly thank Matthew Loper and Naureen Mahmood.
12 |
13 |
14 | Please Note:
15 | ============
16 | This is a demo version of the script for driving the SMPL+H model with python.
17 | We would be happy to receive comments, help and suggestions on improving this code
18 | and in making it available on more platforms.
19 |
20 |
21 | System Requirements:
22 | ====================
23 | Operating system: OSX, Linux
24 |
25 | Python Dependencies:
26 | - Numpy & Scipy [http://www.scipy.org/scipylib/download.html]
27 | - Chumpy [https://github.com/mattloper/chumpy]
28 |
29 |
30 | About the Script:
31 | =================
32 | This script demonstrates a few basic functions to help users get started with using
33 | the SMPL+H model. The code shows how to:
34 | - Load the SMPL+H model
35 | - Edit pose & shape parameters of the model to create a new body in a new pose
36 | - Save the resulting body as a mesh in .OBJ format
37 |
38 |
39 | Running the Hello World code:
40 | =============================
41 | Inside Terminal, navigate to the mano/webuser/hello_world directory. You can run
42 | the hello world script now by typing the following:
43 | > python SMPL+H___hello_world.py
44 |
45 | '''
46 |
47 | from webuser.smpl_handpca_wrapper import load_model
48 | import numpy as np
49 |
50 | # Load SMPL+H model (here we load the female model)
51 | m = load_model('../../models/SMPLH_female.pkl', ncomps=12, flat_hand_mean=False)
52 |
53 | # Assign random pose and shape parameters
54 | m.betas[:] = np.random.rand(m.betas.size) * .03
55 | #m.pose[:] = np.random.rand(m.pose.size) * .2
56 | m.pose[:] = [-0.17192541, +0.36310464, +0.05572387, -0.42836206, -0.00707548, +0.03556427,
57 | +0.18696896, -0.22704364, -0.39019834, +0.20273526, +0.07125099, +0.07105988,
58 | +0.71328310, -0.29426986, -0.18284189, +0.72134655, +0.07865227, +0.08342645,
59 | +0.00934835, +0.12881420, -0.02610217, -0.15579594, +0.25352553, -0.26097519,
60 | -0.04529948, -0.14718626, +0.52724564, -0.07638319, +0.03324086, +0.05886086,
61 | -0.05683995, -0.04069042, +0.68593617, -0.75870686, -0.08579930, -0.55086359,
62 | -0.02401033, -0.46217096, -0.03665799, +0.12397343, +0.10974685, -0.41607569,
63 | -0.26874970, +0.40249335, +0.21223768, +0.03365140, -0.05243080, +0.16074013,
64 | +0.13433811, +0.10414972, -0.98688595, -0.17270103, +0.29374368, +0.61868383,
65 | +0.00458329, -0.15357027, +0.09531648, -0.10624117, +0.94679869, -0.26851003,
66 | +0.58547889, -0.13735695, -0.39952280, -0.16598853, -0.14982575, -0.27937399,
67 | +0.12354536, -0.55101035, -0.41938681, +0.52238684, -0.23376718, -0.29814804,
68 | -0.42671473, -0.85829819, -0.50662164, +1.97374622, -0.84298473, -1.29958491]
69 | # the first 66 elements correspond to body pose
70 | # the next ncomps to left and right hand pose (ncomps/2 + ncomps/2)
71 |
72 | # Write to an .obj file
73 | outmesh_path = './SMPL+H___hello_world___PosedShaped.obj'
74 | with open(outmesh_path, 'w') as fp:
75 | for v in m.r:
76 | fp.write( 'v %f %f %f\n' % ( v[0], v[1], v[2]) )
77 |
78 | for f in m.f+1: # Faces are 1-based, not 0-based in obj files
79 | fp.write( 'f %d %d %d\n' % (f[0], f[1], f[2]) )
80 |
81 | # Print message
82 | print '..Output mesh saved to: ', outmesh_path
83 |
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/webuser/lbs.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 | Acknowledgements:
10 | The code file is based on the release code of http://smpl.is.tue.mpg.de.
11 | Therefore, we would like to kindly thank Matthew Loper and Naureen Mahmood.
12 |
13 |
14 | About this file:
15 | ================
16 | This file defines linear blend skinning for the SMPL loader which
17 | defines the effect of bones and blendshapes on the vertices of the template mesh.
18 |
19 | Modules included:
20 | - global_rigid_transformation:
21 | computes global rotation & translation of the model
22 | - verts_core: [overloaded function inherited from verts.verts_core]
23 | computes the blending of joint-influences for each vertex based on type of skinning
24 |
25 | '''
26 |
27 | from posemapper import posemap
28 | import chumpy
29 | import numpy as np
30 |
31 | def global_rigid_transformation(pose, J, kintree_table, xp):
32 | results = {}
33 | pose = pose.reshape((-1,3))
34 | id_to_col = {kintree_table[1,i] : i for i in range(kintree_table.shape[1])}
35 | parent = {i : id_to_col[kintree_table[0,i]] for i in range(1, kintree_table.shape[1])}
36 |
37 | if xp == chumpy:
38 | from posemapper import Rodrigues
39 | rodrigues = lambda x : Rodrigues(x)
40 | else:
41 | import cv2
42 | rodrigues = lambda x : cv2.Rodrigues(x)[0]
43 |
44 | with_zeros = lambda x : xp.vstack((x, xp.array([[0.0, 0.0, 0.0, 1.0]])))
45 | results[0] = with_zeros(xp.hstack((rodrigues(pose[0,:]), J[0,:].reshape((3,1)))))
46 |
47 | for i in range(1, kintree_table.shape[1]):
48 | results[i] = results[parent[i]].dot(with_zeros(xp.hstack((
49 | rodrigues(pose[i,:]),
50 | ((J[i,:] - J[parent[i],:]).reshape((3,1)))
51 | ))))
52 |
53 | pack = lambda x : xp.hstack([np.zeros((4, 3)), x.reshape((4,1))])
54 |
55 | results = [results[i] for i in sorted(results.keys())]
56 | results_global = results
57 |
58 | if True:
59 | results2 = [results[i] - (pack(
60 | results[i].dot(xp.concatenate( ( (J[i,:]), 0 ) )))
61 | ) for i in range(len(results))]
62 | results = results2
63 | result = xp.dstack(results)
64 | return result, results_global
65 |
66 |
67 | def verts_core(pose, v, J, weights, kintree_table, want_Jtr=False, xp=chumpy):
68 | A, A_global = global_rigid_transformation(pose, J, kintree_table, xp)
69 | T = A.dot(weights.T)
70 |
71 | rest_shape_h = xp.vstack((v.T, np.ones((1, v.shape[0]))))
72 |
73 | v =(T[:,0,:] * rest_shape_h[0, :].reshape((1, -1)) +
74 | T[:,1,:] * rest_shape_h[1, :].reshape((1, -1)) +
75 | T[:,2,:] * rest_shape_h[2, :].reshape((1, -1)) +
76 | T[:,3,:] * rest_shape_h[3, :].reshape((1, -1))).T
77 |
78 | v = v[:,:3]
79 |
80 | class result_meta(object):
81 | pass
82 |
83 | if not want_Jtr:
84 | Jtr = None
85 | else:
86 | Jtr = xp.vstack([g[:3, 3] for g in A_global])
87 |
88 | meta = result_meta()
89 | meta.Jtr = Jtr
90 | meta.A = A
91 | meta.A_global = A_global
92 | meta.A_weighted = T
93 |
94 | return v, meta
95 |
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/webuser/posemapper.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 | Acknowledgements:
10 | The code file is based on the release code of http://smpl.is.tue.mpg.de.
11 | Therefore, we would like to kindly thank Matthew Loper and Naureen Mahmood.
12 |
13 |
14 | About this file:
15 | ================
16 | This module defines the mapping of joint-angles to pose-blendshapes.
17 |
18 | Modules included:
19 | - posemap:
20 | computes the joint-to-pose blend shape mapping given a mapping type as input
21 |
22 | '''
23 |
24 | import chumpy as ch
25 | import numpy as np
26 | import cv2
27 |
28 |
29 | class Rodrigues(ch.Ch):
30 | dterms = 'rt'
31 |
32 | def compute_r(self):
33 | return cv2.Rodrigues(self.rt.r)[0]
34 |
35 | def compute_dr_wrt(self, wrt):
36 | if wrt is self.rt:
37 | return cv2.Rodrigues(self.rt.r)[1].T
38 |
39 |
40 | def lrotmin(p):
41 | if isinstance(p, np.ndarray):
42 | p = p.ravel()[3:]
43 | return np.concatenate([(cv2.Rodrigues(np.array(pp))[0]-np.eye(3)).ravel() for pp in p.reshape((-1,3))]).ravel()
44 | if p.ndim != 2 or p.shape[1] != 3:
45 | p = p.reshape((-1,3))
46 | p = p[1:]
47 | return ch.concatenate([(Rodrigues(pp)-ch.eye(3)).ravel() for pp in p]).ravel()
48 |
49 | def posemap(s):
50 | if s == 'lrotmin':
51 | return lrotmin
52 | else:
53 | raise Exception('Unknown posemapping: %s' % (str(s),))
54 |
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/webuser/smpl_handpca_wrapper_HAND_only.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 |
10 | About this file:
11 | ================
12 | This file defines a wrapper for the loading functions of the MANO model.
13 |
14 | Modules included:
15 | - load_model:
16 | loads the MANO model from a given file location (i.e. a .pkl file location),
17 | or a dictionary object.
18 |
19 | '''
20 |
21 | def ready_arguments(fname_or_dict, posekey4vposed='pose'):
22 | import numpy as np
23 | import cPickle as pickle
24 | import chumpy as ch
25 | from chumpy.ch import MatVecMult
26 | from webuser.posemapper import posemap
27 |
28 | if not isinstance(fname_or_dict, dict):
29 | dd = pickle.load(open(fname_or_dict))
30 | else:
31 | dd = fname_or_dict
32 |
33 | want_shapemodel = 'shapedirs' in dd
34 | nposeparms = dd['kintree_table'].shape[1]*3
35 |
36 | if 'trans' not in dd:
37 | dd['trans'] = np.zeros(3)
38 | if 'pose' not in dd:
39 | dd['pose'] = np.zeros(nposeparms)
40 | if 'shapedirs' in dd and 'betas' not in dd:
41 | dd['betas'] = np.zeros(dd['shapedirs'].shape[-1])
42 |
43 | for s in ['v_template', 'weights', 'posedirs', 'pose', 'trans', 'shapedirs', 'betas', 'J']:
44 | if (s in dd) and not hasattr(dd[s], 'dterms'):
45 | dd[s] = ch.array(dd[s])
46 |
47 | assert(posekey4vposed in dd)
48 | if want_shapemodel:
49 | dd['v_shaped'] = dd['shapedirs'].dot(dd['betas'])+dd['v_template']
50 | v_shaped = dd['v_shaped']
51 | J_tmpx = MatVecMult(dd['J_regressor'], v_shaped[:, 0])
52 | J_tmpy = MatVecMult(dd['J_regressor'], v_shaped[:, 1])
53 | J_tmpz = MatVecMult(dd['J_regressor'], v_shaped[:, 2])
54 | dd['J'] = ch.vstack((J_tmpx, J_tmpy, J_tmpz)).T
55 | dd['v_posed'] = v_shaped + dd['posedirs'].dot(posemap(dd['bs_type'])(dd[posekey4vposed]))
56 | else:
57 | dd['v_posed'] = dd['v_template'] + dd['posedirs'].dot(posemap(dd['bs_type'])(dd[posekey4vposed]))
58 |
59 | return dd
60 |
61 |
62 | def load_model(fname_or_dict='./models/MANO_RIGHT.pkl', ncomps=6, flat_hand_mean=False, v_template=None):
63 | ''' This model loads the fully articulable HAND SMPL model,
64 | and replaces the pose DOFS by ncomps from PCA'''
65 |
66 | from webuser.verts import verts_core
67 | import numpy as np
68 | import chumpy as ch
69 | import pickle
70 | import scipy.sparse as sp
71 | np.random.seed(1)
72 |
73 | if not isinstance(fname_or_dict, dict):
74 | smpl_data = pickle.load(open(fname_or_dict))
75 | else:
76 | smpl_data = fname_or_dict
77 |
78 | rot = 3 # for global orientation!!!
79 |
80 | hands_components = smpl_data['hands_components']
81 | hands_mean = np.zeros(hands_components.shape[1]) if flat_hand_mean else smpl_data['hands_mean']
82 | hands_coeffs = smpl_data['hands_coeffs'][:, :ncomps]
83 |
84 | selected_components = np.vstack((hands_components[:ncomps]))
85 | hands_mean = hands_mean.copy()
86 |
87 | pose_coeffs = ch.zeros(rot + selected_components.shape[0])
88 | full_hand_pose = pose_coeffs[rot:(rot+ncomps)].dot(selected_components)
89 |
90 | smpl_data['fullpose'] = ch.concatenate((pose_coeffs[:rot], hands_mean + full_hand_pose))
91 | smpl_data['pose'] = pose_coeffs
92 |
93 | Jreg = smpl_data['J_regressor']
94 | if not sp.issparse(Jreg):
95 | smpl_data['J_regressor'] = (sp.csc_matrix((Jreg.data, (Jreg.row, Jreg.col)), shape=Jreg.shape))
96 |
97 | # slightly modify ready_arguments to make sure that it uses the fullpose
98 | # (which will NOT be pose) for the computation of posedirs
99 | dd = ready_arguments(smpl_data, posekey4vposed='fullpose')
100 |
101 | # create the smpl formula with the fullpose,
102 | # but expose the PCA coefficients as smpl.pose for compatibility
103 | args = {
104 | 'pose': dd['fullpose'],
105 | 'v': dd['v_posed'],
106 | 'J': dd['J'],
107 | 'weights': dd['weights'],
108 | 'kintree_table': dd['kintree_table'],
109 | 'xp': ch,
110 | 'want_Jtr': True,
111 | 'bs_style': dd['bs_style'],
112 | }
113 |
114 | result_previous, meta = verts_core(**args)
115 | result = result_previous + dd['trans'].reshape((1, 3))
116 | result.no_translation = result_previous
117 |
118 | if meta is not None:
119 | for field in ['Jtr', 'A', 'A_global', 'A_weighted']:
120 | if(hasattr(meta, field)):
121 | setattr(result, field, getattr(meta, field))
122 |
123 | if hasattr(result, 'Jtr'):
124 | result.J_transformed = result.Jtr + dd['trans'].reshape((1, 3))
125 |
126 | for k, v in dd.items():
127 | setattr(result, k, v)
128 |
129 | if v_template is not None:
130 | result.v_template[:] = v_template
131 |
132 | return result
133 |
134 | if __name__ == '__main__':
135 | m = load_model()
136 | m.J_transformed
137 | print 'FINITO'
138 |
--------------------------------------------------------------------------------
/src/encoder/assets/mano/mano_v1_2/webuser/verts.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 | Acknowledgements:
10 | The code file is based on the release code of http://smpl.is.tue.mpg.de.
11 | Therefore, we would like to kindly thank Matthew Loper and Naureen Mahmood.
12 |
13 |
14 | About this file:
15 | ================
16 | This file defines the basic skinning modules for the MANO/SMPL+H loader which
17 | defines the effect of bones and blendshapes on the vertices of the template mesh.
18 |
19 | Modules included:
20 | - verts_decorated:
21 | creates an instance of the SMPL model which inherits model attributes from another
22 | SMPL model.
23 | - verts_core: [overloaded function inherited by lbs.verts_core]
24 | computes the blending of joint-influences for each vertex based on type of skinning
25 |
26 | '''
27 |
28 | import chumpy
29 | import lbs
30 | from posemapper import posemap
31 | import scipy.sparse as sp
32 | from chumpy.ch import MatVecMult
33 |
34 | def ischumpy(x): return hasattr(x, 'dterms')
35 |
36 | def verts_decorated(trans, pose,
37 | v_template, J, weights, kintree_table, bs_style, f,
38 | bs_type=None, posedirs=None, betas=None, shapedirs=None, want_Jtr=False):
39 |
40 | for which in [trans, pose, v_template, weights, posedirs, betas, shapedirs]:
41 | if which is not None:
42 | assert ischumpy(which)
43 |
44 | v = v_template
45 |
46 | if shapedirs is not None:
47 | if betas is None:
48 | betas = chumpy.zeros(shapedirs.shape[-1])
49 | v_shaped = v + shapedirs.dot(betas)
50 | else:
51 | v_shaped = v
52 |
53 | if posedirs is not None:
54 | v_posed = v_shaped + posedirs.dot(posemap(bs_type)(pose))
55 | else:
56 | v_posed = v_shaped
57 |
58 | v = v_posed
59 |
60 | if sp.issparse(J):
61 | regressor = J
62 | J_tmpx = MatVecMult(regressor, v_shaped[:,0])
63 | J_tmpy = MatVecMult(regressor, v_shaped[:,1])
64 | J_tmpz = MatVecMult(regressor, v_shaped[:,2])
65 | J = chumpy.vstack((J_tmpx, J_tmpy, J_tmpz)).T
66 | else:
67 | assert(ischumpy(J))
68 |
69 | assert(bs_style=='lbs')
70 | result, Jtr = lbs.verts_core(pose, v, J, weights, kintree_table, want_Jtr=True, xp=chumpy)
71 |
72 | tr = trans.reshape((1,3))
73 | result = result + tr
74 | Jtr = Jtr + tr
75 |
76 | result.trans = trans
77 | result.f = f
78 | result.pose = pose
79 | result.v_template = v_template
80 | result.J = J
81 | result.weights = weights
82 | result.kintree_table = kintree_table
83 | result.bs_style = bs_style
84 | result.bs_type =bs_type
85 | if posedirs is not None:
86 | result.posedirs = posedirs
87 | result.v_posed = v_posed
88 | if shapedirs is not None:
89 | result.shapedirs = shapedirs
90 | result.betas = betas
91 | result.v_shaped = v_shaped
92 | if want_Jtr:
93 | result.J_transformed = Jtr
94 | return result
95 |
96 | def verts_core(pose, v, J, weights, kintree_table, bs_style, want_Jtr=False, xp=chumpy):
97 |
98 | if xp == chumpy:
99 | assert(hasattr(pose, 'dterms'))
100 | assert(hasattr(v, 'dterms'))
101 | assert(hasattr(J, 'dterms'))
102 | assert(hasattr(weights, 'dterms'))
103 |
104 | assert(bs_style=='lbs')
105 | result = lbs.verts_core(pose, v, J, weights, kintree_table, want_Jtr, xp)
106 |
107 | return result
108 |
--------------------------------------------------------------------------------
/src/encoder/mano/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/mano/__init__.py
--------------------------------------------------------------------------------
/src/encoder/mano/webuser/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/encoder/mano/webuser/__init__.py
--------------------------------------------------------------------------------
/src/encoder/mano/webuser/lbs.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 |
10 | About this file:
11 | ================
12 | This file defines a wrapper for the loading functions of the MANO model.
13 |
14 | Modules included:
15 | - load_model:
16 | loads the MANO model from a given file location (i.e. a .pkl file location),
17 | or a dictionary object.
18 |
19 | '''
20 |
21 |
22 | from mano.webuser.posemapper import posemap
23 | import chumpy
24 | import numpy as np
25 |
26 |
27 | def global_rigid_transformation(pose, J, kintree_table, xp):
28 | results = {}
29 | pose = pose.reshape((-1, 3))
30 | id_to_col = {kintree_table[1, i]: i for i in range(kintree_table.shape[1])}
31 | parent = {
32 | i: id_to_col[kintree_table[0, i]]
33 | for i in range(1, kintree_table.shape[1])
34 | }
35 |
36 | if xp == chumpy:
37 | from mano.webuser.posemapper import Rodrigues
38 | rodrigues = lambda x: Rodrigues(x)
39 | else:
40 | import cv2
41 | rodrigues = lambda x: cv2.Rodrigues(x)[0]
42 |
43 | with_zeros = lambda x: xp.vstack((x, xp.array([[0.0, 0.0, 0.0, 1.0]])))
44 | results[0] = with_zeros(
45 | xp.hstack((rodrigues(pose[0, :]), J[0, :].reshape((3, 1)))))
46 |
47 | for i in range(1, kintree_table.shape[1]):
48 | results[i] = results[parent[i]].dot(
49 | with_zeros(
50 | xp.hstack((rodrigues(pose[i, :]), ((J[i, :] - J[parent[i], :]
51 | ).reshape((3, 1)))))))
52 |
53 | pack = lambda x: xp.hstack([np.zeros((4, 3)), x.reshape((4, 1))])
54 |
55 | results = [results[i] for i in sorted(results.keys())]
56 | results_global = results
57 |
58 | if True:
59 | results2 = [
60 | results[i] - (pack(results[i].dot(xp.concatenate(((J[i, :]), 0)))))
61 | for i in range(len(results))
62 | ]
63 | results = results2
64 | result = xp.dstack(results)
65 | return result, results_global
66 |
67 |
68 | def verts_core(pose, v, J, weights, kintree_table, want_Jtr=False, xp=chumpy):
69 | A, A_global = global_rigid_transformation(pose, J, kintree_table, xp)
70 | T = A.dot(weights.T)
71 |
72 | rest_shape_h = xp.vstack((v.T, np.ones((1, v.shape[0]))))
73 |
74 | v = (T[:, 0, :] * rest_shape_h[0, :].reshape(
75 | (1, -1)) + T[:, 1, :] * rest_shape_h[1, :].reshape(
76 | (1, -1)) + T[:, 2, :] * rest_shape_h[2, :].reshape(
77 | (1, -1)) + T[:, 3, :] * rest_shape_h[3, :].reshape((1, -1))).T
78 |
79 | v = v[:, :3]
80 |
81 | if not want_Jtr:
82 | return v
83 | Jtr = xp.vstack([g[:3, 3] for g in A_global])
84 | return (v, Jtr)
85 |
--------------------------------------------------------------------------------
/src/encoder/mano/webuser/posemapper.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 |
10 | About this file:
11 | ================
12 | This file defines a wrapper for the loading functions of the MANO model.
13 |
14 | Modules included:
15 | - load_model:
16 | loads the MANO model from a given file location (i.e. a .pkl file location),
17 | or a dictionary object.
18 |
19 | '''
20 |
21 |
22 | import chumpy as ch
23 | import numpy as np
24 | import cv2
25 |
26 |
27 | class Rodrigues(ch.Ch):
28 | dterms = 'rt'
29 |
30 | def compute_r(self):
31 | return cv2.Rodrigues(self.rt.r)[0]
32 |
33 | def compute_dr_wrt(self, wrt):
34 | if wrt is self.rt:
35 | return cv2.Rodrigues(self.rt.r)[1].T
36 |
37 |
38 | def lrotmin(p):
39 | if isinstance(p, np.ndarray):
40 | p = p.ravel()[3:]
41 | return np.concatenate(
42 | [(cv2.Rodrigues(np.array(pp))[0] - np.eye(3)).ravel()
43 | for pp in p.reshape((-1, 3))]).ravel()
44 | if p.ndim != 2 or p.shape[1] != 3:
45 | p = p.reshape((-1, 3))
46 | p = p[1:]
47 | return ch.concatenate([(Rodrigues(pp) - ch.eye(3)).ravel()
48 | for pp in p]).ravel()
49 |
50 |
51 | def posemap(s):
52 | if s == 'lrotmin':
53 | return lrotmin
54 | else:
55 | raise Exception('Unknown posemapping: %s' % (str(s), ))
56 |
--------------------------------------------------------------------------------
/src/encoder/mano/webuser/serialization.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 |
10 | About this file:
11 | ================
12 | This file defines a wrapper for the loading functions of the MANO model.
13 |
14 | Modules included:
15 | - load_model:
16 | loads the MANO model from a given file location (i.e. a .pkl file location),
17 | or a dictionary object.
18 |
19 | '''
20 |
21 |
22 | __all__ = ['load_model', 'save_model']
23 |
24 | import numpy as np
25 | import pickle
26 | import chumpy as ch
27 | from chumpy.ch import MatVecMult
28 | from mano.webuser.posemapper import posemap
29 | from mano.webuser.verts import verts_core
30 |
31 | def ready_arguments(fname_or_dict):
32 |
33 | if not isinstance(fname_or_dict, dict):
34 | dd = pickle.load(open(fname_or_dict, 'rb'), encoding='latin1')
35 | else:
36 | dd = fname_or_dict
37 |
38 | backwards_compatibility_replacements(dd)
39 |
40 | want_shapemodel = 'shapedirs' in dd
41 | nposeparms = dd['kintree_table'].shape[1] * 3
42 |
43 | if 'trans' not in dd:
44 | dd['trans'] = np.zeros(3)
45 | if 'pose' not in dd:
46 | dd['pose'] = np.zeros(nposeparms)
47 | if 'shapedirs' in dd and 'betas' not in dd:
48 | dd['betas'] = np.zeros(dd['shapedirs'].shape[-1])
49 |
50 | for s in [
51 | 'v_template', 'weights', 'posedirs', 'pose', 'trans', 'shapedirs',
52 | 'betas', 'J'
53 | ]:
54 | if (s in dd) and not hasattr(dd[s], 'dterms'):
55 | dd[s] = ch.array(dd[s])
56 |
57 | if want_shapemodel:
58 | dd['v_shaped'] = dd['shapedirs'].dot(dd['betas']) + dd['v_template']
59 | v_shaped = dd['v_shaped']
60 | J_tmpx = MatVecMult(dd['J_regressor'], v_shaped[:, 0])
61 | J_tmpy = MatVecMult(dd['J_regressor'], v_shaped[:, 1])
62 | J_tmpz = MatVecMult(dd['J_regressor'], v_shaped[:, 2])
63 | dd['J'] = ch.vstack((J_tmpx, J_tmpy, J_tmpz)).T
64 | dd['v_posed'] = v_shaped + dd['posedirs'].dot(
65 | posemap(dd['bs_type'])(dd['pose']))
66 | else:
67 | dd['v_posed'] = dd['v_template'] + dd['posedirs'].dot(
68 | posemap(dd['bs_type'])(dd['pose']))
69 |
70 | return dd
71 |
72 |
73 | def load_model(fname_or_dict):
74 | dd = ready_arguments(fname_or_dict)
75 |
76 | args = {
77 | 'pose': dd['pose'],
78 | 'v': dd['v_posed'],
79 | 'J': dd['J'],
80 | 'weights': dd['weights'],
81 | 'kintree_table': dd['kintree_table'],
82 | 'xp': ch,
83 | 'want_Jtr': True,
84 | 'bs_style': dd['bs_style']
85 | }
86 |
87 | result, Jtr = verts_core(**args)
88 | result = result + dd['trans'].reshape((1, 3))
89 | result.J_transformed = Jtr + dd['trans'].reshape((1, 3))
90 |
91 | for k, v in dd.items():
92 | setattr(result, k, v)
93 |
94 | return result
95 |
--------------------------------------------------------------------------------
/src/encoder/mano/webuser/smpl_handpca_wrapper_HAND_only.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 |
10 | About this file:
11 | ================
12 | This file defines a wrapper for the loading functions of the MANO model.
13 |
14 | Modules included:
15 | - load_model:
16 | loads the MANO model from a given file location (i.e. a .pkl file location),
17 | or a dictionary object.
18 |
19 | '''
20 |
21 |
22 | def ready_arguments(fname_or_dict, posekey4vposed='pose'):
23 | import numpy as np
24 | import pickle
25 | import chumpy as ch
26 | from chumpy.ch import MatVecMult
27 | from ..webuser.posemapper import posemap
28 |
29 | if not isinstance(fname_or_dict, dict):
30 | dd = pickle.load(open(fname_or_dict, 'rb'), encoding='latin1')
31 | # dd = pickle.load(open(fname_or_dict, 'rb'))
32 | else:
33 | dd = fname_or_dict
34 |
35 | want_shapemodel = 'shapedirs' in dd
36 | nposeparms = dd['kintree_table'].shape[1] * 3
37 |
38 | if 'trans' not in dd:
39 | dd['trans'] = np.zeros(3)
40 | if 'pose' not in dd:
41 | dd['pose'] = np.zeros(nposeparms)
42 | if 'shapedirs' in dd and 'betas' not in dd:
43 | dd['betas'] = np.zeros(dd['shapedirs'].shape[-1])
44 |
45 | for s in [
46 | 'v_template', 'weights', 'posedirs', 'pose', 'trans', 'shapedirs',
47 | 'betas', 'J'
48 | ]:
49 | if (s in dd) and not hasattr(dd[s], 'dterms'):
50 | dd[s] = ch.array(dd[s])
51 |
52 | assert (posekey4vposed in dd)
53 | if want_shapemodel:
54 | dd['v_shaped'] = dd['shapedirs'].dot(dd['betas']) + dd['v_template']
55 | v_shaped = dd['v_shaped']
56 | J_tmpx = MatVecMult(dd['J_regressor'], v_shaped[:, 0])
57 | J_tmpy = MatVecMult(dd['J_regressor'], v_shaped[:, 1])
58 | J_tmpz = MatVecMult(dd['J_regressor'], v_shaped[:, 2])
59 | dd['J'] = ch.vstack((J_tmpx, J_tmpy, J_tmpz)).T
60 | pose_map_res = posemap(dd['bs_type'])(dd[posekey4vposed])
61 | dd['v_posed'] = v_shaped + dd['posedirs'].dot(pose_map_res)
62 | else:
63 | pose_map_res = posemap(dd['bs_type'])(dd[posekey4vposed])
64 | dd_add = dd['posedirs'].dot(pose_map_res)
65 | dd['v_posed'] = dd['v_template'] + dd_add
66 |
67 | return dd
68 |
69 |
70 | def load_model(fname_or_dict, ncomps=6, flat_hand_mean=False, v_template=None):
71 | ''' This model loads the fully articulable HAND SMPL model,
72 | and replaces the pose DOFS by ncomps from PCA'''
73 |
74 | from mano.webuser.verts import verts_core
75 | import numpy as np
76 | import chumpy as ch
77 | import pickle
78 | import scipy.sparse as sp
79 | np.random.seed(1)
80 |
81 | if not isinstance(fname_or_dict, dict):
82 | smpl_data = pickle.load(open(fname_or_dict, 'rb'), encoding='latin1')
83 | # smpl_data = pickle.load(open(fname_or_dict, 'rb'))
84 | else:
85 | smpl_data = fname_or_dict
86 |
87 | rot = 3 # for global orientation!!!
88 |
89 | hands_components = smpl_data['hands_components']
90 | hands_mean = np.zeros(hands_components.shape[
91 | 1]) if flat_hand_mean else smpl_data['hands_mean']
92 | hands_coeffs = smpl_data['hands_coeffs'][:, :ncomps]
93 |
94 | selected_components = np.vstack((hands_components[:ncomps]))
95 | hands_mean = hands_mean.copy()
96 |
97 | pose_coeffs = ch.zeros(rot + selected_components.shape[0])
98 | full_hand_pose = pose_coeffs[rot:(rot + ncomps)].dot(selected_components)
99 |
100 | smpl_data['fullpose'] = ch.concatenate((pose_coeffs[:rot],
101 | hands_mean + full_hand_pose))
102 | smpl_data['pose'] = pose_coeffs
103 |
104 | Jreg = smpl_data['J_regressor']
105 | if not sp.issparse(Jreg):
106 | smpl_data['J_regressor'] = (sp.csc_matrix(
107 | (Jreg.data, (Jreg.row, Jreg.col)), shape=Jreg.shape))
108 |
109 | # slightly modify ready_arguments to make sure that it uses the fullpose
110 | # (which will NOT be pose) for the computation of posedirs
111 | dd = ready_arguments(smpl_data, posekey4vposed='fullpose')
112 |
113 | # create the smpl formula with the fullpose,
114 | # but expose the PCA coefficients as smpl.pose for compatibility
115 | args = {
116 | 'pose': dd['fullpose'],
117 | 'v': dd['v_posed'],
118 | 'J': dd['J'],
119 | 'weights': dd['weights'],
120 | 'kintree_table': dd['kintree_table'],
121 | 'xp': ch,
122 | 'want_Jtr': True,
123 | 'bs_style': dd['bs_style'],
124 | }
125 |
126 | result_previous, meta = verts_core(**args)
127 |
128 | result = result_previous + dd['trans'].reshape((1, 3))
129 | result.no_translation = result_previous
130 |
131 | if meta is not None:
132 | for field in ['Jtr', 'A', 'A_global', 'A_weighted']:
133 | if (hasattr(meta, field)):
134 | setattr(result, field, getattr(meta, field))
135 |
136 | setattr(result, 'Jtr', meta)
137 | if hasattr(result, 'Jtr'):
138 | result.J_transformed = result.Jtr + dd['trans'].reshape((1, 3))
139 |
140 | for k, v in dd.items():
141 | setattr(result, k, v)
142 |
143 | if v_template is not None:
144 | result.v_template[:] = v_template
145 |
146 | return result
147 |
148 |
149 | if __name__ == '__main__':
150 | load_model()
151 |
--------------------------------------------------------------------------------
/src/encoder/mano/webuser/verts.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright 2017 Javier Romero, Dimitrios Tzionas, Michael J Black and the Max Planck Gesellschaft. All rights reserved.
3 | This software is provided for research purposes only.
4 | By using this software you agree to the terms of the MANO/SMPL+H Model license here http://mano.is.tue.mpg.de/license
5 |
6 | More information about MANO/SMPL+H is available at http://mano.is.tue.mpg.de.
7 | For comments or questions, please email us at: mano@tue.mpg.de
8 |
9 |
10 | About this file:
11 | ================
12 | This file defines a wrapper for the loading functions of the MANO model.
13 |
14 | Modules included:
15 | - load_model:
16 | loads the MANO model from a given file location (i.e. a .pkl file location),
17 | or a dictionary object.
18 |
19 | '''
20 |
21 |
22 | import chumpy
23 | import mano.webuser.lbs as lbs
24 | from mano.webuser.posemapper import posemap
25 | import scipy.sparse as sp
26 | from chumpy.ch import MatVecMult
27 |
28 |
29 | def ischumpy(x):
30 | return hasattr(x, 'dterms')
31 |
32 |
33 | def verts_decorated(trans,
34 | pose,
35 | v_template,
36 | J_regressor,
37 | weights,
38 | kintree_table,
39 | bs_style,
40 | f,
41 | bs_type=None,
42 | posedirs=None,
43 | betas=None,
44 | shapedirs=None,
45 | want_Jtr=False):
46 |
47 | for which in [
48 | trans, pose, v_template, weights, posedirs, betas, shapedirs
49 | ]:
50 | if which is not None:
51 | assert ischumpy(which)
52 |
53 | v = v_template
54 |
55 | if shapedirs is not None:
56 | if betas is None:
57 | betas = chumpy.zeros(shapedirs.shape[-1])
58 | v_shaped = v + shapedirs.dot(betas)
59 | else:
60 | v_shaped = v
61 |
62 | if posedirs is not None:
63 | v_posed = v_shaped + posedirs.dot(posemap(bs_type)(pose))
64 | else:
65 | v_posed = v_shaped
66 |
67 | v = v_posed
68 |
69 | if sp.issparse(J_regressor):
70 | J_tmpx = MatVecMult(J_regressor, v_shaped[:, 0])
71 | J_tmpy = MatVecMult(J_regressor, v_shaped[:, 1])
72 | J_tmpz = MatVecMult(J_regressor, v_shaped[:, 2])
73 | J = chumpy.vstack((J_tmpx, J_tmpy, J_tmpz)).T
74 | else:
75 | assert (ischumpy(J))
76 |
77 | assert (bs_style == 'lbs')
78 | result, Jtr = lbs.verts_core(
79 | pose, v, J, weights, kintree_table, want_Jtr=True, xp=chumpy)
80 |
81 | tr = trans.reshape((1, 3))
82 | result = result + tr
83 | Jtr = Jtr + tr
84 |
85 | result.trans = trans
86 | result.f = f
87 | result.pose = pose
88 | result.v_template = v_template
89 | result.J = J
90 | result.J_regressor = J_regressor
91 | result.weights = weights
92 | result.kintree_table = kintree_table
93 | result.bs_style = bs_style
94 | result.bs_type = bs_type
95 | if posedirs is not None:
96 | result.posedirs = posedirs
97 | result.v_posed = v_posed
98 | if shapedirs is not None:
99 | result.shapedirs = shapedirs
100 | result.betas = betas
101 | result.v_shaped = v_shaped
102 | if want_Jtr:
103 | result.J_transformed = Jtr
104 | return result
105 |
106 |
107 | def verts_core(pose,
108 | v,
109 | J,
110 | weights,
111 | kintree_table,
112 | bs_style,
113 | want_Jtr=False,
114 | xp=chumpy):
115 |
116 | if xp == chumpy:
117 | assert (hasattr(pose, 'dterms'))
118 | assert (hasattr(v, 'dterms'))
119 | assert (hasattr(J, 'dterms'))
120 | assert (hasattr(weights, 'dterms'))
121 |
122 | assert (bs_style == 'lbs')
123 | result = lbs.verts_core(pose, v, J, weights, kintree_table, want_Jtr, xp)
124 | return result
125 |
--------------------------------------------------------------------------------
/src/encoder/manopth/__init__.py:
--------------------------------------------------------------------------------
1 | name = 'manopth'
2 |
--------------------------------------------------------------------------------
/src/encoder/manopth/anchorlayer.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import numpy as np
4 | import torch
5 | from torch.nn import Module
6 |
7 | from .anchorutils import anchor_load, recover_anchor, recover_anchor_batch
8 |
9 |
10 | class AnchorLayer(Module):
11 | def __init__(self, anchor_root):
12 | super().__init__()
13 |
14 | face_vert_idx, anchor_weight, merged_vertex_assignment, anchor_mapping = anchor_load(anchor_root)
15 | self.register_buffer("face_vert_idx", torch.from_numpy(face_vert_idx).long().unsqueeze(0))
16 | self.register_buffer("anchor_weight", torch.from_numpy(anchor_weight).float().unsqueeze(0))
17 | self.register_buffer("merged_vertex_assignment", torch.from_numpy(merged_vertex_assignment).long())
18 | self.anchor_mapping = anchor_mapping
19 |
20 | def forward(self, vertices):
21 | """
22 | vertices: TENSOR[N_BATCH, 778, 3]
23 | """
24 | anchor_pos = recover_anchor_batch(vertices, self.face_vert_idx, self.anchor_weight)
25 | # anchor_pos2 = recover_anchor(vertices[vertices.shape[0] - 1], self.face_vert_idx[0], self.anchor_weight[0])
26 | return anchor_pos
27 |
--------------------------------------------------------------------------------
/src/encoder/manopth/argutils.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import os
3 | import pickle
4 | import subprocess
5 | import sys
6 |
7 |
8 | def print_args(args):
9 | opts = vars(args)
10 | print('======= Options ========')
11 | for k, v in sorted(opts.items()):
12 | print('{}: {}'.format(k, v))
13 | print('========================')
14 |
15 |
16 | def save_args(args, save_folder, opt_prefix='opt', verbose=True):
17 | opts = vars(args)
18 | # Create checkpoint folder
19 | if not os.path.exists(save_folder):
20 | os.makedirs(save_folder, exist_ok=True)
21 |
22 | # Save options
23 | opt_filename = '{}.txt'.format(opt_prefix)
24 | opt_path = os.path.join(save_folder, opt_filename)
25 | with open(opt_path, 'a') as opt_file:
26 | opt_file.write('====== Options ======\n')
27 | for k, v in sorted(opts.items()):
28 | opt_file.write(
29 | '{option}: {value}\n'.format(option=str(k), value=str(v)))
30 | opt_file.write('=====================\n')
31 | opt_file.write('launched {} at {}\n'.format(
32 | str(sys.argv[0]), str(datetime.datetime.now())))
33 |
34 | # Add git info
35 | label = subprocess.check_output(["git", "describe",
36 | "--always"]).strip()
37 | if subprocess.call(
38 | ["git", "branch"],
39 | stderr=subprocess.STDOUT,
40 | stdout=open(os.devnull, 'w')) == 0:
41 | opt_file.write('=== Git info ====\n')
42 | opt_file.write('{}\n'.format(label))
43 | commit = subprocess.check_output(['git', 'rev-parse', 'HEAD'])
44 | opt_file.write('commit : {}\n'.format(commit.strip()))
45 |
46 | opt_picklename = '{}.pkl'.format(opt_prefix)
47 | opt_picklepath = os.path.join(save_folder, opt_picklename)
48 | with open(opt_picklepath, 'wb') as opt_file:
49 | pickle.dump(opts, opt_file)
50 | if verbose:
51 | print('Saved options to {}'.format(opt_path))
52 |
--------------------------------------------------------------------------------
/src/encoder/manopth/axislayer.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import numpy as np
4 | import torch
5 | from torch.nn import Module
6 |
7 |
8 | class AxisLayer(Module):
9 | def __init__(self):
10 | super(AxisLayer, self).__init__()
11 | self.joints_mapping = [5, 6, 7, 9, 10, 11, 17, 18, 19, 13, 14, 15, 1, 2, 3]
12 | up_axis_base = np.vstack((np.array([[0, 1, 0]]).repeat(12, axis=0), np.array([[1, 1, 1]]).repeat(3, axis=0)))
13 | self.register_buffer("up_axis_base", torch.from_numpy(up_axis_base).float().unsqueeze(0))
14 |
15 | def forward(self, hand_joints, transf):
16 | """
17 | input: hand_joints[B, 21, 3], transf[B, 16, 4, 4]
18 | output: b_axis[B, 15, 3], u_axis[B, 15, 3], l_axis[B, 15, 3]
19 | """
20 | bs = transf.shape[0]
21 |
22 | b_axis = hand_joints[:, self.joints_mapping] - hand_joints[:, [i + 1 for i in self.joints_mapping]]
23 | b_axis = (transf[:, 1:, :3, :3].transpose(2, 3) @ b_axis.unsqueeze(-1)).squeeze(-1)
24 |
25 | l_axis = torch.cross(b_axis, self.up_axis_base.expand(bs, 15, 3))
26 |
27 | u_axis = torch.cross(l_axis, b_axis)
28 |
29 | return (
30 | b_axis / torch.norm(b_axis, dim=2, keepdim=True),
31 | u_axis / torch.norm(u_axis, dim=2, keepdim=True),
32 | l_axis / torch.norm(l_axis, dim=2, keepdim=True),
33 | )
34 |
--------------------------------------------------------------------------------
/src/encoder/manopth/demo.py:
--------------------------------------------------------------------------------
1 | from matplotlib import pyplot as plt
2 | from mpl_toolkits.mplot3d import Axes3D
3 | from mpl_toolkits.mplot3d.art3d import Poly3DCollection
4 | import numpy as np
5 | import torch
6 |
7 | from manolayer import ManoLayer
8 |
9 |
10 | def generate_random_hand(batch_size=1, ncomps=6, mano_root='mano/models'):
11 | nfull_comps = ncomps + 3 # Add global orientation dims to PCA
12 | random_pcapose = torch.rand(batch_size, nfull_comps)
13 | mano_layer = ManoLayer(mano_root=mano_root)
14 | verts, joints = mano_layer(random_pcapose)
15 | return {'verts': verts, 'joints': joints, 'faces': mano_layer.th_faces}
16 |
17 |
18 | def display_hand(hand_info, mano_faces=None, ax=None, alpha=0.2, cam_view=False, batch_idx=0, show=True, save=''):
19 | """
20 | Displays hand batch_idx in batch of hand_info, hand_info as returned by
21 | generate_random_hand
22 | """
23 | if ax is None:
24 | fig = plt.figure()
25 | ax = fig.add_subplot(111, projection='3d')
26 | verts, joints = hand_info['verts'][batch_idx], hand_info['joints'][
27 | batch_idx]
28 | if mano_faces is None:
29 | ax.scatter(verts[:, 0], verts[:, 1], verts[:, 2], alpha=0.5)
30 | else:
31 | mesh = Poly3DCollection(verts[mano_faces], alpha=alpha)
32 | face_color = (141 / 255, 184 / 255, 226 / 255)
33 | edge_color = (50 / 255, 50 / 255, 50 / 255)
34 | mesh.set_edgecolor(edge_color)
35 | mesh.set_facecolor(face_color)
36 | ax.add_collection3d(mesh)
37 |
38 | ax.scatter(joints[0, 0], joints[0, 1], joints[0, 2], s=42, color='c', marker='p')
39 |
40 | ax.scatter(joints[1, 0], joints[1, 1], joints[1, 2], color='y', marker='s')
41 | ax.scatter(joints[2, 0], joints[2, 1], joints[2, 2], color='y', marker='^')
42 | ax.scatter(joints[3, 0], joints[3, 1], joints[3, 2], color='y', marker='o')
43 | ax.scatter(joints[4, 0], joints[4, 1], joints[4, 2], color='y', marker='*')
44 |
45 | ax.scatter(joints[5, 0], joints[5, 1], joints[5, 2], color='r', marker='s')
46 | ax.scatter(joints[6, 0], joints[6, 1], joints[6, 2], color='r', marker='^')
47 | ax.scatter(joints[7, 0], joints[7, 1], joints[7, 2], color='r', marker='o')
48 | ax.scatter(joints[8, 0], joints[8, 1], joints[8, 2], color='r', marker='*')
49 |
50 | ax.scatter(joints[9, 0], joints[9, 1], joints[9, 2], color='b', marker='s')
51 | ax.scatter(joints[10, 0], joints[10, 1], joints[10, 2], color='b', marker='^')
52 | ax.scatter(joints[11, 0], joints[11, 1], joints[11, 2], color='b', marker='o')
53 | ax.scatter(joints[12, 0], joints[12, 1], joints[12, 2], color='b', marker='*')
54 |
55 | ax.scatter(joints[13, 0], joints[13, 1], joints[13, 2], color='g', marker='s')
56 | ax.scatter(joints[14, 0], joints[14, 1], joints[14, 2], color='g', marker='^')
57 | ax.scatter(joints[15, 0], joints[15, 1], joints[15, 2], color='g', marker='o')
58 | ax.scatter(joints[16, 0], joints[16, 1], joints[16, 2], color='g', marker='*')
59 |
60 | ax.scatter(joints[17, 0], joints[17, 1], joints[17, 2], color='m', marker='s')
61 | ax.scatter(joints[18, 0], joints[18, 1], joints[18, 2], color='m', marker='^')
62 | ax.scatter(joints[19, 0], joints[19, 1], joints[19, 2], color='m', marker='o')
63 | ax.scatter(joints[20, 0], joints[20, 1], joints[20, 2], color='m', marker='*')
64 |
65 | if cam_view:
66 | ax.view_init(azim=-90.0, elev=-90.0)
67 | cam_equal_aspect_3d(ax, verts.numpy())
68 | if show:
69 | plt.show()
70 | if save:
71 | plt.savefig("{}.png".format(save))
72 |
73 | def _display_hand(hand_info, mano_faces=None, ax=None, alpha=0.2, batch_idx=0, show=True):
74 | """
75 | Displays hand batch_idx in batch of hand_info, hand_info as returned by
76 | generate_random_hand
77 | """
78 | if ax is None:
79 | fig = plt.figure()
80 | ax = fig.add_subplot(111, projection='3d')
81 | verts, joints = hand_info['verts'][batch_idx], hand_info['joints'][
82 | batch_idx]
83 | if mano_faces is None:
84 | ax.scatter(verts[:, 0], verts[:, 1], verts[:, 2], alpha=0.1)
85 | else:
86 | mesh = Poly3DCollection(verts[mano_faces], alpha=alpha)
87 | face_color = (141 / 255, 184 / 255, 226 / 255)
88 | edge_color = (50 / 255, 50 / 255, 50 / 255)
89 | mesh.set_edgecolor(edge_color)
90 | mesh.set_facecolor(face_color)
91 | ax.add_collection3d(mesh)
92 | ax.scatter(joints[:, 0], joints[:, 1], joints[:, 2], color='r')
93 | cam_equal_aspect_3d(ax, verts.numpy())
94 | if show:
95 | plt.show()
96 |
97 |
98 | def cam_equal_aspect_3d(ax, verts, flip_x=False):
99 | """
100 | Centers view on cuboid containing hand and flips y and z axis
101 | and fixes azimuth
102 | """
103 | extents = np.stack([verts.min(0), verts.max(0)], axis=1)
104 | sz = extents[:, 1] - extents[:, 0]
105 | centers = np.mean(extents, axis=1)
106 | maxsize = max(abs(sz))
107 | r = maxsize / 2
108 | if flip_x:
109 | ax.set_xlim(centers[0] + r, centers[0] - r)
110 | else:
111 | ax.set_xlim(centers[0] - r, centers[0] + r)
112 | # Invert y and z axis
113 | ax.set_ylim(centers[1] + r, centers[1] - r)
114 | ax.set_zlim(centers[2] + r, centers[2] - r)
115 |
--------------------------------------------------------------------------------
/src/encoder/manopth/rodrigues_layer.py:
--------------------------------------------------------------------------------
1 | """
2 | This part reuses code from https://github.com/MandyMo/pytorch_HMR/blob/master/src/util.py
3 | which is part of a PyTorch port of SMPL.
4 | Thanks to Zhang Xiong (MandyMo) for making this great code available on github !
5 | """
6 |
7 | import argparse
8 | from torch.autograd import gradcheck
9 | import torch
10 | from torch.autograd import Variable
11 |
12 | from ..manopth import argutils
13 |
14 |
15 | def quat2mat(quat):
16 | """Convert quaternion coefficients to rotation matrix.
17 | Args:
18 | quat: size = [batch_size, 4] 4 <===>(w, x, y, z)
19 | Returns:
20 | Rotation matrix corresponding to the quaternion -- size = [batch_size, 3, 3]
21 | """
22 | norm_quat = quat
23 | norm_quat = norm_quat / norm_quat.norm(p=2, dim=1, keepdim=True)
24 | w, x, y, z = norm_quat[:, 0], norm_quat[:, 1], norm_quat[:, 2], norm_quat[:, 3]
25 |
26 | batch_size = quat.size(0)
27 |
28 | w2, x2, y2, z2 = w.pow(2), x.pow(2), y.pow(2), z.pow(2)
29 | wx, wy, wz = w * x, w * y, w * z
30 | xy, xz, yz = x * y, x * z, y * z
31 |
32 | rotMat = torch.stack(
33 | [
34 | w2 + x2 - y2 - z2,
35 | 2 * xy - 2 * wz,
36 | 2 * wy + 2 * xz,
37 | 2 * wz + 2 * xy,
38 | w2 - x2 + y2 - z2,
39 | 2 * yz - 2 * wx,
40 | 2 * xz - 2 * wy,
41 | 2 * wx + 2 * yz,
42 | w2 - x2 - y2 + z2,
43 | ],
44 | dim=1,
45 | ).view(batch_size, 3, 3)
46 | return rotMat
47 |
48 |
49 | def batch_rodrigues(axisang):
50 | # axisang N x 3
51 | axisang_norm = torch.norm(axisang + 1e-8, p=2, dim=1)
52 | angle = torch.unsqueeze(axisang_norm, -1)
53 | axisang_normalized = torch.div(axisang, angle)
54 | angle = angle * 0.5
55 | v_cos = torch.cos(angle)
56 | v_sin = torch.sin(angle)
57 | quat = torch.cat([v_cos, v_sin * axisang_normalized], dim=1)
58 | rot_mat = quat2mat(quat)
59 | rot_mat = rot_mat.view(rot_mat.shape[0], 9)
60 | return rot_mat
61 |
62 |
63 | def th_get_axis_angle(vector):
64 | angle = torch.norm(vector, 2, 1)
65 | axes = vector / angle.unsqueeze(1)
66 | return axes, angle
67 |
68 |
69 | if __name__ == "__main__":
70 | parser = argparse.ArgumentParser()
71 | parser.add_argument("--batch_size", default=1, type=int)
72 | parser.add_argument("--cuda", action="store_true")
73 | args = parser.parse_args()
74 |
75 | argutils.print_args(args)
76 |
77 | n_components = 6
78 | rot = 3
79 | inputs = torch.rand(args.batch_size, rot)
80 | inputs_var = Variable(inputs.double(), requires_grad=True)
81 | if args.cuda:
82 | inputs = inputs.cuda()
83 | # outputs = batch_rodrigues(inputs)
84 | test_function = gradcheck(batch_rodrigues, (inputs_var,))
85 | print("batch test passed !")
86 |
87 | inputs = torch.rand(rot)
88 | inputs_var = Variable(inputs.double(), requires_grad=True)
89 | test_function = gradcheck(th_cv2_rod_sub_id.apply, (inputs_var,))
90 | print("th_cv2_rod test passed")
91 |
92 | inputs = torch.rand(rot)
93 | inputs_var = Variable(inputs.double(), requires_grad=True)
94 | test_th = gradcheck(th_cv2_rod.apply, (inputs_var,))
95 | print("th_cv2_rod_id test passed !")
96 |
--------------------------------------------------------------------------------
/src/encoder/manopth/rot6d.py:
--------------------------------------------------------------------------------
1 | import torch
2 |
3 |
4 | def compute_rotation_matrix_from_ortho6d(poses):
5 | """
6 | Code from
7 | https://github.com/papagina/RotationContinuity
8 | On the Continuity of Rotation Representations in Neural Networks
9 | Zhou et al. CVPR19
10 | https://zhouyisjtu.github.io/project_rotation/rotation.html
11 | """
12 | x_raw = poses[:, 0:3] # batch*3
13 | y_raw = poses[:, 3:6] # batch*3
14 |
15 | x = normalize_vector(x_raw) # batch*3
16 | z = cross_product(x, y_raw) # batch*3
17 | z = normalize_vector(z) # batch*3
18 | y = cross_product(z, x) # batch*3
19 |
20 | x = x.view(-1, 3, 1)
21 | y = y.view(-1, 3, 1)
22 | z = z.view(-1, 3, 1)
23 | matrix = torch.cat((x, y, z), 2) # batch*3*3
24 | return matrix
25 |
26 | def robust_compute_rotation_matrix_from_ortho6d(poses):
27 | """
28 | Instead of making 2nd vector orthogonal to first
29 | create a base that takes into account the two predicted
30 | directions equally
31 | """
32 | x_raw = poses[:, 0:3] # batch*3
33 | y_raw = poses[:, 3:6] # batch*3
34 |
35 | x = normalize_vector(x_raw) # batch*3
36 | y = normalize_vector(y_raw) # batch*3
37 | middle = normalize_vector(x + y)
38 | orthmid = normalize_vector(x - y)
39 | x = normalize_vector(middle + orthmid)
40 | y = normalize_vector(middle - orthmid)
41 | # Their scalar product should be small !
42 | # assert torch.einsum("ij,ij->i", [x, y]).abs().max() < 0.00001
43 | z = normalize_vector(cross_product(x, y))
44 |
45 | x = x.view(-1, 3, 1)
46 | y = y.view(-1, 3, 1)
47 | z = z.view(-1, 3, 1)
48 | matrix = torch.cat((x, y, z), 2) # batch*3*3
49 | # Check for reflection in matrix ! If found, flip last vector TODO
50 | assert (torch.stack([torch.det(mat) for mat in matrix ])< 0).sum() == 0
51 | return matrix
52 |
53 |
54 | def normalize_vector(v):
55 | batch = v.shape[0]
56 | v_mag = torch.sqrt(v.pow(2).sum(1)) # batch
57 | v_mag = torch.max(v_mag, v.new([1e-8]))
58 | v_mag = v_mag.view(batch, 1).expand(batch, v.shape[1])
59 | v = v/v_mag
60 | return v
61 |
62 |
63 | def cross_product(u, v):
64 | batch = u.shape[0]
65 | i = u[:, 1] * v[:, 2] - u[:, 2] * v[:, 1]
66 | j = u[:, 2] * v[:, 0] - u[:, 0] * v[:, 2]
67 | k = u[:, 0] * v[:, 1] - u[:, 1] * v[:, 0]
68 |
69 | out = torch.cat((i.view(batch, 1), j.view(batch, 1), k.view(batch, 1)), 1)
70 |
71 | return out
72 |
--------------------------------------------------------------------------------
/src/encoder/manopth/rotproj.py:
--------------------------------------------------------------------------------
1 | import torch
2 |
3 |
4 | def batch_rotprojs(batches_rotmats):
5 | device = batches_rotmats.device
6 | proj_rotmats = []
7 | for batch_idx, batch_rotmats in enumerate(batches_rotmats):
8 | proj_batch_rotmats = []
9 | for rot_idx, rotmat in enumerate(batch_rotmats):
10 | # GPU implementation of svd is VERY slow
11 | # ~ 2 10^-3 per hit vs 5 10^-5 on cpu
12 | U, S, V = rotmat.cpu().svd()
13 | rotmat = torch.matmul(U, V.transpose(0, 1))
14 | orth_det = rotmat.det()
15 | # Remove reflection
16 | if orth_det < 0:
17 | rotmat[:, 2] = -1 * rotmat[:, 2]
18 |
19 | rotmat = rotmat.to(device)
20 | proj_batch_rotmats.append(rotmat)
21 | proj_rotmats.append(torch.stack(proj_batch_rotmats))
22 | return torch.stack(proj_rotmats)
23 |
--------------------------------------------------------------------------------
/src/encoder/manopth/tensutils.py:
--------------------------------------------------------------------------------
1 | import torch
2 |
3 | from ..manopth import rodrigues_layer
4 |
5 |
6 | def th_posemap_axisang(pose_vectors):
7 | rot_nb = int(pose_vectors.shape[1] / 3)
8 | pose_vec_reshaped = pose_vectors.contiguous().view(-1, 3)
9 | rot_mats = rodrigues_layer.batch_rodrigues(pose_vec_reshaped)
10 | rot_mats = rot_mats.view(pose_vectors.shape[0], rot_nb * 9)
11 | pose_maps = subtract_flat_id(rot_mats)
12 | return pose_maps, rot_mats
13 |
14 |
15 | def th_with_zeros(tensor):
16 | batch_size = tensor.shape[0]
17 | padding = tensor.new([0.0, 0.0, 0.0, 1.0])
18 | padding.requires_grad = False
19 |
20 | concat_list = [tensor, padding.view(1, 1, 4).repeat(batch_size, 1, 1)]
21 | cat_res = torch.cat(concat_list, 1)
22 | return cat_res
23 |
24 |
25 | def th_pack(tensor):
26 | batch_size = tensor.shape[0]
27 | padding = tensor.new_zeros((batch_size, 4, 3))
28 | padding.requires_grad = False
29 | pack_list = [padding, tensor]
30 | pack_res = torch.cat(pack_list, 2)
31 | return pack_res
32 |
33 |
34 | def subtract_flat_id(rot_mats):
35 | # Subtracts identity as a flattened tensor
36 | rot_nb = int(rot_mats.shape[1] / 9)
37 | id_flat = torch.eye(
38 | 3, dtype=rot_mats.dtype, device=rot_mats.device).view(1, 9).repeat(
39 | rot_mats.shape[0], rot_nb)
40 | # id_flat.requires_grad = False
41 | results = rot_mats - id_flat
42 | return results
43 |
44 |
45 | def make_list(tensor):
46 | # type: (List[int]) -> List[int]
47 | return tensor
48 |
--------------------------------------------------------------------------------
/src/inferencing.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from collections import defaultdict
3 | from tqdm import tqdm
4 |
5 |
6 | class BaseInference(object):
7 | ''' Base trainer class.
8 | '''
9 |
10 | def inference_step(self, *args, **kwargs):
11 | ''' Performs a training step.
12 | '''
13 | raise NotImplementedError
14 |
15 |
--------------------------------------------------------------------------------
/src/training.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from collections import defaultdict
3 | from tqdm import tqdm
4 |
5 |
6 | class BaseTrainer(object):
7 | ''' Base trainer class.
8 | '''
9 |
10 | def evaluate(self, val_loader, vf_dict):
11 | ''' Performs an evaluation.
12 | Args:
13 | val_loader (dataloader): pytorch dataloader
14 | '''
15 | eval_list = defaultdict(list)
16 |
17 | for data in tqdm(val_loader):
18 | eval_step_dict = self.eval_step(data, vf_dict)
19 |
20 | for k, v in eval_step_dict.items():
21 | eval_list[k].append(v)
22 |
23 | eval_dict = {k: np.mean(v) for k, v in eval_list.items()}
24 | return eval_dict
25 |
26 | def train_step(self, *args, **kwargs):
27 | ''' Performs a training step.
28 | '''
29 | raise NotImplementedError
30 |
31 | def eval_step(self, *args, **kwargs):
32 | ''' Performs an evaluation step.
33 | '''
34 | raise NotImplementedError
35 |
36 | def visualize(self, *args, **kwargs):
37 | ''' Performs visualization.
38 | '''
39 | raise NotImplementedError
40 |
--------------------------------------------------------------------------------
/src/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jeffsonyu/VTacO/1fada2dd02888fba270fe8b8296f0b570d107ba9/src/utils/__init__.py
--------------------------------------------------------------------------------
/src/utils/icp.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from sklearn.neighbors import NearestNeighbors
3 |
4 |
5 | def best_fit_transform(A, B):
6 | '''
7 | Calculates the least-squares best-fit transform that maps corresponding
8 | points A to B in m spatial dimensions
9 | Input:
10 | A: Nxm numpy array of corresponding points
11 | B: Nxm numpy array of corresponding points
12 | Returns:
13 | T: (m+1)x(m+1) homogeneous transformation matrix that maps A on to B
14 | R: mxm rotation matrix
15 | t: mx1 translation vector
16 | '''
17 |
18 | assert A.shape == B.shape
19 |
20 | # get number of dimensions
21 | m = A.shape[1]
22 |
23 | # translate points to their centroids
24 | centroid_A = np.mean(A, axis=0)
25 | centroid_B = np.mean(B, axis=0)
26 | AA = A - centroid_A
27 | BB = B - centroid_B
28 |
29 | # rotation matrix
30 | H = np.dot(AA.T, BB)
31 | U, S, Vt = np.linalg.svd(H)
32 | R = np.dot(Vt.T, U.T)
33 |
34 | # special reflection case
35 | if np.linalg.det(R) < 0:
36 | Vt[m-1,:] *= -1
37 | R = np.dot(Vt.T, U.T)
38 |
39 | # translation
40 | t = centroid_B.T - np.dot(R,centroid_A.T)
41 |
42 | # homogeneous transformation
43 | T = np.identity(m+1)
44 | T[:m, :m] = R
45 | T[:m, m] = t
46 |
47 | return T, R, t
48 |
49 |
50 | def nearest_neighbor(src, dst):
51 | '''
52 | Find the nearest (Euclidean) neighbor in dst for each point in src
53 | Input:
54 | src: Nxm array of points
55 | dst: Nxm array of points
56 | Output:
57 | distances: Euclidean distances of the nearest neighbor
58 | indices: dst indices of the nearest neighbor
59 | '''
60 |
61 | assert src.shape == dst.shape
62 |
63 | neigh = NearestNeighbors(n_neighbors=1)
64 | neigh.fit(dst)
65 | distances, indices = neigh.kneighbors(src, return_distance=True)
66 | return distances.ravel(), indices.ravel()
67 |
68 |
69 | def icp(A, B, init_pose=None, max_iterations=20, tolerance=0.001):
70 | '''
71 | The Iterative Closest Point method: finds best-fit transform that maps
72 | points A on to points B
73 | Input:
74 | A: Nxm numpy array of source mD points
75 | B: Nxm numpy array of destination mD point
76 | init_pose: (m+1)x(m+1) homogeneous transformation
77 | max_iterations: exit algorithm after max_iterations
78 | tolerance: convergence criteria
79 | Output:
80 | T: final homogeneous transformation that maps A on to B
81 | distances: Euclidean distances (errors) of the nearest neighbor
82 | i: number of iterations to converge
83 | '''
84 |
85 | assert A.shape == B.shape
86 |
87 | # get number of dimensions
88 | m = A.shape[1]
89 |
90 | # make points homogeneous, copy them to maintain the originals
91 | src = np.ones((m+1,A.shape[0]))
92 | dst = np.ones((m+1,B.shape[0]))
93 | src[:m,:] = np.copy(A.T)
94 | dst[:m,:] = np.copy(B.T)
95 |
96 | # apply the initial pose estimation
97 | if init_pose is not None:
98 | src = np.dot(init_pose, src)
99 |
100 | prev_error = 0
101 |
102 | for i in range(max_iterations):
103 | # find the nearest neighbors between the current source and destination points
104 | distances, indices = nearest_neighbor(src[:m,:].T, dst[:m,:].T)
105 |
106 | # compute the transformation between the current source and nearest destination points
107 | T,_,_ = best_fit_transform(src[:m,:].T, dst[:m,indices].T)
108 |
109 | # update the current source
110 | src = np.dot(T, src)
111 |
112 | # check error
113 | mean_error = np.mean(distances)
114 | if np.abs(prev_error - mean_error) < tolerance:
115 | break
116 | prev_error = mean_error
117 |
118 | # calculate final transformation
119 | T,_,_ = best_fit_transform(A, src[:m,:].T)
120 |
121 | return T, distances, i
122 |
--------------------------------------------------------------------------------
/src/utils/io.py:
--------------------------------------------------------------------------------
1 | import os
2 | from plyfile import PlyElement, PlyData
3 | import numpy as np
4 |
5 |
6 | def export_pointcloud(vertices, out_file, as_text=True):
7 | assert(vertices.shape[1] == 3)
8 | vertices = vertices.astype(np.float32)
9 | vertices = np.ascontiguousarray(vertices)
10 | vector_dtype = [('x', 'f4'), ('y', 'f4'), ('z', 'f4')]
11 | vertices = vertices.view(dtype=vector_dtype).flatten()
12 | plyel = PlyElement.describe(vertices, 'vertex')
13 | plydata = PlyData([plyel], text=as_text)
14 | plydata.write(out_file)
15 |
16 |
17 | def load_pointcloud(in_file):
18 | plydata = PlyData.read(in_file)
19 | vertices = np.stack([
20 | plydata['vertex']['x'],
21 | plydata['vertex']['y'],
22 | plydata['vertex']['z']
23 | ], axis=1)
24 | return vertices
25 |
26 |
27 | def read_off(file):
28 | """
29 | Reads vertices and faces from an off file.
30 |
31 | :param file: path to file to read
32 | :type file: str
33 | :return: vertices and faces as lists of tuples
34 | :rtype: [(float)], [(int)]
35 | """
36 |
37 | assert os.path.exists(file), 'file %s not found' % file
38 |
39 | with open(file, 'r') as fp:
40 | lines = fp.readlines()
41 | lines = [line.strip() for line in lines]
42 |
43 | # Fix for ModelNet bug were 'OFF' and the number of vertices and faces
44 | # are all in the first line.
45 | if len(lines[0]) > 3:
46 | assert lines[0][:3] == 'OFF' or lines[0][:3] == 'off', \
47 | 'invalid OFF file %s' % file
48 |
49 | parts = lines[0][3:].split(' ')
50 | assert len(parts) == 3
51 |
52 | num_vertices = int(parts[0])
53 | assert num_vertices > 0
54 |
55 | num_faces = int(parts[1])
56 | assert num_faces > 0
57 |
58 | start_index = 1
59 | # This is the regular case!
60 | else:
61 | assert lines[0] == 'OFF' or lines[0] == 'off', \
62 | 'invalid OFF file %s' % file
63 |
64 | parts = lines[1].split(' ')
65 | assert len(parts) == 3
66 |
67 | num_vertices = int(parts[0])
68 | assert num_vertices > 0
69 |
70 | num_faces = int(parts[1])
71 | assert num_faces > 0
72 |
73 | start_index = 2
74 |
75 | vertices = []
76 | for i in range(num_vertices):
77 | vertex = lines[start_index + i].split(' ')
78 | vertex = [float(point.strip()) for point in vertex if point != '']
79 | assert len(vertex) == 3
80 |
81 | vertices.append(vertex)
82 |
83 | faces = []
84 | for i in range(num_faces):
85 | face = lines[start_index + num_vertices + i].split(' ')
86 | face = [index.strip() for index in face if index != '']
87 |
88 | # check to be sure
89 | for index in face:
90 | assert index != '', \
91 | 'found empty vertex index: %s (%s)' \
92 | % (lines[start_index + num_vertices + i], file)
93 |
94 | face = [int(index) for index in face]
95 |
96 | assert face[0] == len(face) - 1, \
97 | 'face should have %d vertices but as %d (%s)' \
98 | % (face[0], len(face) - 1, file)
99 | assert face[0] == 3, \
100 | 'only triangular meshes supported (%s)' % file
101 | for index in face:
102 | assert index >= 0 and index < num_vertices, \
103 | 'vertex %d (of %d vertices) does not exist (%s)' \
104 | % (index, num_vertices, file)
105 |
106 | assert len(face) > 1
107 |
108 | faces.append(face)
109 |
110 | return vertices, faces
111 |
112 | assert False, 'could not open %s' % file
113 |
--------------------------------------------------------------------------------
/src/utils/visualize.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from matplotlib import pyplot as plt
3 | from mpl_toolkits.mplot3d import Axes3D
4 | import src.common as common
5 |
6 |
7 | def visualize_data(data, data_type, out_file):
8 | r''' Visualizes the data with regard to its type.
9 |
10 | Args:
11 | data (tensor): batch of data
12 | data_type (string): data type (img, voxels or pointcloud)
13 | out_file (string): output file
14 | '''
15 | if data_type == 'voxels':
16 | visualize_voxels(data, out_file=out_file)
17 | elif data_type == 'pointcloud':
18 | visualize_pointcloud(data, out_file=out_file)
19 | elif data_type is None or data_type == 'idx':
20 | pass
21 | else:
22 | raise ValueError('Invalid data_type "%s"' % data_type)
23 |
24 |
25 | def visualize_voxels(voxels, out_file=None, show=False):
26 | r''' Visualizes voxel data.
27 |
28 | Args:
29 | voxels (tensor): voxel data
30 | out_file (string): output file
31 | show (bool): whether the plot should be shown
32 | '''
33 | # Use numpy
34 | voxels = np.asarray(voxels)
35 | # Create plot
36 | fig = plt.figure()
37 | ax = fig.gca(projection=Axes3D.name)
38 | voxels = voxels.transpose(2, 0, 1)
39 | ax.voxels(voxels, edgecolor='k')
40 | ax.set_xlabel('Z')
41 | ax.set_ylabel('X')
42 | ax.set_zlabel('Y')
43 | ax.view_init(elev=30, azim=45)
44 | if out_file is not None:
45 | plt.savefig(out_file)
46 | if show:
47 | plt.show()
48 | plt.close(fig)
49 |
50 |
51 | def visualize_pointcloud(points, normals=None,
52 | out_file=None, show=False):
53 | r''' Visualizes point cloud data.
54 |
55 | Args:
56 | points (tensor): point data
57 | normals (tensor): normal data (if existing)
58 | out_file (string): output file
59 | show (bool): whether the plot should be shown
60 | '''
61 | # Use numpy
62 | points = np.asarray(points)
63 | # Create plot
64 | fig = plt.figure()
65 | ax = fig.gca(projection=Axes3D.name)
66 | ax.scatter(points[:, 2], points[:, 0], points[:, 1])
67 | if normals is not None:
68 | ax.quiver(
69 | points[:, 2], points[:, 0], points[:, 1],
70 | normals[:, 2], normals[:, 0], normals[:, 1],
71 | length=0.1, color='k'
72 | )
73 | ax.set_xlabel('Z')
74 | ax.set_ylabel('X')
75 | ax.set_zlabel('Y')
76 | ax.set_xlim(-0.5, 0.5)
77 | ax.set_ylim(-0.5, 0.5)
78 | ax.set_zlim(-0.5, 0.5)
79 | ax.view_init(elev=30, azim=45)
80 | if out_file is not None:
81 | plt.savefig(out_file)
82 | if show:
83 | plt.show()
84 | plt.close(fig)
85 |
86 |
--------------------------------------------------------------------------------