### Face Effect Mobile Android Example Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md Face effect example for Android. This example works for a single face and requires a specific build target. ```bash mediapipe/examples/android/src/java/com/google/mediapipe/apps/faceeffect ``` -------------------------------- ### Face Geometry Calculator Implementation Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md This C++ code defines the implementation of the face geometry calculator, responsible for processing face landmarks and generating 3D face geometry. ```cpp #include "mediapipe/modules/face_geometry/geometry_pipeline_calculator.h" #include "mediapipe/modules/face_geometry/protos/face_geometry.proto.h" #include "mediapipe/framework/calculator_runner.h" #include "mediapipe/framework/formats/image_frame.h" #include "mediapipe/framework/formats/image_frame_opencv.h" #include "mediapipe/framework/port/gmock.h" #include "mediapipe/framework/port/gtest.h" #include "mediapipe/framework/port/parse_text_proto.h" #include "mediapipe/framework/port/status.h" #include "mediapipe/util/tflite/tflite_utils.h" #include #include "absl/strings/str_cat.h" #include "absl/types/optional.h" namespace mediapipe { namespace { // Helper function to convert normalized landmark coordinates to screen coordinates. std::vector NormalizedLandmarksToScreen(const std::vector& landmarks, int width, int height) { std::vector screen_landmarks; screen_landmarks.reserve(landmarks.size()); for (const auto& landmark : landmarks) { screen_landmarks.push_back({ landmark.x() * width, landmark.y() * height, }); } return screen_landmarks; } // Helper function to convert screen coordinates to Metric 3D space coordinates. std::vector ScreenToMetric3D(const std::vector& screen_landmarks, const LandmarkTransform& transform, float scale) { std::vector metric_landmarks; metric_landmarks.reserve(screen_landmarks.size()); for (const auto& landmark : screen_landmarks) { metric_landmarks.push_back({ (landmark.x - transform.tx) * scale, (landmark.y - transform.ty) * scale, transform.tz * scale, }); } return metric_landmarks; } // Helper function to estimate the face pose transformation matrix. LandmarkTransform EstimateFacePose(const std::vector& canonical_landmarks, const std::vector& runtime_landmarks) { LandmarkTransform transform; // For simplicity, we'll just use the centroid of the landmarks as the translation. // A more robust implementation would use Procrustes analysis or similar. cv::Point3f canonical_centroid(0.0f, 0.0f, 0.0f); for (const auto& p : canonical_landmarks) { canonical_centroid += p; } canonical_centroid /= canonical_landmarks.size(); cv::Point3f runtime_centroid(0.0f, 0.0f, 0.0f); for (const auto& p : runtime_landmarks) { runtime_centroid += p; } runtime_centroid /= runtime_landmarks.size(); transform.tx = runtime_centroid.x; transform.ty = runtime_centroid.y; transform.tz = runtime_centroid.z; // In a real implementation, you would calculate rotation and scale here. // For this example, we assume no rotation and a scale of 1. transform.rx = 0.0f; transform.ry = 0.0f; transform.rz = 0.0f; transform.scale = 1.0f; return transform; } // Helper function to create a face mesh from runtime landmarks and canonical model. FaceLandmark CreateFaceMesh(const std::vector& runtime_landmarks, const FaceLandmark& canonical_face_model) { FaceLandmark face_mesh; // Copy vertex positions from runtime landmarks. for (const auto& p : runtime_landmarks) { auto* vertex = face_mesh.add_landmark(); vertex->set_x(p.x); vertex->set_y(p.y); vertex->set_z(p.z); } // Inherit texture coordinates and triangle topology from the canonical model. for (int i = 0; i < canonical_face_model.landmark_size(); ++i) { auto* canonical_vertex = canonical_face_model.landmark(i); auto* mesh_vertex = face_mesh.add_landmark(); // Copy UV coordinates if available in canonical model // For simplicity, we are not handling UVs here, assuming they are part of the canonical model definition. } // Copy triangle indices from canonical model. for (int i = 0; i < canonical_face_model.triangle_size(); ++i) { face_mesh.add_triangle(canonical_face_model.triangle(i)); } return face_mesh; } } // namespace class GeometryPipelineCalculatorTest : public ::testing::Test { protected: void SetUp() override { // Load the canonical face model. // In a real scenario, this would be loaded from a file or resource. // For this test, we'll create a dummy canonical model. canonical_face_model_.mutable_landmark()->Reserve(468); for (int i = 0; i < 468; ++i) { canonical_face_model_.add_landmark(); } // Add dummy triangle indices for testing purposes. canonical_face_model_.add_triangle(0); canonical_face_model_.add_triangle(1); canonical_face_model_.add_triangle(2); } mediapipe::CalculatorRunner runner_; FaceLandmark canonical_face_model_; }; TEST_F(GeometryPipelineCalculatorTest, BasicTransform) { // Configure the calculator. CalculatorGraphConfig config; auto* calculator_options = config.add_node()->add_options()->MutableExtension( mediapipe::GeometryPipelineCalculator::ext); calculator_options->set_canonical_model_path("dummy/path/to/canonical_face_model.fbx"); calculator_options->set_metric_scale(0.01f); // 1 unit = 1 cm // Create a runner for the calculator. runner_ = mediapipe::CalculatorRunner(config); // Prepare input data: normalized face landmarks. std::vector input_landmarks; input_landmarks.reserve(468); for (int i = 0; i < 468; ++i) { auto* landmark = new NormalizedLandmark(); landmark->set_x(0.5f); landmark->set_y(0.5f); landmark->set_z(0.0f); input_landmarks.push_back(*landmark); } // Add input stream. runner_.MutableInputs()->Tag("NORM_LANDMARKS").packets.push_back( runner_.CreatePacket>( input_landmarks, mediapipe::Timestamp(0))); // Add canonical face model input stream. runner_.MutableInputs()->Tag("CANONICAL_FACE_MODEL").packets.push_back( runner_.CreatePacket(canonical_face_model_, mediapipe::Timestamp(0))); // Run the calculator. ASSERT_TRUE(runner_.Run().ok()); // Get output data: face transform and face mesh. const std::vector& output_packets = runner_.Outputs().Tag("FACE_GEOMETRY").packets; ASSERT_EQ(output_packets.size(), 1); const auto& face_geometry = output_packets[0].Get(); ASSERT_TRUE(face_geometry.has_face_transform()); ASSERT_TRUE(face_geometry.has_face_landmarks()); // Assertions on the output. // The exact values will depend on the dummy input and the simplified estimation logic. // Here we just check if the output is populated. EXPECT_GT(face_geometry.face_transform().tx(), 0.0f); EXPECT_GT(face_geometry.face_landmarks().landmark_size(), 0); } TEST_F(GeometryPipelineCalculatorTest, NoInput) { // Configure the calculator. CalculatorGraphConfig config; auto* calculator_options = config.add_node()->add_options()->MutableExtension( mediapipe::GeometryPipelineCalculator::ext); calculator_options->set_canonical_model_path("dummy/path/to/canonical_face_model.fbx"); calculator_options->set_metric_scale(0.01f); // 1 unit = 1 cm // Create a runner for the calculator. runner_ = mediapipe::CalculatorRunner(config); // Run the calculator without any input. mediapipe::Status status = runner_.Run(); // Expect an error because input landmarks are missing. EXPECT_FALSE(status.ok()); EXPECT_EQ(status.code(), mediapipe::StatusCode::kInternal); EXPECT_THAT(status.message(), ::testing::HasSubstr("Input stream NORM_LANDMARKS is missing.")); } } // namespace mediapipe ``` -------------------------------- ### Initialize and Configure Face Detection for Video Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_detection.md Sets up Face Detection options for video mode and initializes the FaceDetection and VideoInput instances. Includes error handling for face detection. ```java // For video input and result rendering with OpenGL. FaceDetectionOptions faceDetectionOptions = FaceDetectionOptions.builder() .setStaticImageMode(false) .setModelSelection(0).build(); FaceDetection faceDetection = new FaceDetection(this, faceDetectionOptions); faceDetection.setErrorListener( (message, e) -> Log.e(TAG, "MediaPipe Face Detection error:" + message)); // Initializes a new VideoInput instance and connects it to MediaPipe Face Detection Solution. VideoInput videoInput = new VideoInput(this); videoInput.setNewFrameListener( textureFrame -> faceDetection.send(textureFrame)); ``` -------------------------------- ### Face Mesh Desktop CPU Example Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md Run Face Mesh on desktop using CPU. The graph file and target build are specified. ```bash mediapipe/examples/desktop/face_mesh:face_mesh_cpu ``` -------------------------------- ### Face Geometry Protocol Buffer Definition Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md This .proto file defines the data structures for face geometry, including face transform and face landmarks, used within MediaPipe. ```protobuf syntax = "proto3"; package mediapipe; import "mediapipe/framework/formats/landmark.proto"; // Options for GeometryPipelineCalculator. message GeometryPipelineCalculatorOptions { // Path to the canonical face model FBX file. optional string canonical_model_path = 1; // Scale factor to convert canonical model units to metric units (e.g., centimeters). optional float metric_scale = 2 [default = 0.01]; } // Represents the transformation of a face in 3D space. message FaceTransform { // Rotation angles (roll, pitch, yaw) in radians. optional float rx = 1; optional float ry = 2; optional float rz = 3; // Translation vector. optional float tx = 4; optional float ty = 5; optional float tz = 6; // Scale factor. optional float scale = 7; } // Represents the 3D geometry of a face, including landmarks and mesh. message FaceGeometry { // The transformation matrix that maps the canonical face model to the runtime face. optional FaceTransform face_transform = 1; // The face landmarks in the runtime 3D space. optional NormalizedLandmarkList face_landmarks = 2; // The face mesh, represented as a list of landmarks and triangle indices. optional NormalizedLandmarkList face_mesh = 3; } ``` -------------------------------- ### Face Effect Mobile iOS Example Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md Face effect example for iOS. This example works for a single face and requires a specific build target. ```bash mediapipe/examples/ios/faceeffect ``` -------------------------------- ### Process Face Detection Results and Render Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_detection.md Sets a listener to process face detection results, extract nose tip coordinates, and request rendering of the results on the GL surface view. Handles cases where no faces are detected. ```java faceDetection.setResultListener( faceDetectionResult -> { if (faceDetectionResult.multiFaceDetections().isEmpty()) { return; } RelativeKeypoint noseTip = faceDetectionResult .multiFaceDetections() .get(0) .getLocationData() .getRelativeKeypoints(FaceKeypoint.NOSE_TIP); Log.i( TAG, String.format( "MediaPipe Face Detection nose tip normalized coordinates (value range: [0, 1]): x=%f, y=%f", noseTip.getX(), noseTip.getY())); // Request GL rendering. glSurfaceView.setRenderData(faceDetectionResult); glSurfaceView.requestRender(); }); ``` -------------------------------- ### Face Mesh Desktop GPU Example Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md Run Face Mesh on desktop using GPU. The graph file and target build are specified. ```bash mediapipe/examples/desktop/face_mesh:face_mesh_gpu ``` -------------------------------- ### Initialize and Run Face Detection on an Image Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_detection.md Configures Face Detection options, sets up the listener for results and errors, and launches an intent to pick an image from the gallery for processing. ```java // For reading images from gallery and drawing the output in an ImageView. FaceDetectionOptions faceDetectionOptions = FaceDetectionOptions.builder() .setStaticImageMode(true) .setModelSelection(0).build(); FaceDetection faceDetection = new FaceDetection(this, faceDetectionOptions); // Connects MediaPipe Face Detection Solution to the user-defined ImageView // instance that allows users to have the custom drawing of the output landmarks // on it. See mediapipe/examples/android/solutions/facedetection/src/main/java/com/google/mediapipe/examples/facedetection/FaceDetectionResultImageView.java // as an example. FaceDetectionResultImageView imageView = new FaceDetectionResultImageView(this); faceDetection.setResultListener( faceDetectionResult -> { if (faceDetectionResult.multiFaceDetections().isEmpty()) { return; } int width = faceDetectionResult.inputBitmap().getWidth(); int height = faceDetectionResult.inputBitmap().getHeight(); RelativeKeypoint noseTip = faceDetectionResult .multiFaceDetections() .get(0) .getLocationData() .getRelativeKeypoints(FaceKeypoint.NOSE_TIP); Log.i( TAG, String.format( "MediaPipe Face Detection nose tip coordinates (pixel values): x=%f, y=%f", noseTip.getX() * width, noseTip.getY() * height)); // Request canvas drawing. imageView.setFaceDetectionResult(faceDetectionResult); runOnUiThread(() -> imageView.update()); }); faceDetection.setErrorListener( (message, e) -> Log.e(TAG, "MediaPipe Face Detection error:" + message)); // ActivityResultLauncher to get an image from the gallery as Bitmap. ActivityResultLauncher imageGetter = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { Intent resultIntent = result.getData(); if (resultIntent != null && result.getResultCode() == RESULT_OK) { Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap( this.getContentResolver(), resultIntent.getData()); // Please also rotate the Bitmap based on its orientation. } catch (IOException e) { Log.e(TAG, "Bitmap reading error:" + e); } if (bitmap != null) { faceDetection.send(bitmap); } } }); Intent pickImageIntent = new Intent(Intent.ACTION_PICK); pickImageIntent.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*"); imageGetter.launch(pickImageIntent); ``` -------------------------------- ### face_transform Protos Source: https://github.com/google-ai-edge/mediapipe/blob/master/mediapipe/modules/face_geometry/README.md Protocol buffer definitions for face geometry and related metadata. ```APIDOC ## face_transform Protos ### Description Protocol buffer definitions for face geometry and related metadata. ### Protos - **face_geometry.Environment** (Proto) - Describes an environment; includes the camera frame origin point location as well as virtual camera parameters. - **face_geometry.GeometryPipelineMetadata** (Proto) - Describes metadata needed to estimate face 3D transform based on the face landmark module result. - **face_geometry.FaceGeometry** (Proto) - Describes 3D transform data for a single face; includes a face mesh surface and a face pose in a given environment. - **face_geometry.Mesh3d** (Proto) - Describes a 3D mesh triangular surface. ``` -------------------------------- ### Detect faces in images with MediaPipe Source: https://context7.com/google-ai-edge/mediapipe/llms.txt Uses the FaceDetection module to identify faces and extract key points like the nose and eyes. Requires an input image and the OpenCV library for image processing. ```python with mp_face_detection.FaceDetection( model_selection=0, # 0=short-range (2m), 1=full-range (5m) min_detection_confidence=0.5 ) as face_detection: image = cv2.imread('image.jpg') results = face_detection.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) if results.detections: for detection in results.detections: # Get key points nose_tip = mp_face_detection.get_key_point( detection, mp_face_detection.FaceKeyPoint.NOSE_TIP) right_eye = mp_face_detection.get_key_point( detection, mp_face_detection.FaceKeyPoint.RIGHT_EYE) left_eye = mp_face_detection.get_key_point( detection, mp_face_detection.FaceKeyPoint.LEFT_EYE) print(f"Nose tip: ({nose_tip.x:.3f}, {nose_tip.y:.3f})") print(f"Detection score: {detection.score[0]:.2f}") # Get bounding box bbox = detection.location_data.relative_bounding_box print(f"Bounding box: x={bbox.xmin:.3f}, y={bbox.ymin:.3f}, w={bbox.width:.3f}, h={bbox.height:.3f}") mp_drawing.draw_detection(image, detection) cv2.imwrite('face_detected.jpg', image) ``` -------------------------------- ### Initialize Face Mesh Detection Source: https://context7.com/google-ai-edge/mediapipe/llms.txt Setup code for the MediaPipe Face Mesh solution to estimate 468 3D face landmarks. ```python import cv2 import mediapipe as mp mp_face_mesh = mp.solutions.face_mesh mp_drawing = mp.solutions.drawing_utils mp_drawing_styles = mp.solutions.drawing_styles ``` -------------------------------- ### Image Input for Face Mesh Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md Processes a static image from the gallery using Face Mesh and displays results in an ImageView. Requires setting up an ActivityResultLauncher to pick an image. ```java // For reading images from gallery and drawing the output in an ImageView. FaceMeshOptions faceMeshOptions = FaceMeshOptions.builder() .setStaticImageMode(true) .setRefineLandmarks(true) .setMaxNumFaces(1) .setRunOnGpu(true).build(); FaceMesh faceMesh = new FaceMesh(this, faceMeshOptions); // Connects MediaPipe Face Mesh Solution to the user-defined ImageView instance // that allows users to have the custom drawing of the output landmarks on it. // See mediapipe/examples/android/solutions/facemesh/src/main/java/com/google/mediapipe/examples/facemesh/FaceMeshResultImageView.java // as an example. FaceMeshResultImageView imageView = new FaceMeshResultImageView(this); faceMesh.setResultListener( faceMeshResult -> { int width = faceMeshResult.inputBitmap().getWidth(); int height = faceMeshResult.inputBitmap().getHeight(); NormalizedLandmark noseLandmark = result.multiFaceLandmarks().get(0).getLandmarkList().get(1); Log.i( TAG, String.format( "MediaPipe Face Mesh nose coordinates (pixel values): x=%f, y=%f", noseLandmark.getX() * width, noseLandmark.getY() * height)); // Request canvas drawing. imageView.setFaceMeshResult(faceMeshResult); runOnUiThread(() -> imageView.update()); }); faceMesh.setErrorListener( (message, e) -> Log.e(TAG, "MediaPipe Face Mesh error:" + message)); // ActivityResultLauncher to get an image from the gallery as Bitmap. ActivityResultLauncher imageGetter = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { Intent resultIntent = result.getData(); if (resultIntent != null && result.getResultCode() == RESULT_OK) { Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap( this.getContentResolver(), resultIntent.getData()); // Please also rotate the Bitmap based on its orientation. } catch (IOException e) { Log.e(TAG, "Bitmap reading error:" + e); } if (bitmap != null) { faceMesh.send(bitmap); } } }); Intent pickImageIntent = new Intent(Intent.ACTION_PICK); pickImageIntent.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*"); imageGetter.launch(pickImageIntent); ``` -------------------------------- ### Implement Face Detection in JavaScript Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_detection.md HTML structure and JavaScript logic for running MediaPipe Face Detection in a browser environment. ```html
``` ```javascript ``` -------------------------------- ### Initialize MediaPipe Face Detection in Python Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_detection.md Setup the face detection module and drawing utilities for processing images. ```python import cv2 import mediapipe as mp mp_face_detection = mp.solutions.face_detection mp_drawing = mp.solutions.drawing_utils ``` -------------------------------- ### Initialize Face Detection Source: https://context7.com/google-ai-edge/mediapipe/llms.txt Initializes MediaPipe Face Detection, which uses the BlazeFace model for ultrafast face detection with key facial points. This snippet sets up the necessary imports. ```python import cv2 import mediapipe as mp mp_face_detection = mp.solutions.face_detection mp_drawing = mp.solutions.drawing_utils ``` -------------------------------- ### Initialize and Run Face Mesh in JavaScript Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md Configures the FaceMesh instance, handles result callbacks, and starts the camera stream. ```javascript ``` -------------------------------- ### Detect Faces with MediaPipe Face Detector Source: https://github.com/google-ai-edge/mediapipe/blob/master/mediapipe/tasks/web/vision/README.md Detects the presence and location of faces within an image. It requires a FilesetResolver and the BlazeFace model path to return detection coordinates. ```javascript const vision = await FilesetResolver.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm"); const faceDetector = await FaceDetector.createFromModelPath(vision, "https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite"); const image = document.getElementById("image") as HTMLImageElement; const detections = faceDetector.detect(image); ``` -------------------------------- ### Detect Faces in Python Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_detection.md Examples for processing static images and real-time webcam streams using the MediaPipe Python API. ```python # For static images: IMAGE_FILES = [] with mp_face_detection.FaceDetection( model_selection=1, min_detection_confidence=0.5) as face_detection: for idx, file in enumerate(IMAGE_FILES): image = cv2.imread(file) # Convert the BGR image to RGB and process it with MediaPipe Face Detection. results = face_detection.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) # Draw face detections of each face. if not results.detections: continue annotated_image = image.copy() for detection in results.detections: print('Nose tip:') print(mp_face_detection.get_key_point( detection, mp_face_detection.FaceKeyPoint.NOSE_TIP)) mp_drawing.draw_detection(annotated_image, detection) cv2.imwrite('/tmp/annotated_image' + str(idx) + '.png', annotated_image) ``` ```python # For webcam input: cap = cv2.VideoCapture(0) with mp_face_detection.FaceDetection( model_selection=0, min_detection_confidence=0.5) as face_detection: while cap.isOpened(): success, image = cap.read() if not success: print("Ignoring empty camera frame.") # If loading a video, use 'break' instead of 'continue'. continue # To improve performance, optionally mark the image as not writeable to # pass by reference. image.flags.writeable = False image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = face_detection.process(image) # Draw the face detection annotations on the image. image.flags.writeable = True image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) if results.detections: for detection in results.detections: mp_drawing.draw_detection(image, detection) # Flip the image horizontally for a selfie-view display. cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1)) if cv2.waitKey(5) & 0xFF == 27: break cap.release() ``` -------------------------------- ### Camera Input for Face Mesh Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md Sets up camera input and OpenGL rendering for real-time face mesh detection. Requires initialization of FaceMesh, CameraInput, and SolutionGlSurfaceView. ```java // For camera input and result rendering with OpenGL. FaceMeshOptions faceMeshOptions = FaceMeshOptions.builder() .setStaticImageMode(false) .setRefineLandmarks(true) .setMaxNumFaces(1) .setRunOnGpu(true).build(); FaceMesh faceMesh = new FaceMesh(this, faceMeshOptions); faceMesh.setErrorListener( (message, e) -> Log.e(TAG, "MediaPipe Face Mesh error:" + message)); // Initializes a new CameraInput instance and connects it to MediaPipe Face Mesh Solution. CameraInput cameraInput = new CameraInput(this); cameraInput.setNewFrameListener( textureFrame -> faceMesh.send(textureFrame)); // Initializes a new GlSurfaceView with a ResultGlRenderer instance // that provides the interfaces to run user-defined OpenGL rendering code. // See mediapipe/examples/android/solutions/facemesh/src/main/java/com/google/mediapipe/examples/facemesh/FaceMeshResultGlRenderer.java // as an example. SolutionGlSurfaceView glSurfaceView = new SolutionGlSurfaceView<>( this, faceMesh.getGlContext(), faceMesh.getGlMajorVersion()); glSurfaceView.setSolutionResultRenderer(new FaceMeshResultGlRenderer()); glSurfaceView.setRenderInputImage(true); faceMesh.setResultListener( faceMeshResult -> { NormalizedLandmark noseLandmark = result.multiFaceLandmarks().get(0).getLandmarkList().get(1); Log.i( TAG, String.format( "MediaPipe Face Mesh nose normalized coordinates (value range: [0, 1]): x=%f, y=%f", noseLandmark.getX(), noseLandmark.getY())); // Request GL rendering. glSurfaceView.setRenderData(faceMeshResult); glSurfaceView.requestRender(); }); // The runnable to start camera after the GLSurfaceView is attached. glSurfaceView.post( () -> cameraInput.start( this, faceMesh.getGlContext(), CameraInput.CameraFacing.FRONT, glSurfaceView.getWidth(), glSurfaceView.getHeight())); ``` -------------------------------- ### Track body, face, and hands with Holistic Tracking Source: https://context7.com/google-ai-edge/mediapipe/llms.txt Performs simultaneous tracking of pose, face, and hand landmarks. Useful for comprehensive body analysis in a single pipeline. ```python import cv2 import mediapipe as mp mp_holistic = mp.solutions.holistic mp_drawing = mp.solutions.drawing_utils mp_drawing_styles = mp.solutions.drawing_styles cap = cv2.VideoCapture(0) with mp_holistic.Holistic( model_complexity=1, enable_segmentation=True, refine_face_landmarks=True, min_detection_confidence=0.5, min_tracking_confidence=0.5 ) as holistic: while cap.isOpened(): success, image = cap.read() if not success: continue image.flags.writeable = False image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = holistic.process(image) image.flags.writeable = True image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # Draw face mesh mp_drawing.draw_landmarks( image, results.face_landmarks, mp_holistic.FACEMESH_CONTOURS, landmark_drawing_spec=None, connection_drawing_spec=mp_drawing_styles.get_default_face_mesh_contours_style()) # Draw pose landmarks mp_drawing.draw_landmarks( image, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS, landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style()) # Draw hand landmarks mp_drawing.draw_landmarks( image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS) mp_drawing.draw_landmarks( image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS) cv2.imshow('Holistic Tracking', cv2.flip(image, 1)) if cv2.waitKey(5) & 0xFF == 27: break cap.release() ``` -------------------------------- ### face_transform Calculators Source: https://github.com/google-ai-edge/mediapipe/blob/master/mediapipe/modules/face_geometry/README.md Calculators for generating environments, processing face geometry, and rendering effects. ```APIDOC ## face_transform Calculators ### Description Calculators for generating environments, processing face geometry, and rendering effects. ### Calculators - **FaceGeometryEnvGeneratorCalculator** (Calculator) - Generates an environment that describes a virtual scene. - **FaceGeometryPipelineCalculator** (Calculator) - Extracts face 3D transform for multiple faces from a vector of landmark lists. - **FaceGeometryEffectRendererCalculator** (Calculator) - Renders a face effect. ``` -------------------------------- ### Webcam Face Mesh Detection and Drawing Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md This snippet captures video from the webcam, processes each frame to detect face landmarks using MediaPipe Face Mesh, and draws the detected landmarks onto the image. It includes drawing options for tesselation, contours, and irises. The processed image is displayed in a window, flipped horizontally for a selfie view. Press ESC to exit. ```python drawing_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1) cap = cv2.VideoCapture(0) with mp_face_mesh.FaceMesh( max_num_faces=1, refine_landmarks=True, min_detection_confidence=0.5, min_tracking_confidence=0.5) as face_mesh: while cap.isOpened(): success, image = cap.read() if not success: print("Ignoring empty camera frame.") # If loading a video, use 'break' instead of 'continue'. continue # To improve performance, optionally mark the image as not writeable to # pass by reference. image.flags.writeable = False image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = face_mesh.process(image) # Draw the face mesh annotations on the image. image.flags.writeable = True image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) if results.multi_face_landmarks: for face_landmarks in results.multi_face_landmarks: mp_drawing.draw_landmarks( image=image, landmark_list=face_landmarks, connections=mp_face_mesh.FACEMESH_TESSELATION, landmark_drawing_spec=None, connection_drawing_spec=mp_drawing_styles .get_default_face_mesh_tesselation_style()) mp_drawing.draw_landmarks( image=image, landmark_list=face_landmarks, connections=mp_face_mesh.FACEMESH_CONTOURS, landmark_drawing_spec=None, connection_drawing_spec=mp_drawing_styles .get_default_face_mesh_contours_style()) mp_drawing.draw_landmarks( image=image, landmark_list=face_landmarks, connections=mp_face_mesh.FACEMESH_IRISES, landmark_drawing_spec=None, connection_drawing_spec=mp_drawing_styles .get_default_face_mesh_iris_connections_style()) # Flip the image horizontally for a selfie-view display. cv2.imshow('MediaPipe Face Mesh', cv2.flip(image, 1)) if cv2.waitKey(5) & 0xFF == 27: break cap.release() ``` -------------------------------- ### Process static images with Face Mesh in Python Source: https://github.com/google-ai-edge/mediapipe/blob/master/docs/solutions/face_mesh.md This example demonstrates how to initialize the FaceMesh solution, process a list of images, and draw the detected landmarks including tessellation, contours, and irises. ```python import cv2 import mediapipe as mp mp_drawing = mp.solutions.drawing_utils mp_drawing_styles = mp.solutions.drawing_styles mp_face_mesh = mp.solutions.face_mesh # For static images: IMAGE_FILES = [] drawing_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1) with mp_face_mesh.FaceMesh( static_image_mode=True, max_num_faces=1, refine_landmarks=True, min_detection_confidence=0.5) as face_mesh: for idx, file in enumerate(IMAGE_FILES): image = cv2.imread(file) # Convert the BGR image to RGB before processing. results = face_mesh.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) # Print and draw face mesh landmarks on the image. if not results.multi_face_landmarks: continue annotated_image = image.copy() for face_landmarks in results.multi_face_landmarks: print('face_landmarks:', face_landmarks) mp_drawing.draw_landmarks( image=annotated_image, landmark_list=face_landmarks, connections=mp_face_mesh.FACEMESH_TESSELATION, landmark_drawing_spec=None, connection_drawing_spec=mp_drawing_styles .get_default_face_mesh_tesselation_style()) mp_drawing.draw_landmarks( image=annotated_image, landmark_list=face_landmarks, connections=mp_face_mesh.FACEMESH_CONTOURS, landmark_drawing_spec=None, connection_drawing_spec=mp_drawing_styles .get_default_face_mesh_contours_style()) mp_drawing.draw_landmarks( image=annotated_image, landmark_list=face_landmarks, connections=mp_face_mesh.FACEMESH_IRISES, landmark_drawing_spec=None, connection_drawing_spec=mp_drawing_styles .get_default_face_mesh_iris_connections_style()) cv2.imwrite('/tmp/annotated_image' + str(idx) + '.png', annotated_image) ```