Beri label pada gambar dengan model yang dilatih AutoML di platform Apple

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

Ada dua cara untuk mengintegrasikan model yang dilatih dari AutoML Vision Edge. Anda dapat menggabungkan model dengan menyalin file model ke proyek Xcode, atau mengunduhnya secara dinamis dari Firebase.

Opsi bundling model
Dibundel dalam aplikasi Anda
  • Model adalah bagian dari bundel
  • Modelnya segera tersedia, bahkan saat perangkat Apple sedang offline
  • Tidak perlu proyek Firebase
Dihosting dengan Firebase
  • Host model dengan menguploadnya ke Firebase Machine Learning
  • Mengurangi ukuran bundel aplikasi
  • Model diunduh sesuai permintaan
  • Dorong pembaruan model tanpa memublikasikan ulang aplikasi Anda
  • Pengujian A/B yang mudah dengan Firebase Remote Config
  • Memerlukan proyek Firebase

Sebelum kamu memulai

  1. Sertakan library ML Kit di Podfile Anda:

    Untuk menggabungkan model dengan aplikasi Anda:

    pod 'GoogleMLKit/ImageLabelingCustom'
    

    Untuk mengunduh model secara dinamis dari Firebase, tambahkan ketergantungan LinkFirebase :

    pod 'GoogleMLKit/ImageLabelingCustom'
    pod 'GoogleMLKit/LinkFirebase'
    
  2. Setelah Anda menginstal atau memperbarui Pod proyek Anda, buka proyek Xcode Anda menggunakan .xcworkspace . ML Kit didukung di Xcode versi 12.2 atau lebih tinggi.

  3. Jika Anda ingin mengunduh model , pastikan Anda menambahkan Firebase ke proyek Android Anda , jika Anda belum melakukannya. Ini tidak diperlukan saat Anda menggabungkan model.

1. Muat modelnya

Konfigurasikan sumber model lokal

Untuk menggabungkan model dengan aplikasi Anda:

  1. Ekstrak model dan metadatanya dari arsip zip yang Anda unduh dari Firebase console ke dalam folder:

    your_model_directory
      |____dict.txt
      |____manifest.json
      |____model.tflite
    

    Ketiga file tersebut harus berada dalam satu folder yang sama. Kami menyarankan Anda menggunakan file saat Anda mengunduhnya, tanpa modifikasi (termasuk nama file).

  2. Salin folder ke proyek Xcode Anda, berhati-hatilah untuk memilih Buat referensi folder saat Anda melakukannya. File model dan metadata akan disertakan dalam app bundle dan tersedia untuk ML Kit.

  3. Buat objek LocalModel , tentukan jalur ke file manifes model:

    Cepat

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

    Objective-C

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

Konfigurasikan sumber model yang dihosting Firebase

Untuk menggunakan model yang dihosting dari jarak jauh, buat objek CustomRemoteModel , tentukan nama yang Anda tetapkan untuk model saat Anda menerbitkannya:

Cepat

// Initialize the model source with the name you assigned in
// the Firebase console.
let remoteModelSource = FirebaseModelSource(name: "your_remote_model")
let remoteModel = CustomRemoteModel(remoteModelSource: remoteModelSource)

Objective-C

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

Kemudian, mulai tugas pengunduhan model, tentukan kondisi di mana Anda ingin mengizinkan pengunduhan. Jika model tidak ada di perangkat, atau jika versi model yang lebih baru tersedia, tugas akan mengunduh model secara asinkron dari Firebase:

Cepat

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] downloadRemoteModel:remoteModel
                                             conditions:downloadConditions];

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

Buat pelabel gambar dari model Anda

Setelah Anda mengonfigurasi sumber model Anda, buat objek ImageLabeler dari salah satunya.

Jika Anda hanya memiliki model yang dibundel secara lokal, cukup buat pelabel dari objek LocalModel Anda dan konfigurasikan ambang batas skor kepercayaan yang ingin Anda perlukan (lihat Mengevaluasi model Anda ):

Cepat

let options = CustomImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = NSNumber(value: 0.0)  // Evaluate your model in the Cloud console
                                                    // to determine an appropriate value.
let imageLabeler = ImageLabeler.imageLabeler(options)

Objective-C

CustomImageLabelerOptions *options =
    [[CustomImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = @(0.0f);  // Evaluate your model in the Cloud 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 telah diunduh sebelum Anda menjalankannya. Anda dapat memeriksa status tugas pengunduhan model menggunakan metode isModelDownloaded(remoteModel:) manajer model.

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

Cepat

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

MLKCustomImageLabelerOptions *options;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
  options = [[MLKCustomImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
  options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = @(0.0f);  // 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 fungsionalitas terkait model—misalnya, menghilangkan warna abu-abu atau menyembunyikan sebagian UI—sampai Anda mengonfirmasi bahwa model telah diunduh.

Anda bisa mendapatkan status unduhan model dengan melampirkan pengamat ke Pusat Pemberitahuan default. Pastikan untuk menggunakan referensi lemah ke self di blok pengamat, karena unduhan dapat memakan waktu lama, dan objek asal dapat dibebaskan pada saat unduhan selesai. Sebagai contoh:

Cepat

NotificationCenter.default.addObserver(
    forName: .mlkitMLModelDownloadDidSucceed,
    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: .mlkitMLModelDownloadDidFail,
    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 CMSampleBufferRef .

Jika Anda menggunakan UIImage , ikuti langkah-langkah berikut:

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

    Cepat

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

    Objective-C

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

Jika Anda menggunakan CMSampleBufferRef , ikuti langkah-langkah berikut:

  • Tentukan orientasi data gambar yang terdapat dalam buffer CMSampleBufferRef .

    Untuk mendapatkan orientasi gambar:

    Cepat

    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 position == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored
                                                          : UIImageOrientationRight;
    
        case UIDeviceOrientationLandscapeLeft:
          return position == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored
                                                          : UIImageOrientationUp;
        case UIDeviceOrientationPortraitUpsideDown:
          return position == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored
                                                          : UIImageOrientationLeft;
        case UIDeviceOrientationLandscapeRight:
          return position == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored
                                                          : UIImageOrientationDown;
        case UIDeviceOrientationUnknown:
        case UIDeviceOrientationFaceUp:
        case UIDeviceOrientationFaceDown:
          return UIImageOrientationUp;
      }
    }
          
  • Buat objek VisionImage menggunakan objek dan orientasi CMSampleBufferRef :

    Cepat

    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 pelabel gambar

Secara tidak sinkron:

Cepat

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<MLKImageLabel *> *_Nullable labels,
                   NSError *_Nullable error) {
        if (label.count == 0) {
            // Handle the error.
            return;
        }
        // Show results.
     }];

Serentak:

Cepat

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

Objective-C

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

4. Dapatkan informasi tentang objek berlabel

Jika operasi pelabelan gambar berhasil, ia mengembalikan larik ImageLabel . Setiap ImageLabel mewakili sesuatu yang diberi label pada gambar. Anda bisa mendapatkan deskripsi teks setiap label (jika tersedia di metadata file model TensorFlow Lite), skor kepercayaan, dan indeks. Sebagai contoh:

Cepat

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

Kiat untuk meningkatkan kinerja waktu nyata

Jika Anda ingin memberi label pada gambar dalam aplikasi waktu nyata, ikuti panduan ini untuk mencapai frekuensi gambar terbaik:

  • Panggilan throttle ke detektor. Jika bingkai video baru tersedia saat detektor sedang berjalan, jatuhkan bingkai.
  • Jika Anda menggunakan output detektor untuk melapisi grafik pada gambar input, pertama-tama dapatkan hasilnya, lalu render gambar dan overlay dalam satu langkah. Dengan melakukannya, Anda merender ke permukaan tampilan hanya sekali untuk setiap bingkai input. Lihat kelas previewOverlayView dan FIRDetectionOverlayView di aplikasi contoh etalase sebagai contoh.