Разметка изображений с помощью модели, обученной на AutoML, на iOS.
После обучения собственной модели с помощью AutoML Vision Edge вы можете использовать ее в своем приложении для разметки изображений.
Существует два способа интеграции моделей, обученных с помощью AutoML Vision Edge. Вы можете упаковать модель, скопировав файлы модели в свой проект Xcode, или вы можете динамически загрузить ее из Firebase.
| Варианты комплектации моделей | |
|---|---|
| Встроено в ваше приложение |
|
| Размещено на Firebase |
|
Попробуйте!
- Поэкспериментируйте с примером приложения , чтобы увидеть, как используется этот API.
Прежде чем начать
1. Добавьте библиотеки ML Kit в свой Podfile:Для включения модели в ваше приложение:
pod 'GoogleMLKit/ImageLabelingAutoML'
LinkFirebase :
pod 'GoogleMLKit/ImageLabelingAutoML'
pod 'GoogleMLKit/LinkFirebase'
.xcworkspace . ML Kit поддерживается в Xcode версии 13.2.1 или выше. 3. Если вы хотите загрузить модель , убедитесь, что вы добавили Firebase в свой проект iOS , если вы еще этого не сделали. Это не требуется при сборке модели.1. Загрузите модель.
Настройте локальный источник модели.
Чтобы включить модель в ваше приложение:1. Извлеките модель и её метаданные из загруженного ZIP-архива из консоли Firebase в папку:
your_model_directory
|____dict.txt
|____manifest.json
|____model.tflite
2. Скопируйте папку в свой проект Xcode, обязательно выбрав при этом пункт «Создать ссылки на папку» . Файл модели и метаданные будут включены в пакет приложения и станут доступны для ML Kit.
3. Создайте объект
AutoMLImageLabelerLocalModel , указав путь к файлу манифеста модели: Быстрый
guard let manifestPath = Bundle.main.path( forResource: "manifest", ofType: "json", inDirectory: "your_model_directory" ) else { return } let localModel = AutoMLImageLabelerLocalModel(manifestPath: manifestPath)
Objective-C
NSString *manifestPath = [NSBundle.mainBundle pathForResource:@"manifest" ofType:@"json" inDirectory:@"your_model_directory"]; MLKAutoMLImageLabelerLocalModel *localModel = [[MLKAutoMLImageLabelerLocalModel alloc] initWithManifestPath:manifestPath];
Настройте источник модели, размещенный в Firebase.
Для использования удаленно размещенной модели создайте объект AutoMLImageLabelerRemoteModel , указав имя, которое вы присвоили модели при ее публикации:
Быстрый
let remoteModel = AutoMLImageLabelerRemoteModel( name: "your_remote_model" // The name you assigned in // the Firebase console. )
Objective-C
MLKAutoMLImageLabelerRemoteModel *remoteModel = [[MLKAutoMLImageLabelerRemoteModel alloc] initWithName:@"your_remote_model"]; // The name you assigned in // the Firebase console.
Затем запустите задачу загрузки модели, указав условия, при которых вы хотите разрешить загрузку. Если модель отсутствует на устройстве или если доступна более новая версия модели, задача асинхронно загрузит модель из Firebase:
Быстрый
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];
Во многих приложениях задача загрузки запускается в коде инициализации, но вы можете сделать это в любой момент до того, как вам понадобится использовать модель.
Создайте средство разметки изображений на основе вашей модели.
После настройки источников модели создайте объект ImageLabeler на основе одного из них.
Если у вас есть только локально упакованная модель, просто создайте объект разметки из вашего объекта AutoMLImageLabelerLocalModel и настройте требуемый пороговый уровень достоверности (см. раздел «Оценка вашей модели» :
Быстрый
let options = AutoMLImageLabelerOptions(localModel: localModel) options.confidenceThreshold = NSNumber(value: 0.0) // Evaluate your model in the Firebase console // to determine an appropriate value. let imageLabeler = ImageLabeler.imageLabeler(options: options)
Objective-C
MLKAutoMLImageLabelerOptions *options = [[MLKAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel]; options.confidenceThreshold = @(0.0); // Evaluate your model in the Firebase console // to determine an appropriate value. MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
Если у вас есть удаленно размещенная модель, вам необходимо убедиться, что она загружена, прежде чем запускать ее. Вы можете проверить статус задачи загрузки модели, используя метод isModelDownloaded (remoteModel:) менеджера моделей.
Хотя подтверждение этого требуется только перед запуском разметчика, если у вас есть как удаленно размещенная модель, так и локально упакованная модель, имеет смысл выполнить эту проверку при создании экземпляра ImageLabeler : создать разметчик из удаленной модели, если она была загружена, и из локальной модели в противном случае.
Быстрый
var options: AutoMLImageLabelerOptions! if (ModelManager.modelManager().isModelDownloaded(remoteModel)) { options = AutoMLImageLabelerOptions(remoteModel: remoteModel) } else { options = AutoMLImageLabelerOptions(localModel: localModel) } options.confidenceThreshold = NSNumber(value: 0.0) // Evaluate your model in the Firebase console // to determine an appropriate value. let imageLabeler = ImageLabeler.imageLabeler(options: options)
Objective-C
MLKAutoMLImageLabelerOptions *options; if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) { options = [[MLKAutoMLImageLabelerOptions alloc] initWithRemoteModel:remoteModel]; } else { options = [[MLKAutoMLImageLabelerOptions alloc] initWithLocalModel:localModel]; } options.confidenceThreshold = @(0.0); // Evaluate your model in the Firebase console // to determine an appropriate value. MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
Если у вас есть только удаленно размещенная модель, следует отключить связанные с ней функции — например, сделать часть пользовательского интерфейса неактивной или скрытой — до тех пор, пока вы не убедитесь, что модель загружена.
Статус загрузки модели можно получить, прикрепив наблюдателей к центру уведомлений по умолчанию. Обязательно используйте слабую ссылку на self в блоке наблюдателя, поскольку загрузка может занять некоторое время, и исходный объект может быть освобожден к моменту завершения загрузки. Например:
Быстрый
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. Подготовьте входное изображение.
Создайте объект VisionImage , используя UIImage или CMSampleBuffer .
Если вы используете UIImage , выполните следующие действия:
- Создайте объект
VisionImageс использованиемUIImage. Убедитесь, что указана правильная.orientation).Быстрый
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Если вы используете
CMSampleBuffer, выполните следующие действия:Укажите ориентацию данных изображения, содержащихся в
CMSampleBuffer.Чтобы определить ориентацию изображения:
Быстрый
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; } }
- Создайте объект
VisionImage, используя объектCMSampleBufferи заданную ориентацию:Быстрый
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. Запустите программу для разметки изображений.
Асинхронно:
Быстрый
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 (labels.count == 0) { // Handle the error. return; } // Show results. }]; Синхронно:
Быстрый
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. Получите информацию об объектах с соответствующими обозначениями.
Если операция разметки изображения прошла успешно, она возвращает массив объектовImageLabel. КаждыйImageLabelпредставляет собой то, что было помечено на изображении. Вы можете получить текстовое описание каждой метки (если оно доступно в метаданных файла модели TensorFlow Lite), оценку достоверности и индекс. Например:Быстрый
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; }
Советы по повышению производительности в режиме реального времени
Если вы хотите маркировать изображения в приложении реального времени, следуйте этим рекомендациям, чтобы добиться наилучшей частоты кадров:
- Для обработки видеокадров используйте синхронный API
results(in:)детектора. Вызовите этот метод из функцииcaptureOutput(_, didOutput:from:)вAVCaptureVideoDataOutputSampleBufferDelegate, чтобы синхронно получить результаты из заданного видеокадра. Установите параметрalwaysDiscardsLateVideoFramesвAVCaptureVideoDataOutputв значениеtrue, чтобы ограничить количество вызовов детектора. Если во время работы детектора появится новый видеокадр, он будет отброшен. - Если вы используете выходные данные детектора для наложения графики на входное изображение, сначала получите результат от ML Kit, а затем отрендерите изображение и наложение за один шаг. Таким образом, вы будете отрендеривать изображение на поверхности дисплея только один раз для каждого обработанного входного кадра. Пример можно увидеть в функции updatePreviewOverlayViewWithLastFrame в примере быстрого запуска ML Kit.
- Для обработки видеокадров используйте синхронный API
Если не указано иное, контент на этой странице предоставляется по лицензии Creative Commons "С указанием авторства 4.0", а примеры кода – по лицензии Apache 2.0. Подробнее об этом написано в правилах сайта. Java – это зарегистрированный товарный знак корпорации Oracle и ее аффилированных лиц.
Последнее обновление: 2026-01-28 UTC.
[null,null,["Последнее обновление: 2026-01-28 UTC."],[],[]]