Görüntüleri Apple platformlarında AutoML eğitimi almış bir modelle etiketleyin

AutoML Vision Edge'i kullanarak kendi modelinizi eğittikten sonra, bunu uygulamanızda görüntüleri etiketlemek için kullanabilirsiniz.

AutoML Vision Edge'den eğitilen modelleri entegre etmenin iki yolu vardır. Modelin dosyalarını Xcode projenize kopyalayarak modeli paketleyebilir veya Firebase'den dinamik olarak indirebilirsiniz.

Model paketleme seçenekleri
Uygulamanızda paketlenmiştir
  • Model paketin bir parçasıdır
  • Model, Apple cihazı çevrimdışı olduğunda bile anında kullanılabilir
  • Firebase projesine gerek yok
Firebase'de barındırılıyor
  • Modeli Firebase Machine Learning'e yükleyerek barındırın
  • Uygulama paketi boyutunu azaltır
  • Model talep üzerine indirilir
  • Uygulamanızı yeniden yayınlamadan model güncellemelerini aktarın
  • Firebase Remote Config ile kolay A/B testi
  • Firebase projesi gerektirir

Sen başlamadan önce

  1. ML Kit kitaplıklarını Pod dosyanıza ekleyin:

    Bir modeli uygulamanızla birlikte paketlemek için:

    pod 'GoogleMLKit/ImageLabelingCustom'
    

    Firebase'den dinamik olarak bir model indirmek için LinkFirebase bağımlılığını ekleyin:

    pod 'GoogleMLKit/ImageLabelingCustom'
    pod 'GoogleMLKit/LinkFirebase'
    
  2. Projenizin Pod'larını yükledikten veya güncelledikten sonra Xcode projenizi .xcworkspace kullanarak açın. ML Kit, Xcode sürüm 12.2 veya üzeri sürümlerde desteklenir.

  3. Bir model indirmek istiyorsanız , henüz yapmadıysanız Firebase'i Android projenize eklediğinizden emin olun. Modeli paketlediğinizde buna gerek yoktur.

1. Modeli yükleyin

Yerel bir model kaynağı yapılandırma

Modeli uygulamanızla paketlemek için:

  1. Modeli ve meta verilerini Firebase konsolundan indirdiğiniz zip arşivinden bir klasöre çıkarın:

    your_model_directory
      |____dict.txt
      |____manifest.json
      |____model.tflite
    

    Her üç dosya da aynı klasörde olmalıdır. Dosyaları indirdiğiniz gibi, değişiklik yapmadan (dosya adları dahil) kullanmanızı öneririz.

  2. Klasörü Xcode projenize kopyalayın ve bunu yaparken Klasör referansları oluştur'u seçmeye dikkat edin. Model dosyası ve meta veriler uygulama paketine dahil edilecek ve ML Kit'e sunulacak.

  3. Model bildirim dosyasının yolunu belirterek LocalModel nesnesi oluşturun:

    Süratli

    guard let manifestPath = Bundle.main.path(
        forResource: "manifest",
        ofType: "json",
        inDirectory: "your_model_directory"
    ) else { return true }
    let localModel = LocalModel(manifestPath: manifestPath)
    

    Amaç-C

    NSString *manifestPath =
        [NSBundle.mainBundle pathForResource:@"manifest"
                                      ofType:@"json"
                                 inDirectory:@"your_model_directory"];
    MLKLocalModel *localModel =
        [[MLKLocalModel alloc] initWithManifestPath:manifestPath];
    

Firebase tarafından barındırılan bir model kaynağı yapılandırma

Uzaktan barındırılan modeli kullanmak için, modeli yayınladığınızda atadığınız adı belirterek bir CustomRemoteModel nesnesi oluşturun:

Süratli

// Initialize the model source with the name you assigned in
// the Firebase console.
let remoteModelSource = FirebaseModelSource(name: "your_remote_model")
let remoteModel = CustomRemoteModel(remoteModelSource: remoteModelSource)

Amaç-C

// Initialize the model source with the name you assigned in
// the Firebase console.
MLKFirebaseModelSource *firebaseModelSource =
    [[MLKFirebaseModelSource alloc] initWithName:@"your_remote_model"];
MLKCustomRemoteModel *remoteModel =
    [[MLKCustomRemoteModel alloc] initWithRemoteModelSource:firebaseModelSource];

Ardından, indirmeye izin vermek istediğiniz koşulları belirterek model indirme görevini başlatın. Model cihazda yoksa veya modelin daha yeni bir sürümü mevcutsa görev, modeli Firebase'den eşzamansız olarak indirir:

Süratli

let downloadConditions = ModelDownloadConditions(
  allowsCellularAccess: true,
  allowsBackgroundDownloading: true
)

let downloadProgress = ModelManager.modelManager().download(
  remoteModel,
  conditions: downloadConditions
)

Amaç-C

MLKModelDownloadConditions *downloadConditions =
    [[MLKModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
                                         allowsBackgroundDownloading:YES];

NSProgress *downloadProgress =
    [[MLKModelManager modelManager] downloadRemoteModel:remoteModel
                                             conditions:downloadConditions];

Çoğu uygulama, indirme görevini kendi başlatma kodunda başlatır, ancak bunu, modeli kullanmanız gerekmeden önce herhangi bir noktada yapabilirsiniz.

Modelinizden bir görüntü etiketleyici oluşturun

Model kaynaklarınızı yapılandırdıktan sonra bunlardan birinden ImageLabeler nesnesi oluşturun.

Yalnızca yerel olarak paketlenmiş bir modeliniz varsa, LocalModel nesnenizden bir etiketleyici oluşturmanız ve gerek duymak istediğiniz güven puanı eşiğini yapılandırmanız yeterlidir (bkz. Modelinizi değerlendirin ):

Süratli

let options = CustomImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = NSNumber(value: 0.0)  // Evaluate your model in the Cloud console
                                                    // to determine an appropriate value.
let imageLabeler = ImageLabeler.imageLabeler(options)

Amaç-C

CustomImageLabelerOptions *options =
    [[CustomImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = @(0.0f);  // Evaluate your model in the Cloud console
                                        // to determine an appropriate value.
MLKImageLabeler *imageLabeler =
    [MLKImageLabeler imageLabelerWithOptions:options];

Uzaktan barındırılan bir modeliniz varsa, çalıştırmadan önce indirilip indirilmediğini kontrol etmeniz gerekecektir. Model yöneticisinin isModelDownloaded(remoteModel:) yöntemini kullanarak model indirme görevinin durumunu kontrol edebilirsiniz.

Etiketleyiciyi çalıştırmadan önce bunu yalnızca onaylamanız gerekmesine rağmen, hem uzaktan barındırılan bir modeliniz hem de yerel olarak paketlenmiş bir modeliniz varsa, ImageLabeler başlatırken bu kontrolü gerçekleştirmek mantıklı olabilir: eğer uzak modelden bir etiketleyici oluşturun indirilmiş ve aksi takdirde yerel modelden.

Süratli

var options: CustomImageLabelerOptions
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
  options = CustomImageLabelerOptions(remoteModel: remoteModel)
} else {
  options = CustomImageLabelerOptions(localModel: localModel)
}
options.confidenceThreshold = NSNumber(value: 0.0)  // Evaluate your model in the Firebase console
                                                    // to determine an appropriate value.
let imageLabeler = ImageLabeler.imageLabeler(options: options)

Amaç-C

MLKCustomImageLabelerOptions *options;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
  options = [[MLKCustomImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
  options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = @(0.0f);  // Evaluate your model in the Firebase console
                                        // to determine an appropriate value.
MLKImageLabeler *imageLabeler =
    [MLKImageLabeler imageLabelerWithOptions:options];

Yalnızca uzaktan barındırılan bir modeliniz varsa, modelin indirildiğini onaylayana kadar modelle ilgili işlevleri devre dışı bırakmalısınız (örneğin, kullanıcı arayüzünüzün bir kısmını grileştirme veya gizleme).

Gözlemcileri varsayılan Bildirim Merkezine ekleyerek model indirme durumunu alabilirsiniz. İndirme işlemleri biraz zaman alabileceğinden ve indirme işlemi tamamlandığında kaynak nesne serbest bırakılabileceğinden gözlemci bloğunda self zayıf bir referans kullandığınızdan emin olun. Örneğin:

Süratli

NotificationCenter.default.addObserver(
    forName: .mlkitMLModelDownloadDidSucceed,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel,
        model.name == "your_remote_model"
        else { return }
    // The model was downloaded and is available on the device
}

NotificationCenter.default.addObserver(
    forName: .mlkitMLModelDownloadDidFail,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel
        else { return }
    let error = userInfo[ModelDownloadUserInfoKey.error.rawValue]
    // ...
}

Amaç-C

__weak typeof(self) weakSelf = self;

[NSNotificationCenter.defaultCenter
    addObserverForName:MLKModelDownloadDidSucceedNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;

              MLKRemoteModel *model = note.userInfo[MLKModelDownloadUserInfoKeyRemoteModel];
              if ([model.name isEqualToString:@"your_remote_model"]) {
                // The model was downloaded and is available on the device
              }
            }];

[NSNotificationCenter.defaultCenter
    addObserverForName:MLKModelDownloadDidFailNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;

              NSError *error = note.userInfo[MLKModelDownloadUserInfoKeyError];
            }];

2. Giriş görüntüsünü hazırlayın

UIImage veya CMSampleBufferRef kullanarak bir VisionImage nesnesi oluşturun.

UIImage kullanıyorsanız şu adımları izleyin:

  • UIImage ile bir VisionImage nesnesi oluşturun. Doğru .orientation değerini belirttiğinizden emin olun.

    Süratli

    let image = VisionImage(image: uiImage)
    visionImage.orientation = image.imageOrientation

    Amaç-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
    visionImage.orientation = image.imageOrientation;

CMSampleBufferRef kullanıyorsanız şu adımları izleyin:

  • CMSampleBufferRef arabelleğinde bulunan görüntü verilerinin yönünü belirtin.

    Görüntü yönünü elde etmek için:

    Süratli

    func imageOrientation(
      deviceOrientation: UIDeviceOrientation,
      cameraPosition: AVCaptureDevice.Position
    ) -> UIImage.Orientation {
      switch deviceOrientation {
      case .portrait:
        return cameraPosition == .front ? .leftMirrored : .right
      case .landscapeLeft:
        return cameraPosition == .front ? .downMirrored : .up
      case .portraitUpsideDown:
        return cameraPosition == .front ? .rightMirrored : .left
      case .landscapeRight:
        return cameraPosition == .front ? .upMirrored : .down
      case .faceDown, .faceUp, .unknown:
        return .up
      }
    }
          

    Amaç-C

    - (UIImageOrientation)
      imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                             cameraPosition:(AVCaptureDevicePosition)cameraPosition {
      switch (deviceOrientation) {
        case UIDeviceOrientationPortrait:
          return position == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored
                                                          : UIImageOrientationRight;
    
        case UIDeviceOrientationLandscapeLeft:
          return position == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored
                                                          : UIImageOrientationUp;
        case UIDeviceOrientationPortraitUpsideDown:
          return position == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored
                                                          : UIImageOrientationLeft;
        case UIDeviceOrientationLandscapeRight:
          return position == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored
                                                          : UIImageOrientationDown;
        case UIDeviceOrientationUnknown:
        case UIDeviceOrientationFaceUp:
        case UIDeviceOrientationFaceDown:
          return UIImageOrientationUp;
      }
    }
          
  • CMSampleBufferRef nesnesini ve yönlendirmeyi kullanarak bir VisionImage nesnesi oluşturun:

    Süratli

    let image = VisionImage(buffer: sampleBuffer)
    image.orientation = imageOrientation(
      deviceOrientation: UIDevice.current.orientation,
      cameraPosition: cameraPosition)

    Amaç-C

     MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
     image.orientation =
       [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                    cameraPosition:cameraPosition];

3. Görüntü etiketleyiciyi çalıştırın

Eşzamansız olarak:

Süratli

imageLabeler.process(image) { labels, error in
    guard error == nil, let labels = labels, !labels.isEmpty else {
        // Handle the error.
        return
    }
    // Show results.
}

Amaç-C

[imageLabeler
    processImage:image
      completion:^(NSArray<MLKImageLabel *> *_Nullable labels,
                   NSError *_Nullable error) {
        if (label.count == 0) {
            // Handle the error.
            return;
        }
        // Show results.
     }];

Eşzamanlı olarak:

Süratli

var labels: [ImageLabel]
do {
    labels = try imageLabeler.results(in: image)
} catch let error {
    // Handle the error.
    return
}
// Show results.

Amaç-C

NSError *error;
NSArray<MLKImageLabel *> *labels =
    [imageLabeler resultsInImage:image error:&error];
// Show results or handle the error.

4. Etiketli nesneler hakkında bilgi edinin

Görüntü etiketleme işlemi başarılı olursa ImageLabel dizisini döndürür. Her ImageLabel görüntüde etiketlenen bir şeyi temsil eder. Her etiketin metin açıklamasını (TensorFlow Lite model dosyasının meta verilerinde mevcutsa), güven puanını ve dizini alabilirsiniz. Örneğin:

Süratli

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

Amaç-C

for (MLKImageLabel *label in labels) {
  NSString *labelText = label.text;
  float confidence = label.confidence;
  NSInteger index = label.index;
}

Gerçek zamanlı performansı artırmaya yönelik ipuçları

Görüntüleri gerçek zamanlı bir uygulamada etiketlemek istiyorsanız en iyi kare hızlarına ulaşmak için şu yönergeleri izleyin:

  • Gaz kelebeği dedektöre çağrı yapar. Dedektör çalışırken yeni bir video karesi kullanılabilir hale gelirse kareyi bırakın.
  • Dedektörün çıkışını grafikleri giriş görüntüsüne yerleştirmek için kullanıyorsanız, önce sonucu alın, ardından tek adımda görüntüyü oluşturun ve üst üste koyun. Bunu yaparak, her giriş karesi için ekran yüzeyini yalnızca bir kez görüntüleyebilirsiniz. Örnek için vitrin örnek uygulamasındaki önizlemeOverlayView ve FIRDetectionOverlayView sınıflarına bakın.