Görüntüleri iOS'te AutoML tarafından eğitilmiş bir modelle etiketleyin

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

AutoML Vision Edge'den eğitilen modelleri iki şekilde entegre edebilirsiniz. Modelin dosyalarını Xcode projenize kopyalayarak modeli gruplandırabilir veya Firebase'den dinamik olarak indirebilirsiniz.

Model paketi seçenekleri
Uygulamanızda paket halinde olanlar
  • Bu model paketin bir parçasıdır
  • Model, iOS cihaz çevrimdışı olsa bile hemen kullanılabilir
  • Firebase projesine gerek yoktur
Firebase ile barındırılan
  • Modeli Firebase Makine Öğrenimi'ne yükleyerek barındırın
  • Uygulama paketi boyutunu küçültür
  • Model isteğe bağlı olarak indirilir
  • Uygulamanızı yeniden yayınlamadan model güncellemelerini aktarın
  • Firebase Remote Config ile kolay A/B testi
  • Firebase projesi gereklidir

Deneyin

Başlamadan önce

1. ML Kit kitaplıklarını Podfile'ınıza ekleyin:

Uygulamanızla bir model paketi oluşturmak için:
    pod 'GoogleMLKit/ImageLabelingAutoML'
    
Firebase'den dinamik olarak bir model indirmek için LinkFirebase bağımlılığını ekleyin:
    pod 'GoogleMLKit/ImageLabelingAutoML'
    pod 'GoogleMLKit/LinkFirebase'
    
2. Projenizin Kapsüllerini yükledikten veya güncelledikten sonra Xcode projenizi, .xcworkspacecode> kodunu kullanarak açın. ML Kit, Xcode 13.2.1 veya üzeri sürümlerde desteklenir. 3. Model indirmek istiyorsanız henüz yapmadıysanız Firebase'i iOS projenize eklediğinizden emin olun. Modeli gruplandırırken bunu yapmanız gerekmez.

1. Modeli yükle

Yerel model kaynağını 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
    
Üç dosyanın tümü aynı klasörde olmalıdır. Dosyaları, değişiklik yapmadan (dosya adları dahil) indirdiğiniz gibi kullanmanızı öneririz.

2. Klasörü Xcode projenize kopyalayın ve bunu yaparken Klasör referansları oluştur'u seçin. Model dosyası ve meta veriler uygulama paketine dahil edilir ve ML Kit'te kullanılabilir.

3. Model manifest dosyasının yolunu belirterek AutoMLImageLabelerLocalModel nesnesi oluşturun:

Swift

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

Objective-C

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

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

Uzaktan barındırılan modeli kullanmak için modeli yayınlarken verdiğiniz adı belirterek bir AutoMLImageLabelerRemoteModel nesnesi oluşturun:

Swift

let remoteModel = AutoMLImageLabelerRemoteModel(
    name: "your_remote_model"  // The name you assigned in
                               // the Firebase console.
)

Objective-C

MLKAutoMLImageLabelerRemoteModel *remoteModel =
    [[MLKAutoMLImageLabelerRemoteModel alloc]
        initWithName:@"your_remote_model"];  // The name you assigned in
                                             // the Firebase console.

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ü varsa görev, modeli Firebase'den eşzamansız olarak indirir:

Swift

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

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

Objective-C

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

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

Birçok uygulama, indirme görevini başlatma kodlarında başlatır ancak bu işlemi, modeli kullanmadan önce istediğiniz zaman yapabilirsiniz.

Modelinizden görüntü etiketleyici oluşturma

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

Yalnızca yerel olarak paket haline getirilmiş bir modeliniz varsa AutoMLImageLabelerLocalModel nesnenizden bir etiketleyici oluşturmanız ve zorunlu kılmak istediğiniz güven puanı eşiğini yapılandırmanız yeterlidir (Modunuzu değerlendirme bölümüne bakın:

Swift

let options = AutoMLImageLabelerOptions(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)

Objective-C

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

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

Etiketleyiciyi çalıştırmadan önce bunu yalnızca doğrulamanız gerekse de hem uzaktan barındırılan bir modeliniz hem de yerel olarak paketlenmiş bir modeliniz varsa ImageLabeler örneğini oluştururken bu kontrolü gerçekleştirmek mantıklı olabilir: İndirilmişse uzak modelden veya yerel modelden bir etiketleyici oluşturun.

Swift

var options: AutoMLImageLabelerOptions!
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
  options = AutoMLImageLabelerOptions(remoteModel: remoteModel)
} else {
  options = AutoMLImageLabelerOptions(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)

Objective-C

MLKAutoMLImageLabelerOptions *options;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
  options = [[MLKAutoMLImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
  options = [[MLKAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = @(0.0);  // 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 (örneğin, devre dışı bırakma veya kullanıcı arayüzünüzün bir bölümünü gizleme) devre dışı bırakmanız gerekir.

Gözlemcileri varsayılan Bildirim Merkezi'ne ekleyerek model indirme durumunu öğrenebilirsiniz. İndirmeler biraz zaman alabildiği ve kaynak nesne indirme işlemi tamamlandığında serbest bırakılabileceği için gözlemci bloğunda self öğesine zayıf bir referans kullandığınızdan emin olun. Örneğin:

Swift

NotificationCenter.default.addObserver(
    forName: .mlkitModelDownloadDidSucceed,
    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: .mlkitModelDownloadDidFail,
    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]
    // ...
}

Objective-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ırlama

UIImage veya CMSampleBuffer kullanarak VisionImage nesnesi oluşturun.

UIImage kullanıyorsanız şu adımları uygulayın:

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

    Swift

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

    Objective-C

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

CMSampleBuffer kullanıyorsanız şu adımları uygulayın:

  • CMSampleBuffer içinde yer alan resim verilerinin yönünü belirtin.

    Resmin yönünü belirlemek için:

    Swift

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

    Objective-C

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

    Swift

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

    Objective-C

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

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

Eşzamansız olarak:

Swift

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

Objective-C

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

Eşzamanlı olarak:

Swift

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

Objective-C

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

4. Etiketli nesneler hakkında bilgi alma

Görüntü etiketleme işlemi başarılı olursa ImageLabel dizisi döndürür. Her ImageLabel, resimde etiketlenmiş 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:

Swift

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

Objective-C

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

Gerçek zamanlı performansı iyileştirmeye yönelik ipuçları

Resimleri gerçek zamanlı bir uygulamada etiketlemek istiyorsanız en iyi kare hızlarını elde etmek için şu yönergeleri uygulayın:

  • Video karelerini işlemek için algılayıcının results(in:) eşzamanlı API'sini kullanın. Belirtilen video karesinden eşzamanlı olarak sonuç almak için bu yöntemi AVCaptureVideoDataOutputSampleBufferDelegate captureOutput(_, didOutput:from:) işlevinden çağırın. Algılayıcıya gelen çağrıları kısmak için AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames özelliğini true olarak bırakın. Algılayıcı çalışırken yeni bir video karesi kullanılabilir hale gelirse atlanır.
  • Algılayıcının çıkışını giriş görüntüsünün üzerine grafik yerleştirmek için kullanırsanız önce sonucu ML Kit'ten alın, ardından görüntüyü ve yer paylaşımını tek bir adımda oluşturun. Böylece, işlenen her giriş çerçevesi için görüntü yüzeyinde yalnızca bir kez görüntü oluşturursunuz. Örnek için Makine Öğrenimi Kiti hızlı başlangıç örneğindeki updatePreviewOverlayViewWithLastFrame konusuna bakın.