Class PoseTracker

PoseTracker keeps track of a landmarks for a single pose. This is useful for tracking the movement of a pose or its landmarks over time. It does this by making a PointTracker for each keypoint of a pose.

Note: You probably don't want to create this yourself! Rather, use a PosesTracker to access.

// Create a tracker (fromId is the id of sender, poseId is the id of the pose)
const pt = new PoseTracker(fromId, poseId, options);
// ...and whenever there is data, call .seen()
pt.seen(pose);

When creating, the most useful tuning options are sampleLimit which governs how many of the most recent samples to keep, and storeIntermediate (true/false) to store intermediate data.

You can get the raw keypoint data from the pose

// Get a single point
const nosePoint = pose.landmarkValue(`nose`); // { x, y, score, name }
// Get all points
for (const kp of poses.landmarkValues()) {
// { x, y, score, name }
}

But the real power comes from getting the PointTracker for a keypoint, since it keeps track of not just the last data, but a whole trail of historical data for a given keypoint.

const noseTracker = pose.landmark(`nose`); // PointTracker

Once we have the PointTracker, there are a lot of things to access:

Constructors

Accessors

  • get middle(): Point | {
        x: 0;
        y: 0;
    }
  • Returns the middle of the pose bounding box using normalised coordinates

    pose.middle; // { x, y }
    

    Returns Point | {
        x: 0;
        y: 0;
    }

  • get poseId(): string
  • Returns the original pose id from TFjs Warning: this may not be unique if there are multiple senders

    Returns string

Methods

  • Gets the bounding box of the pose, computed using the normalised landmarks.

    pose.box(); // { x, y, width, height }
    

    Returns an empty rectangle if there's no data.

    You can also provide a list of landmark names/indexes to compute the bounding box for just those:

    // Get bounding box of torso
    pose.box(`left_shoulder`, `right_shoulder`, `left_hip`, `right_`hip`);

    See also {@link boxWorld} for same behaviour but using world coordinates.

    Parameters

    Returns RectPositioned | Readonly<{
        height: 0;
        width: 0;
        x: 0;
        y: 0;
    }>

  • Parameters

    Returns RectPositioned | Readonly<{
        height: 0;
        width: 0;
        x: 0;
        y: 0;
    }>

  • Returns the 2D centroid of all the pose points (uses normalised landmarks)

    pose.centroid(); // { x, y }
    

    Or you can pass in the names/indexes of landmarks:

    pose.centroid(`left_shoulder`, `right_shoulder`);
    

    Returns { x: 0.5, y: 0.5 } is data is missing

    Parameters

    Returns Point

  • Returns a PointTracker for a given normalised landmark by name or index.

    // Eg. get tracker for the 'nose' landmark
    const nose = pose.landmark(`nose`);

    // Get the angle of nose movement since the start
    const a = nose.angleFromStart();

    // Get the distance of nose since start
    const d = nose.distanceFromStart();

    Parameters

    Returns undefined | PointTracker<NormalizedLandmark>

  • Returns all the PointTrackers (ie. landmark) for this pose.

    for (const pt of pose.landmarks()) {
    // Do something with 'pt' (which tracks one individual landmark)
    }

    Or provide a list of landmark indexes or name:

    // Get landmarks for right arm
    for (const pt of pose.landmarks(11, 13, 15)) {
    }

    Parameters

    Returns Generator<PointTracker<NormalizedLandmark>, void, undefined>

  • Returns a PointTracker for a given normalised landmark by name or index.

    // Eg. get tracker for the 'nose' landmark
    const nose = pose.landmark(`nose`);

    // Get the angle of nose movement since the start
    const a = nose.angleFromStart();

    // Get the distance of nose since start
    const d = nose.distanceFromStart();

    Parameters

    Returns undefined | PointTracker<Landmark>