Bir resimdeki öğeleri 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 koşulları, ö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 APK'sının bir parçasıdır ve bu da uygulamanızın boyutunu artırır. | Model, APK'nızı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.
Başlamadan önce
Podfile'ınıza ML Kit kitaplıklarını ekleyin:
pod 'GoogleMLKit/ImageLabelingCustom', '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. Model 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.
Resim etiketleyiciyi yapılandırma
Model kaynaklarınızı yapılandırdıktan sonra bunlardan birinden ImageLabeler nesnesi oluşturun.
Aşağıdaki seçenekler kullanılabilir:
| Seçenekler | |
|---|---|
confidenceThreshold
|
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. |
maxResultCount
|
Döndürülecek maksimum etiket sayısı. Ayarlanmazsa varsayılan 10 değeri 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 indirildiğinden emin olmanız gerekir.
Bu işlemi yalnızca etiketleyiciyi çalıştırmadan önce onaylamanız gerekse de hem uzaktan barındırılan bir modeliniz hem de yerel olarak paketlenmiş bir modeliniz varsa ImageLabeler oluşturulurken bu kontrolü yapmanız mantıklı olabilir: Uzak model indirilmişse bu modelden, aksi takdirde yerel modelden etiketleyici 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 = CustomImageLabelerOptions(localModel: model) let imageLabeler = ImageLabeler.imageLabeler(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]; } MLKCustomImageLabelerOptions *options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:model]; MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions: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.initializeLabeler(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 labeler self.initializeLabeler(with: modelURL) } } } func initializeLabeler(with modelURL: URL) { let localModel = LocalModel(path: modelURL.path) let options = CustomImageLabelerOptions(localModel: localModel) self.imageLabeler = ImageLabeler.imageLabeler(options: options) // Enable ML-related UI features here 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 initializeLabelerWithURL: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 labeler [self initializeLabelerWithURL:URL]; } }]; } - (void)initializeLabelerWithURL:(NSURL *)modelURL { MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:modelURL.path]; MLKCustomImageLabelerOptions *options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel]; self.imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options]; // Enable ML-related UI features here [self enableMLFeatures]; }
2. 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];
3. Resim etiketleyicisini çalıştırma
Resimdeki nesneleri etiketlemek için image nesnesini ImageLabeler'nin process() yöntemine iletin.
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. Etiketlenmiş öğeler hakkında bilgi alma
Resim etiketleme işlemi başarılı olursaImageLabel dizisi döndürülür. Her ImageLabel, resimde etiketlenen bir şeyi temsil eder. Her etiketin metin açıklamasını (LiteRT model dosyasının meta verilerinde varsa), güven puanını ve dizinini 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; }
Anlık performansı artırmaya yönelik ipuçları
Görüntüleri gerçek zamanlı bir uygulamada etiketlemek istiyorsanız en iyi kare hızlarını elde etmek için aşağıdaki yönergeleri uygulayı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.