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 bisa 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 Machine Learning Firebase
  • 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 LinkFirebase dependensi:
    pod 'GoogleMLKit/ImageLabelingAutoML'
    pod 'GoogleMLKit/LinkFirebase'
    
2. Setelah menginstal atau mengupdate Pod project, buka project Xcode Anda menggunakan .xcworkspacekode>. 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 Anda belum melakukannya. Hal ini tidak diperlukan jika Anda memaketkan model transformer.

1. Muat model

Mengonfigurasi sumber model lokal

Untuk memaketkan model dengan aplikasi Anda:

Akun Layanan 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 saat Anda mengunduhnya, tanpa modifikasi (termasuk nama file).

2. Salin folder ke proyek Xcode Anda, dan berhati-hatilah saat memilih Buat referensi folder jika 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 ini:

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 AutoMLImageLabelerRemoteModel , dengan menentukan nama yang Anda berikan pada model saat memublikasikannya:

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 izinkan untuk diunduh. Jika model tidak ada di perangkat, atau jika model versi baru yang tersedia, tugas ini akan mendownload dari Firebase:

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 Anda perlu menggunakan model.

Membuat pemberi label gambar dari model Anda

Setelah sumber model dikonfigurasi, buat objek ImageLabeler dari sumber model tersebut tersebut lebih mendalam.

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

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 diunduh sebelum Anda menjalankannya. Anda dapat memeriksa status download model tugas menggunakan metode isModelDownloaded(remoteModel:) pengelola model.

Meskipun Anda hanya perlu mengonfirmasi hal ini sebelum menjalankan pemberi label, jika Anda baik memiliki model yang dihosting dari jarak jauh maupun model yang dipaketkan secara lokal, masuk akal untuk melakukan pemeriksaan ini saat membuat instance ImageLabeler: buat pemberi label dari model jarak jauh jika telah didownload, dan dari model lokal sebaliknya.

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 hanya memiliki model yang dihosting dari jarak jauh, Anda harus menonaktifkan model lainnya—misalnya, menyamarkan atau menyembunyikan sebagian UI—hingga Anda mengonfirmasi bahwa model telah didownload.

Anda bisa mendapatkan status download model dengan melampirkan observer ke default Pusat Notifikasi. Pastikan untuk menggunakan referensi lemah ke self di observer karena unduhan bisa memakan waktu beberapa saat, dan objek asalnya dapat yang dibebaskan pada saat pengunduhan 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. Menyiapkan gambar input

Buat objek VisionImage menggunakan UIImage atau objek 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, ia akan mengembalikan larik ImageLabel Setiap ImageLabel mewakili sesuatu yang yang diberi label dalam gambar. Anda bisa mendapatkan deskripsi teks setiap label (jika tersedia di 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 untuk mencapai kecepatan frame terbaik:

  • Untuk memproses frame video, gunakan API sinkron results(in:) dari detektor. Telepon metode ini dari class AVCaptureVideoDataOutputSampleBufferDelegate captureOutput(_, didOutput:from:) untuk mendapatkan hasil dari video yang diberikan secara sinkron {i>frame<i}. Simpan AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames sebagai true untuk men-throttle panggilan ke detektor. Jika frame video tersedia saat detektor sedang berjalan, dan frame tersebut akan dihapus.
  • Jika Anda menggunakan output detektor untuk menempatkan grafik gambar input, pertama-tama dapatkan hasilnya dari ML Kit, lalu render gambar dan overlay dalam satu langkah. Dengan demikian, Anda merender ke permukaan tampilan hanya sekali untuk setiap {i> frame<i} input yang diproses. Lihat updatePreviewOverlayViewWithLastFrame dalam contoh panduan memulai ML Kit sebagai contoh.