This repository combines the Pennington body-scanning Python work into one
staged project. The main entry point is python -m unified.
The original work was tied to MATLAB workflows. Python makes the project easier to share, test, automate, and run without MATLAB licensing. It also gives the team access to the scientific Python ecosystem for mesh processing, machine learning, image processing, notebooks, and future GUIs.
The goal is not to erase the research history. The goal is to keep the useful algorithms, data, and experiments in one layout that a new student can install, run, test, and extend.
From this folder:
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install --upgrade pip
.\.venv\Scripts\python.exe -m pip install -r requirements.txtUse the venv Python for the commands below:
$py = ".\.venv\Scripts\python.exe"If you are using macOS or Linux, replace .\.venv\Scripts\python.exe with
.venv/bin/python.
| Path | Purpose |
|---|---|
unified/ |
Main staged wrapper and package entry point. |
unified/img2obj/ |
Image-to-OBJ tooling and visual reconstruction tests. |
unified/obj2anthro/ |
OBJ-to-anthropometry orchestration. |
unified/obj2anthro/backends/segmentation/ |
Landmark/region segmentation backend. |
unified/obj2anthro/backends/slice/ |
Slice-based biomarker backend. |
unified/obj2anthro/backends/avatar/ |
Pure-Python port of Avatar.m, faithful to the MATLAB reference. |
unified/obj2anthro/backends/matlab/ |
Drives the real Avatar.m through the MATLAB Engine. |
unified/ml/experiment/ |
Historical ML, PCA, DOE, and Tkinter GUI code. |
data/obj/ |
Core OBJ files used for local runs and smoke tests. |
Generated outputs go under runs/. Every run folder gets a
combined_measurements.csv: one row per (subject, anthropometry method) with
the method, its runtime, and every measurement column side by side.
Run the test suites from this folder:
& $py -m pytest unified\tests unified\obj2anthro\tests -q
pushd unified\img2obj
..\..\.venv\Scripts\python.exe -m pytest tests -q
popd
pushd unified\obj2anthro\backends\segmentation
..\..\..\..\.venv\Scripts\python.exe -m pytest tests -q
popdProcess one OBJ through the slice backend:
& $py -m unified obj2anthro --input "data\obj\CanCan01_A 2025-10-27_11-10-43.obj" --method slice --units auto --out runs\slice_demoProcess all core OBJ examples:
& $py -m unified obj2anthro --input data\obj --method slice --units auto --out runs\slice_allRun every anthropometry backend:
& $py -m unified obj2anthro --input "data\obj\CanCan01_A 2025-10-27_11-10-43.obj" --method all --units auto --out runs\all_backends_demo --no-images --no-aligned-objEvery backend over every core OBJ, into one comparison table:
& $py -m unified --input data --anthro-method auto --units autoThen open combined_measurements.csv in the new runs/<run_id>/ folder.
auto expands to AUTO_BACKENDS in unified/obj2anthro/pipeline.py. The
matlab method needs the MATLAB Engine for Python (CPython 3.9-3.11); on other
interpreters it records a failed row with that reason instead of aborting.
For a direct OBJ:
& $py -m unified --input "data\obj\CanCan01_A 2025-10-27_11-10-43.obj" --anthro-method slice --units auto --out runs\unified_obj_demoFor images, the lightweight dummy/test path is covered by tests. Real image backends need their own model weights and setup. Start with:
& $py -m unified img2obj --helpThen read unified/img2obj/README.md for the model-backed options.
Use these from an activated or explicit venv. Desktop GUIs must be run in the foreground; do not launch them detached, because the viewer window owns the process lifetime.
The ML GUI is a historical Tkinter application. Launch it from the ML experiment folder so its relative asset paths resolve:
pushd unified\ml\experiment
..\..\.venv\Scripts\python.exe python\ml_GUI.py
popdIn the window:
- Pick the Styku, DXA, Blood, Questionnaire, and Manual input files.
- Choose an output folder and output name.
- Select features, targets, and a regressor.
- Click the run button.
The GUI expects the old ShapeUp-style spreadsheets and CSVs. If a file picker
opens in the wrong place, browse to unified/ml/experiment/python/data/.
The PCA app includes a Tkinter folder picker that launches the bundled
ganger.exe fitting tool for .ply/.mkr batches. This is Windows-only and
expects the Ganger files already present under python/PCA_App/ganger/.
pushd unified\ml\experiment
..\..\.venv\Scripts\python.exe python\PCA_App\run_ganger.py
popdIn the folder picker, select the directory containing the .ply files and their
matching .mkr marker files. The script creates a fitted/ output folder next
to the selected inputs.
There is also an older toy Tkinter prototype at
unified/ml/experiment/old_ML/ML2019Summer/GUI.py. It only opens a basic window
and is useful as historical reference, not as a production workflow:
pushd unified\ml\experiment
..\..\.venv\Scripts\python.exe old_ML\ML2019Summer\GUI.py
popdSeveral pipelines write HTML or viewer artifacts rather than opening a desktop
GUI directly. After running a command, look under the selected runs/... folder
for files such as interactive_3d.html, index.html, or relight viewer HTML.
Open those files in a browser.
Slice backend browser viewer:
& $py -m unified obj2anthro --input "data\obj\CanCan01_A 2025-10-27_11-10-43.obj" --method slice --units auto --out runs\slice_viewerThen open runs/slice_viewer/.../interactive_3d.html.
Image-to-OBJ browser viewer:
pushd unified\img2obj
..\..\.venv\Scripts\python.exe -m pipeline.run single --image tests\fixtures\person_stub.png --out ..\..\runs\img2obj_dummy --backend dummy --quick
popdThen open runs/img2obj_dummy/index.html.
The segmentation backend can open an interactive mesh window when --show is
passed:
& $py -m unified obj2anthro --input "data\obj\man.obj" --method segmentation --units auto --show --out runs\segmentation_viewerThe window is controlled by the trimesh viewer. Close the viewer to return to
the terminal.
- The MATLAB files are preserved under
MATLAB Code/for comparison and reference. - External HMR research stacks require model-specific setup. They are documented
in
unified/img2obj/docs/setup/. - Keep new datasets under
data/and generated outputs underruns/.