Update README.md
Browse files
README.md
CHANGED
|
@@ -8,4 +8,204 @@ tags:
|
|
| 8 |
- yoga
|
| 9 |
- human
|
| 10 |
- mediapipe
|
| 11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
- yoga
|
| 9 |
- human
|
| 10 |
- mediapipe
|
| 11 |
+
language:
|
| 12 |
+
- en
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
# Yoga Pose Classification Toolkit
|
| 17 |
+
|
| 18 |
+
This repository contains a small, script-first pipeline to prepare data, extract pose landmarks with MediaPipe, train machine‑learning pose classifiers, and run a real‑time webcam demo.
|
| 19 |
+
|
| 20 |
+
The sections below explain what each Python script in the project root does and how to use it on macOS (zsh). For dependencies, see `requirements.txt`.
|
| 21 |
+
|
| 22 |
+
## Prerequisites
|
| 23 |
+
|
| 24 |
+
- Python 3.x
|
| 25 |
+
- Install Python packages:
|
| 26 |
+
|
| 27 |
+
```bash
|
| 28 |
+
pip install -r requirements.txt
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
Optional but recommended: create and activate a virtual environment before installing.
|
| 32 |
+
|
| 33 |
+
## Typical end‑to‑end workflow
|
| 34 |
+
|
| 35 |
+
1) (Optional) Extract raw images from the included Parquet dataset into train/test folders using `extract_images.py`.
|
| 36 |
+
2) Run `pose_detection.py` to generate per‑image pose landmark JSON files under `PoseData/label_*`.
|
| 37 |
+
3) Train and evaluate a classifier with `ml_pose_classifier.py`. Optionally export to ONNX or TFLite.
|
| 38 |
+
4) Run the webcam demo with `realtime_pose_classifier.py` using your saved model.
|
| 39 |
+
|
| 40 |
+
---
|
| 41 |
+
|
| 42 |
+
## Script: extract_images.py
|
| 43 |
+
|
| 44 |
+
Purpose
|
| 45 |
+
- Extract images and labels from the provided Parquet files (in `YogaDataSet/data/`) and save them into folders by label for training and testing.
|
| 46 |
+
|
| 47 |
+
Inputs/Outputs
|
| 48 |
+
- Input: `YogaDataSet/data/train-00000-of-00001.parquet`, `YogaDataSet/data/test-00000-of-00001.parquet`
|
| 49 |
+
- Output: Images under `TrainData/train/label_*` and/or `TrainData/test/label_*`
|
| 50 |
+
|
| 51 |
+
Usage
|
| 52 |
+
|
| 53 |
+
```bash
|
| 54 |
+
# Process both train and test (default behavior)
|
| 55 |
+
python extract_images.py
|
| 56 |
+
|
| 57 |
+
# Train only
|
| 58 |
+
python extract_images.py --train --output TrainData
|
| 59 |
+
|
| 60 |
+
# Test only to a custom folder
|
| 61 |
+
python extract_images.py --test --output MyOutputDir
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
Notes
|
| 65 |
+
- The script creates `label_0`, `label_1`, … subfolders and writes image files with their original extensions.
|
| 66 |
+
|
| 67 |
+
---
|
| 68 |
+
|
| 69 |
+
## Script: pose_detection.py
|
| 70 |
+
|
| 71 |
+
Purpose
|
| 72 |
+
- Run MediaPipe Pose on your labeled image folders and save normalized landmark coordinates to JSON files for training.
|
| 73 |
+
|
| 74 |
+
Preprocessing
|
| 75 |
+
- Uses the nose as the head reference point and applies: position = (pos − headPos) × 100, rounded to 2 decimals. This matches the training pipeline.
|
| 76 |
+
|
| 77 |
+
Inputs/Outputs
|
| 78 |
+
- Input: An images root (default `TrainData/train`) organized as `label_*/*.jpg|png|…`
|
| 79 |
+
- Output: JSON files under `PoseData/label_*/<image_name>.json`
|
| 80 |
+
|
| 81 |
+
Usage
|
| 82 |
+
|
| 83 |
+
```bash
|
| 84 |
+
# Process images from default input into PoseData
|
| 85 |
+
python pose_detection.py
|
| 86 |
+
|
| 87 |
+
# Custom input and output
|
| 88 |
+
python pose_detection.py --input TrainData/train --output PoseData --batch-size 100
|
| 89 |
+
```
|
| 90 |
+
|
| 91 |
+
Tips
|
| 92 |
+
- Supported image extensions: .jpg, .jpeg, .png, .bmp, .tiff
|
| 93 |
+
- Requires a working OpenCV + MediaPipe install (see `requirements.txt`).
|
| 94 |
+
|
| 95 |
+
---
|
| 96 |
+
|
| 97 |
+
## Script: ml_pose_classifier.py
|
| 98 |
+
|
| 99 |
+
Purpose
|
| 100 |
+
- Train, evaluate, and export pose classifiers from landmark JSONs. Supports Random Forest, SVM, Gradient Boosting, Logistic Regression, and a knowledge‑distilled RF→MLP variant.
|
| 101 |
+
|
| 102 |
+
Data expectation
|
| 103 |
+
- Directory structure like:
|
| 104 |
+
- `PoseData/label_0/*.json`
|
| 105 |
+
- `PoseData/label_1/*.json`
|
| 106 |
+
- …
|
| 107 |
+
|
| 108 |
+
Common options
|
| 109 |
+
- `--data/-d` Pose JSON root (default: `PoseData`)
|
| 110 |
+
- `--model/-m` Model type: `random_forest` (default), `svm`, `gradient_boost`, `logistic`, `distilled_rf`
|
| 111 |
+
- `--test-size/-t` Test split ratio (default: 0.2)
|
| 112 |
+
- `--save-model/-s` Path to save the trained model (`.pkl` via joblib)
|
| 113 |
+
- `--load-model/-l` Path to load an existing model
|
| 114 |
+
- `--predict/-p` Predict a single JSON file
|
| 115 |
+
- `--evaluate/-e` Evaluate a folder of JSON files
|
| 116 |
+
- `--export-onnx` Export the trained model to ONNX (tree models or distilled MLP)
|
| 117 |
+
- `--export-model-type` Controls which model flavor to export
|
| 118 |
+
- `--export-tflite` Export distilled student MLP to TFLite (requires extra deps)
|
| 119 |
+
|
| 120 |
+
Typical commands
|
| 121 |
+
|
| 122 |
+
```bash
|
| 123 |
+
# 1) Train a Random Forest and save it
|
| 124 |
+
python ml_pose_classifier.py \
|
| 125 |
+
--data PoseData \
|
| 126 |
+
--model random_forest \
|
| 127 |
+
--test-size 0.2 \
|
| 128 |
+
--save-model models/pose_classifier_random_forest.pkl
|
| 129 |
+
|
| 130 |
+
# 2) Evaluate a saved model on a held‑out folder (e.g., TestData)
|
| 131 |
+
python ml_pose_classifier.py \
|
| 132 |
+
--model random_forest \
|
| 133 |
+
--load-model models/pose_classifier_random_forest.pkl \
|
| 134 |
+
--evaluate TestData
|
| 135 |
+
|
| 136 |
+
# 3) Export to ONNX (Random Forest or distilled MLP)
|
| 137 |
+
python ml_pose_classifier.py \
|
| 138 |
+
--model random_forest \
|
| 139 |
+
--load-model models/pose_classifier_random_forest.pkl \
|
| 140 |
+
--export-onnx models/pose_classifier_random_forest.onnx
|
| 141 |
+
|
| 142 |
+
# 4) Knowledge distillation: train RF teacher + MLP student
|
| 143 |
+
python ml_pose_classifier.py \
|
| 144 |
+
--data PoseData \
|
| 145 |
+
--model distilled_rf \
|
| 146 |
+
--save-model models/pose_classifier_distilled_rf.pkl
|
| 147 |
+
|
| 148 |
+
# 5) Export the student MLP to TFLite (extra packages required)
|
| 149 |
+
python ml_pose_classifier.py \
|
| 150 |
+
--model distilled_rf \
|
| 151 |
+
--load-model models/pose_classifier_distilled_rf.pkl \
|
| 152 |
+
--export-tflite models/pose_classifier_distilled_mlp.tflite
|
| 153 |
+
```
|
| 154 |
+
|
| 155 |
+
Notes
|
| 156 |
+
- ONNX export depends on `skl2onnx` and `onnx`. TFLite export additionally needs `onnx-tf` and `tensorflow`.
|
| 157 |
+
- Linear classifiers (`svm`, `logistic`) are not supported by Unity Barracuda. Prefer `random_forest` or the distilled MLP for deployment.
|
| 158 |
+
|
| 159 |
+
---
|
| 160 |
+
|
| 161 |
+
## Script: realtime_pose_classifier.py
|
| 162 |
+
|
| 163 |
+
Purpose
|
| 164 |
+
- Run live pose classification from your webcam using a previously trained model. Draws the skeleton, highlights the used joints, and overlays prediction + confidence.
|
| 165 |
+
|
| 166 |
+
Model loading
|
| 167 |
+
- If `--model` is not provided, the script auto‑searches common filenames in the project root:
|
| 168 |
+
- `pose_classifier_random_forest.pkl`
|
| 169 |
+
- `pose_classifier_logistic.pkl`
|
| 170 |
+
- `pose_classifier_distilled_rf.pkl`
|
| 171 |
+
|
| 172 |
+
Usage
|
| 173 |
+
|
| 174 |
+
```bash
|
| 175 |
+
# Auto‑detect a model and open the default camera (0)
|
| 176 |
+
python realtime_pose_classifier.py
|
| 177 |
+
|
| 178 |
+
# Specify a model file and camera index
|
| 179 |
+
python realtime_pose_classifier.py \
|
| 180 |
+
--model models/pose_classifier_random_forest.pkl \
|
| 181 |
+
--camera 0
|
| 182 |
+
```
|
| 183 |
+
|
| 184 |
+
Keyboard controls
|
| 185 |
+
- Q: Quit
|
| 186 |
+
- L: Toggle landmark keypoints
|
| 187 |
+
- C: Toggle pose connections
|
| 188 |
+
- R: Reset prediction history (smoothing window)
|
| 189 |
+
|
| 190 |
+
Notes
|
| 191 |
+
- Uses the same preprocessing as training (nose‑relative coordinates ×100, 2‑decimal rounding, StandardScaler).
|
| 192 |
+
- For smoother predictions, a small history window is used to compute a stable label and average confidence.
|
| 193 |
+
|
| 194 |
+
---
|
| 195 |
+
|
| 196 |
+
## Useful folders and artifacts
|
| 197 |
+
|
| 198 |
+
- `YogaDataSet/data/` — Parquet files used by `extract_images.py`.
|
| 199 |
+
- `TrainData/train|test/label_*/` — Image folders produced by extraction.
|
| 200 |
+
- `PoseData/label_*/` — Landmark JSONs generated by `pose_detection.py`.
|
| 201 |
+
- `models/` — Example trained/exported models and label mappings.
|
| 202 |
+
- `confusion_matrix_*.png` — Saved confusion matrix plots (when enabled in training script).
|
| 203 |
+
|
| 204 |
+
## Troubleshooting
|
| 205 |
+
|
| 206 |
+
- MediaPipe install issues on macOS: ensure you’re using a supported Python version and the latest pip; try reinstalling `mediapipe` and `opencv-python`.
|
| 207 |
+
- Camera cannot open: try a different `--camera` index, close other apps using the camera, or allow camera permissions for Python in macOS Privacy settings.
|
| 208 |
+
- Model not found in real‑time script: pass `--model` with an explicit path to your `.pkl` file.
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
|