Задача MediaPipe Face Landmarker позволяет обнаруживать ориентиры лиц и выражения лица на изображениях и видео. Эту задачу можно использовать для распознавания выражений лица человека, применения фильтров и эффектов лица, а также создания виртуальных аватаров. В этой задаче используются модели машинного обучения (ML), которые могут работать с отдельными изображениями или с непрерывным потоком изображений. Задача выводит трехмерные ориентиры лица, показатели blendshape (коэффициенты, представляющие выражение лица) для получения подробной информации о поверхностях лица в режиме реального времени, а также матрицы преобразований для выполнения преобразований, необходимых для рендеринга эффектов.
Пример кода, описанный в этой инструкции, доступен на GitHub . Дополнительные сведения о возможностях, моделях и параметрах конфигурации этой задачи см. в разделе Обзор .
Пример кода
Пример кода задач MediaPipe — это простая реализация приложения Face Landmarker для Android. В примере используется камера на физическом устройстве Android для обнаружения лиц в непрерывном видеопотоке. Приложение также может распознавать лица на изображениях и видео из галереи устройства.
Вы можете использовать это приложение в качестве отправной точки для своего собственного приложения для Android или обращаться к нему при изменении существующего приложения. Пример кода Face Landmarker размещен на GitHub .
Загрузите код
Следующие инструкции показывают, как создать локальную копию кода примера с помощью инструмента командной строки git .
Чтобы загрузить пример кода:
-  Клонируйте репозиторий git, используя следующую команду: 
git clone https://github.com/google-ai-edge/mediapipe-samples
 - При желании настройте свой экземпляр git на использование разреженной проверки, чтобы у вас были только файлы для примера приложения Face Landmarker: 
cd mediapipe-samples git sparse-checkout init --cone git sparse-checkout set examples/face_landmarker/android
 
После создания локальной версии кода примера вы можете импортировать проект в Android Studio и запустить приложение. Инструкции см. в Руководстве по установке для Android .
Ключевые компоненты
Следующие файлы содержат ключевой код для этого примера приложения для определения ориентиров по лицу:
- FaceLandmarkerHelper.kt — инициализирует маркер лица и обрабатывает выбор модели и делегата.
 - CameraFragment.kt — управляет камерой устройства и обрабатывает входные данные изображения и видео.
 -  GalleryFragment.kt — взаимодействует с 
OverlayViewдля отображения выходного изображения или видео. - OverlayView.kt — реализует отображение сетки лица для обнаруженных лиц.
 
Настраивать
В этом разделе описаны ключевые шаги по настройке среды разработки и проектов кода специально для использования Face Landmarker. Общие сведения о настройке среды разработки для использования задач MediaPipe, включая требования к версии платформы, см. в руководстве по настройке для Android .
Зависимости
 Задача Face Landmarker использует библиотеку com.google.mediapipe:tasks-vision . Добавьте эту зависимость в файл build.gradle вашего приложения Android:
dependencies {
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Модель
Для задачи MediaPipe Face Landmarker требуется пакет обученной модели, совместимый с этой задачей. Дополнительную информацию о доступных обученных моделях для Face Landmarker смотрите в разделе «Модели обзора задач».
Выберите и загрузите модель и сохраните ее в каталоге вашего проекта:
<dev-project-root>/src/main/assets
 Укажите путь к модели в параметре ModelAssetPath . В примере кода модель определена в файле FaceLandmarkerHelper.kt :
baseOptionsBuilder.setModelAssetPath(MP_FACE_LANDMARKER_TASK)
Создать задачу
 Задача MediaPipe Face Landmarker использует функцию createFromOptions() для настройки задачи. Функция createFromOptions() принимает значения параметров конфигурации. Дополнительные сведения о параметрах конфигурации см. в разделе Параметры конфигурации .
Face Landmarker поддерживает следующие типы входных данных: неподвижные изображения, видеофайлы и прямые видеопотоки. При создании задачи вам необходимо указать режим работы, соответствующий вашему типу входных данных. Выберите вкладку для вашего типа входных данных, чтобы узнать, как создать задачу и выполнить вывод.
Изображение
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)
     Реализация примера кода Face Landmarker позволяет пользователю переключаться между режимами обработки. Такой подход усложняет код создания задачи и может не подойти для вашего варианта использования. Вы можете увидеть этот код в функции setupFaceLandmarker() в файле FaceLandmarkerHelper.kt .
Варианты конфигурации
Эта задача имеет следующие параметры конфигурации для приложений Android:
| Название опции | Описание | Диапазон значений | Значение по умолчанию | 
|---|---|---|---|
 runningMode |  Устанавливает режим выполнения задачи. Есть три режима: ИЗОБРАЖЕНИЕ: Режим для ввода одного изображения. ВИДЕО: Режим декодированных кадров видео. 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 | Выводит ли Face Landmarker формы лица. Формы смешивания лиц используются для рендеринга 3D-модели лица. |  Boolean |  False | 
 outputFacialTransformationMatrixes | Выводит ли FaceLandmarker матрицу преобразования лица. FaceLandmarker использует матрицу для преобразования ориентиров лица из канонической модели лица в обнаруженное лицо, поэтому пользователи могут применять эффекты к обнаруженным ориентирам. |  Boolean |  False | 
 resultListener |  Настраивает прослушиватель результатов на асинхронное получение результатов ориентира, когда FaceLandmarker находится в режиме прямой трансляции. Может использоваться только в том случае, если для режима работы установлено значение LIVE_STREAM |  ResultListener |  N/A | 
 errorListener | Устанавливает дополнительный прослушиватель ошибок. |  ErrorListener |  N/A | 
Подготовьте данные
Face Landmarker работает с изображениями, видеофайлами и прямыми видеопотоками. Задача выполняет предварительную обработку входных данных, включая изменение размера, поворот и нормализацию значений.
Следующий код демонстрирует, как передать данные для обработки. Эти примеры включают подробную информацию о том, как обрабатывать данные из изображений, видеофайлов и потоков видео в реальном времени.
Изображение
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()
 В примере кода Face Landmarker подготовка данных выполняется в файле FaceLandmarkerHelper.kt .
Запустить задачу
 В зависимости от типа данных, с которыми вы работаете, используйте метод FaceLandmarker.detect...() специфичный для этого типа данных. Используйте detect() для отдельных изображений, detectForVideo() для кадров в видеофайлах и detectAsync() для видеопотоков. Когда вы выполняете обнаружения в видеопотоке, убедитесь, что вы запускаете обнаружения в отдельном потоке, чтобы избежать блокировки потока пользовательского интерфейса.
В следующих примерах кода показаны простые примеры запуска Face Landmarker в различных режимах данных:
Изображение
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)
    Обратите внимание на следующее:
- При работе в режиме видео или режиме прямой трансляции необходимо предоставить метку времени входного кадра задаче Face Landmarker.
 - При работе в режиме изображения или видео задача Face Landmarker блокирует текущий поток до тех пор, пока не завершится обработка входного изображения или кадра. Чтобы избежать блокировки пользовательского интерфейса, выполняйте обработку в фоновом потоке.
 - При работе в режиме прямой трансляции задача Face Landmarker немедленно возвращается и не блокирует текущий поток. Он будет вызывать прослушиватель результатов с результатом обнаружения каждый раз, когда завершает обработку входного кадра.
 
 В примере кода Face Landmarker функции detect , detectForVideo и detectAsync определены в файле FaceLandmarkerHelper.kt .
Обработка и отображение результатов
 Face Landmarker возвращает объект 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]
    ...
На следующем изображении показана визуализация результатов задачи:

 Пример кода Face Landmarker демонстрирует, как отображать результаты, возвращаемые задачей. Дополнительные сведения см. в классе OverlayView .