<br />

The MediaPipe Holistic Landmarker task lets you combine components of the face, hand, and pose
landmarkers to detect a total of 553 human body landmarks in real time. You can
use this task to analyze full-body gestures, poses, and actions across a
continuous stream of images or video. The task outputs a combination of
normalized landmarks, world landmarks, blendshapes (optional), and segmentation
masks (optional).


<iframe class="mp-demo-frame mp-demo-frame--studio" aria-label="Holistic Landmarker interactive Web SDK demo" loading="lazy" data-src="https://developers.devsite.google/frame/edge/mediapipe/demos/embed/holistic_landmarker.jshtml" allow="camera *; microphone *"></iframe>

[Open in Web Demos](https://google-ai-edge.github.io/mediapipe-samples-web/#/vision/holistic_landmarker)[Edit in StackBlitz](https://stackblitz.com/github/google-ai-edge/mediapipe-samples-web?file=src/tasks/holistic-landmarker.ts)

<br />

## Quickstart

Install the SDK for your platform,
[prepare input data](https://developers.google.com/edge/mediapipe/solutions/prepare_data.md.txt#vision), choose a
running mode, and run inference.

### Web

npm`npm install @mediapipe/tasks-vision`[Web demo](https://google-ai-edge.github.io/mediapipe-samples-web/#/vision/holistic_landmarker)·[Edit in StackBlitz](https://stackblitz.com/github/google-ai-edge/mediapipe-samples-web?file=src/tasks/holistic-landmarker.ts)·[Setup guide](https://developers.google.com/edge/mediapipe/solutions/setup_web.md.txt)

#### Image

`IMAGE`Stateless · single frameSynchronous call on independent still images. Resets temporal tracking state on every call.

```typescript
import { FilesetResolver, HolisticLandmarker } from "@mediapipe/tasks-vision";

const vision = await FilesetResolver.forVisionTasks(
  "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"
);
const holisticLandmarker = await HolisticLandmarker.createFromOptions(vision, {
  baseOptions: { modelAssetPath: "holistic_landmarker.task", delegate: "GPU" },
  runningMode: "IMAGE",
  minFaceDetectionConfidence: 0.5,
  minPoseDetectionConfidence: 0.5,
});

// Synchronous single-frame call (stateless across images)
const image = document.getElementById("image") as HTMLImageElement;
const result = holisticLandmarker.detect(image);
```

#### Video

`VIDEO`Every frame · no dropsSynchronous tracking across decoded video frames with monotonic timestamps. Processes every frame in order and never drops frames.

```typescript
import { FilesetResolver, HolisticLandmarker } from "@mediapipe/tasks-vision";

const vision = await FilesetResolver.forVisionTasks(
  "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"
);
const holisticLandmarker = await HolisticLandmarker.createFromOptions(vision, {
  baseOptions: { modelAssetPath: "holistic_landmarker.task", delegate: "GPU" },
  runningMode: "VIDEO",
  minFaceDetectionConfidence: 0.5,
  minPoseDetectionConfidence: 0.5,
});

// Synchronous across decoded frames with monotonic timestamps (never drops frames)
for (const { frame, timestampMs } of decodedVideoFrames) {
  const result = holisticLandmarker.detectForVideo(frame, timestampMs);
}
```

#### Livestream

`VIDEO + rAF`Live camera · latest frameWeb tasks run synchronously---pair `runningMode: "VIDEO"` with `requestAnimationFrame` so each paint inspects only the latest camera frame (skipping intermediate frames when busy).

```typescript
import { FilesetResolver, HolisticLandmarker } from "@mediapipe/tasks-vision";

const vision = await FilesetResolver.forVisionTasks(
  "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"
);
// On Web, live camera loops pair runningMode: "VIDEO" with requestAnimationFrame
const holisticLandmarker = await HolisticLandmarker.createFromOptions(vision, {
  baseOptions: { modelAssetPath: "holistic_landmarker.task", delegate: "GPU" },
  runningMode: "VIDEO",
  minFaceDetectionConfidence: 0.5,
  minPoseDetectionConfidence: 0.5,
});

const video = document.getElementById("webcam") as HTMLVideoElement;
video.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
await video.play();
let lastVideoTime = -1;

function renderLoop() {
  if (video.readyState >= 2 && video.currentTime !== lastVideoTime) {
    lastVideoTime = video.currentTime;
    const result = holisticLandmarker.detectForVideo(video, performance.now());
    console.log(result.poseLandmarks, result.faceLandmarks);
  }
  requestAnimationFrame(renderLoop);
}
renderLoop();
```

### Android (Kotlin)

Gradle`implementation("com.google.mediapipe:tasks-vision:latest.release")`[Sample code](https://github.com/google-ai-edge/mediapipe-samples/tree/main/examples/holistic_landmarker/android)·[Setup guide](https://developers.google.com/edge/mediapipe/solutions/setup_android.md.txt)

#### Image

`IMAGE`Stateless · single frameSynchronous call on independent still images. Resets temporal tracking state on every call.

```kotlin
import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage
import com.google.mediapipe.tasks.core.BaseOptions
import com.google.mediapipe.tasks.vision.core.RunningMode
import com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker

val baseOptions = BaseOptions.builder()
    .setModelAssetPath("holistic_landmarker.task")
    .build()
val options = HolisticLandmarker.HolisticLandmarkerOptions.builder()
    .setBaseOptions(baseOptions)
    .setRunningMode(RunningMode.IMAGE)
    .setMinFaceDetectionConfidence(0.5f)
    .setMinPoseDetectionConfidence(0.5f)
    .build()

val holisticLandmarker = HolisticLandmarker.createFromOptions(context, options)

// Synchronous single-image call (no temporal tracking across calls)
val mpImage = BitmapImageBuilder(bitmap).build()
val result = holisticLandmarker.detect(mpImage)
```

#### Video

`VIDEO`Every frame · no dropsSynchronous tracking across decoded video frames with monotonic timestamps. Processes every frame in order and never drops frames.

```kotlin
import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage
import com.google.mediapipe.tasks.core.BaseOptions
import com.google.mediapipe.tasks.vision.core.RunningMode
import com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker

val baseOptions = BaseOptions.builder()
    .setModelAssetPath("holistic_landmarker.task")
    .build()
val options = HolisticLandmarker.HolisticLandmarkerOptions.builder()
    .setBaseOptions(baseOptions)
    .setRunningMode(RunningMode.VIDEO)
    .setMinFaceDetectionConfidence(0.5f)
    .setMinPoseDetectionConfidence(0.5f)
    .build()

val holisticLandmarker = HolisticLandmarker.createFromOptions(context, options)

// Synchronous: processes every frame in order with monotonic timestamps (no frame drops)
val mpImage = BitmapImageBuilder(frameBitmap).build()
val result = holisticLandmarker.detectForVideo(mpImage, frameTimestampMs)
```

#### Livestream

`LIVE_STREAM`Async · drops frames when busyAsynchronous camera pipeline with a result callback. Automatically drops incoming frames when busy so results stay current with low latency.

```kotlin
import android.os.SystemClock
import android.util.Log
import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage
import com.google.mediapipe.tasks.core.BaseOptions
import com.google.mediapipe.tasks.vision.core.RunningMode
import com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker

val baseOptions = BaseOptions.builder()
    .setModelAssetPath("holistic_landmarker.task")
    .build()
val options = HolisticLandmarker.HolisticLandmarkerOptions.builder()
    .setBaseOptions(baseOptions)
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMinFaceDetectionConfidence(0.5f)
    .setMinPoseDetectionConfidence(0.5f)
    .setResultListener { result, _ -> val pose = result.poseLandmarks() }
    .setErrorListener { error -> Log.e("MediaPipe", error.message.orEmpty()) }
    .build()

val holisticLandmarker = HolisticLandmarker.createFromOptions(context, options)

// Async: automatically drops incoming camera frames when busy so results stay current
holisticLandmarker.detectAsync(mpImage, SystemClock.uptimeMillis())
```

### Android (Java)

Gradle`implementation 'com.google.mediapipe:tasks-vision:latest.release'`[Sample code](https://github.com/google-ai-edge/mediapipe-samples/tree/main/examples/holistic_landmarker/android)·[Setup guide](https://developers.google.com/edge/mediapipe/solutions/setup_android.md.txt)

#### Image

`IMAGE`Stateless · single frameSynchronous call on independent still images. Resets temporal tracking state on every call.

```java
import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;
import com.google.mediapipe.tasks.core.BaseOptions;
import com.google.mediapipe.tasks.vision.core.RunningMode;
import com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker;
import com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarkerResult;

BaseOptions baseOptions = BaseOptions.builder()
    .setModelAssetPath("holistic_landmarker.task")
    .build();
HolisticLandmarker.HolisticLandmarkerOptions options = HolisticLandmarker.HolisticLandmarkerOptions.builder()
    .setBaseOptions(baseOptions)
    .setRunningMode(RunningMode.IMAGE)
    .setMinFaceDetectionConfidence(0.5f)
    .setMinPoseDetectionConfidence(0.5f)
    .build();

HolisticLandmarker holisticLandmarker = HolisticLandmarker.createFromOptions(context, options);

// Synchronous single-image call (no temporal tracking across calls)
MPImage mpImage = new BitmapImageBuilder(bitmap).build();
HolisticLandmarkerResult result = holisticLandmarker.detect(mpImage);
```

#### Video

`VIDEO`Every frame · no dropsSynchronous tracking across decoded video frames with monotonic timestamps. Processes every frame in order and never drops frames.

```java
import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;
import com.google.mediapipe.tasks.core.BaseOptions;
import com.google.mediapipe.tasks.vision.core.RunningMode;
import com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker;
import com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarkerResult;

BaseOptions baseOptions = BaseOptions.builder()
    .setModelAssetPath("holistic_landmarker.task")
    .build();
HolisticLandmarker.HolisticLandmarkerOptions options = HolisticLandmarker.HolisticLandmarkerOptions.builder()
    .setBaseOptions(baseOptions)
    .setRunningMode(RunningMode.VIDEO)
    .setMinFaceDetectionConfidence(0.5f)
    .setMinPoseDetectionConfidence(0.5f)
    .build();

HolisticLandmarker holisticLandmarker = HolisticLandmarker.createFromOptions(context, options);

// Synchronous: processes every frame in order with monotonic timestamps (no frame drops)
MPImage mpImage = new BitmapImageBuilder(frameBitmap).build();
HolisticLandmarkerResult result = holisticLandmarker.detectForVideo(mpImage, frameTimestampMs);
```

#### Livestream

`LIVE_STREAM`Async · drops frames when busyAsynchronous camera pipeline with a result callback. Automatically drops incoming frames when busy so results stay current with low latency.

```java
import android.os.SystemClock;
import android.util.Log;
import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;
import com.google.mediapipe.tasks.core.BaseOptions;
import com.google.mediapipe.tasks.vision.core.RunningMode;
import com.google.mediapipe.tasks.vision.holisticlandmarker.HolisticLandmarker;

BaseOptions baseOptions = BaseOptions.builder()
    .setModelAssetPath("holistic_landmarker.task")
    .build();
HolisticLandmarker.HolisticLandmarkerOptions options = HolisticLandmarker.HolisticLandmarkerOptions.builder()
    .setBaseOptions(baseOptions)
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMinFaceDetectionConfidence(0.5f)
    .setMinPoseDetectionConfidence(0.5f)
    .setResultListener((result, inputImage) -> { var pose = result.poseLandmarks(); })
    .setErrorListener(error -> Log.e("MediaPipe", String.valueOf(error.getMessage())))
    .build();

HolisticLandmarker holisticLandmarker = HolisticLandmarker.createFromOptions(context, options);

// Async: automatically drops incoming camera frames when busy so results stay current
holisticLandmarker.detectAsync(mpImage, SystemClock.uptimeMillis());
```

### iOS

SwiftPM`https://github.com/google-ai-edge/mediapipe → MediaPipeTasksVision`[Package.swift](https://developers.google.com/edge/mediapipe/solutions/setup_ios.md.txt#package_swift)·[Sample code](https://github.com/google-ai-edge/mediapipe-samples/tree/main/examples/holistic_landmarker/ios)·[Setup guide](https://developers.google.com/edge/mediapipe/solutions/setup_ios.md.txt)

#### Image

`IMAGE`Stateless · single frameSynchronous call on independent still images. Resets temporal tracking state on every call.

```swift
import Foundation
import MediaPipeTasksVision

guard let modelPath = Bundle.main.path(forResource: "holistic_landmarker", ofType: "task") else { return }

let options = HolisticLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.minFaceDetectionConfidence = 0.5
options.minPoseDetectionConfidence = 0.5

let holisticLandmarker = try HolisticLandmarker(options: options)

// Synchronous single-image call (stateless across images)
let mpImage = try MPImage(uiImage: image)
let result = try holisticLandmarker.detect(image: mpImage)
```

#### Video

`VIDEO`Every frame · no dropsSynchronous tracking across decoded video frames with monotonic timestamps. Processes every frame in order and never drops frames.

```swift
import Foundation
import MediaPipeTasksVision

guard let modelPath = Bundle.main.path(forResource: "holistic_landmarker", ofType: "task") else { return }

let options = HolisticLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.minFaceDetectionConfidence = 0.5
options.minPoseDetectionConfidence = 0.5

let holisticLandmarker = try HolisticLandmarker(options: options)

// Synchronous: processes every frame in order with monotonic timestamps (no frame drops)
let mpImage = try MPImage(pixelBuffer: pixelBuffer)
let result = try holisticLandmarker.detect(videoFrame: mpImage, timestampInMilliseconds: timestampMs)
```

#### Livestream

`LIVE_STREAM`Async · drops frames when busyAsynchronous camera pipeline with a result callback. Automatically drops incoming frames when busy so results stay current with low latency.

```swift
import Foundation
import MediaPipeTasksVision

final class HolisticLandmarkerStreamService: NSObject {
    private var holisticLandmarker: HolisticLandmarker?

    func setUp() throws {
        guard let modelPath = Bundle.main.path(
            forResource: "holistic_landmarker",
            ofType: "task"
        ) else { return }

        let options = HolisticLandmarkerOptions()
        options.baseOptions.modelAssetPath = modelPath
        options.runningMode = .liveStream
        options.minFaceDetectionConfidence = 0.5
        options.minPoseDetectionConfidence = 0.5
        options.holisticLandmarkerLiveStreamDelegate = self

        holisticLandmarker = try HolisticLandmarker(options: options)
    }

    func detectAsync(mpImage: MPImage, timestampMs: Int) throws {
        // Async: automatically drops incoming camera frames when busy so results stay current
        try holisticLandmarker?.detectAsync(image: mpImage, timestampInMilliseconds: timestampMs)
    }
}

extension HolisticLandmarkerStreamService: HolisticLandmarkerLiveStreamDelegate {
    func holisticLandmarker(
        _ holisticLandmarker: HolisticLandmarker,
        didFinishDetection result: HolisticLandmarkerResult?,
        timestampInMilliseconds: Int,
        error: (any Error)?
    ) {
        guard let result else { return }
        DispatchQueue.main.async {
            let pose = result.poseLandmarks
        }
    }
}
```

### Python

pip`pip install mediapipe`[Sample code](https://github.com/google-ai-edge/mediapipe-samples/tree/main/examples/holistic_landmarker/python)·[Setup guide](https://developers.google.com/edge/mediapipe/solutions/setup_python.md.txt)

#### Image

`IMAGE`Stateless · single frameSynchronous call on independent still images. Resets temporal tracking state on every call.

```python
import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
HolisticLandmarker = mp.tasks.vision.HolisticLandmarker
HolisticLandmarkerOptions = mp.tasks.vision.HolisticLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

options = HolisticLandmarkerOptions(
    base_options=BaseOptions(model_asset_path="holistic_landmarker.task"),
    running_mode=VisionRunningMode.IMAGE,
    min_face_detection_confidence=0.5,
    min_pose_detection_confidence=0.5,
)

with HolisticLandmarker.create_from_options(options) as landmarker:
    # Synchronous single-image call (stateless across images)
    mp_image = mp.Image.create_from_file("input.jpg")
    result = landmarker.detect(mp_image)
```

#### Video

`VIDEO`Every frame · no dropsSynchronous tracking across decoded video frames with monotonic timestamps. Processes every frame in order and never drops frames.

```python
import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
HolisticLandmarker = mp.tasks.vision.HolisticLandmarker
HolisticLandmarkerOptions = mp.tasks.vision.HolisticLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

options = HolisticLandmarkerOptions(
    base_options=BaseOptions(model_asset_path="holistic_landmarker.task"),
    running_mode=VisionRunningMode.VIDEO,
    min_face_detection_confidence=0.5,
    min_pose_detection_confidence=0.5,
)

with HolisticLandmarker.create_from_options(options) as landmarker:
    # Synchronous: processes every frame in order with monotonic timestamps (no frame drops)
    for mp_image, timestamp_ms in decoded_video_frames:
        result = landmarker.detect_for_video(mp_image, timestamp_ms)
```

#### Livestream

`LIVE_STREAM`Async · drops frames when busyAsynchronous camera pipeline with a result callback. Automatically drops incoming frames when busy so results stay current with low latency.

```python
import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
HolisticLandmarker = mp.tasks.vision.HolisticLandmarker
HolisticLandmarkerOptions = mp.tasks.vision.HolisticLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

def on_result(result, output_image: mp.Image, timestamp_ms: int):
    print(f"Pose landmarks at {timestamp_ms} ms: {len(result.pose_landmarks)}")

options = HolisticLandmarkerOptions(
    base_options=BaseOptions(model_asset_path="holistic_landmarker.task"),
    running_mode=VisionRunningMode.LIVE_STREAM,
    min_face_detection_confidence=0.5,
    min_pose_detection_confidence=0.5,
    result_callback=on_result,
)

with HolisticLandmarker.create_from_options(options) as landmarker:
    # Async: automatically drops incoming camera frames when busy so results stay current
    mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=rgb_frame)
    landmarker.detect_async(mp_image, timestamp_ms)
```

### Flutter

pub`flutter pub add mediapipe_vision`[Live gallery](https://google.github.io/flutter-mediapipe/)·[Sample code](https://github.com/google/flutter-mediapipe/tree/main/samples/vision/holistic_landmarker)·[Setup guide](https://developers.google.com/edge/mediapipe/solutions/setup_flutter.md.txt)

#### Image

`RunningMode.image`Stateless · single frameOne call per independent still image. No tracking state carries over between calls.

```dart
import 'package:mediapipe_vision/mediapipe_vision.dart';

Future<void> trackPerson(VisionImage image) async {
  final landmarker = await HolisticLandmarker.create(
    HolisticLandmarkerOptions(model: VisionModels.holisticLandmarker),
  );
  try {
    final result = await landmarker.detect(image);
    print('Face: ${result.faceLandmarks.length} landmarks');
    print('Pose: ${result.poseLandmarks.length} landmarks');
    print('Left hand: ${result.leftHandLandmarks.length} landmarks');
    print('Right hand: ${result.rightHandLandmarks.length} landmarks');
  } finally {
    await landmarker.dispose();
  }
}
```

#### Video

`RunningMode.video`Every frame · no dropsTracking across decoded video frames with strictly increasing timestamps. Processes every frame in order and never drops frames.

```dart
import 'dart:typed_data';

import 'package:mediapipe_vision/mediapipe_vision.dart';

typedef Frame = ({Uint8List rgba, int width, int height, int milliseconds});

Future<void> trackPersonInVideo(Stream<Frame> frames) async {
  final landmarker = await HolisticLandmarker.create(
    HolisticLandmarkerOptions(
      model: VisionModels.holisticLandmarker,
      runningMode: RunningMode.video,
    ),
  );
  try {
    await for (final frame in frames) {
      final result = await landmarker.detectForVideo(
        VisionImage.fromPixels(
          pixels: frame.rgba,
          width: frame.width,
          height: frame.height,
          format: VisionPixelFormat.rgba,
        ),
        timestampMilliseconds: frame.milliseconds,
      );
      final ms = result.timestampMilliseconds;
      print(
        '$ms ms: ${result.faceLandmarks.length} face, '
        '${result.poseLandmarks.length} pose, '
        '${result.leftHandLandmarks.length} left hand and '
        '${result.rightHandLandmarks.length} right hand landmarks',
      );
    }
  } finally {
    await landmarker.dispose();
  }
}
```

#### Livestream

`RunningMode.liveStream`Async · drops frames when busyEach call returns at once and results arrive on the task's `results` stream. One frame runs at a time; a newer frame replaces one that's waiting, so results stay current.

```dart
import 'dart:typed_data';

import 'package:mediapipe_vision/mediapipe_vision.dart';

typedef Frame = ({Uint8List rgba, int width, int height, int milliseconds});

Future<void> trackPersonLive(Stream<Frame> frames) async {
  final landmarker = await HolisticLandmarker.create(
    HolisticLandmarkerOptions(
      model: VisionModels.holisticLandmarker,
      runningMode: RunningMode.liveStream,
    ),
  );
  // Listen before the first frame, as Google requires a result listener.
  final results = landmarker.results.listen((result) {
    final ms = result.timestampMilliseconds;
    print(
      '$ms ms: ${result.faceLandmarks.length} face, '
      '${result.poseLandmarks.length} pose, '
      '${result.leftHandLandmarks.length} left hand and '
      '${result.rightHandLandmarks.length} right hand landmarks',
    );
  });
  try {
    await for (final frame in frames) {
      landmarker.detectAsync(
        VisionImage.fromPixels(
          pixels: frame.rgba,
          width: frame.width,
          height: frame.height,
          format: VisionPixelFormat.rgba,
        ),
        timestampMilliseconds: frame.milliseconds,
      );
    }
  } finally {
    // Runs the frame in flight and the waiting one, then closes results.
    await landmarker.dispose();
    await results.cancel();
    print('${landmarker.droppedFrames} frames dropped');
  }
}
```

On Web, you can use `DrawingUtils(ctx).drawConnectors(...)` with `PoseLandmarker.POSE_CONNECTIONS`, `HandLandmarker.HAND_CONNECTIONS`, and `FaceLandmarker.FACE_LANDMARKS_TESSELATION` from `@mediapipe/tasks-vision` to render holistic overlays on an HTML `<canvas>`.

## Task details

This section describes the capabilities, inputs, outputs, and configuration
options of this task.

### Features

- **Input image processing** - Processing includes image rotation, resizing, normalization, and color space conversion.
- **Score thresholds** - Filter results based on prediction and confidence scores.
- **Optional outputs** - Optional output of face blendshapes and pose segmentation masks.

Inputs The Holistic Landmarker accepts an input of one of the following data types:

- Still images
- Decoded video frames
- Live video feed

See [Prepare vision input data](https://developers.google.com/edge/mediapipe/solutions/prepare_data.md.txt#vision) for `MPImage`, `mp.Image`, `VisionImage`, and browser media examples.
Outputs The Holistic Landmarker outputs the following results:

- Face landmarks in normalized image coordinates (478 landmarks)
- Pose landmarks in normalized image coordinates and 3D world coordinates (33 landmarks)
- Left hand landmarks in normalized image coordinates and 3D world coordinates (21 landmarks)
- Right hand landmarks in normalized image coordinates and 3D world coordinates (21 landmarks)
- Optional: Face blendshapes scores
- Optional: A segmentation mask for the pose region

### Configuration options

This task has the following configuration options:

### Web

| Option Name | Description | Value Range | Default Value |
|---|---|---|---|
| `runningMode` | Sets the running mode for the task: `IMAGE`: Single image inputs. `VIDEO`: Decoded video frames and live camera streams. | {`IMAGE`, `VIDEO`} | `IMAGE` |
| `minFaceDetectionConfidence` | The minimum confidence score for face detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `minFaceSuppressionThreshold` | The minimum non-maximum-suppression threshold for overlapping face detections. | Float `[0.0, 1.0]` | `0.3` |
| `minFacePresenceConfidence` | The minimum confidence score for face presence in face landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `minPoseDetectionConfidence` | The minimum confidence score for pose detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `minPoseSuppressionThreshold` | The minimum non-maximum-suppression threshold for overlapping pose detections. | Float `[0.0, 1.0]` | `0.3` |
| `minPosePresenceConfidence` | The minimum confidence score for pose presence in pose landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `minHandLandmarksConfidence` | The minimum confidence score for hand presence in hand landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `outputFaceBlendshapes` | Whether to output face blendshape classifications for 3D facial expression rendering. | `Boolean` | `false` |
| `outputPoseSegmentationMasks` | Whether to output segmentation masks for the detected pose. | `Boolean` | `false` |

### Android

| Option Name | Description | Value Range | Default Value |
|---|---|---|---|
| `runningMode` | Sets the running mode for the task: `IMAGE`: Single image inputs. `VIDEO`: Decoded frames of a video. `LIVE_STREAM`: Livestream of camera input data (requires asynchronous listener/delegate). | {`IMAGE`, `VIDEO`, `LIVE_STREAM`} | `IMAGE` |
| `minFaceDetectionConfidence` | The minimum confidence score for face detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `minFaceSuppressionThreshold` | The minimum non-maximum-suppression threshold for overlapping face detections. | Float `[0.0, 1.0]` | `0.3` |
| `minFacePresenceConfidence` | The minimum confidence score for face presence in face landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `minPoseDetectionConfidence` | The minimum confidence score for pose detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `minPoseSuppressionThreshold` | The minimum non-maximum-suppression threshold for overlapping pose detections. | Float `[0.0, 1.0]` | `0.3` |
| `minPosePresenceConfidence` | The minimum confidence score for pose presence in pose landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `minHandLandmarksConfidence` | The minimum confidence score for hand presence in hand landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `outputFaceBlendshapes` | Whether to output face blendshape classifications for 3D facial expression rendering. | `Boolean` | `false` |
| `outputPoseSegmentationMasks` | Whether to output segmentation masks for the detected pose. | `Boolean` | `false` |
| `resultListener` | Asynchronous callback for `LIVE_STREAM` mode results. | `OutputHandler.ResultListener<HolisticLandmarkerResult, MPImage>` | Not set |
| `errorListener` | Optional error listener for `LIVE_STREAM` mode. | `ErrorListener` | Not set |

### iOS

| Option Name | Description | Value Range | Default Value |
|---|---|---|---|
| `runningMode` | Sets the running mode for the task: `IMAGE`: Single image inputs. `VIDEO`: Decoded frames of a video. `LIVE_STREAM`: Livestream of camera input data (requires asynchronous listener/delegate). | {`IMAGE`, `VIDEO`, `LIVE_STREAM`} | `IMAGE` |
| `minFaceDetectionConfidence` | The minimum confidence score for face detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `minFaceSuppressionThreshold` | The minimum non-maximum-suppression threshold for overlapping face detections. | Float `[0.0, 1.0]` | `0.3` |
| `minFacePresenceConfidence` | The minimum confidence score for face presence in face landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `minPoseDetectionConfidence` | The minimum confidence score for pose detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `minPoseSuppressionThreshold` | The minimum non-maximum-suppression threshold for overlapping pose detections. | Float `[0.0, 1.0]` | `0.3` |
| `minPosePresenceConfidence` | The minimum confidence score for pose presence in pose landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `minHandLandmarksConfidence` | The minimum confidence score for hand presence in hand landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `outputFaceBlendshapes` | Whether to output face blendshape classifications for 3D facial expression rendering. | `Boolean` | `false` |
| `outputPoseSegmentationMasks` | Whether to output segmentation masks for the detected pose. | `Boolean` | `false` |
| `holisticLandmarkerLiveStreamDelegate` | Asynchronous delegate for `LIVE_STREAM` mode results (invoked on a serial background queue). | `HolisticLandmarkerLiveStreamDelegate` | Not set |

### Python

| Option Name | Description | Value Range | Default Value |
|---|---|---|---|
| `running_mode` | Sets the running mode for the task: `IMAGE`: Single image inputs. `VIDEO`: Decoded frames of a video. `LIVE_STREAM`: Livestream of camera input data (requires `result_callback`). | {`IMAGE`, `VIDEO`, `LIVE_STREAM`} | `IMAGE` |
| `min_face_detection_confidence` | The minimum confidence score for face detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `min_face_suppression_threshold` | The minimum non-maximum-suppression threshold for overlapping face detections. | Float `[0.0, 1.0]` | `0.3` |
| `min_face_presence_confidence` | The minimum confidence score for face presence in face landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `min_pose_detection_confidence` | The minimum confidence score for pose detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `min_pose_suppression_threshold` | The minimum non-maximum-suppression threshold for overlapping pose detections. | Float `[0.0, 1.0]` | `0.3` |
| `min_pose_presence_confidence` | The minimum confidence score for pose presence in pose landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `min_hand_landmarks_confidence` | The minimum confidence score for hand presence in hand landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `output_face_blendshapes` | Whether to output face blendshape classifications for 3D facial expression rendering. | `Boolean` | `False` |
| `output_pose_segmentation_masks` | Whether to output segmentation masks for the detected pose. | `Boolean` | `False` |
| `result_callback` | Asynchronous callback function for `LIVE_STREAM` mode results. | `Callable` | Not set |

### Flutter

| Option Name | Description | Value Range | Default Value |
|---|---|---|---|
| `runningMode` | Sets the running mode for the task: `RunningMode.image`: Single image inputs. `RunningMode.video`: Decoded frames of a video. `RunningMode.liveStream`: Livestream of camera input data (results arrive on the task's `results` stream). | {`RunningMode.image`, `RunningMode.video`, `RunningMode.liveStream`} | `RunningMode.image` |
| `minFaceDetectionConfidence` | The minimum confidence score for face detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `minFaceSuppressionThreshold` | The minimum non-maximum-suppression threshold for overlapping face detections. | Float `[0.0, 1.0]` | `0.5` |
| `minFacePresenceConfidence` | The minimum confidence score for face presence in face landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `minPoseDetectionConfidence` | The minimum confidence score for pose detection to be considered successful. | Float `[0.0, 1.0]` | `0.5` |
| `minPoseSuppressionThreshold` | The minimum non-maximum-suppression threshold for overlapping pose detections. | Float `[0.0, 1.0]` | `0.5` |
| `minPosePresenceConfidence` | The minimum confidence score for pose presence in pose landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `minHandLandmarksConfidence` | The minimum confidence score for hand presence in hand landmark detection. | Float `[0.0, 1.0]` | `0.5` |
| `outputFaceBlendshapes` | Whether to output face blendshape classifications for 3D facial expression rendering. | `bool` | `false` |
| `outputPoseSegmentationMask` | Whether to output a segmentation mask for the detected pose. | `bool` | `false` |

### Task output

Each `HolisticLandmarkerResult` returns synchronized face, pose, and left/right hand landmarks from a single unified pipeline:

| Field | Type / Coordinate Space | Description |
|---|---|---|
| `faceLandmarks` | `NormalizedLandmark[]` (`x, y` in `[0.0, 1.0]`) | 478 3D facial landmarks normalized by image width and height, with `z` relative to the center of the head (`face_landmarks` in Python). |
| `poseLandmarks` | `NormalizedLandmark[]` (`x, y` in `[0.0, 1.0]`) | 33 pose landmarks normalized by image width and height, with `z` relative to the midpoint of the hips (`pose_landmarks` in Python). |
| `poseWorldLandmarks` | `Landmark[]` (meters) | 33 3D pose landmarks in real-world meters with the origin at the midpoint of the hips (`pose_world_landmarks` in Python). |
| `leftHandLandmarks` | `NormalizedLandmark[]` (`x, y` in `[0.0, 1.0]`) | 21 left-hand 3D landmarks normalized by image width and height (`left_hand_landmarks` in Python). |
| `leftHandWorldLandmarks` | `Landmark[]` (meters) | 21 left-hand 3D landmarks in real-world meters (`left_hand_world_landmarks` in Python). |
| `rightHandLandmarks` | `NormalizedLandmark[]` (`x, y` in `[0.0, 1.0]`) | 21 right-hand 3D landmarks normalized by image width and height (`right_hand_landmarks` in Python). |
| `rightHandWorldLandmarks` | `Landmark[]` (meters) | 21 right-hand 3D landmarks in real-world meters (`right_hand_world_landmarks` in Python). |
| `faceBlendshapes` | `Classifications` (`score` in `[0.0, 1.0]`) | Optional 52 facial expression coefficients when `outputFaceBlendshapes` is enabled (`face_blendshapes` in Python; in Dart, a `List<MediaPipeCategory>?` with no `categories` wrapper, `null` when not requested or no face is found). |
| `segmentationMask` | `MPMask` (`Float32` in `[0.0, 1.0]`) | Optional single-channel float pose confidence mask when `outputPoseSegmentationMasks` is enabled (`segmentation_mask` in Python; `poseSegmentationMask` in Dart, a `ConfidenceMask?` enabled with `outputPoseSegmentationMask`). |

#### Example `HolisticLandmarkerResult` payload

The following example shows synchronized face, pose, and hand landmarks for a single subject:

```javascript
{
  faceLandmarks: [
    { x: 0.4980, y: 0.3120, z: -0.0240 }, // #0..#477 (478 normalized face landmarks)
  ],
  poseLandmarks: [
    { x: 0.5010, y: 0.2640, z: -0.4120, visibility: 0.9980, presence: 0.9990 }, // #0 nose (33 pose landmarks)
  ],
  poseWorldLandmarks: [
    { x: 0.0120, y: -0.5480, z: -0.2850, visibility: 0.9980, presence: 0.9990 }, // #0 nose (3D meters)
  ],
  leftHandLandmarks: [
    { x: 0.6840, y: 0.6120, z: 0.0 }, // #0 WRIST (21 left hand landmarks)
  ],
  rightHandLandmarks: [
    { x: 0.3180, y: 0.6050, z: 0.0 }, // #0 WRIST (21 right hand landmarks)
  ]
}
```

## Models

![Holistic Landmarker pipeline overview](https://developers.google.com/static/edge/mediapipe/images/solutions/diagrams/holistic_landmarker.svg)

The Holistic Landmarker uses a series of packaged models to perform holistic landmarks
detection. These models include face detection, facial landmarks, pose
detection, pose landmarker, palm detection, and hand landmark models.

The following models are packaged together into a downloadable model bundle:

- **Pose detection and landmark model**: tracks 33 body pose coordinates.
- **Face detection and landmark model**: detects and tracks 478 3D facial landmarks, including 10 iris landmarks with optional 52 blendshape coefficients.
- **Palm detection and hand landmark model**: tracks 21 knuckle coordinates per hand.

| Model bundle | Data type | Model Cards | Versions |
|---|---|---|---|
| [Holistic landmarker](https://storage.googleapis.com/mediapipe-models/holistic_landmarker/holistic_landmarker/float16/latest/holistic_landmarker.task) | float 16 | [BlazePose](https://storage.googleapis.com/mediapipe-assets/Model%20Card%20BlazePose%20GHUM%203D.pdf) [FaceLandmarker-V2](https://storage.googleapis.com/mediapipe-assets/Model%20Card%20MediaPipe%20Face%20Mesh%20V2.pdf) [HandLandmarker](https://storage.googleapis.com/mediapipe-assets/Model%20Card%20Hand%20Tracking%20(Lite_Full)%20with%20Fairness%20Oct%202021.pdf) | [Latest](https://storage.googleapis.com/mediapipe-models/holistic_landmarker/holistic_landmarker/float16/latest/holistic_landmarker.task) |

## Landmark coordinates

The Holistic Landmarker outputs a total of 553 landmarks that represent the full body:

- **Pose landmarks** : 33 landmarks representing key body coordinate points (same as the [Pose Landmarker](https://developers.google.com/edge/mediapipe/solutions/vision/pose_landmarker.md.txt)).
- **Face landmarks** : 478 landmarks representing the facial structure including 10 iris landmarks (same as the [Face
  Landmarker](https://developers.google.com/edge/mediapipe/solutions/vision/face_landmarker)).
- **Hand landmarks** : 21 landmarks per hand (42 total) representing knuckle coordinates (same as the [Hand Landmarker](https://developers.google.com/edge/mediapipe/solutions/vision/hand_landmarker.md.txt)).