适用于 Android 的人脸特征点检测指南

借助 MediaPipe Face Markerer 任务,你可以检测 Google Cloud 上的 图片和视频。您可以使用此任务来识别人类的面部表情, 应用面部滤镜和特效,创建虚拟头像。此任务使用 可以处理单张图片或连续图片 图像流。该任务会输出三维人脸特征点、融合变形 分数(表示面部表情的系数)来推断详细的面部 以及转换矩阵 效果渲染所需的转换。

您可在 GitHub 如需详细了解功能、模型和配置选项 部分,请参阅概览

代码示例

MediaPipe Tasks 示例代码是人脸特征点标记器的简单实现 Android 版应用。该示例使用 Android 实体设备上的相机 检测人脸。该应用还可以检测人脸, 从设备图库中选择图片和视频

您可以用该应用作为基础来开发自己的 Android 应用,也可以指代该应用 对现有应用进行了修改。人脸识别标记器示例代码托管在 GitHub

下载代码

以下说明介绍了如何创建示例的本地副本 使用 git 命令行工具运行 git 代码库。

<ph type="x-smartling-placeholder">

如需下载示例代码,请执行以下操作:

  1. 使用以下命令克隆 git 代码库:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. (可选)配置您的 git 实例以使用稀疏检出,这样您 只有 Face Markerer 示例应用的文件:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_landmarker/android
    

创建示例代码的本地版本后,您可以导入项目 进入 Android Studio 并运行应用。有关说明,请参阅适用于 Android 设备

关键组件

以下文件包含此人脸特征标记示例的关键代码 应用:

设置

本部分介绍了设置开发环境和 代码项目。有关 设置开发环境以使用 MediaPipe 任务,包括 平台版本要求,请参阅适用于 Android 设备

<ph type="x-smartling-placeholder">

依赖项

人脸特征点标记器任务使用 com.google.mediapipe:tasks-vision 库。将 将此依赖项添加到 Android 应用的 build.gradle 文件中:

dependencies {
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

型号

MediaPipe Face Markerer 任务需要一个与以下对象兼容的经过训练的模型包: 此任务。如需详细了解可用于人脸识别特征器的经过训练的模型, 请参阅任务概览的“模型”部分

选择并下载模型,并将其存储在项目目录中:

<dev-project-root>/src/main/assets

ModelAssetPath 参数中指定模型的路径。在 示例代码,则模型是在 FaceLandmarkerHelper.kt 文件:

baseOptionsBuilder.setModelAssetPath(MP_FACE_LANDMARKER_TASK)

创建任务

MediaPipe Face Markerer 任务使用 createFromOptions() 函数来设置 任务。createFromOptions() 函数接受配置的值 选项。如需详细了解配置选项,请参阅配置选项 选项

人脸特征点标记器支持以下输入数据类型:静态图片、视频 文件以及实时视频流。你需要指定跑步模式 与输入数据类型相对应的日期。选择标签页 输入数据类型,了解如何创建任务并运行 推理。

映像

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_FACE_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
FaceLandmarker = FaceLandmarker.createFromOptions(context, options)
    

视频

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_FACE_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
FaceLandmarker = FaceLandmarker.createFromOptions(context, options)
    

直播

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_FACE_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
FaceLandmarker = FaceLandmarker.createFromOptions(context, options)
    

人脸识别标记器示例代码实现可让用户 处理模式这种方法使得任务创建代码更加复杂, 可能不适合您的用例。您可以在 setupFaceLandmarker() 函数, FaceLandmarkerHelper.kt 文件。

配置选项

此任务具有以下适用于 Android 应用的配置选项:

选项名称 说明 值范围 默认值
runningMode 设置任务的运行模式。有三个 模式:

IMAGE:单图输入的模式。

VIDEO:视频已解码帧的模式。

LIVE_STREAM:输入流媒体直播模式 例如来自相机的数据。在此模式下,resultListener 必须为 调用以设置监听器以接收结果 异步执行。
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numFaces 通过 FaceLandmarker。仅当 num_faces 设置为 1。 Integer > 0 1
minFaceDetectionConfidence 人脸检测的最低置信度分数 则视为成功 Float [0.0,1.0] 0.5
minFacePresenceConfidence 人脸存在的最低置信度分数 得分。 Float [0.0,1.0] 0.5
minTrackingConfidence 面部跟踪的最低置信度分数 才会被视为成功 Float [0.0,1.0] 0.5
outputFaceBlendshapes 指定面部特征点是否输出面部融合变形。 人脸融合变形用于渲染 3D 人脸模型。 Boolean False
outputFacialTransformationMatrixes FaceMarkerer 是否输出面部图像 转换矩阵。FaceMarkerer 使用 矩阵将人脸特征点从规范人脸模型转换为 以便用户可以对检测到的特征点应用效果。 Boolean False
resultListener 设置结果监听器以接收地标器结果 异步触发。 仅在跑步模式设为“LIVE_STREAM”时才能使用 ResultListener N/A
errorListener 设置一个可选的错误监听器。 ErrorListener N/A

准备数据

人脸特征点工具适用于图片、视频文件和实时视频流。任务 处理数据输入预处理,包括调整大小、旋转和值 标准化。

以下代码演示了如何移交数据进行处理。这些 示例包括关于如何处理来自图片、视频文件和实时 视频流。

映像

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(image).build()
    

视频

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

val argb8888Frame =
    if (frame.config == Bitmap.Config.ARGB_8888) frame
    else frame.copy(Bitmap.Config.ARGB_8888, false)

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(argb8888Frame).build()
    

直播

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    

在人脸识别工具示例代码中,数据准备在 FaceLandmarkerHelper.kt 文件。

运行任务

根据您处理的数据类型,使用 FaceLandmarker.detect...() 方法。使用 detect() 表示单张图片,detectForVideo() 表示视频文件中的帧, detectAsync() 表示视频流。当您在 Google Analytics 4 上 则务必在单独的线程中运行检测, 阻塞用户界面线程

以下代码示例展示如何运行人脸特征点标记的简单示例 数据模式:

映像

val result = FaceLandmarker.detect(mpImage)
    

视频

val timestampMs = i * inferenceIntervalMs

FaceLandmarker.detectForVideo(mpImage, timestampMs)
    .let { detectionResult ->
        resultList.add(detectionResult)
    }
    

直播

val mpImage = BitmapImageBuilder(rotatedBitmap).build()
val frameTime = SystemClock.uptimeMillis()

FaceLandmarker.detectAsync(mpImage, frameTime)
    

请注意以下几点:

  • 在视频模式或直播模式下投放广告时,您必须提供 人脸特征点标记器任务的输入帧的时间戳。
  • 在图片模式或视频模式下运行时,人脸识别标记器任务会受阻 当前线程,直到它处理完输入图像或帧。接收者 避免阻塞界面,在后台执行处理 线程。
  • 在直播模式下运行时,人脸特征码器任务会返回 而且不会阻塞当前线程它将调用结果 并在每次处理完一个监听器后都返回检测结果 输入帧。

在人脸识别工具示例代码中,detectdetectForVideodetectAsync 函数在 FaceLandmarkerHelper.kt 文件。

处理和显示结果

人脸特征点标记器会针对每次检测返回一个 FaceLandmarkerResult 对象 运行。结果对象包含检测到的每个面部的面部网格, 坐标。结果对象也可以 包含表示面部表情的融合变形,以及 转换矩阵对检测到的特征点应用人脸效果。

以下示例展示了此任务的输出数据:

FaceLandmarkerResult:
  face_landmarks:
    NormalizedLandmark #0:
      x: 0.5971359014511108
      y: 0.485361784696579
      z: -0.038440968841314316
    NormalizedLandmark #1:
      x: 0.3302789330482483
      y: 0.29289937019348145
      z: -0.09489090740680695
    ... (478 landmarks for each face)
  face_blendshapes:
    browDownLeft: 0.8296722769737244
    browDownRight: 0.8096957206726074
    browInnerUp: 0.00035583582939580083
    browOuterUpLeft: 0.00035752105759456754
    ... (52 blendshapes for each face)
  facial_transformation_matrixes:
    [9.99158978e-01, -1.23036895e-02, 3.91213447e-02, -3.70770246e-01]
    [1.66496094e-02,  9.93480563e-01, -1.12779640e-01, 2.27719707e+01]
    ...

下图直观显示了任务输出:

人脸特征点标记器示例代码演示了如何显示返回的结果 请参阅 OverlayView 类以了解更多详情。