mediapipe_face_mesh 2.7.1
mediapipe_face_mesh: ^2.7.1 copied to clipboard
Real-time on-device MediaPipe face detection and face mesh: 478 landmarks with iris, multi-face tracking, ARKit-style blendshapes, and 3D head pose.
2.7.1 #
- docs: add a Performance section to the README and a benchmark report
(
doc/BENCHMARKS.md): single-image and streaming latency, and app size
2.7.0 #
- fix a crash on iOS when
FaceMeshDelegate.xnnpackwas selected, present since 2.1.0- the bundled
TensorFlowLiteCheaders and the shipped binary disagreed on the layout ofTfLiteXNNPackDelegateOptions, so creating the delegate corrupted the stack - the default CPU delegate was never affected, and neither were Android, Windows, or macOS
- the rest of the bundled iOS headers are now synced with the declarations the other platforms use, so the mismatch cannot recur in another header
- the bundled
- add native Apple Silicon simulator (arm64) support: the iOS runtime now ships
as
TensorFlowLiteC.xcframeworkinstead of a fatTensorFlowLiteC.framework- Intel Macs keep an
x86_64simulator slice - the bundled runtime grows from ~18 MB to ~25 MB, all of it simulator-only, so a shipped app is unaffected
- upgrading may need
pod deintegrate && pod installinios/and a cleared build folder and DerivedData; a build that fails to link againstTensorFlowLiteCis still picking up the old cached copy
- Intel Macs keep an
- doc: a debug
flutter runon a physical iOS 17+ device can hang on Flutter older than 3.38.0 (doc/IOS_DEBUG_RUN.md)
2.6.0 #
- Performance: large cross-the-board speedup of the inference path. On a
Dimensity 9400 test device, streaming dropped from ~9.7ms to ~1.5ms per
frame (468 mesh) and ~2.2ms with attention; a cold detector+mesh pass
dropped from ~16ms to ~3ms. The changes:
- native code is now always compiled with optimization (
-O3//O2), including Flutter debug and profile app builds, which previously built the plugin's C++ at-O0 - per-call frame upload now reuses a per-processor native scratch buffer instead of allocating, zero-filling, copying, and freeing the whole frame on every call
FaceMeshResult.trianglesis now built lazily on first access (the field became a getter; reading code is source-compatible)- landmark results are read through one typed-data view instead of a per-landmark FFI struct view
- native code is now always compiled with optimization (
threadsnow defaults to half the CPU cores clamped to 1..4 (MediaPipe's own default) instead of 2. The parameter type widened toint?; passing an explicit value behaves as before- Delegate robustness: previously
allowDelegateFallbackonly covered a delegate that could not be created. A delegate that was created but then failed while the interpreter was built or allocated made creation fail outright; that stage now falls back to CPU as well FaceMeshDelegate.gpuV2is now@Deprecatedand will be removed in 3.0.0. The bundled runtimes have never included the GPU delegate (the value has always fallen back to CPU), and benchmarks with a GPU-enabled runtime showed the delegate running these small models several times slower than CPU/XNNPACK while adding megabytes per ABI, so GPU support is not planned. Usecpuorxnnpack
2.5.0 #
- Windows:
enableAttentionMeshis now supported. The bundledtensorflowlite_c.dllincludes the MediaPipe custom TFLite ops theface_landmark_with_attentionmodel needsFaceMeshProcessor.create(enableAttentionMesh: true)no longer throwsUnsupportedErroron Windows- XNNPACK note: the custom ops run on the reference CPU kernels (XNNPACK partitions around them), same as on the other platforms
- example: the mesh-model dropdown now offers Attention Mesh on Windows too, and the default mesh mode is attention on all platforms
2.4.0 #
- add optional OneEuro landmark smoothing, a Dart port of the official
FaceLandmarker stream-mode behavior (
LandmarksSmoothingCalculatorone_euro path,min_cutoff 0.05 / beta 80 / derivate_cutoff 1.0): passlandmarkSmoothing: LandmarkSmoothingOptions()toFaceMeshInferencePipeline(default off, so existing setups are unchanged)- smoothing applies to output landmarks only; ROI tracking keeps running on the raw mesh output, so tracking behavior is identical with it on or off
- the multi-face flow smooths each tracked face independently; with
enableLandmarkTracking: falsethe multi-face flow is not smoothed - filter state resets on face loss/re-acquisition, input geometry changes,
and
resetTracking() - the pipeline
process*methods accept an optionaltimestamp; it defaults to an internal clock, pass frame timestamps when replaying recorded video FaceLandmarkSmoother(smooths aFaceMeshResult), plus the underlyingOneEuroLandmarksSmoother/OneEuroFilter/LandmarkSmoothingOptions, are public for custom pipelines
- example: the demo enables landmark smoothing on all its pipelines
2.3.0 #
- add Windows (x64) desktop support: the same native pipeline (detector, mesh,
iris, blendshapes, geometry) now builds and runs on Windows via the Flutter
Windows CMake toolchain
enableAttentionMeshis not supported on Windows —createthrows anUnsupportedErrorthere- GPU delegate (
FaceMeshDelegate.gpuV2) is not available on Windows; the existing delegate fallback resolves to CPU/XNNPACK - the example app gains a Windows live demo using a USB (UVC) camera via
flutter_ffi_uvc, feeding its RGBA frames straight intoFaceMeshImage
- fix:
IrisRectFromEyeCornersreturned an uninitialized rect on a degenerate eye distance, which could bypass the invalid-ROI check with garbage values
2.2.0 #
- align tracking-confidence semantics with the official graph: when a tracked
face's presence score falls below
minTrackingConfidence, the native tracked ROI is now dropped (andFaceMeshInferencePipelinere-acquires via the detector on the next frame) instead of freezing the last ROI while landmarks kept coming — previously a documented caveat when raisingminTrackingConfidenceabove 0.5- the first tracked ROI seed is no longer smoothed against the initial full-frame rect, so the first tracked frame crops the actual face extent
- add
FaceMeshProcessor.isTracking: whether the internal ROI currently follows a face - expose
minFacePresenceConfidenceonFaceMeshProcessor.createandcreateForMultiFace(the score below which a frame returns no landmarks; was always the native default 0.5 before) plus a matching getter - add
FaceMeshProcessor.processRois/processNv21Rois: one mesh inference per ROI on a single native frame upload, instead of copying the full frame into native memory once per face — if you loopprocess(roi: ...)per face on the same frame, switch toprocessRoisfor the single-upload pathprocessMultiFace/processNv21MultiFaceand theFaceMeshInferencePipelinemulti-face flow now route through it, so multi-face frames copy the frame across the FFI boundary once regardless of face count
2.1.0 #
- add
enableAttentionMeshonFaceMeshProcessor.createandFaceMeshProcessor.createForMultiFace(defaultfalse, so existing setups are unchanged)- runs the official
face_landmark_with_attentionmodel, which refines lips, eyes, and irises in a single inference and outputs the 478-landmark layout directly, instead of the base 468-point mesh plus a separate iris pass - iris is always included when it is enabled, so it supersedes
enableIris(the separate iris model is not loaded andactiveIrisDelegateis null);irisEnabledstays true, soFaceBlendshapesProcessorkeeps working - the attention outputs are merged into the existing index layout exactly as the official
LandmarksRefinementCalculatordoes, so mesh/iris/blendshape/geometry consumers need no changes - XNNPACK does not support the model's custom ops; TFLite partitions the graph and runs those
nodes on the reference CPU kernels, so
FaceMeshDelegate.xnnpackaccelerates only the rest of the model on the attention path
- runs the official
- add
FaceMeshProcessor.irisEnabled(true whenever the processor returns 478 landmarks) andFaceMeshProcessor.attentionMeshEnabled - rebuild the bundled TensorFlow Lite C runtimes (Android
arm64-v8a/x86_64, iOSTensorFlowLiteC.framework) with the MediaPipe custom ops the attention model requires; the iOS framework also shrinks from ~47 MB to ~18 MB - bundle
assets/models/face_landmark_with_attention.tflite(~2.4 MB); it is only materialized to disk whenenableAttentionMeshis set - example: replace the
Iristoggle with a mesh-mode selector (Base / Iris / Attention Mesh)
2.0.0 #
- BREAKING:
FaceMeshInferencePipelinesingle-face flow now follows the official MediaPipe Face Mesh design — the detector runs only to (re)acquire a face, and tracked frames derive the mesh ROI from the previous frame's landmarks- improves mesh accuracy when the raw detection box is imprecise (e.g. a wide-open mouth no longer distorts the mesh) and roughly halves the per-frame compute on tracked frames
FaceMeshInferenceResult.detectionResultis now nullable; it is null on landmark-tracked frames where the detector did not run- on tracked frames
FaceMeshInferenceResult.selectedRoicarries the tracked ROI used for mesh inference - since the detector is not consulted on tracked frames,
detectorRoiand the detector ROI scale/shift overrides apply only to (re)acquisition frames - tracking resets automatically when input type, frame size, rotation, or mirroring changes; call
resetTracking()when switching input sources that the pipeline cannot distinguish - add
FaceMeshInferencePipeline.isTrackingandFaceMeshInferencePipeline.resetTracking(), anddetectorRanon both result types - add
FaceMeshProcessor.roiTrackingEnabled; single-face landmark tracking requires a mesh processor created withenableRoiTracking: true(the default)
- BREAKING: multi-face pipeline methods (
processMultiFace/processNv21MultiFace) also track by landmarks — each tracked face runs on an ROI derived from its previous frame's landmarks, and the detector runs only while fewer thanmaxMeshFacesfaces are tracked, with IoU-gated association for newly detected faces (matching the official graph'snum_facesbehavior)FaceMeshMultiInferenceResult.detectionResultis now nullable (null when all face slots were served by tracking) and results are exposed asfaces— aList<TrackedFaceMesh>with a per-facetrackIdthat stays stable while the face is tracked- multi-face tracking is managed in Dart with explicit per-face ROIs, so it works with
createForMultiFaceprocessors; the single- and multi-face flows share the native mesh state, so calling one resets the other's tracking and the other flow re-acquires via the detector on its next call - a tracked face is dropped — and its slot re-acquired via the detector — when its mesh presence score falls below
minTrackingConfidence(now exposed asFaceMeshProcessor.minTrackingConfidence), matching the official tracking-confidence semantics
- add
FaceMeshResult.trackingRoi()— the landmark-derived ROI a tracker uses for the next frame, matching the native formula; useful for custom pipelines - add
FaceMeshPainter.scaleWithFace— scales stroke widths and dot radii with each face's on-screen size (per face when drawing multiple results), so overlays keep their proportions as faces move closer or farther; the example enables it - fix internal ROI tracking (
enableRoiTracking) computing its square ROI in normalized space, which vertically stretched the ROI on portrait frames and degraded tracked landmark quality (present since 1.2.1); the ROI square and eye-line rotation are now computed in pixel space, matching the official graph - fix ROI size sanitation clamping width and height independently, which could stretch very small or very large ROIs anisotropically; the size bounds are now applied with a single scale factor that preserves the ROI aspect
- fix a native result leak when copying a detector or mesh result to Dart throws; the native result is now released in a
finally - reduce internal ROI smoothing (alpha 0.8 → 0.5) so the tracked ROI follows fast face changes with less lag
- example: draw the tracked ROI overlay and show a
Trackingstatus chip while the detector is skipped - example: add a
Multitoggle that switches to the multi-face tracking flow, rendering every tracked face's mesh and ROI with itstrackIdlabel - example: remove the legacy ML Kit detector flow from the app; README links the v1.10.1 ML Kit integration for users who need an external detector example
Migrating from 1.x #
FaceMeshInferenceResult.detectionResultandFaceMeshMultiInferenceResult.detectionResultare nullable — handle the null (tracked-frame) case; usedetectorRanto tell the two frame types apart- multi-face results moved from a
meshResultsconstructor field tofaces(List<TrackedFaceMesh>); readingresult.meshResultsstill works via a getter - to restore the previous every-frame detector behavior, pass
enableLandmarkTracking: falsetoFaceMeshInferencePipeline(the nullable type change still applies)
1.10.1 #
- docs: update the example image
- add
.pubignoreto exclude README images from the published package (~7 MB smaller download) - example: remove an unused asset
1.10.0 #
- add support for ARKit-style face blendshapes
FaceBlendshapesProcessor, a post-processor that turns aFaceMeshResultinto the 52 blendshape coefficients (Map<FaceBlendshape, double>); requires a mesh created withenableIris: trueFaceBlendshapeenum (52 categories,neutralat index 0)- bundles the
face_blendshapes.tflitemodel (~0.9 MB)
- example: add a blendshapes-based expression detection demo
1.9.1 #
- patch release to re-trigger pub.dev analysis after 1.9.0 was stuck in pending state
1.9.0 #
- add
FaceMeshResult.estimateGeometry()for 3D face geometrygeometry.headPose— head pose estimation (yaw, pitch, roll)geometry.distanceCm()— centimeter distance between any two landmarksgeometry.measurements— preset bundle of common face measurements- accepts
verticalFovDegreesfor improved centimeter accuracy when the actual camera FOV is known (default: 63°)
- add
FaceMeshResult.distancePixels()for 2D pixel distance between landmarks
1.8.1 #
- expose camera plane conversion logic as public
FaceMeshNv21Imagehelper APIs
1.8.0 #
- add delegate fallback controls and active delegate diagnostics for face detector, face mesh, and optional iris model
1.7.1 #
- fix Android build configuration to align with Flutter 3.32.x (Dart 3.8.1) defaults
- set plugin
compileSdkto 35 andndkVersionto 26.3.11579264 - set example
minSdkto 24
1.7.0 #
- add multi-face mesh inference APIs with
FaceMeshMultiInferenceResult,processMultiFace, andprocessNv21MultiFace - add reusable
FaceMeshPainterandFaceDetectionPainterpreview overlay painters as package files - update the examples to use the public overlay painters
- update README docs for multi-face inference
1.6.0 #
- add
FaceMeshInferencePipelineandFaceMeshInferenceResultfor one-call unified detector and face mesh inference - add
FaceMeshInferenceStreamProcessorfor stream-based unified inference - update the MediaPipe detector example to use
FaceMeshInferencePipeline - update README usage docs for the unified inference API
1.5.0 #
- add bundled full-range dense and sparse face detector model support
- add
FaceDetectionModelselection toFaceDetectorProcessor.create
1.4.1 #
- update docs
1.4.0 #
- add optional iris landmark output through
FaceMeshProcessor.create(enableIris: true)
1.3.2 #
- add stream processing support to
FaceDetectorStreamProcessor(process/processNv21) - update README and example to cover FaceDetectorStreamProcessor stream inference
1.3.1 #
- lower the Dart SDK constraint to
^3.8.1 - update the example camera adapter to handle multiple Android YUV layouts in Dart
1.3.0 #
- add
FaceDetectorProcessorwith bundled MediaPipe short-range face detection model - support detector-driven ROI flow for face mesh inference and expose
FaceDetection/FaceDetectionResult - refactor example app to include both MediaPipe and ML Kit detection flows
- update README and change license to BSD 3-Clause
1.2.6 #
- add pub.dev topics and update package description
1.2.5 #
- rewrite example app: live camera demo using
google_mlkit_face_detection+FaceMeshStreamProcessor - render face mesh as polygon wireframe via
result.triangles(MpFaceMeshTriangle) - clean up README
1.2.4 #
- add MediaPipe face mesh triangulation topology and expose
FaceMeshResult.triangles. - sanitize the cache filename without
RegExpto avoid the deprecation warning.
1.2.3 #
- update README to cover
FaceMeshResultoutput fields, normalization rules, and ROI behavior - add
toString()overrides for core value classes (rect, box, image, landmark, result)
1.2.2 #
- add
enableRoiTrackingoption inFaceMeshProcessor.createto control internal ROI tracking between frames
1.2.1 #
- add
enableRoiTrackingoption inFaceMeshProcessor.createto control internal ROI tracking between frames
1.2.0 #
- improve README usage guidance and stream/camera documentation
- rename
FaceMeshStreamProcessor.processImagestoFaceMeshStreamProcessor.process - adjust default
_boxScalefrom 1.3 to 1.2 inmediapipe_face_mesh.dart
1.1.1 #
- document official LiteRT build instructions and expected binary locations in README
1.1.0 #
- replace bundled
tensorflow/liteandtensorflow/compilerheaders with upstream copies - add runtime delegate selection (CPU / XNNPACK / GPU V2) and expose the option through the Dart API
- update README to reflect delegate support and document TensorFlow source folders
1.0.3 #
- run
dart format .across the repo - shorten
pubspec.yamldescription to satisfy length requirements
1.0.2 #
- add detailed plugin description and document key public APIs
- enable
public_member_api_docslint - update README.md
- fix corrupted
example/assets/img.pngbinary
1.0.1 #
- update docs
1.0.0 #
- Initial public release of the MediaPipe Face Mesh FFI plugin for Android and iOS