Oznaczanie obrazów etykietami za pomocą Firebase ML na platformach Apple

Możesz użyć Firebase ML, aby oznaczać etykietami obiekty rozpoznane na obrazie. Informacje o funkcjach tego interfejsu API znajdziesz w omówieniu.

Zanim zaczniesz

    Jeśli nie dodano jeszcze Firebase do aplikacji, wykonaj czynności opisane w przewodniku dla początkujących.

    Do instalacji zależności Firebase i zarządzania nimi możesz używać menedżera pakietów Swift.

    1. Po otwarciu projektu aplikacji w Xcode wybierz Plik > Dodaj pakiety.
    2. Gdy pojawi się prośba, dodaj repozytorium pakietu SDK Firebase na platformy Apple:
    3.   https://github.com/firebase/firebase-ios-sdk.git
    4. Wybierz bibliotekę Firebase ML.
    5. Dodaj flagę -ObjC do sekcji Inne flagi linkera w ustawieniach kompilacji docelowej.
    6. Gdy to zrobisz, Xcode automatycznie zacznie wyszukiwać i pobierać zależności w tle.

    Następnie skonfiguruj aplikację:

    1. W aplikacji zaimportuj Firebase:
      import FirebaseMLModelDownloader
      @import FirebaseMLModelDownloader;
  1. Jeśli interfejsy API oparte na chmurze nie są jeszcze włączone w Twoim projekcie, zrób to teraz:

    1. Otwórz stronę Firebase ML Interfejsy API w konsoli Firebase.
    2. Jeśli nie przeszedłeś(-aś) jeszcze na abonament Blaze z modelem płatności „pay-as-you-go”, kliknij Przejdź na wyższy abonament. (Prośba o przejście na wyższy abonament pojawi się tylko wtedy, gdy Twój projekt nie jest objęty abonamentem Blaze).

      Interfejsów API w chmurze mogą używać tylko projekty korzystające z abonamentu Blaze.

    3. Jeśli interfejsy API oparte na chmurze nie są jeszcze włączone, kliknij Włącz interfejsy API oparte na chmurze.

Możesz już oznaczać obrazy.

1. Przygotuj obraz wejściowy

Utwórz obiekt VisionImage za pomocą obiektu UIImage lub CMSampleBufferRef.

Aby użyć UIImage:

  1. W razie potrzeby obróć obraz tak, aby jego właściwość imageOrientation miała wartość .up.
  2. Utwórz obiekt VisionImage, używając prawidłowo obróconego obiektu UIImage. Nie określaj żadnych metadanych rotacji – musisz użyć wartości domyślnej .topLeft.
    let image = VisionImage(image: uiImage)
    FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

Aby użyć CMSampleBufferRef:

  1. Utwórz obiekt VisionImageMetadata, który określa orientację danych obrazu zawartych w buforze CMSampleBufferRef.

    Aby uzyskać orientację obrazu:

    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
        }
    }
    - (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;
      }
    }

    Następnie utwórz obiekt metadanych:

    let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
    let metadata = VisionImageMetadata()
    metadata.orientation = imageOrientation(
        deviceOrientation: UIDevice.current.orientation,
        cameraPosition: cameraPosition
    )
    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. Utwórz obiekt VisionImage, używając obiektu CMSampleBufferRef i metadanych rotacji:
    let image = VisionImage(buffer: sampleBuffer)
    image.metadata = metadata
    FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
    image.metadata = metadata;

2. Konfigurowanie i uruchamianie narzędzia do etykietowania obrazów

Aby oznaczać etykietami obiekty na obrazie, przekaż obiekt VisionImage do metody processImage() obiektu VisionImageLabeler.

  1. Najpierw pobierz instancję VisionImageLabeler:

    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)
    
    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. Następnie przekaż obraz metodzie processImage():

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

3. Uzyskiwanie informacji o oznaczonych obiektach

Jeśli etykietowanie obrazu się powiedzie, do modułu obsługi zakończenia zostanie przekazana tablica obiektów VisionImageLabel. W przypadku każdego obiektu możesz uzyskać informacje o cechach rozpoznawanych na obrazie.

Przykład:

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

Dalsze kroki