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

Задача «Детектор лиц» позволяет обнаруживать лица на изображении или видео. Эту задачу можно использовать для поиска лиц и черт лица в кадре. В этой задаче используется модель машинного обучения (ML), которая работает с отдельными изображениями или непрерывным потоком изображений. Задача выводит местоположение лица, а также следующие ключевые точки лица: левый глаз, правый глаз, кончик носа, рот, трагикцию левого глаза и трагицию правого глаза.

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

Пример кода

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

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

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

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

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

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

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

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

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

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

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

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

Настраивать

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

Зависимости

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

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

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

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

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

Модель

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

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

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

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

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

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

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

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

Быстрый

Изображение

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image

let faceDetector = try FaceDetector(options: options)
    

видео

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video

let faceDetector = try FaceDetector(options: options)
    

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

import MediaPipeTasksVision

// Class that conforms to the `FaceDetectorLiveStreamDelegate` protocol and
// implements the method that the face detector calls once it finishes
// detecting faces in each input frame.
class FaceDetectorResultProcessor: NSObject, FaceDetectorLiveStreamDelegate {

  func faceDetector(
    _ faceDetector: FaceDetector,
    didFinishDetection result: FaceDetectorResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the face detection result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "model",
  ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream

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

let faceDetector = try FaceDetector(options: options)
    

Цель-C

Изображение

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

видео

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

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

@import MediaPipeTasksVision;

// Class that conforms to the `MPPFaceDetectorLiveStreamDelegate` protocol
// and implements the method that the face detector calls once it finishes
// detecting faces in each input frame.

@interface APPFaceDetectorResultProcessor : NSObject 

@end

@implementation APPFaceDetectorResultProcessor

-   (void)faceDetector:(MPPFaceDetector *)faceDetector
    didFinishDetectionWithResult:(MPPFaceDetectorResult *)faceDetectorResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the face detector result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;

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

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

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

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

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

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

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

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

LIVE_STREAM: режим прямой трансляции входных данных, например, с камеры. В этом режиме необходимо вызвать resultListener, чтобы настроить прослушиватель на асинхронное получение результатов.
{ RunningMode.image, RunningMode.video, RunningMode.liveStream } RunningMode.image
minDetectionConfidence Минимальный показатель достоверности, позволяющий считать обнаружение лица успешным. Float [0,1] 0.5
minSuppressionThreshold Минимальный, не максимальный порог подавления для обнаружения лиц, который считается перекрытым. Float [0,1] 0.3

Конфигурация прямой трансляции

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

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

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

Вам необходимо преобразовать входное изображение или кадр в объект MPImage перед передачей его в Детектор лиц. 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 Detector не поддерживает зеркальные ориентации, такие как .upMirrored , .downMirrored , .leftMirrored , .rightMirrored .

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

CVPixelBuffer

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

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

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

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

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

Быстрый

// 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 для разработчиков .

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

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

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

Детектор лиц возвращает обнаруженные лица во входном изображении или кадре.

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

Быстрый

Изображение

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

видео

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

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

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

Цель-C

Изображение

MPPFaceDetectorResult *result = [faceDetector detectInImage:image
                                                      error:nil];
    

видео

MPPFaceDetectorResult *result = [faceDetector detectInVideoFrame:image
                                         timestampInMilliseconds:timestamp
                                                           error:nil];
    

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

BOOL success = [faceDetector detectAsyncInImage:image
                        timestampInMilliseconds:timestamp
                                          error:nil];
    

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

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

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

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

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

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

После выполнения вывода задача «Детектор лиц» возвращает объект FaceDetectorResult , который содержит ограничивающие рамки для обнаруженных лиц и оценку достоверности для каждого обнаруженного лица.

Ниже показан пример выходных данных этой задачи:

FaceDetectionResult:
  Detections:
    Detection #0:
      BoundingBox:
        origin_x: 126
        origin_y: 100
        width: 463
        height: 463
      Categories:
        Category #0:
          index: 0
          score: 0.9729152917861938
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.18298381567001343
          y: 0.2961040139198303
        NormalizedKeypoint #1:
          x: 0.3302789330482483
          y: 0.29289937019348145
        ... (6 keypoints for each face)
    Detection #1:
      BoundingBox:
        origin_x: 616
        origin_y: 193
        width: 430
        height: 430
      Categories:
        Category #0:
          index: 0
          score: 0.9251380562782288
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.6151331663131714
          y: 0.3713381886482239
        NormalizedKeypoint #1:
          x: 0.7460576295852661
          y: 0.38825345039367676
        ... (6 keypoints for each face)

На следующем изображении показана визуализация результатов задачи:

Изображение без ограничивающих рамок см. в исходном изображении .

Пример кода Face Detector демонстрирует, как отображать результаты. Подробности смотрите в примере кода .