Oznacz obrazy za pomocą zestawu ML na iOS

Możesz użyć ML Kit do etykietowania obiektów rozpoznanych na obrazie, używając modelu na urządzeniu lub modelu w chmurze. Zobacz przegląd , aby poznać zalety każdego podejścia.

Zanim zaczniesz

  1. Jeśli nie dodałeś jeszcze Firebase do swojej aplikacji, wykonaj czynności opisane w przewodniku wprowadzającym .
  2. Dołącz biblioteki ML Kit do swojego pliku Podfile:
    pod 'Firebase/MLVision', '6.25.0'

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

    Po zainstalowaniu lub zaktualizowaniu podów projektu pamiętaj, aby otworzyć projekt Xcode przy użyciu jego .xcworkspace .
  3. W swojej aplikacji zaimportuj Firebase:

    Szybki

    import Firebase

    Cel C

    @import Firebase;
  4. Jeśli chcesz korzystać z modelu opartego na chmurze, a nie masz jeszcze włączonych interfejsów API opartych na chmurze dla swojego projektu, zrób to teraz:

    1. Otwórz stronę ML Kit APIs w konsoli Firebase.
    2. Jeśli Twój projekt nie został jeszcze uaktualniony do planu cenowego Blaze, kliknij Uaktualnij , aby to zrobić. (Zostaniesz poproszony o uaktualnienie tylko wtedy, gdy Twój projekt nie jest objęty planem Blaze).

      Tylko projekty na poziomie Blaze mogą korzystać z interfejsów API opartych na chmurze.

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

    Jeśli chcesz używać tylko modelu na urządzeniu, możesz pominąć ten krok.

Teraz możesz oznaczyć obrazy etykietami za pomocą modelu na urządzeniu lub modelu opartego na chmurze.

1. Przygotuj obraz wejściowy

Utwórz obiekt VisionImage przy użyciu 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 przy użyciu poprawnie obróconego UIImage . Nie określaj żadnych metadanych rotacji — należy użyć wartości domyślnej .topLeft .

    Szybki

    let image = VisionImage(image: uiImage)

    Cel C

    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:

    Szybki

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

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

    Następnie utwórz obiekt metadanych:

    Szybki

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

    Cel 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. Utwórz obiekt VisionImage przy użyciu obiektu CMSampleBufferRef i metadanych obrotu:

    Szybki

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

    Cel C

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

2. Skonfiguruj i uruchom program do etykietowania obrazów

Aby oznaczyć obiekty na obrazie, przekaż obiekt VisionImage do VisionImageLabeler processImage() .

  1. Najpierw pobierz wystąpienie VisionImageLabeler .

    Jeśli chcesz użyć urządzenia do etykietowania obrazów na urządzeniu:

    Szybki

    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)
    

    Cel 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];
    

    Jeśli chcesz użyć drukarki do etykietowania obrazów w chmurze:

    Szybki

    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)
    

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

    Szybki

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

    Cel C

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

3. Uzyskaj informacje o oznaczonych obiektach

Jeśli etykietowanie obrazu powiedzie się, tablica obiektów VisionImageLabel zostanie przekazana do procedury obsługi uzupełniania. Z każdego obiektu można uzyskać informacje o funkcji rozpoznanej na obrazie.

Na przykład:

Szybki

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

Cel C

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

Wskazówki dotyczące poprawy wydajności w czasie rzeczywistym

Jeśli chcesz opisywać obrazy w aplikacji działającej w czasie rzeczywistym, postępuj zgodnie z poniższymi wskazówkami, aby uzyskać najlepszą liczbę klatek na sekundę:

  • Przepustnica wywołania drukarki etykiet obrazu. Jeśli nowa ramka wideo stanie się dostępna, gdy drukarka etykiet obrazu jest uruchomiona, upuść ramkę.
  • Jeśli używasz danych wyjściowych drukarki etykiet do nakładania grafiki na obraz wejściowy, najpierw pobierz wynik z ML Kit, a następnie wyrenderuj obraz i nakładkę w jednym kroku. W ten sposób renderujesz na powierzchnię wyświetlania tylko raz dla każdej klatki wejściowej. Zobacz na przykład klasy previewOverlayView i FIRDetectionOverlayView w przykładowej aplikacji prezentacji.

Następne kroki