iOS'te özel bir sınıflandırma modeliyle nesneleri algılama, izleme ve sınıflandırma

Art arda gelen video karelerindeki nesneleri algılamak ve takip etmek için ML Kit'i kullanabilirsiniz.

Bir resmi ML Kit'e ilettiğinizde, resimdeki beşe kadar nesneyi algılar konumla birlikte resimdeki her bir nesnenin konumunu da içerir. Şu yolda nesneleri algılarken: her nesnenin, nesneyi izlemek için kullanabileceğiniz benzersiz bir kimliği vardır her kareden kareye geçelim.

Gösterilen nesneleri sınıflandırmak için özel bir görüntü sınıflandırma modeli algılandı. Ayrıntılı bilgi için Makine Öğrenimi Kiti ile özel modeller başlıklı makaleyi inceleyin. model uyumluluk gereksinimleri hakkında rehberlik, önceden eğitilmiş modellerin nerede 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 .ipa dosyasının bir parçasıdır. Bu dosya boyutunu büyütür. Model, uygulamanızın .ipa dosyasının bir parçası değil. Evet adresine yükleyerek barındırılıyor 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 gruplandırmak için:

    pod 'GoogleMLKit/ObjectDetectionCustom', '3.2.0'
    

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

    pod 'GoogleMLKit/ObjectDetectionCustom', '3.2.0'
    pod 'GoogleMLKit/LinkFirebase', '3.2.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, (onaylamadıysanız). Bu, 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 CustomRemoteModel nesnesi oluşturun. modeli yayınlarken atadığınız adı belirtin:

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 işleminde 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.

2. Nesne algılayıcıyı yapılandırma

Model kaynaklarınızı yapılandırdıktan sonra bir CustomObjectDetectorOptions nesnesidir. Bu ayarı değiştirmek için şu ayarları kullanın:

Nesne Algılayıcı Ayarları
Algılama modu STREAM_MODE (varsayılan) | SINGLE_IMAGE_MODE

STREAM_MODE ürününde (varsayılan) nesne algılayıcısı çalışır düşük gecikme süresi vardır, ancak eksik sonuçlar oluşturabilir (ör. (belirtilmemiş sınırlayıcı kutular veya kategori etiketleri) yer alır. çağrılarına karşılık gelir. Ayrıca STREAM_MODE içinde, algılayıcı, nesnelere izleme kimlikleri atar. Bu kimlikleri çerçevelerde nesneleri izler. YouTube TV'yi izlemek istediğinizde veya veri işleme sırasında olduğu gibi düşük gecikmenin gerçek zamanlı video akışı sağlar.

SINGLE_IMAGE_MODE işlevinde, nesne algılayıcısı nesnenin sınırlayıcı kutusu belirlendikten sonra sonuç elde edilir. Şu durumda: sınıflandırmayı da etkinleştirdiğinde sınırlayıcıdan sonra sonucu döndürür kutu ve kategori etiketi kullanılabilir. Sonuç olarak, algılama gecikmesi potansiyel olarak daha yüksektir. Ayrıca, SINGLE_IMAGE_MODE, izleme kimlikleri atanmadı. Tekliflerinizi otomatikleştirmek ve optimize etmek için bu modu kullanırsanız ve gecikmeyle uğraşmak istemezseniz kısmi sonuçlar sağlar.

Birden çok nesneyi algılama ve izleme false (varsayılan) | true

Beş adede kadar veya yalnızca en fazla nesne algılayıp takip etme belirgin nesne (varsayılan).

Nesneleri sınıflandırma false (varsayılan) | true

Sağlanan veriler kullanılarak algılanan nesnelerin sınıflandırılması özel sınıflandırıcı modeli. Özel sınıflandırmanızı kullanmak için: modeli için bunu true olarak ayarlamanız gerekir.

Sınıflandırma güven eşiği

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.

Nesne başına maksimum etiket

Algılayıcının nesne başına maksimum etiket sayısı dön. Ayarlanmazsa varsayılan değer olan 10 kullanılır.

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

Swift

let options = CustomObjectDetectorOptions(localModel: localModel)
options.detectorMode = .singleImage
options.shouldEnableClassification = true
options.shouldEnableMultipleObjects = true
options.classificationConfidenceThreshold = NSNumber(value: 0.5)
options.maxPerObjectLabelCount = 3

Objective-C

MLKCustomObjectDetectorOptions *options =
    [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel];
options.detectorMode = MLKObjectDetectorModeSingleImage;
options.shouldEnableClassification = YES;
options.shouldEnableMultipleObjects = YES;
options.classificationConfidenceThreshold = @(0.5);
options.maxPerObjectLabelCount = 3;

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.

Nesne algılayıcıyı çalıştırmadan önce bunu onaylamanız yeterli olsa da, hem uzaktan barındırılan hem de yerel olarak paketlenmiş bir modeliniz varsa bu durum, ObjectDetector örneğini örneklendirirken şu kontrolü gerçekleştirmek mantıklıdır: dedektör, indirilmişse uzak modelden ve yerel modelden aksi takdirde.

Swift

var options: CustomObjectDetectorOptions!
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
  options = CustomObjectDetectorOptions(remoteModel: remoteModel)
} else {
  options = CustomObjectDetectorOptions(localModel: localModel)
}
options.detectorMode = .singleImage
options.shouldEnableClassification = true
options.shouldEnableMultipleObjects = true
options.classificationConfidenceThreshold = NSNumber(value: 0.5)
options.maxPerObjectLabelCount = 3

Objective-C

MLKCustomObjectDetectorOptions *options;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
  options = [[MLKCustomObjectDetectorOptions alloc] initWithRemoteModel:remoteModel];
} else {
  options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel];
}
options.detectorMode = MLKObjectDetectorModeSingleImage;
options.shouldEnableClassification = YES;
options.shouldEnableMultipleObjects = YES;
options.classificationConfidenceThreshold = @(0.5);
options.maxPerObjectLabelCount = 3;

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

Nesne algılama ve izleme API'si, bu iki temel kullanım için optimize edilmiştir vakalar:

  • Kameradaki en belirgin nesnenin canlı algılanması ve takip edilmesi vizör.
  • Statik görüntüden birden fazla nesnenin algılanması.

API'yi bu kullanım alanlarına göre yapılandırmak için:

Swift

// Live detection and tracking
let options = CustomObjectDetectorOptions(localModel: localModel)
options.shouldEnableClassification = true
options.maxPerObjectLabelCount = 3

// Multiple object detection in static images
let options = CustomObjectDetectorOptions(localModel: localModel)
options.detectorMode = .singleImage
options.shouldEnableMultipleObjects = true
options.shouldEnableClassification = true
options.maxPerObjectLabelCount = 3

Objective-C

// Live detection and tracking
MLKCustomObjectDetectorOptions *options =
    [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel];
options.shouldEnableClassification = YES;
options.maxPerObjectLabelCount = 3;

// Multiple object detection in static images
MLKCustomObjectDetectorOptions *options =
    [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel];
options.detectorMode = MLKObjectDetectorModeSingleImage;
options.shouldEnableMultipleObjects = YES;
options.shouldEnableClassification = YES;
options.maxPerObjectLabelCount = 3;

3. 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];

4. Nesne algılayıcıyı oluşturma ve çalıştırma

  1. Yeni bir nesne algılayıcısı oluşturun:

    Swift

    let objectDetector = ObjectDetector.objectDetector(options: options)

    Objective-C

    MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
  2. Ardından algılayıcıyı kullanın:

    Eşzamansız olarak:

    Swift

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

    Objective-C

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

    Eşzamanlı olarak:

    Swift

    var objects: [Object]
    do {
        objects = try objectDetector.results(in: image)
    } catch let error {
        // Handle the error.
        return
    }
    // Show results.

    Objective-C

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

5. Etiketli nesneler hakkında bilgi edinme

Görüntü işlemciye yapılan çağrı başarılı olursa Şuna bağlı olarak tamamlama işleyiciye Object ekler veya listeyi geri döndürür: eşzamansız yöntemi mi yoksa eşzamanlı yöntemi mi çağırdığınız.

Her Object aşağıdaki özellikleri içerir:

frame NesneninCGRect görüntüsüdür.
trackingID Nesneyi resimlerde tanımlayan bir tam sayı veya resimlerde "nil" TEK_IMAGE_MODE.
labels
label.text Etiketin metin açıklaması. Yalnızca TensorFlow Lite modelinin meta verileri etiket açıklamaları içeriyor.
label.index Desteklenen tüm etiketler arasından etiketin dizini sınıflandırıcıyı kullanın.
label.confidence Nesne sınıflandırmasının güven değeri.

Swift

// objects contains one item if multiple object detection wasn't enabled.
for object in objects {
  let frame = object.frame
  let trackingID = object.trackingID
  let description = object.labels.enumerated().map { (index, label) in
    "Label \(index): \(label.text), \(label.confidence), \(label.index)"
  }.joined(separator: "\n")
}

Objective-C

// The list of detected objects contains one item if multiple object detection
// wasn't enabled.
for (MLKObject *object in objects) {
  CGRect frame = object.frame;
  NSNumber *trackingID = object.trackingID;
  for (MLKObjectLabel *label in object.labels) {
    NSString *labelString =
        [NSString stringWithFormat:@"%@, %f, %lu",
                                   label.text,
                                   label.confidence,
                                   (unsigned long)label.index];
  }
}

Mükemmel bir kullanıcı deneyimi sağlama

En iyi kullanıcı deneyimi için uygulamanızda aşağıdaki yönergelere uyun:

  • Nesne algılama işleminin başarılı olması, nesnenin görsel karmaşıklığına bağlıdır. İçinde az sayıda görsel özelliği olan nesnelerin algılanması için kaplamaya başlar. Kullanıcılara şu konularda yol göstermeniz gerekir: algılamak istediğiniz tür nesnelerde iyi çalışan bir giriş yakalamanızı sağlar.
  • Sınıflandırma kullanırken, düşmeyen nesneleri tespit etmek isterseniz desteklenen kategorilere ayırarak, bilinmeyen nesneler'i tıklayın.

Ayrıca, [ML Kit Material Design vitrin uygulaması][showcase-link]{: .external } ve Materyal Tasarım Makine öğrenimi destekli özellikleri içeren kalıplar koleksiyonu.

Performansı artırma

Nesne algılamayı gerçek zamanlı bir uygulamada kullanmak isterseniz aşağıdaki talimatları uygulayın: