Помечайте изображения с помощью ML Kit на iOS

Вы можете использовать ML Kit для маркировки объектов, распознанных на изображении, используя модель на устройстве или облачную модель. Ознакомьтесь с обзором , чтобы узнать о преимуществах каждого подхода.

Прежде чем вы начнете

  1. Если вы еще не добавили Firebase в свое приложение, сделайте это, выполнив действия, описанные в руководстве по началу работы .
  2. Включите библиотеки ML Kit в свой подфайл:
    pod 'Firebase/MLVision', '6.25.0'

    # If using the on-device API: pod 'Firebase/MLVisionLabelModel', '6.25.0'

    После установки или обновления модулей вашего проекта обязательно откройте проект Xcode, используя его .xcworkspace .
  3. Импортируйте Firebase в свое приложение:

    Быстрый

    import Firebase

    Цель-C

    @import Firebase;
  4. Если вы хотите использовать облачную модель и еще не включили облачные API для своего проекта, сделайте это сейчас:

    1. Откройте страницу API ML Kit в консоли Firebase.
    2. Если вы еще не обновили свой проект до тарифного плана Blaze, нажмите «Обновить» , чтобы сделать это. (Вам будет предложено выполнить обновление, только если ваш проект не входит в план Blaze.)

      Только проекты уровня Blaze могут использовать облачные API.

    3. Если облачные API еще не включены, нажмите «Включить облачные API» .

    Если вы хотите использовать только модель на устройстве, вы можете пропустить этот шаг.

Теперь вы готовы маркировать изображения, используя модель на устройстве или облачную модель.

1. Подготовьте входное изображение

Создайте объект VisionImage , используя UIImage или CMSampleBufferRef .

Чтобы использовать UIImage :

  1. При необходимости поверните изображение так, чтобы его свойство imageOrientation имело значение .up .
  2. Создайте объект VisionImage , используя правильно повернутый UIImage . Не указывайте метаданные вращения — необходимо использовать значение по умолчанию .topLeft .

    Быстрый

    let image = VisionImage(image: uiImage)

    Цель-C

    FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

Чтобы использовать CMSampleBufferRef :

  1. Создайте объект VisionImageMetadata , который задает ориентацию данных изображения, содержащихся в буфере CMSampleBufferRef .

    Чтобы получить ориентацию изображения:

    Быстрый

    func imageOrientation(
        deviceOrientation: UIDeviceOrientation,
        cameraPosition: AVCaptureDevice.Position
        ) -> VisionDetectorImageOrientation {
        switch deviceOrientation {
        case .portrait:
            return cameraPosition == .front ? .leftTop : .rightTop
        case .landscapeLeft:
            return cameraPosition == .front ? .bottomLeft : .topLeft
        case .portraitUpsideDown:
            return cameraPosition == .front ? .rightBottom : .leftBottom
        case .landscapeRight:
            return cameraPosition == .front ? .topRight : .bottomRight
        case .faceDown, .faceUp, .unknown:
            return .leftTop
        }
    }

    Цель-C

    - (FIRVisionDetectorImageOrientation)
        imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                               cameraPosition:(AVCaptureDevicePosition)cameraPosition {
      switch (deviceOrientation) {
        case UIDeviceOrientationPortrait:
          if (cameraPosition == AVCaptureDevicePositionFront) {
            return FIRVisionDetectorImageOrientationLeftTop;
          } else {
            return FIRVisionDetectorImageOrientationRightTop;
          }
        case UIDeviceOrientationLandscapeLeft:
          if (cameraPosition == AVCaptureDevicePositionFront) {
            return FIRVisionDetectorImageOrientationBottomLeft;
          } else {
            return FIRVisionDetectorImageOrientationTopLeft;
          }
        case UIDeviceOrientationPortraitUpsideDown:
          if (cameraPosition == AVCaptureDevicePositionFront) {
            return FIRVisionDetectorImageOrientationRightBottom;
          } else {
            return FIRVisionDetectorImageOrientationLeftBottom;
          }
        case UIDeviceOrientationLandscapeRight:
          if (cameraPosition == AVCaptureDevicePositionFront) {
            return FIRVisionDetectorImageOrientationTopRight;
          } else {
            return FIRVisionDetectorImageOrientationBottomRight;
          }
        default:
          return FIRVisionDetectorImageOrientationTopLeft;
      }
    }

    Затем создайте объект метаданных:

    Быстрый

    let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
    let metadata = VisionImageMetadata()
    metadata.orientation = imageOrientation(
        deviceOrientation: UIDevice.current.orientation,
        cameraPosition: cameraPosition
    )

    Цель-C

    FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
    AVCaptureDevicePosition cameraPosition =
        AVCaptureDevicePositionBack;  // Set to the capture device you used.
    metadata.orientation =
        [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                     cameraPosition:cameraPosition];
  2. Создайте объект VisionImage , используя объект CMSampleBufferRef и метаданные вращения:

    Быстрый

    let image = VisionImage(buffer: sampleBuffer)
    image.metadata = metadata

    Цель-C

    FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
    image.metadata = metadata;

2. Настройте и запустите средство разметки изображений.

Чтобы пометить объекты на изображении, передайте объект VisionImage processImage() класса VisionImageLabeler .

  1. Сначала получите экземпляр VisionImageLabeler .

    Если вы хотите использовать маркировку изображений на устройстве:

    Быстрый

    let labeler = Vision.vision().onDeviceImageLabeler()
    
    // Or, to set the minimum confidence required:
    // let options = VisionOnDeviceImageLabelerOptions()
    // options.confidenceThreshold = 0.7
    // let labeler = Vision.vision().onDeviceImageLabeler(options: options)
    

    Цель-C

    FIRVisionImageLabeler *labeler = [[FIRVision vision] onDeviceImageLabeler];
    
    // Or, to set the minimum confidence required:
    // FIRVisionOnDeviceImageLabelerOptions *options =
    //         [[FIRVisionOnDeviceImageLabelerOptions alloc] init];
    // options.confidenceThreshold = 0.7;
    // FIRVisionImageLabeler *labeler =
    //         [[FIRVision vision] onDeviceImageLabelerWithOptions:options];
    

    Если вы хотите использовать средство разметки облачных изображений:

    Быстрый

    let labeler = Vision.vision().cloudImageLabeler()
    
    // Or, to set the minimum confidence required:
    // let options = VisionCloudImageLabelerOptions()
    // options.confidenceThreshold = 0.7
    // let labeler = Vision.vision().cloudImageLabeler(options: options)
    

    Цель-C

    FIRVisionImageLabeler *labeler = [[FIRVision vision] cloudImageLabeler];
    
    // Or, to set the minimum confidence required:
    // FIRVisionCloudImageLabelerOptions *options =
    //         [[FIRVisionCloudImageLabelerOptions alloc] init];
    // options.confidenceThreshold = 0.7;
    // FIRVisionImageLabeler *labeler =
    //         [[FIRVision vision] cloudImageLabelerWithOptions:options];
    
  2. Затем передайте изображение processImage() :

    Быстрый

    labeler.process(image) { labels, error in
        guard error == nil, let labels = labels else { return }
    
        // Task succeeded.
        // ...
    }
    

    Цель-C

    [labeler processImage:image
               completion:^(NSArray<FIRVisionImageLabel *> *_Nullable labels,
                            NSError *_Nullable error) {
                   if (error != nil) { return; }
    
                   // Task succeeded.
                   // ...
               }];
    

3. Получить информацию о помеченных объектах

Если маркировка изображения прошла успешно, обработчику завершения будет передан массив объектов VisionImageLabel . От каждого объекта можно получить информацию о признаке, распознанном на изображении.

Например:

Быстрый

for label in labels {
    let labelText = label.text
    let entityId = label.entityID
    let confidence = label.confidence
}

Цель-C

for (FIRVisionImageLabel *label in labels) {
   NSString *labelText = label.text;
   NSString *entityId = label.entityID;
   NSNumber *confidence = label.confidence;
}

Советы по повышению производительности в реальном времени

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

  • Регулирование вызовов средства разметки изображений. Если новый видеокадр становится доступным во время работы средства разметки изображений, удалите этот кадр.
  • Если вы используете выходные данные средства разметки изображений для наложения графики на входное изображение, сначала получите результат из ML Kit, затем визуализируйте изображение и наложите его за один шаг. При этом вы выполняете рендеринг на поверхность дисплея только один раз для каждого входного кадра. Пример см. в классах PreviewOverlayView и FIRDetectionOverlayView в демонстрационном примере приложения.

Следующие шаги