iOS'te görüntüleri özel bir modelle etiketleme

ML Kit'i kullanarak bir görüntüdeki varlıkları tanıyabilir ve etiketleyebilirsiniz. Bu API, çok çeşitli özel görüntü sınıflandırma modellerini destekler. Lütfen Makine Öğrenimi Kiti ile özel modeller başlıklı makaleyi inceleyin model uyumluluk gereksinimleri, önceden eğitilmiş modellerin ve kendi modellerinizi nasıl eğiteceğinizi öğreneceksiniz.

Özel bir modeli entegre etmenin iki yolu vardır. Modeli şu şekilde gruplandırabilirsiniz: bunu uygulamanızın öğe klasörüne yerleştirebilir veya kendiniz dinamik olarak indirebilirsiniz. Firebase'den geliyor. Aşağıdaki tabloda iki seçenek karşılaştırılmıştır.

Gruplandırılmış Model Barındırılan Model
Model, uygulamanızın APK'sının bir parçasıdır ve bu modelin boyutunu artırır. Model, APK'nızın parçası değil. Şu konuma yükleyerek barındırılır: Firebase Makine Öğrenimi.
Model, Android cihaz çevrimdışı olsa bile hemen kullanılabilir Model istek üzerine indirilir
Firebase projesine gerek yoktur Firebase projesi gerekir
Modeli güncellemek için uygulamanızı yeniden yayınlamanız gerekiyor Uygulamanızı yeniden yayınlamadan model güncellemelerini aktarma
Yerleşik A/B testi yok Firebase Remote Config ile kolay A/B testi

Deneyin

Başlamadan önce

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

    Bir modeli uygulamanızla paketlemek için:

    pod 'GoogleMLKit/ImageLabelingCustom', '15.5.0'
    

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

    pod 'GoogleMLKit/ImageLabelingCustom', '15.5.0'
    pod 'GoogleMLKit/LinkFirebase', '15.5.0'
    
  2. Projenizin kapsüllerini yükledikten veya güncelledikten sonra Xcode projenizi açın (.xcworkspace) kullanılıyor. ML Kit, Xcode 13.2.1 sürümünde desteklenir veya daha yüksek olabilir.

  3. Bir model indirmek istiyorsanız şunu yaptığınızdan emin olun: Firebase'i iOS projenize ekleyin, (ücretsizdir) . modeli.

1. Modeli yükleme

Yerel model kaynağını yapılandırma

Modeli uygulamanızla paket haline getirmek için:

  1. Model dosyasını (genellikle .tflite veya .lite ile biter) Xcode'unuza kopyalayın Copy bundle resources olacaktır. İlgili içeriği oluşturmak için kullanılan model dosyası uygulama paketine dahil edilir ve ML Kit tarafından kullanılabilir.

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

    Swift

    let localModel = LocalModel(path: localModelFilePath)

    Objective-C

    MLKLocalModel *localModel =
        [[MLKLocalModel alloc] initWithPath:localModelFilePath];
ziyaret edin.

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

Uzaktan barındırılan modeli kullanmak için bir RemoteModel nesnesi oluşturun. modeli yayınlarken atadığınız ad:

Swift

let firebaseModelSource = FirebaseModelSource(
    name: "your_remote_model") // The name you assigned in
                               // the Firebase console.
let remoteModel = CustomRemoteModel(remoteModelSource: firebaseModelSource)

Objective-C

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

Ardından, model indirme görevini başlatmak için model indirme görevinizi indirmeye izin vermek istiyorsunuz. Model cihazda yoksa veya sürümü kullanılabiliyorsa görev, yeni bir sürümün yüklü olduğu modeliniz:

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 kodunda başlatır, ancak bunu, modeli kullanmaya başlamadan önce istediğiniz zaman yapabilirsiniz.

Görüntü etiketleyiciyi yapılandırma

Model kaynaklarınızı yapılandırdıktan sonra bir kaynaktan ImageLabeler nesnesi oluşturun sağlayabilir.

Aşağıdaki seçenekler kullanılabilir:

Seçenekler
confidenceThreshold

Algılanan etiketlerin minimum güven puanı. Ayarlanmazsa modelin meta verileri tarafından belirtilen sınıflandırıcı eşiği kullanılır. Model herhangi bir meta veri içermiyorsa veya meta veriler bir sınıflandırıcı eşiği belirtirse 0, 0 varsayılan eşiği kullanılır.

maxResultCount

Döndürülecek maksimum etiket sayısı. Politika ayarlanmazsa 10 kullanılır.

Yalnızca yerel olarak paketlenmiş bir modeliniz varsa LocalModel nesne:

Swift

let options = CustomImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = NSNumber(value: 0.0)
let imageLabeler = ImageLabeler.imageLabeler(options: options)

Objective-C

MLKCustomImageLabelerOptions *options =
    [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = @(0.0);
MLKImageLabeler *imageLabeler =
    [MLKImageLabeler imageLabelerWithOptions:options];

Uzaktan barındırılan bir modeliniz varsa bu modelin indiremezsiniz. Model indirme işleminin durumunu kontrol edebilirsiniz. model yöneticisinin isModelDownloaded(remoteModel:) yöntemini kullanarak görevi tamamlayın.

Etiketleyiciyi çalıştırmadan önce bunu onaylamanız yeterli olsa da hem uzaktan barındırılan hem de yerel olarak paketlenen ImageLabeler örneğini örneklendirirken şu kontrolü gerçekleştirmek mantıklıdır: etiketleyici indirilmişse uzak modelden ve yerel modelden aksi takdirde.

Swift

var options: CustomImageLabelerOptions!
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
  options = CustomImageLabelerOptions(remoteModel: remoteModel)
} else {
  options = CustomImageLabelerOptions(localModel: localModel)
}
options.confidenceThreshold = NSNumber(value: 0.0)
let imageLabeler = ImageLabeler.imageLabeler(options: options)

Objective-C

MLKCustomImageLabelerOptions *options;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
  options = [[MLKCustomImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
  options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = @(0.0);
MLKImageLabeler *imageLabeler =
    [MLKImageLabeler imageLabelerWithOptions:options];

Yalnızca uzaktan barındırılan bir modeliniz varsa modelle ilgili ayarını devre dışı bırakmanız gerekir. (örneğin, kullanıcı arayüzünüzün bir kısmını devre dışı bırakan veya gizleyen) modelin indirildiğini onaylayın.

Varsayılana gözlemleyiciler ekleyerek model indirme durumunu öğrenebilirsiniz. Bildirim Merkezi. Gözlemcide self için zayıf bir referans kullandığınızdan emin olun biraz zaman alabilir ve kaynak nesne indirme tamamlandığında serbest bırakılır. Ö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ş resmini hazırlama

Bir VisionImage nesnesi oluşturmak için UIImage veya CMSampleBuffer.

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:

  • Belgenin CMSampleBuffer

    Resmin yönünü öğrenmek 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;
      }
    }
          
  • Şu komutu kullanarak bir VisionImage nesnesi oluşturun: CMSampleBuffer nesne ve yön:

    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

Bir görüntüdeki nesneleri etiketlemek için image nesnesini ImageLabeler öğesinin process() yöntemi.

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 (label.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 varlıklar hakkında bilgi edinme

Görüntü etiketleme işlemi başarılı olursa bir dizi ImageLabel. Her ImageLabel bir şeyi temsil eder resim olarak etiketlenmiştir. Her etiketin metin açıklamasını (varsa) TensorFlow Lite model dosyasının meta verileri), güven puanı ve dizin. Ö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ı

Görüntüleri gerçek zamanlı bir uygulamada etiketlemek isterseniz şu talimatları uygulayın: