ML Kit'e bir resim ilettiğinizde, resimdeki her nesnenin konumuyla birlikte resimde en fazla beş nesne algılar. Video akışlarındaki nesneleri algılarken her nesnenin, nesneyi kareden kareye takip etmek için kullanabileceğiniz benzersiz bir kimliği vardır.
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 bulunacağı ve kendi modellerinizi nasıl eğiteceğinizle ilgili yönergeler için ML Kit ile özel modeller başlıklı makaleyi inceleyin.
Özel bir modeli entegre etmenin iki yolu vardır. Modeli, uygulamanızın öğe klasörüne koyarak paketleyebilir veya Cloud Storage'dan dinamik olarak indirebilirsiniz. Aşağıdaki tabloda iki seçenek karşılaştırılmaktadır.
| Paketlenmiş Model | Barındırılan Model |
|---|---|
Model, uygulamanızın .ipa dosyasının bir parçasıdır ve bu dosyanın boyutunu artırır. |
Model, uygulamanızın .ipa dosyasının bir parçası değildir. Cloud Storage'a yüklenerek barındırılır. Firebase için Cloud Storage'ı kullanmanızı öneririz. |
| Model, Android cihaz çevrimdışı olsa bile hemen kullanılabilir. | Uygulamanız, modeli isteğe bağlı olarak indirmek için kod içermelidir. |
| Firebase projesi gerekmez | Firebase projesi gerektirir (Cloud Storage for Firebase kullanılıyorsa). |
| Modeli güncellemek için uygulamanızı yeniden yayınlamanız gerekir. | Uygulamanızı yeniden yayınlamadan model güncellemelerini gönderme |
| Yerleşik A/B testi yok | Firebase Remote Config ile A/B testi |
Deneyin
- Paketlenmiş modelin kullanımına ilişkin örnek için Vision hızlı başlangıç uygulamasına, barındırılan modelin kullanımına ilişkin örnek için AutoML hızlı başlangıç uygulamasına bakın.
- Bu API'nin uçtan uca uygulanması için Materyal Tasarım tanıtım uygulamasını inceleyin.
Başlamadan önce
Podfile'ınıza ML Kit kitaplıklarını ekleyin:
pod 'GoogleMLKit/ObjectDetectionCustom', '8.0.0'Projenizin Pod'larını yükledikten veya güncelledikten sonra Xcode projenizi
.xcworkspacekullanarak açın. ML Kit, Xcode 13.2.1 veya sonraki sürümlerde desteklenir.Cloud Storage for Firebase kullanarak bir model indirmek istiyorsanız, henüz yapmadıysanız Firebase'i iOS projenize eklediğinizden emin olun. Bu işlem, modeli paketlediğinizde gerekli değildir.
1. Modeli yükleme
Yerel model kaynağı yapılandırma
Modeli uygulamanızla paketlemek için:
Model dosyasını (genellikle
.tfliteveya.liteile biter) Xcode projenize kopyalayın. Bunu yaparkenCopy bundle resourcesseçeneğini belirlemeye dikkat edin. Model dosyası, uygulama paketine dahil edilir ve ML Kit tarafından kullanılabilir.Model dosyasının yolunu belirterek
LocalModelnesnesi oluşturun:Swift
let localModel = LocalModel(path: localModelFilePath)
Objective-C
MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath];
Uzaktan barındırılan model kaynağını yapılandırma
Uzaktan barındırılan modeli kullanmak için model dosyasını kendi uygulama mantığınızı kullanarak cihazın yerel depolama alanına indirmeniz ve ardından yerel model olarak yüklemeniz gerekir. Bir modeli barındırmak için Firebase için Cloud Storage'ı kullanmanızı öneririz. Uygulama ayrıntıları için Firebase ML'den Cloud Storage'a taşıma kılavuzuna bakın.
2. Nesne algılayıcıyı yapılandırma
Model kaynaklarınızı yapılandırdıktan sonra, CustomObjectDetectorOptions nesnesiyle kullanım alanınız için nesne dedektörünü 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
|
| Birden fazla nesneyi algılama ve izleme |
false (varsayılan) | true
En fazla beş nesnenin mi yoksa yalnızca en belirgin nesnenin mi (varsayılan) algılanıp izleneceği. |
| Nesneleri sınıflandırma |
false (varsayılan) | true
Algılanan nesnelerin, sağlanan özel sınıflandırıcı modeli kullanılarak sınıflandırılıp sınıflandırılmayacağı. Özel sınıflandırma modelinizi kullanmak için bu değeri |
| Sınıflandırma güven eşiği |
Algılanan etiketlerin minimum güven puanı. Ayarlanmazsa modelin meta verilerinde belirtilen sınıflandırıcı eşiği kullanılır. Modelde herhangi bir meta veri yoksa veya meta verilerde bir sınıflandırıcı eşiği belirtilmemişse varsayılan eşik olarak 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ı. Ayarlanmazsa varsayılan değer olan 10 kullanılır. |
Yalnızca yerel olarak paketlenmiş bir modeliniz varsa LocalModel nesnenizden bir nesne algılayıcı 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 indirildiğinden emin olmanız gerekir.
Bu işlemi yalnızca nesne algılayıcıyı çalıştırmadan önce onaylamanız gerekse de hem uzaktan barındırılan hem de yerel olarak paketlenmiş bir modeliniz varsa ObjectDetector oluşturulurken bu kontrolü yapmak mantıklı olabilir: Uzak model indirilmişse bu modelden, aksi takdirde yerel modelden bir algılayıcı oluşturun.
Swift
// Path where your download logic saves the model let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let localModelURL = documentDirectory.appendingPathComponent("my_remote_model.tflite") let model: LocalModel if FileManager.default.fileExists(atPath: localModelURL.path) { // Use the downloaded model model = LocalModel(path: localModelURL.path) } else { // Fall back to bundled model guard let bundledModelPath = Bundle.main.path(forResource: "model", ofType: "tflite") else { return } model = LocalModel(path: bundledModelPath) } let options = CustomObjectDetectorOptions(localModel: model) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true options.classificationConfidenceThreshold = NSNumber(value: 0.5) options.maxPerObjectLabelCount = 3 let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *localModelPath = [documentsDirectory stringByAppendingPathComponent:@"my_remote_model.tflite"]; MLKLocalModel *model; if ([NSFileManager.defaultManager fileExistsAtPath:localModelPath]) { // Use the downloaded model model = [[MLKLocalModel alloc] initWithPath:localModelPath]; } else { // Fall back to bundled model NSString *bundledModelPath = [NSBundle.mainBundle pathForResource:@"model" ofType:@"tflite"]; model = [[MLKLocalModel alloc] initWithPath:bundledModelPath]; } MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:model]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; options.classificationConfidenceThreshold = @(0.5); options.maxPerObjectLabelCount = 3; MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
Yalnızca uzaktan barındırılan bir modeliniz varsa modelin indirildiğini onaylayana kadar modelle ilgili işlevleri (ör. kullanıcı arayüzünüzün bir bölümünü devre dışı bırakma veya gizleme) devre dışı bırakmanız gerekir.
Swift
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let localModelURL = documentDirectory.appendingPathComponent("my_remote_model.tflite") if FileManager.default.fileExists(atPath: localModelURL.path) { // Model is already cached, initialize immediately self.initializeDetector(with: localModelURL) } else { // Model is not yet available, show loading UI and start download self.showLoadingUI() let storage = Storage.storage() let modelRef = storage.reference(forURL: "gs://YOUR_BUCKET/path/to/model.tflite") modelRef.write(toFile: localModelURL) { url, error in self.hideLoadingUI() if let error = error { // Handle download error self.showErrorUI() } else if let modelURL = url { // Download success, initialize detector self.initializeDetector(with: modelURL) } } } func initializeDetector(with modelURL: URL) { let localModel = LocalModel(path: modelURL.path) let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true self.objectDetector = ObjectDetector.objectDetector(options: options) // Enable ML features in UI self.enableMLFeatures() }
Objective-C
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *localModelPath = [documentsDirectory stringByAppendingPathComponent:@"my_remote_model.tflite"]; NSURL *localModelURL = [NSURL fileURLWithPath:localModelPath]; if ([NSFileManager.defaultManager fileExistsAtPath:localModelPath]) { // Model is already cached, initialize immediately [self initializeDetectorWithURL:localModelURL]; } else { // Model is not yet available, show loading UI and start download [self showLoadingUI]; FIRStorage *storage = [FIRStorage storage]; FIRStorageReference *modelRef = [storage referenceForURL:@"gs://YOUR_BUCKET/path/to/model.tflite"]; [modelRef writeToFile:localModelURL completion:^(NSURL * _Nullable URL, NSError * _Nullable error) { [self hideLoadingUI]; if (error != nil) { // Handle download error [self showErrorUI]; } else { // Download success, initialize detector [self initializeDetectorWithURL:URL]; } }]; } - (void)initializeDetectorWithURL:(NSURL *)modelURL { MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:modelURL.path]; MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; self.objectDetector = [MLKObjectDetector objectDetectorWithOptions:options]; // Enable ML features in UI [self enableMLFeatures]; }
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üdeki birden fazla nesnenin algılanması.
API'yi bu kullanım alanları için yapılandırmak üzere:
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 şu adımları uygulayın:
UIImageileVisionImagenesnesi oluşturun. Doğru.orientationdeğ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 şu adımları uygulayın:
-
CMSampleBufferiçinde yer alan resim verilerinin yönünü belirtin.Resim yönünü almak 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; } }
CMSampleBuffernesnesini ve yönünü kullanarakVisionImagenesnesi 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ıyı oluşturma ve çalıştırma
Yeni bir nesne algılayıcı 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, tamamlanma işleyicisine bir Object listesi iletir veya eşzamansız ya da eşzamanlı yöntemi çağırmanıza bağlı olarak listeyi döndürür.
Her Object aşağıdaki özellikleri içerir:
frame |
Nesnenin resimdeki konumunu gösteren bir CGRect. |
||||||
trackingID |
Nesneyi resimler arasında tanımlayan bir tam sayı veya SINGLE_IMAGE_MODE'da "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:
- Nesne tespit etmenin başarılı olması, nesnenin görsel karmaşıklığına bağlıdır. Az sayıda görsel özelliğe sahip nesnelerin tespit edilebilmesi için görüntünün daha büyük bir bölümünü kaplaması gerekebilir. Kullanıcılara, tespit etmek istediğiniz nesne türleriyle iyi çalışan girişler yakalama konusunda rehberlik etmelisiniz.
- Sınıflandırma kullandığınızda, desteklenen kategorilere net bir şekilde girmeyen nesneleri algılamak istiyorsanız bilinmeyen nesneler için özel işlem uygulayın.
Ayrıca, ML Kit Materyal Tasarım vitrin uygulamasına ve Materyal Tasarım Makine öğrenimi destekli özellikler için kalıplar koleksiyonuna da göz atın.
Performansı artırma
Nesne tespit etmeyi gerçek zamanlı bir uygulamada kullanmak istiyorsanız en iyi kare hızlarını elde etmek için aşağıdaki yönergeleri uygulayın:Gerçek zamanlı bir uygulamada akış modunu kullanırken çoğu cihaz yeterli kare hızını sağlayamayacağından birden fazla nesne tespit etme kullanmayın.
- Video karelerini işlemek için algılayıcının
results(in:)senkron API'sini kullanın. Belirli bir video karesinden sonuçları eşzamanlı olarak almak için bu yöntemiAVCaptureVideoDataOutputSampleBufferDelegate'ıncaptureOutput(_, didOutput:from:)işlevinden çağırın. Dedektöre yapılan aramaları sınırlamak içinAVCaptureVideoDataOutput'nınalwaysDiscardsLateVideoFramesdeğerinitrueolarak tutun. Algılayıcı çalışırken yeni bir video karesi kullanılabilir hale gelirse bu kare bırakılır. - Grafikleri giriş resmine yerleştirmek için algılayıcının çıkışını kullanıyorsanız önce ML Kit'ten sonucu alın, ardından resmi ve yerleşimi tek adımda oluşturun. Böylece, işlenen her giriş karesi için yalnızca bir kez görüntüleme yüzeyine oluşturma işlemi yaparsınız. Bir örnek için ML Kit hızlı başlangıç örneğindeki updatePreviewOverlayViewWithLastFrame'e bakın.