Вы можете использовать ML Kit, чтобы распознавать объекты на изображении и маркировать их. Этот API поддерживает широкий спектр пользовательских моделей классификации изображений. Обратитесь к разделу Пользовательские модели с комплектом ML, чтобы узнать о требованиях к совместимости моделей, где найти предварительно обученные модели и как обучать собственные модели.
Существует два способа интеграции пользовательской модели. Вы можете связать модель, поместив ее в папку ресурсов вашего приложения, или динамически загрузить ее из Firebase. В следующей таблице сравниваются два варианта.
| Модель в комплекте | Размещенная модель | 
|---|---|
| Модель является частью APK-файла вашего приложения, что увеличивает его размер. | Модель не является частью вашего APK. Он размещается путем загрузки в Firebase Machine Learning . | 
| Модель доступна сразу, даже когда Android-устройство находится в автономном режиме. | Модель скачивается по запросу. | 
| Нет необходимости в проекте Firebase | Требуется проект Firebase | 
| Вам необходимо повторно опубликовать свое приложение, чтобы обновить модель. | Отправляйте обновления модели без повторной публикации приложения. | 
| Нет встроенного A/B-тестирования. | Простое A/B-тестирование с помощью Firebase Remote Config | 
Попробуйте это
- См. приложение быстрого запуска Vision для примера использования связанной модели и приложение быстрого запуска automl для примера использования размещенной модели.
Прежде чем начать
- Включите библиотеки ML Kit в свой подфайл: - Для объединения модели с вашим приложением: - pod 'GoogleMLKit/ImageLabelingCustom', '8.0.0'- Для динамической загрузки модели из Firebase добавьте зависимость - LinkFirebase:- pod 'GoogleMLKit/ImageLabelingCustom', '8.0.0' pod 'GoogleMLKit/LinkFirebase', '8.0.0'
- После установки или обновления модулей вашего проекта откройте проект Xcode, используя его - .xcworkspace. ML Kit поддерживается в Xcode версии 13.2.1 или выше.
- Если вы хотите загрузить модель , обязательно добавьте Firebase в свой проект iOS , если вы еще этого не сделали. Это не требуется при объединении модели. 
1. Загрузите модель
Настройте источник локальной модели
Чтобы связать модель с вашим приложением:
- Скопируйте файл модели (обычно заканчивающийся на - .tfliteили- .lite) в свой проект Xcode, при этом не забывая выбирать- Copy bundle resources. Файл модели будет включен в пакет приложения и доступен в ML Kit.
- Создайте объект - LocalModel, указав путь к файлу модели:- Быстрый- let localModel = LocalModel(path: localModelFilePath) - Цель-C- MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath]; 
Настройте источник модели, размещенный в Firebase
 Чтобы использовать удаленно размещенную модель, создайте объект RemoteModel , указав имя, которое вы присвоили модели при ее публикации: 
Быстрый
let firebaseModelSource = FirebaseModelSource( name: "your_remote_model") // The name you assigned in // the Firebase console. let remoteModel = CustomRemoteModel(remoteModelSource: firebaseModelSource)
Цель-C
MLKFirebaseModelSource *firebaseModelSource = [[MLKFirebaseModelSource alloc] initWithName:@"your_remote_model"]; // The name you assigned in // the Firebase console. MLKCustomRemoteModel *remoteModel = [[MLKCustomRemoteModel alloc] initWithRemoteModelSource:firebaseModelSource];
Затем запустите задачу загрузки модели, указав условия, при которых вы хотите разрешить загрузку. Если модели нет на устройстве или доступна более новая версия модели, задача асинхронно загрузит модель из Firebase:
Быстрый
let downloadConditions = ModelDownloadConditions( allowsCellularAccess: true, allowsBackgroundDownloading: true ) let downloadProgress = ModelManager.modelManager().download( remoteModel, conditions: downloadConditions )
Цель-C
MLKModelDownloadConditions *downloadConditions = [[MLKModelDownloadConditions alloc] initWithAllowsCellularAccess:YES allowsBackgroundDownloading:YES]; NSProgress *downloadProgress = [[MLKModelManager modelManager] downloadModel:remoteModel conditions:downloadConditions];
Многие приложения запускают задачу загрузки в своем коде инициализации, но вы можете сделать это в любой момент, прежде чем вам понадобится использовать модель.
Настройка маркировщика изображений
 После настройки источников модели создайте объект ImageLabeler на основе одного из них.
Доступны следующие варианты:
| Параметры | |
|---|---|
| confidenceThreshold | Минимальный показатель достоверности обнаруженных меток. Если не установлено, будет использоваться любое пороговое значение классификатора, указанное в метаданных модели. Если модель не содержит метаданных или в метаданных не указан порог классификатора, будет использоваться порог по умолчанию, равный 0,0. | 
| maxResultCount | Максимальное количество возвращаемых меток. Если не установлено, будет использоваться значение по умолчанию 10. | 
 Если у вас есть только локально связанная модель, просто создайте метку из вашего объекта LocalModel : 
Быстрый
let options = CustomImageLabelerOptions(localModel: localModel) options.confidenceThreshold = NSNumber(value: 0.0) let imageLabeler = ImageLabeler.imageLabeler(options: options)
Цель-C
MLKCustomImageLabelerOptions *options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel]; options.confidenceThreshold = @(0.0); MLKImageLabeler *imageLabeler = [MLKImageLabeler imageLabelerWithOptions:options];
 Если у вас есть удаленно размещенная модель, вам придется убедиться, что она загружена, прежде чем запускать ее. Вы можете проверить состояние задачи загрузки модели с помощью метода isModelDownloaded(remoteModel:) менеджера моделей.
 Хотя вам нужно подтвердить это только перед запуском средства разметки, если у вас есть как удаленно размещенная модель, так и локально связанная модель, возможно, имеет смысл выполнить эту проверку при создании экземпляра ImageLabeler : создайте средство разметки из удаленной модели, если оно скачано, а из локальной модели иначе. 
Быстрый
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)
Цель-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];
Если у вас есть только удаленно размещенная модель, вам следует отключить функции, связанные с моделью (например, сделать их серыми или скрыть часть пользовательского интерфейса), пока вы не подтвердите, что модель загружена.
 Вы можете получить статус загрузки модели, присоединив наблюдателей к Центру уведомлений по умолчанию. Обязательно используйте слабую ссылку на 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] // ... }
Цель-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 Цель-CMLKVisionImage *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 } } - Цель-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) Цель-CMLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition]; 3. Запустите программу разметки изображений.Чтобы пометить объекты на изображении, передайте объект imageв методprocess()ImageLabeler.Асинхронно: БыстрыйimageLabeler.process(image) { labels, error in guard error == nil, let labels = labels, !labels.isEmpty else { // Handle the error. return } // Show results. } Цель-C[imageLabeler processImage:image completion:^(NSArray *_Nullable labels, NSError *_Nullable error) { if (label.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. Цель-CNSError *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 } Цель-Cfor (MLKImageLabel *label in labels) { NSString *labelText = label.text; float confidence = label.confidence; NSInteger index = label.index; } Советы по повышению производительности в реальном времениЕсли вы хотите маркировать изображения в приложении реального времени, следуйте этим рекомендациям для достижения наилучшей частоты кадров: -  Для обработки видеокадров используйте синхронный API results(in:)детектора. Вызовите этот метод из функцииcaptureOutput(_, didOutput:from:)AVCaptureVideoDataOutputSampleBufferDelegate, чтобы синхронно получить результаты из данного видеокадра. Оставьте дляAVCaptureVideoDataOutputзначениеalwaysDiscardsLateVideoFramesкакtrue, чтобы ограничить вызовы детектора. Если во время работы детектора появится новый видеокадр, он будет удален.
- Если вы используете выходные данные детектора для наложения графики на входное изображение, сначала получите результат из ML Kit, затем визуализируйте изображение и наложите его за один шаг. При этом вы выполняете рендеринг на поверхность дисплея только один раз для каждого обработанного входного кадра. Пример см. в updatePreviewOverlayViewWithLastFrame в образце быстрого запуска ML Kit.
 Если не указано иное, контент на этой странице предоставляется по лицензии Creative Commons "С указанием авторства 4.0", а примеры кода – по лицензии Apache 2.0. Подробнее об этом написано в правилах сайта. Java – это зарегистрированный товарный знак корпорации Oracle и ее аффилированных лиц. Последнее обновление: 2025-10-29 UTC. [null,null,["Последнее обновление: 2025-10-29 UTC."],[],[]]
-  Для обработки видеокадров используйте синхронный API 
 
