|
9 | 9 | "\n", |
10 | 10 | "Welcome to PyEyesWeb! This library is designed to extract expressive and biomechanical features from motion data in real-time.\n", |
11 | 11 | "\n", |
12 | | - "In this quickstart, we will build a complete, unified pipeline that extracts:\n", |
| 12 | + "## Understanding the Architecture: Concepts vs. Implementation\n", |
13 | 13 | "\n", |
14 | | - "1. A Static Feature: Bounding Box Contraction (How folded/expanded is the body?)\n", |
| 14 | + "PyEyesWeb separates **what** we measure (the conceptual framework) from **how** it is computed (the implementation API).\n", |
15 | 15 | "\n", |
16 | | - "2. A Dynamic Feature: Kinetic Energy (How much total energy is in the movement?)\n", |
| 16 | + "### 1. The Conceptual Framework (What we measure)\n", |
| 17 | + "* **Low-Level Features**: Physical biomechanics, including spatial geometry (Contraction, Expansion) and raw kinematics (Kinetic Energy, Velocity).\n", |
| 18 | + "* **Mid-Level Features**: Qualitative, expressive aspects of movement that represent behavior or intent (e.g., Smoothness, Directness, Rhythmicity).\n", |
| 19 | + "* **Analysis Primitives**: Domain-agnostic mathematical and statistical tools (e.g., Probability/Rarity, Signal Synchronization, Volatility) that can be applied to any data stream.\n", |
17 | 20 | "\n", |
18 | | - "3. An Analysis Primitive: Smoothness (How fluid is the right hand moving?)" |
| 21 | + "### 2. The Implementation API (How we compute it)\n", |
| 22 | + "In the code, every metric is implemented as either a **Static** or **Dynamic** feature, defined purely by its memory requirements:\n", |
| 23 | + "* **Static Features**: Require only the instantaneous state of the *current frame*. For example, the spatial Contraction of a single pose, or instantaneous Kinetic Energy. They operate on a sliding window of size 1.\n", |
| 24 | + "* **Dynamic Features**: Require a historical trajectory to evaluate changes *over time*. For example, checking if a movement was Smooth over the last second. They require a rolling sliding window to store past frames.\n", |
| 25 | + "\n", |
| 26 | + "In this quickstart, we will build a unified pipeline extracting three metrics that cross-reference these categories:\n", |
| 27 | + "1. **Contraction** (Concept: Low-Level | API: Static Feature)\n", |
| 28 | + "2. **Kinetic Energy** (Concept: Low-Level | API: Static Feature)\n", |
| 29 | + "3. **Smoothness** (Concept: Low-Level | API: Dynamic Feature)" |
19 | 30 | ] |
20 | 31 | }, |
21 | 32 | { |
22 | 33 | "cell_type": "code", |
23 | | - "execution_count": 1, |
| 34 | + "execution_count": null, |
24 | 35 | "id": "initial_id", |
25 | 36 | "metadata": { |
26 | 37 | "ExecuteTime": { |
|
39 | 50 | } |
40 | 51 | ], |
41 | 52 | "source": [ |
42 | | - "from utils.data_loader import load_qualisys_tsv\n", |
| 53 | + "from utils.data_loader import load_motion_data\n", |
43 | 54 | "from utils.plot_utils import plot_feature_timeseries\n", |
44 | 55 | "\n", |
45 | 56 | "# Load data into clean 3D tensors: (Time, Joints, Dimensions)\n", |
46 | | - "pos_tensor, vel_tensor, _, marker_names = load_qualisys_tsv(\"data/trial0001_impulsive.tsv\")\n", |
| 57 | + "pos_tensor, vel_tensor, acc_tensor, marker_names = load_motion_data(\"data/trial0001_impulsive.tsv\")\n", |
| 58 | + "\n", |
| 59 | + "# Let's track the Right Hand\n", |
47 | 60 | "hand_idx = marker_names.index(\"HAND_RIGHT\")\n", |
48 | 61 | "\n", |
49 | 62 | "N_frames, N_joints, N_dims = pos_tensor.shape\n", |
50 | | - "print(f\"Ready to process {N_frames} frames tracking {N_joints} joints!\")" |
| 63 | + "print(f\"Loaded {N_frames} frames tracking {N_joints} joints.\")\n", |
| 64 | + "print(f\"Position Tensor Shape: ({N_frames}, {N_joints}, {N_dims})\")" |
51 | 65 | ] |
52 | 66 | }, |
53 | 67 | { |
|
186 | 200 | ], |
187 | 201 | "metadata": { |
188 | 202 | "kernelspec": { |
189 | | - "display_name": "Python 3", |
| 203 | + "display_name": "pwb", |
190 | 204 | "language": "python", |
191 | 205 | "name": "python3" |
192 | 206 | }, |
193 | 207 | "language_info": { |
194 | 208 | "codemirror_mode": { |
195 | 209 | "name": "ipython", |
196 | | - "version": 2 |
| 210 | + "version": 3 |
197 | 211 | }, |
198 | 212 | "file_extension": ".py", |
199 | 213 | "mimetype": "text/x-python", |
200 | 214 | "name": "python", |
201 | 215 | "nbconvert_exporter": "python", |
202 | | - "pygments_lexer": "ipython2", |
203 | | - "version": "2.7.6" |
| 216 | + "pygments_lexer": "ipython3", |
| 217 | + "version": "3.12.11" |
204 | 218 | } |
205 | 219 | }, |
206 | 220 | "nbformat": 4, |
|
0 commit comments