Руководство по обнаружению ориентиров лица для iOS

Задача MediaPipe Face Landmarker позволяет обнаруживать ориентиры лиц и выражения лица на изображениях и видео. Эту задачу можно использовать для распознавания выражений лица человека, применения фильтров и эффектов лица, а также создания виртуальных аватаров. В этой задаче используются модели машинного обучения (ML), которые могут работать с отдельными изображениями, видео или непрерывным потоком изображений. Задача выводит трехмерные ориентиры лица, показатели blendshape (коэффициенты, представляющие выражение лица) для получения подробной информации о поверхностях лица в режиме реального времени, а также матрицы преобразований для выполнения преобразований, необходимых для рендеринга эффектов.

Пример кода, описанный в этой инструкции, доступен на GitHub . Вы можете увидеть эту задачу в действии, просмотрев эту веб-демо . Дополнительные сведения о возможностях, моделях и параметрах конфигурации этой задачи см. в разделе Обзор .

Пример кода

Пример кода задач MediaPipe — это базовая реализация приложения Face Landmarker для iOS. В примере используется камера на физическом устройстве iOS для обнаружения ориентиров лица в непрерывном видеопотоке. Приложение также может обнаруживать ориентиры лиц на изображениях и видео из галереи устройства.

Вы можете использовать это приложение в качестве отправной точки для своего собственного приложения для iOS или обращаться к нему при изменении существующего приложения. Пример кода Face Landmarker размещен на GitHub .

Загрузите код

Следующие инструкции показывают, как создать локальную копию кода примера с помощью инструмента командной строки git .

Чтобы загрузить пример кода:

  1. Клонируйте репозиторий git, используя следующую команду:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. При желании настройте свой экземпляр git на использование разреженной проверки, чтобы у вас были только файлы для примера приложения Face Landmarker:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_landmarker/ios
    

После создания локальной версии примера кода вы можете установить библиотеку задач MediaPipe, открыть проект с помощью Xcode и запустить приложение. Инструкции см. в Руководстве по установке для iOS .

Ключевые компоненты

Следующие файлы содержат ключевой код для примера приложения Face Landmarker:

  • FaceLandmarkerService.swift : инициализирует Face Landmarker, обрабатывает выбор модели и выполняет логический вывод на основе входных данных.
  • CameraViewController.swift : реализует пользовательский интерфейс для режима ввода изображения с камеры в реальном времени и визуализирует результаты.
  • MediaLibraryViewController.swift : реализует пользовательский интерфейс для режимов ввода неподвижных изображений и видеофайлов и визуализирует результаты.

Настраивать

В этом разделе описаны ключевые шаги по настройке среды разработки и проектов кода для использования Face Landmarker. Общие сведения о настройке среды разработки для использования задач MediaPipe, включая требования к версии платформы, см. в руководстве по настройке для iOS .

Зависимости

Face Landmarker использует библиотеку MediaPipeTasksVision , которую необходимо установить с помощью CocoaPods. Библиотека совместима с приложениями Swift и Objective-C и не требует дополнительной настройки для конкретного языка.

Инструкции по установке CocoaPods на MacOS см. в руководстве по установке CocoaPods . Инструкции о том, как создать Podfile с необходимыми модулями для вашего приложения, см. в разделе Использование CocoaPods .

Добавьте модуль MediaPipeTasksVision в Podfile используя следующий код:

target 'MyFaceLandmarkerApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

Если ваше приложение включает в себя цели модульного тестирования, обратитесь к Руководству по настройке для iOS для получения дополнительной информации о настройке вашего Podfile .

Модель

Для задачи MediaPipe Face Landmarker требуется пакет обученной модели, совместимый с этой задачей. Дополнительную информацию о доступных обученных моделях для Face Landmarker смотрите в разделе «Модели обзора задач».

Выберите и загрузите модель и добавьте ее в каталог проекта с помощью Xcode. Инструкции по добавлению файлов в проект Xcode см. в разделе Управление файлами и папками в проекте Xcode .

Используйте свойство BaseOptions.modelAssetPath , чтобы указать путь к модели в вашем пакете приложений. Пример кода см. в следующем разделе.

Создать задачу

Вы можете создать задачу Face Landmarker, вызвав один из ее инициализаторов. Инициализатор FaceLandmarker(options:) принимает значения параметров конфигурации.

Если вам не нужен ориентир Face Landmarker, инициализированный с настраиваемыми параметрами конфигурации, вы можете использовать инициализатор FaceLandmarker(modelPath:) для создания Face Landmarker с параметрами по умолчанию. Дополнительную информацию о параметрах конфигурации см. в Обзоре конфигурации .

Задача Face Landmarker поддерживает 3 типа входных данных: неподвижные изображения, видеофайлы и прямые видеопотоки. По умолчанию FaceLandmarker(modelPath:) инициализирует задачу для неподвижных изображений. Если вы хотите, чтобы ваша задача была инициализирована для обработки видеофайлов или прямых видеопотоков, используйте FaceLandmarker(options:) чтобы указать режим работы видео или прямой трансляции. Для режима прямой трансляции также требуется дополнительный параметр конфигурации faceLandmarkerLiveStreamDelegate , который позволяет Face Landmarker асинхронно доставлять делегату результаты ориентиров лица.

Выберите вкладку, соответствующую вашему режиму работы, чтобы узнать, как создать задачу и выполнить вывод.

Быстрый

Изображение

import MediaPipeTasksVision

let modelPath = Bundle.main.path(
  forResource: "face_landmarker",
  ofType: "task")

let options = FaceLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.minFaceDetectionConfidence = minFaceDetectionConfidence
options.minFacePresenceConfidence = minFacePresenceConfidence
options.minTrackingConfidence = minTrackingConfidence
options.numFaces = numFaces

let faceLandmarker = try FaceLandmarker(options: options)
    

Видео

import MediaPipeTasksVision

let modelPath = Bundle.main.path(
  forResource: "face_landmarker",
  ofType: "task")

let options = FaceLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.minFaceDetectionConfidence = minFaceDetectionConfidence
options.minFacePresenceConfidence = minFacePresenceConfidence
options.minTrackingConfidence = minTrackingConfidence
options.numFaces = numFaces

let faceLandmarker = try FaceLandmarker(options: options)
    

Прямая трансляция

import MediaPipeTasksVision

// Class that conforms to the `FaceLandmarkerLiveStreamDelegate` protocol and
// implements the method that the face landmarker calls once it finishes
// performing face landmark detection in each input frame.
class FaceLandmarkerResultProcessor: NSObject, FaceLandmarkerLiveStreamDelegate {

  func faceLandmarker(
    _ faceLandmarker: FaceLandmarker,
    didFinishDetection result: FaceLandmarkerResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the face landmarker result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "face_landmarker",
  ofType: "task")

let options = FaceLandmarkerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.minFaceDetectionConfidence = minFaceDetectionConfidence
options.minFacePresenceConfidence = minFacePresenceConfidence
options.minTrackingConfidence = minTrackingConfidence
options.numFaces = numFaces

// Assign an object of the class to the `faceLandmarkerLiveStreamDelegate`
// property.
let processor = FaceLandmarkerResultProcessor()
options.faceLandmarkerLiveStreamDelegate = processor

let faceLandmarker = try FaceLandmarker(options: options)
    

Цель-C

Изображение

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"face_landmarker"
                                                      ofType:@"task"];

MPPFaceLandmarkerOptions *options = [[MPPFaceLandmarkerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.minFaceDetectionConfidence = minFaceDetectionConfidence;
options.minFacePresenceConfidence = minFacePresenceConfidence;
options.minTrackingConfidence = minTrackingConfidence;
options.numFaces = numFaces;

MPPFaceLandmarker *faceLandmarker =
  [[MPPFaceLandmarker alloc] initWithOptions:options error:nil];
    

Видео

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"face_landmarker"
                                                      ofType:@"task"];

MPPFaceLandmarkerOptions *options = [[MPPFaceLandmarkerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.minFaceDetectionConfidence = minFaceDetectionConfidence;
options.minFacePresenceConfidence = minFacePresenceConfidence;
options.minTrackingConfidence = minTrackingConfidence;
options.numFaces = numFaces;

MPPFaceLandmarker *faceLandmarker =
  [[MPPFaceLandmarker alloc] initWithOptions:options error:nil];
    

Прямая трансляция

@import MediaPipeTasksVision;

// Class that conforms to the `MPPFaceLandmarkerLiveStreamDelegate` protocol
// and implements the method that the face landmarker calls once it finishes
// performing face landmark detection in each input frame.
@interface APPFaceLandmarkerResultProcessor : NSObject 

@end

@implementation APPFaceLandmarkerResultProcessor

-   (void)faceLandmarker:(MPPFaceLandmarker *)faceLandmarker
    didFinishDetectionWithResult:(MPPFaceLandmarkerResult *)faceLandmarkerResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the face landmarker result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"face_landmarker"
                                                      ofType:@"task"];

MPPFaceLandmarkerOptions *options = [[MPPFaceLandmarkerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.minFaceDetectionConfidence = minFaceDetectionConfidence;
options.minFacePresenceConfidence = minFacePresenceConfidence;
options.minTrackingConfidence = minTrackingConfidence;
options.numFaces = numFaces;

// Assign an object of the class to the `faceLandmarkerLiveStreamDelegate`
// property.
APPFaceLandmarkerResultProcessor *processor = [APPFaceLandmarkerResultProcessor new];
options.faceLandmarkerLiveStreamDelegate = processor;

MPPFaceLandmarker *faceLandmarker =
  [[MPPFaceLandmarker alloc] initWithOptions:options error:nil];
    

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

Варианты конфигурации

Эта задача имеет следующие параметры конфигурации для приложений iOS:

Название опции Описание Диапазон значений Значение по умолчанию
runningMode Устанавливает режим выполнения задачи. Face Landmarker имеет три режима:

ИЗОБРАЖЕНИЕ: Режим для ввода одного изображения.

ВИДЕО: Режим декодированных кадров видео.

LIVE_STREAM: режим прямой трансляции входных данных, например с камеры. В этом режиме для FaceLandmarkerLiveStreamDelegate должен быть установлен экземпляр класса, который реализует FaceLandmarkerLiveStreamDelegate, чтобы получать результаты асинхронного обнаружения ориентиров лица.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} {RunningMode.image}
numFaces Максимальное количество лиц, которые может обнаружить Face Landmarker. Сглаживание применяется только в том случае, если для numFaces установлено значение 1. Целое число > 0 1
minFaceDetectionConfidence Минимальный показатель достоверности, позволяющий считать обнаружение лица успешным. Плавающее [0.0,1.0] 0,5
minFacePresenceConfidence Минимальный показатель достоверности оценки присутствия лица при обнаружении ориентиров лица. Плавающее [0.0,1.0] 0,5
minTrackingConfidence Минимальный показатель достоверности, позволяющий считать отслеживание лиц успешным. Плавающее [0.0,1.0] 0,5
outputFaceBlendshapes Выводит ли FaceLandmarker формы лица. Формы смешивания лиц используются для рендеринга 3D-модели лица. Бул ЛОЖЬ
outputFacialTransformationMatrixes Выводит ли FaceLandmarker матрицу преобразования лица. FaceLandmarker использует матрицу для преобразования ориентиров лица из канонической модели лица в обнаруженное лицо, поэтому пользователи могут применять эффекты к обнаруженным ориентирам. Бул ЛОЖЬ

Если для режима работы установлено значение LIVE_STREAM , Face Landmarker требует дополнительного параметра конфигурации faceLandmarkerLiveStreamDelegate , который позволяет Face Landmarker асинхронно доставлять результаты обнаружения ориентиров лица. Делегат должен реализовать метод faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) , который Face Landmarker вызывает после обработки результатов обнаружения ориентиров лица в каждом кадре.

Название опции Описание Диапазон значений Значение по умолчанию
faceLandmarkerLiveStreamDelegate Позволяет Face Landmarker получать результаты асинхронного обнаружения ориентиров лица в режиме прямой трансляции. Класс, экземпляру которого присвоено это свойство, должен реализовать метод faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) . Непригодный Не установлено

Подготовьте данные

Вам необходимо преобразовать входное изображение или кадр в объект MPImage , прежде чем передавать его в Face Landmarker. MPImage поддерживает различные типы форматов изображений iOS и может использовать их в любом рабочем режиме для вывода. Для получения дополнительной информации о MPImage обратитесь к MPImage API .

Выберите формат изображения iOS в зависимости от вашего варианта использования и режима работы, который требуется вашему приложению. MPImage принимает форматы изображений iOS UIImage , CVPixelBuffer и CMSampleBuffer .

UIImage

Формат UIImage хорошо подходит для следующих режимов работы:

  • Изображения: изображения из пакета приложения, пользовательской галереи или файловой системы, отформатированные как изображения UIImage можно преобразовать в объект MPImage .

  • Видео: используйте AVAssetImageGenerator для извлечения видеокадров в формат CGImage , а затем преобразуйте их в изображения UIImage .

Быстрый

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(uiImage: image)
    

Цель-C

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

В примере инициализируется MPImage с ориентацией UIImage.Orientation.Up по умолчанию. Вы можете инициализировать MPImage любым из поддерживаемых значений UIImage.Orientation . Face Landmarker не поддерживает зеркальные ориентации, такие как .upMirrored , .downMirrored , .leftMirrored , .rightMirrored .

Для получения дополнительной информации о UIImage обратитесь к документации UIImage Apple Developer Documentation .

CVPixelBuffer

Формат CVPixelBuffer хорошо подходит для приложений, генерирующих кадры и использующих для обработки платформу iOS CoreImage .

Формат CVPixelBuffer хорошо подходит для следующих режимов работы:

  • Изображения: приложения, которые генерируют изображения CVPixelBuffer после некоторой обработки с использованием платформы iOS CoreImage , могут быть отправлены в Face Landmarker в режиме работы изображения.

  • Видео: видеокадры можно конвертировать в формат CVPixelBuffer для обработки, а затем отправлять в Face Landmarker в видеорежиме.

  • прямая трансляция: приложения, использующие камеру iOS для создания кадров, могут быть преобразованы в формат CVPixelBuffer для обработки перед отправкой на Face Landmarker в режиме прямой трансляции.

Быстрый

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(pixelBuffer: pixelBuffer)
    

Цель-C

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

Дополнительные сведения о CVPixelBuffer см. в документации разработчика Apple CVPixelBuffer .

CMSampleBuffer

Формат CMSampleBuffer хранит образцы мультимедиа единого типа и хорошо подходит для режима прямой трансляции. Живые кадры с камер iOS асинхронно доставляются в формате CMSampleBuffer с помощью iOS AVCaptureVideoDataOutput .

Быстрый

// Obtain a CMSampleBuffer.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(sampleBuffer: sampleBuffer)
    

Цель-C

// Obtain a `CMSampleBuffer`.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
    

Дополнительные сведения о CMSampleBuffer см. в документации CMSampleBuffer Apple для разработчиков .

Запустить задачу

Чтобы запустить Face Landmarker, используйте метод detect() специфичный для назначенного режима бега:

  • Неподвижное изображение: detect(image:)
  • Видео: detect(videoFrame:timestampInMilliseconds:)
  • Прямая трансляция: detectAsync(image:timestampInMilliseconds:)

В следующих примерах кода показаны основные примеры запуска Face Landmarker в различных режимах работы:

Быстрый

Изображение

let result = try faceLandmarker.detect(image: image)
    

Видео

let result = try faceLandmarker.detect(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

Прямая трансляция

try faceLandmarker.detectAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Цель-C

Изображение

MPPFaceLandmarkerResult *result =
  [faceLandmarker detectImage:image error:nil];
    

Видео

MPPFaceLandmarkerResult *result =
  [faceLandmarker detectVideoFrame:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

Прямая трансляция

BOOL success =
  [faceLandmarker detectAsyncImage:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

В примере кода Face Landmarker более detect(image:) показаны реализации каждого detectAsync(image:timestampInMilliseconds:) этих режимов detect(videoFrame:timestampInMilliseconds:) Пример кода позволяет пользователю переключаться между режимами обработки, которые могут не потребоваться для вашего варианта использования.

Обратите внимание на следующее:

  • При работе в режиме видео или режиме прямой трансляции вы также должны предоставить метку времени входного кадра задаче Face Landmarker.

  • При работе в режиме изображения или видео задача Face Landmarker блокирует текущий поток до тех пор, пока не завершится обработка входного изображения или кадра. Чтобы избежать блокировки текущего потока, выполните обработку в фоновом потоке с помощью платформ iOS Dispatch или NSOperation . Если ваше приложение создано с использованием Swift, вы также можете использовать Swift Concurrency для фонового выполнения потоков.

  • При работе в режиме прямой трансляции задача Face Landmarker немедленно возвращается и не блокирует текущий поток. Он вызывает метод faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) с результатом обнаружения ориентира лица после обработки каждого входного кадра. Face Landmarker вызывает этот метод асинхронно в выделенной последовательной очереди отправки. Для отображения результатов в пользовательском интерфейсе отправьте результаты в основную очередь после обработки результатов.

Обработка и отображение результатов

После выполнения вывода 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 демонстрирует, как отображать результаты, возвращаемые задачей. Дополнительные сведения см. в FaceOverlay.swift .