Saat Anda meneruskan gambar ke ML Kit, ML Kit akan mendeteksi hingga lima objek dalam gambar beserta posisi setiap objek dalam gambar. Ketika mendeteksi objek dalam streaming video. Setiap objek memiliki ID unik yang dapat Anda gunakan untuk melacak objek dari satu {i>frame<i} ke {i>frame<i}.
Anda dapat menggunakan model klasifikasi gambar kustom untuk mengklasifikasikan objek terdeteksi. Silakan baca Model kustom dengan ML Kit untuk panduan tentang persyaratan kompatibilitas model, tempat menemukan model terlatih, dan cara melatih model Anda sendiri.
Ada dua cara untuk mengintegrasikan model kustom. Anda dapat memaketkan model dengan memasukkannya ke dalam folder aset aplikasi, atau Anda dapat mendownloadnya secara dinamis dari Firebase. Tabel berikut membandingkan kedua opsi tersebut.
Model Paket | Model yang Dihosting |
---|---|
Model ini adalah bagian dari file .ipa aplikasi Anda, yang
memperbesar ukurannya. |
Model bukan bagian dari file .ipa aplikasi Anda. Penting
dihosting dengan mengupload ke
Machine Learning Firebase. |
Model akan langsung tersedia, bahkan saat perangkat Android sedang offline | Model didownload sesuai permintaan |
Tidak memerlukan project Firebase | Memerlukan project Firebase |
Anda harus memublikasikan ulang aplikasi untuk memperbarui model | Update model dapat dikirim tanpa memublikasikan ulang aplikasi |
Tidak ada pengujian A/B bawaan | Pengujian A/B yang mudah dengan Firebase Remote Config |
Cobalah
- Lihat aplikasi panduan memulai visi untuk contoh penggunaan model yang dipaketkan dan aplikasi panduan memulai automl untuk contoh penggunaan dari model yang di-host.
- Lihat Etalase Desain Material untuk implementasi end-to-end API ini.
Sebelum memulai
Sertakan library ML Kit di Podfile Anda:
Untuk memaketkan model dengan aplikasi Anda:
pod 'GoogleMLKit/ObjectDetectionCustom', '15.5.0'
Untuk mendownload model dari Firebase secara dinamis, tambahkan
LinkFirebase
dependensi:pod 'GoogleMLKit/ObjectDetectionCustom', '15.5.0' pod 'GoogleMLKit/LinkFirebase', '15.5.0'
Setelah menginstal atau mengupdate Pod project, buka project Xcode Anda menggunakan
.xcworkspace
-nya. ML Kit didukung di Xcode versi 13.2.1 atau yang lebih tinggi.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:
Salin file model (biasanya berakhiran
.tflite
atau.lite
) ke Xcode Anda , berhati-hatilah saat memilihCopy bundle resources
saat Anda melakukannya. Tujuan file model akan disertakan dalam app bundle dan tersedia untuk ML Kit.Buat objek
LocalModel
, dengan menentukan jalur ke file model:Swift
let localModel = LocalModel(path: localModelFilePath)
Objective-C
MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath];
Mengonfigurasi sumber model yang dihosting Firebase
Untuk menggunakan model yang dihosting dari jarak jauh, buat objek CustomRemoteModel
,
menentukan nama yang Anda tetapkan pada model saat memublikasikannya:
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];
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.
2. Mengonfigurasi detektor objek
Setelah sumber model dikonfigurasi, konfigurasikan detektor objek untuk
kasus penggunaan dengan objek CustomObjectDetectorOptions
. Anda dapat mengubah
setelan berikut:
Setelan Detektor Objek | |
---|---|
Mode deteksi |
STREAM_MODE (default) | SINGLE_IMAGE_MODE
Di Di |
Mendeteksi dan melacak beberapa objek |
false (default) | true
Apakah akan mendeteksi dan melacak hingga lima objek atau hanya yang paling yang menonjol (default). |
Mengklasifikasikan objek |
false (default) | true
Mengklasifikasikan objek yang terdeteksi atau tidak menggunakan
model pengklasifikasi kustom. Untuk menggunakan klasifikasi kustom
Anda harus menyetelnya ke |
Nilai minimum keyakinan klasifikasi |
Skor keyakinan minimum dari label yang terdeteksi. Jika tidak disetel, setiap batas pengklasifikasi yang ditentukan oleh metadata model akan digunakan. Jika model tidak berisi metadata apa pun atau metadata tidak menentukan ambang batas pengklasifikasi, ambang batas default 0,0 akan data |
Label maksimum per objek |
Jumlah label maksimum per objek yang akan dideteksi oleh detektor kembali. Jika tidak disetel, nilai default 10 akan digunakan. |
Jika Anda hanya memiliki model yang dipaketkan secara lokal, cukup buat detektor objek dari
objek LocalModel
Anda:
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;
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 mengkonfirmasi ini
sebelum menjalankan detektor objek, jika
baik memiliki model yang dihosting dari jarak jauh maupun model yang dipaketkan secara lokal,
masuk akal untuk melakukan pemeriksaan ini saat membuat instance ObjectDetector
: buat
detektor dari model jarak jauh jika telah diunduh, dan dari model lokal
sebaliknya.
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;
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]; }];
API deteksi dan pelacakan objek dioptimalkan untuk dua penggunaan inti ini kasus:
- Deteksi langsung dan pelacakan objek paling terlihat di kamera jendela bidik.
- Deteksi beberapa objek dari gambar statis.
Untuk mengonfigurasi API bagi kasus penggunaan ini:
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. Menyiapkan gambar input
Buat objek VisionImage
menggunakan UIImage
atau objek
CMSampleBuffer
.
Jika Anda menggunakan UIImage
, ikuti langkah-langkah berikut:
- Buat objek
VisionImage
denganUIImage
. 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 orientasiCMSampleBuffer
: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. Membuat dan menjalankan detektor objek
Buat detektor objek baru:
Swift
let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
Kemudian, gunakan pendeteksi:
Secara asinkron:
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. }]; Secara sinkron:
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. Mendapatkan informasi tentang objek berlabel
Jika panggilan ke prosesor gambar berhasil, panggilan tersebut akan meneruskan daftar
Object
ke pengendali penyelesaian atau menampilkan daftar, bergantung pada
baik Anda memanggil metode
asinkron atau sinkron.
Setiap Object
berisi properti berikut:
frame |
CGRect yang menunjukkan posisi objek di
gambar. |
||||||
trackingID |
Bilangan bulat yang mengidentifikasi objek di seluruh gambar, atau `nil` dalam SINGLE_IMAGE_MODE. | ||||||
labels |
|
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]; } }
Memastikan pengalaman pengguna yang baik
Untuk pengalaman pengguna terbaik, ikuti panduan ini di aplikasi Anda:
- Keberhasilan deteksi objek bergantung pada kompleksitas visual objek. Di beberapa untuk dideteksi, objek dengan sedikit fitur visual mungkin memerlukan untuk mengambil bagian yang lebih besar dari gambar. Anda harus memberikan panduan kepada pengguna tentang menangkap input yang bekerja dengan baik dengan jenis objek yang ingin Anda deteksi.
- Saat menggunakan klasifikasi, jika ingin mendeteksi objek yang tidak jatuh kategori yang didukung, terapkan penanganan khusus untuk objek terstruktur dalam jumlah besar.
Selain itu, lihat [aplikasi etalase Desain Material ML Kit][showcase-link]{: .external} dan Desain Material Kumpulan Pola untuk fitur yang didukung machine learning.
Meningkatkan performa
Jika Anda ingin menggunakan deteksi objek dalam aplikasi real-time, ikuti panduan untuk mencapai kecepatan frame terbaik:Saat Anda menggunakan mode streaming dalam aplikasi real-time, jangan gunakan beberapa deteksi objek, karena sebagian besar perangkat tidak akan mampu menghasilkan frekuensi gambar yang memadai.
- Untuk memproses frame video, gunakan API sinkron
results(in:)
dari detektor. Telepon metode ini dari classAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
untuk mendapatkan hasil dari video yang diberikan secara sinkron {i>frame<i}. SimpanAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
sebagaitrue
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.