Memberikan label pada gambar dengan model yang dilatih AutoML di iOS

Setelah melatih model sendiri menggunakan AutoML Vision Edge, Anda dapat menggunakannya di aplikasi untuk memberi label pada gambar.

Ada dua cara untuk mengintegrasikan model yang dilatih dari AutoML Vision Edge. Anda dapat memaketkan model dengan menyalin file model ke dalam project Xcode, atau Anda dapat mendownloadnya secara dinamis dari Firebase.

Opsi pemaketan model
Dipaketkan dalam aplikasi Anda
  • Model merupakan bagian dari paket
  • Model akan langsung tersedia, bahkan saat perangkat iOS sedang offline
  • Tidak memerlukan project Firebase
Dihosting dengan Firebase
  • Hosting model dengan menguploadnya ke Firebase Machine Learning
  • Mengurangi ukuran app bundle
  • Model didownload sesuai permintaan
  • Update model dapat dikirim tanpa memublikasikan ulang aplikasi
  • Pengujian A/B yang mudah dengan Firebase Remote Config
  • Memerlukan project Firebase

Cobalah

Sebelum memulai

1. Sertakan library ML Kit di Podfile Anda:

Untuk memaketkan model dengan aplikasi Anda:
    pod 'GoogleMLKit/ImageLabelingAutoML'
    
Untuk mendownload model dari Firebase secara dinamis, tambahkan dependensi LinkFirebase:
    pod 'GoogleMLKit/ImageLabelingAutoML'
    pod 'GoogleMLKit/LinkFirebase'
    
2. Setelah menginstal atau mengupdate Pod project, buka project Xcode menggunakan .xcworkspacecode>-nya. ML Kit didukung di Xcode versi 13.2.1 atau yang lebih baru. 3. Jika ingin mendownload model, pastikan Anda menambahkan Firebase ke project iOS, jika belum melakukannya. Langkah ini tidak diperlukan jika Anda memaketkan model.

1. Muat model

Mengonfigurasi sumber model lokal

Untuk memaketkan model dengan aplikasi Anda:

1. Ekstrak model dan metadatanya dari arsip zip yang Anda download dari Firebase console ke folder:
    your_model_directory
      |____dict.txt
      |____manifest.json
      |____model.tflite
    
Ketiga file tersebut harus berada di folder yang sama. Sebaiknya gunakan file sebagaimana yang didownload, tanpa melakukan perubahan (termasuk nama file).

2. Salin folder ke project Xcode dan berhati-hatilah saat memilih Create folder references ketika Anda melakukannya. File model dan metadata akan disertakan dalam app bundle dan tersedia untuk ML Kit.

3. Buat objek AutoMLImageLabelerLocalModel, dengan menentukan jalur ke file manifes model:

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

Mengonfigurasi sumber model yang dihosting Firebase

Untuk menggunakan model yang dihosting dari jarak jauh, buat objek AutoMLImageLabelerRemoteModel, dengan menentukan nama yang ditetapkan pada model saat dipublikasikan:

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.

Kemudian, mulai tugas download model dengan menentukan kondisi yang Anda inginkan untuk mengizinkan download. Jika model tidak ada di perangkat, atau jika versi model yang lebih baru tersedia, tugas ini akan mendownload model dari Firebase secara asinkron:

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

Banyak aplikasi memulai tugas download dalam kode inisialisasinya, tetapi Anda dapat melakukannya kapan saja sebelum menggunakan model.

Membuat pemberi label gambar dari model Anda

Setelah sumber model dikonfigurasi, buat objek ImageLabeler dari salah satu sumber model tersebut.

Jika Anda hanya memiliki model yang dipaketkan secara lokal, cukup buat pemberi label dari objek AutoMLImageLabelerLocalModel dan konfigurasikan nilai minimum skor keyakinan yang ingin Anda wajibkan (lihat Mengevaluasi mode:

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

Jika Anda memiliki model yang dihosting dari jarak jauh, Anda harus memeriksa apakah model tersebut sudah didownload sebelum menjalankannya. Anda dapat memeriksa status tugas download model menggunakan metode isModelDownloaded(remoteModel:) pengelola model.

Meskipun Anda hanya perlu mengonfirmasi hal ini sebelum menjalankan pemberi label, jika Anda memiliki model yang dihosting dari jarak jauh dan model yang dipaketkan secara lokal, mungkin pemeriksaan ini perlu dilakukan saat membuat instance ImageLabeler: buat pemberi label dari model jarak jauh jika model tersebut telah didownload, dan dari model lokal jika belum didownload.

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

Jika Anda hanya memiliki model yang dihosting dari jarak jauh, Anda harus menonaktifkan fungsi yang berkaitan dengan model—misalnya, menyamarkan atau menyembunyikan sebagian UI—sampai Anda mengonfirmasi bahwa model telah didownload.

Anda bisa mendapatkan status download model dengan menambahkan observer ke Pusat Notifikasi default. Pastikan untuk menggunakan referensi lemah ke self di blok observer, karena proses download mungkin memerlukan waktu beberapa saat, dan objek asal dapat dibebaskan pada saat download selesai. Contoh:

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. Siapkan gambar input

Buat objek VisionImage menggunakan UIImage atau CMSampleBuffer.

Jika Anda menggunakan UIImage, ikuti langkah-langkah berikut:

  • Buat objek VisionImage dengan UIImage. Pastikan untuk menentukan .orientation yang benar.

    Swift

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

    Objective-C

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

Jika Anda menggunakan CMSampleBuffer, ikuti langkah-langkah berikut:

  • Tentukan orientasi data gambar yang terdapat dalam CMSampleBuffer.

    Untuk mendapatkan orientasi gambar:

    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;
      }
    }
          
  • Buat objek VisionImage menggunakan objek dan orientasi CMSampleBuffer:

    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. Jalankan pemberi label gambar

Secara asinkron:

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

Secara sinkron:

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. Mendapatkan informasi tentang objek berlabel

Jika operasi pelabelan pada gambar berhasil, array ImageLabel akan ditampilkan. Setiap ImageLabel mewakili sesuatu yang dilabeli dalam gambar. Anda bisa mendapatkan deskripsi teks setiap label (jika tersedia dalam metadata file model TensorFlow Lite), skor keyakinan, dan indeks. Contoh:

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

Tips untuk meningkatkan performa real-time

Jika Anda ingin memberikan label pada gambar dalam aplikasi real-time, ikuti panduan ini untuk mencapai frekuensi gambar terbaik: