Measure the SMPL/SMPLX body models and visualize the measurements and landmarks.
You can use a docker container to facilitate running the code. Run in terminal:
cd docker
sh build.sh
sh docker_run.sh CODE_PATH
by adjusting the CODE_PATH
to the SMPL-Anthropometry
directory location. This creates a smpl-anthropometry-container
container.
If you do not want to use a docker container, you can also just install the necessary packages from docker/requirements.txt
into your own enviroment.
Next, provide the body models (SMPL or SMPLX) and:
- put the
SMPL_{GENDER}.pkl
(MALE, FEMALE and NEUTRAL) models into thedata/smpl
folder - put the
SMPLX_{GENDER}.pkl
(MALE, FEMALE and NEUTRAL) models into thedata/smplx
folder
All the models can be found here.
First import the necessary libraries:
from measure import MeasureBody
from measurement_definitions import STANDARD_LABELS
Next define the measurer by setting the body model you want to measure with model_type
(smpl
or smplx
):
measurer = MeasureBody(model_type)
Then, there are two ways of using the code for measuring a body model depending on how you want to define the body:
- Define the body model using the shape
betas
and gendergender
parameters:
measurer.from_body_model(gender=gender, shape=betas)
- Define the body model using the N x 3 vertices
verts
(N=6890 if SMPL, and 10475 if SMPLX):
measurer.from_verts(verts=verts)
📣 Defining the body using the vertices can be especially useful when the SMPL/SMPLX vertices have been
further refined to fit a 2D/3D model and do not satsify perfectly a set of shape parameters anymore.
Finally, you can measure the body with:
measurement_names = measurer.all_possible_measurements # or chose subset of measurements
measurer.measure(measurement_names)
measurer.label_measurements(STANDARD_LABELS)
Then, the measurements dictionary can be obtained with measurer.measurements
and the labeled measurements can be obtained with measurer.labeled_measurements
. The list of the predefined measurements along with its standard literature labels are:
STANDARD_MEASUREMENT = {
'A': 'head circumference',
'B': 'neck circumference',
'C': 'shoulder to crotch height',
'D': 'chest circumference',
'E': 'waist circumference',
'F': 'hip circumference',
'G': 'wrist right circumference',
'H': 'bicep right circumference',
'I': 'forearm right circumference',
'J': 'arm right length',
'K': 'inside leg height',
'L': 'thigh left circumference',
'M': 'calf left circumference',
'N': 'ankle left circumference',
'O': 'shoulder breadth',
'P': 'height'
}
All the measurements are expressed in cm.
You can also compute the mean absolute error (MAE) between two sets of measurements as:
from evaluate import evaluate_mae
MAE = evaluate_mae(measurer1.measurements,measurer2.measurements)
where measurer1
and measurer2
are two intances of the MeasureBody
class.
You can run the measure.py
script to measure all the predefined measurements (mentioned above) and visualize the results for a zero-shaped T-posed neutral gender SMPL body model:
python measure.py --measure_neutral_smpl_with_mean_shape
The output consists of a dictionary of measurements expressed in cm, the labeled measurements using standard labels,and the viualization of the measurements in the browser, as in the Figure above.
Similarly, you can measure a zero-shaped T-posed neutral gender SMPLX body model with:
python measure.py --measure_neutral_smplx_with_mean_shape
You can run the evaluate.py
script to compare two sets of measurements of randomly shaped SMPL bodies as:
python evaluate.py
The output consists of the mean absolute error (MAE) between two sets of measurements.
There are two types of measurements: lenghts and circumferences.
- Lengths are defined as distances between landmark points defined on the body model
- Circumferences are defiend as plane cuts of the body model
To define a new measurement:
- Open
measurement_definitions.py
- add the new measurement to the
MEASUREMENT_TYPES
dict and set its type:LENGTH
orCIRCUMFERENCE
- depending on the measurement type, define the measurement in the
LENGTHS
orCIRCUMFERENCES
dict of the appropriate body model (SMPLMeasurementDefinitions
orSMPLXMeasurementDefinitions
)LENGTHS
are defined using 2 landmarks - the measurement is found as the distance between the landmarksCIRCUMFERENCES
are defined with landmarks and joints - the measurement is found by cutting the body model with the plane defined by a point (landmark point) and normal ( vector connecting the two joints)
- If the measurement is a
CIRCUMFERENCE
, a possible issue that arises is that the plane cutting results in multiple body part slices. To alleviate that, define the body part where the measurement should be located inCIRCUMFERENCE_TO_BODYPARTS
dict. This way, only the slice in the corresponding body part is used for finding the measurement. The body parts are defined by the face segmentation located indata/smpl_body_parts_2_faces.json
ordata/smplx_body_parts_2_faces.json
.
If a body model has unknown scale (ex. the body was regressed from an image), the measurements can be height-normalized as so:
measurer = MeasureBody(model_type) # assume given model type
measurer.from_body_model(shape=betas, gender=gender) # assume given betas and gender
all_measurement_names = measurer.possible_measurements
measurer.measure(all_measurement_names)
new_height = 175
measurer.height_normalize_measurements(new_height)
This creates a dict of measurements measurer.height_normalized_measurements
where each measurement was normalized with:
new_measurement = (old_measurement / old_height) * new_height
To visualize the SMPL and SMPLX face segmentation on two separate plots, run:
python visualize.py --visualize_smpl_and_smplx_face_segmentation
To visualize the SMPL and SMPLX joints on the same plot, run:
python visualize.py --visualize_smpl_and_smplx_joints
To visualize the SMPL and SMPLX point segmentations on two side-by-side plots, run:
python visualize.py --visualize_smpl_and_smplx_point_segmentation
NOTE: You need to provide the point_segmentation_meshcapade.json
files in the folders data/smpl
and data/smplx
from here.
To visualize the SMPL and SMPLX landmarks on two side-by-side plots, run:
python visualize.py --visualize_smpl_and_smplx_landmarks
- Implement SMPL-X body model
- Implement STAR body model
- Implement SUPR body model
- Add height normalization for the measurements
- Allow posed and shaped body models as inputs, and measure them after unposing
⭐ Leave a star if you find this repository useful ⭐