Bir görüntüyü ML Kit'e ilettiğinizde bu cihaz, görüntüdeki her nesnenin konumuyla birlikte görüntüde beşe kadar nesne algılar. Video akışlarında nesneleri algılarken her nesnenin benzersiz bir kimliği vardır. Bu kimliği, nesneyi kareden kareye izlemek için kullanabilirsiniz.
Algılanan nesneleri sınıflandırmak için özel bir görüntü sınıflandırma modeli kullanabilirsiniz. Model uyumluluğu gereksinimleri, önceden eğitilmiş modellerin nerede bulunduğu ve kendi modellerinizi nasıl eğiteceğiniz hakkında yardım almak için lütfen ML Kit ile özel modeller bölümüne bakın.
Özel bir modeli iki şekilde entegre edebilirsiniz. Modeli uygulamanızın öğe klasörüne yerleştirerek paketleyebilir veya Firebase'den dinamik olarak indirebilirsiniz. Aşağıdaki tabloda iki seçenek karşılaştırılmaktadır.
Gruplandırılmış Model | Barındırılan Model |
---|---|
Model, uygulamanızın .ipa dosyasının bir parçasıdır ve bu nedenle boyutu artırır. |
Model, uygulamanızın .ipa dosyasının bir parçası değil. Firebase Makine Öğrenimi'ne yüklenerek barındırılır. |
Model, Android cihaz çevrimdışı olsa bile hemen kullanılabilir | Model istek üzerine indirilir |
Firebase projesine gerek yoktur | Firebase projesi gereklidir |
Modeli güncellemek için uygulamanızı yeniden yayınlamanız gerekir | Uygulamanızı yeniden yayınlamadan model güncellemelerini aktarın |
Yerleşik A/B testi yok | Firebase Remote Config ile kolay A/B testi |
Deneyin
- Paketlenmiş modelin örnek kullanımı için vision hızlı başlangıç uygulamasına ve barındırılan modelin örnek kullanımı için automl hızlı başlangıç uygulamasına göz atın.
- Bu API'nin uçtan uca uygulanması için Materyal Tasarım vitrin uygulamasına bakın.
Başlamadan önce
ML Kit kitaplıklarını Podfile dosyanıza ekleyin:
Uygulamanızla bir model paketi sunmak için:
pod 'GoogleMLKit/ObjectDetectionCustom', '3.2.0'
Firebase'den dinamik olarak bir model indirmek için
LinkFirebase
bağımlılığını ekleyin:pod 'GoogleMLKit/ObjectDetectionCustom', '3.2.0' pod 'GoogleMLKit/LinkFirebase', '3.2.0'
Projenizin Kapsüllerini yükledikten veya güncelledikten sonra
.xcworkspace
ile Xcode projenizi açın. ML Kiti, 13.2.1 veya sonraki Xcode sürümlerinde desteklenir.Bir model indirmek istiyorsanız henüz yapmadıysanız Firebase'i iOS projenize eklediğinizden emin olun. Modeli paketlediğinizde bu gerekli değildir.
1. Modeli yükleme
Yerel model kaynağını yapılandırma
Modeli uygulamanızla birlikte gruplandırmak için:
Model dosyasını (genellikle
.tflite
veya.lite
ile biter) Xcode projenize kopyalayın ve bunu yaparkenCopy bundle resources
öğesini seçmeyi unutmayın. Model dosyası, uygulama paketine dahil edilir ve ML Kiti tarafından kullanılabilir.Model dosyasının yolunu belirterek
LocalModel
nesnesi oluşturun:Swift
let localModel = LocalModel(path: localModelFilePath)
Objective-C
MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath];
Firebase tarafından barındırılan bir model kaynağını yapılandırma
Uzaktan barındırılan modeli kullanmak için modeli yayınlarken atadığınız adı belirterek bir CustomRemoteModel
nesnesi oluşturun:
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, indirme işlemine izin vermek istediğiniz koşulları belirterek model indirme görevini başlatın. Model cihazda yoksa veya modelin daha yeni bir sürümü varsa görev, modeli Firebase'den eşzamansız olarak indirir:
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 modeli kullanmanız gerekmeden istediğiniz zaman bu işlemi gerçekleştirebilirsiniz.
2. Nesne algılayıcısını yapılandırın
Model kaynaklarınızı yapılandırdıktan sonra, bir CustomObjectDetectorOptions
nesnesi kullanarak kullanım alanınız için nesne algılayıcıyı yapılandırın. Aşağıdaki ayarları değiştirebilirsiniz:
Nesne Algılayıcı Ayarları | |
---|---|
Algılama modu |
STREAM_MODE (varsayılan) | SINGLE_IMAGE_MODE
Nesne algılayıcı,
|
Birden fazla nesneyi algılama ve izleme |
false (varsayılan) | true
En fazla beş nesnenin mı yoksa yalnızca en belirgin nesnenin mı (varsayılan) algılanacağını ve izleneceğini belirtir. |
Nesneleri sınıflandırma |
false (varsayılan) | true
Sağlanan özel sınıflandırıcı modeli kullanılarak algılanan nesnelerin sınıflandırılıp sınıflandırılmayacağı. Özel sınıflandırma modelinizi kullanmak için bunu |
Sınıflandırma güven eşiği |
Algılanan etiketlerin minimum güven puanı. Ayarlanmazsa modelin meta verileri tarafından belirtilen herhangi bir 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 belirtmiyorsa varsayılan eşik olan 0, 0 kullanılır. |
Nesne başına maksimum etiket sayısı |
Algılayıcının döndüreceği nesne başına maksimum etiket sayısı. Politika ayarlanmazsa 10 olan varsayılan değer kullanılır. |
Yalnızca yerel olarak paketlenmiş bir modeliniz varsa LocalModel
nesnenizden bir nesne algılayıcısı oluşturmanız yeterlidir:
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 çalıştırmadan önce modelin indirilip indirilmediğini kontrol etmeniz gerekir. Model yöneticisinin isModelDownloaded(remoteModel:)
yöntemini kullanarak model indirme görevinin durumunu kontrol edebilirsiniz.
Nesne algılayıcıyı çalıştırmadan önce bunu doğrulamanız gerekse de hem uzaktan barındırılan bir modeliniz hem de yerel olarak paketlenmiş bir modeliniz varsa ObjectDetector
için örnek oluştururken bu kontrolün yapılması mantıklı olabilir: İndirilmişse uzak modelden, aksi takdirde yerel modelden bir algılayıcı oluşturun.
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 modelin indirildiğini onaylayana kadar modelle ilgili işlevleri (örneğin, devre dışı bırakma veya kullanıcı arayüzünüzün bir bölümünü gizleme) devre dışı bırakmanız gerekir.
Modelin indirme durumunu, varsayılan Bildirim Merkezi'ne gözlemleyiciler ekleyerek alabilirsiniz. İndirme işlemi biraz zaman alabileceği ve indirme işlemi tamamlandığında kaynak nesne serbest bırakılabileceği için gözlemci bloğunda self
öğesine zayıf bir referans kullandığınızdan emin olun. Ö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 aşağıdaki iki temel kullanım alanı için optimize edilmiştir:
- Kamera vizöründeki en belirgin nesnenin canlı olarak algılanması ve izlenmesi.
- Statik bir 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ş görüntüsünü hazırlama
UIImage
veya CMSampleBuffer
kullanarak VisionImage
nesnesi oluşturun.
UIImage
kullanıyorsanız aşağıdaki adımları uygulayın:
UIImage
ile birVisionImage
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 aşağıdaki adımları uygulayın:
-
CMSampleBuffer
içinde yer alan resim verilerinin yönünü belirtin.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; } }
CMSampleBuffer
nesnesini ve yönünü kullanarak birVisionImage
nesnesi oluşturun: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ısını oluşturup çalıştırın
Yeni bir nesne algılayıcısı oluşturun:
Swift
let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
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 alma
Görüntü işlemciye yapılan çağrı başarılı olursa tamamlama işleyicisine bir Object
listesi iletir ya da eşzamansız veya eşzamanlı yöntemi çağırdığınıza bağlı olarak listeyi döndürür.
Her Object
aşağıdaki özellikleri içerir:
frame |
Resimdeki nesnenin konumunu belirten bir CGRect . |
||||||
trackingID |
Nesneyi resimler arasında tanımlayan bir tam sayı veya SINGLE_IMAGE_MODE işlevinde "nil". | ||||||
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]; } }
Mükemmel bir kullanıcı deneyimi sağlama
En iyi kullanıcı deneyimi için uygulamanızda aşağıdaki yönergeleri uygulayın:
- Nesnenin başarılı bir şekilde algılanması, nesnenin görsel karmaşıklığına bağlıdır. Az sayıda görsel özelliğe sahip nesnelerin algılanmaları için resmin daha büyük bir bölümünü kaplamaları gerekebilir. Kullanıcılara, algılamak istediğiniz nesne türlerinde iyi çalışan girdileri yakalama konusunda yol göstermeniz gerekir.
- Sınıflandırma kullanırken, desteklenen kategorilere düzgün bir şekilde girmeyen nesneleri algılamak isterseniz bilinmeyen nesneler için özel işlem uygulayın.
Ayrıca, [ML Kit Material Design vitrin uygulaması][showcase-link]{: .external } ve Materyal Tasarım Makine öğrenimi destekli özellikler için kalıplar koleksiyonuna göz atın.
Performansı artırma
Nesne algılamayı gerçek zamanlı bir uygulamada kullanmak istiyorsanız en iyi kare hızlarına ulaşmak için şu yönergeleri uygulayın:Çoğu cihaz yeterli kare hızı üretemeyeceğinden gerçek zamanlı bir uygulamada akış modunu kullanırken birden fazla nesne algılamayı kullanmayın.
- Video karelerini işlemek için algılayıcının
results(in:)
eşzamanlı API'sini kullanın. Belirtilen video karesinden sonuçları eşzamanlı olarak almak için bu yöntemiAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
işlevinden çağırın. Çağrıları algılayıcıya kısıtlamak içinAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
özelliğinitrue
olarak bırakın. Algılayıcı çalışırken yeni bir video karesi kullanılabilir hale gelirse atlanır. - Algılayıcının çıkışını giriş görüntüsünün üzerine grafik yerleştirmek için kullanırsanız önce sonucu ML Kit'ten alın, ardından görüntüyü tek bir adımda oluşturun ve yer paylaşımlı yapın. Bu şekilde, işlenen her giriş çerçevesi için görüntü yüzeyinde yalnızca bir kez görüntü oluşturursunuz. Örneği görmek için ML Kit hızlı başlangıç örneğindeki updatePreviewOverlayViewWithLastFrame) örneğine bakın.