Маркируйте изображения с помощью обученной модели 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, не забудьте выбрать Create folder references, когда вы это сделаете. Файл модели и метаданные будут включены в пакет приложения и станут доступны для 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 и ее аффилированных лиц.
Последнее обновление: 2025-08-29 UTC.
[null,null,["Последнее обновление: 2025-08-29 UTC."],[[["\u003cp\u003eLabel images using a custom-trained AutoML Vision Edge model on iOS devices by bundling the model with your app or dynamically downloading it from Firebase.\u003c/p\u003e\n"],["\u003cp\u003ePrepare the input image by creating a VisionImage object using a UIImage or CMSampleBuffer, ensuring correct orientation is specified.\u003c/p\u003e\n"],["\u003cp\u003eRun the image labeler asynchronously or synchronously to process the image and get labels with confidence scores and indexes.\u003c/p\u003e\n"],["\u003cp\u003eTo improve real-time performance, use the synchronous API for video frames and combine rendering with overlaying graphics in a single step.\u003c/p\u003e\n"],["\u003cp\u003eMigrate from the deprecated AutoML Vision Edge specific API to the Custom Image Labeling API for native support.\u003c/p\u003e\n"]]],[],null,[]]