Bir görüntüdeki varlıkları tanımak ve etiketlemek için ML Kit'i kullanabilirsiniz. Bu API, çok çeşitli özel görüntü sınıflandırma modellerini destekler. Model uyumluluğu gereksinimleri, önceden eğitilmiş modellerin nerede bulunduğu ve kendi modellerinizi nasıl eğiteceğiniz hakkında bilgi edinmek 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 APK'sının bir parçası olduğundan boyutunu artırır. | Model, APK'nızı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.
Başlamadan önce
ML Kit kitaplıklarını Podfile dosyanıza ekleyin:
Uygulamanızla bir model paketi sunmak için:
pod 'GoogleMLKit/ImageLabelingCustom', '3.2.0'
Firebase'den dinamik olarak bir model indirmek için
LinkFirebase
bağımlılığını ekleyin:pod 'GoogleMLKit/ImageLabelingCustom', '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 RemoteModel
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.
Resim etiketleyiciyi yapılandırma
Model kaynaklarınızı yapılandırdıktan sonra, bunlardan bir ImageLabeler
nesnesi oluşturun.
Aşağıdaki seçenekler kullanılabilir:
Seçenekler | |
---|---|
confidenceThreshold
|
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. |
maxResultCount
|
Döndürülecek 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 etiketleyici oluşturmanız yeterlidir:
Swift
let options = CustomImageLabelerOptions(localModel: localModel) options.confidenceThreshold = NSNumber(value: 0.0) let imageLabeler = ImageLabeler.imageLabeler(options: options)
Objective-C
MLKCustomImageLabelerOptions *options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel]; options.confidenceThreshold = @(0.0); MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
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.
Etiketleyiciyi çalıştırmadan önce bunu yalnızca onaylamanız gerekse de hem uzaktan barındırılan bir modeliniz hem de yerel olarak paketlenmiş bir modeliniz varsa ImageLabeler
örneğini oluştururken bu kontrolün yapılması mantıklı olabilir: İndirilmişse uzak modelden, aksi takdirde yerel modelden bir etiketleyici oluşturun.
Swift
var options: CustomImageLabelerOptions! if (ModelManager.modelManager().isModelDownloaded(remoteModel)) { options = CustomImageLabelerOptions(remoteModel: remoteModel) } else { options = CustomImageLabelerOptions(localModel: localModel) } options.confidenceThreshold = NSNumber(value: 0.0) 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.0); MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
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]; }];
2. 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];
3. Görüntü etiketleyiciyi çalıştırma
Bir görüntüdeki nesneleri etiketlemek için image
nesnesini ImageLabeler
process()
yöntemine geçirin.
Eş zamansız olarak:
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 (label.count == 0) { // Handle the error. return; } // Show results. }];
Eşzamanlı olarak:
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. Etiketli varlıklar hakkında bilgi edinme
Görüntü etiketleme işlemi başarılı olursaImageLabel
dizisini döndürür. Her ImageLabel
, resimde etiketlenmiş bir şeyi temsil eder. Her etiketin metin açıklamasını (TensorFlow Lite model dosyasının meta verilerinde varsa), güven puanını ve dizini alabilirsiniz.
Örneğin:
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; }
Gerçek zamanlı performansı iyileştirmeye yönelik ipuçları
Resimleri gerçek zamanlı bir uygulamada etiketlemek istiyorsanız en iyi kare hızlarını elde etmek için şu yönergeleri uygulayı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.