При передаче изображения в ML Kit программа обнаруживает до пяти объектов на изображении, а также определяет положение каждого объекта. При обнаружении объектов в видеопотоках каждый объект имеет уникальный идентификатор, который можно использовать для отслеживания объекта от кадра к кадру.
Для классификации обнаруженных объектов можно использовать собственную модель классификации изображений. Подробную информацию о требованиях к совместимости моделей, местах поиска предварительно обученных моделей и способах обучения собственных моделей см. в разделе «Создание пользовательских моделей с помощью ML Kit».
Существует два способа интеграции пользовательской модели. Вы можете включить модель в состав приложения, поместив её в папку ресурсов, или динамически загрузить её из облачного хранилища. В следующей таблице сравниваются эти два варианта.
| Комплексная модель | Хостинговая модель |
|---|---|
Модель является частью файла .ipa вашего приложения, что увеличивает его размер. | Модель не является частью файла .ipa вашего приложения. Она размещается путем загрузки в Cloud Storage. Мы рекомендуем использовать Cloud Storage для Firebase . |
| Данная модель доступна сразу же, даже когда устройство Android находится в автономном режиме. | Ваше приложение должно содержать код для загрузки модели по запросу. |
| Нет необходимости в проекте Firebase. | Требуется проект Firebase (если используется Cloud Storage for Firebase). |
| Для обновления модели необходимо повторно опубликовать приложение. | Обновляйте модель приложения, не переиздавая его. |
| Встроенного A/B-тестирования нет. | A/B-тестирование с использованием Firebase Remote Config |
Попробуйте!
- Пример использования встроенной модели можно найти в приложении Vision Quickstart , а пример использования размещенной модели — в приложении AutoML Quickstart .
- Для получения полной реализации этого API ознакомьтесь с демонстрационным приложением Material Design .
Прежде чем начать
Включите библиотеки ML Kit в свой Podfile:
pod 'GoogleMLKit/ObjectDetectionCustom', '8.0.0'После установки или обновления Pods вашего проекта откройте проект Xcode, используя его
.xcworkspace. ML Kit поддерживается в Xcode версии 13.2.1 или выше.Если вы хотите загрузить модель с помощью Cloud Storage for Firebase , убедитесь, что вы добавили Firebase в свой iOS-проект , если вы еще этого не сделали. Это не требуется при сборке модели.
1. Загрузите модель.
Настройте локальный источник модели.
Чтобы включить модель в ваше приложение:
Скопируйте файл модели (обычно с расширением
.tfliteили.lite) в свой проект Xcode, обязательно выбрав опциюCopy bundle resources. Файл модели будет включен в пакет приложения и станет доступен для ML Kit.Создайте объект
LocalModel, указав путь к файлу модели:Быстрый
let localModel = LocalModel(path: localModelFilePath)
Objective-C
MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath];
Настройте удаленно размещенный источник модели.
Для использования модели, размещенной удаленно, необходимо загрузить файл модели в локальное хранилище устройства, используя собственную логику приложения, а затем загрузить его как локальную модель. Мы рекомендуем использовать Cloud Storage for Firebase для размещения модели. Подробности реализации см. в руководстве по миграции Firebase ML в Cloud Storage .
2. Настройте детектор объектов.
После настройки источников модели настройте детектор объектов для вашего варианта использования с помощью объекта CustomObjectDetectorOptions . Вы можете изменить следующие параметры:
| Настройки детектора объектов | |
|---|---|
| Режим обнаружения | STREAM_MODE (по умолчанию) | SINGLE_IMAGE_MODE В В |
| Обнаружение и отслеживание нескольких объектов | false (по умолчанию) | trueВы можете выбрать, обнаруживать и отслеживать до пяти объектов или только самый заметный объект (по умолчанию). |
| Классифицировать объекты | false (по умолчанию) | true Определяет, следует ли классифицировать обнаруженные объекты с использованием предоставленной пользовательской модели классификации. Чтобы использовать свою собственную модель классификации, необходимо установить этот параметр в |
| Порог достоверности классификации | Минимальный показатель достоверности обнаруженных меток. Если не задано, будет использоваться любой пороговый уровень классификатора, указанный в метаданных модели. Если модель не содержит метаданных или метаданные не указывают пороговый уровень классификатора, будет использоваться пороговое значение по умолчанию, равное 0,0. |
| Максимальное количество меток на объект | Максимальное количество меток для каждого объекта, которое вернет детектор. Если не указано, будет использоваться значение по умолчанию — 10. |
Если у вас есть только локально упакованная модель, просто создайте детектор объектов на основе вашего объекта LocalModel :
Быстрый
let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true options.classificationConfidenceThreshold = NSNumber(value: 0.5) options.maxPerObjectLabelCount = 3
Objective-C
MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; options.classificationConfidenceThreshold = @(0.5); options.maxPerObjectLabelCount = 3;
Если вы используете удаленно размещенную модель, вам необходимо убедиться, что она была загружена, прежде чем запускать ее.
Хотя подтверждение этого требуется только перед запуском детектора объектов, если у вас есть как удаленно размещенная модель, так и локально упакованная модель, имеет смысл выполнить эту проверку при создании экземпляра ObjectDetector : создать детектор из удаленной модели, если она была загружена, и из локальной модели в противном случае.
Быстрый
// 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 = CustomObjectDetectorOptions(localModel: model) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true options.classificationConfidenceThreshold = NSNumber(value: 0.5) options.maxPerObjectLabelCount = 3 let objectDetector = ObjectDetector.objectDetector(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]; } MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:model]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; options.classificationConfidenceThreshold = @(0.5); options.maxPerObjectLabelCount = 3; MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
Если у вас есть только удаленно размещенная модель, следует отключить связанные с ней функции — например, сделать часть пользовательского интерфейса неактивной или скрытой — до тех пор, пока вы не убедитесь, что модель загружена.
Быстрый
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.initializeDetector(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 detector self.initializeDetector(with: modelURL) } } } func initializeDetector(with modelURL: URL) { let localModel = LocalModel(path: modelURL.path) let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true self.objectDetector = ObjectDetector.objectDetector(options: options) // Enable ML features in UI 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 initializeDetectorWithURL: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 detector [self initializeDetectorWithURL:URL]; } }]; } - (void)initializeDetectorWithURL:(NSURL *)modelURL { MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:modelURL.path]; MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; self.objectDetector = [MLKObjectDetector objectDetectorWithOptions:options]; // Enable ML features in UI [self enableMLFeatures]; }
API для обнаружения и отслеживания объектов оптимизирован для двух основных сценариев использования:
- Обнаружение и отслеживание в реальном времени наиболее заметного объекта в видоискателе камеры.
- Обнаружение нескольких объектов на статическом изображении.
Для настройки API под эти сценарии использования:
Быстрый
// Live detection and tracking let options = CustomObjectDetectorOptions(localModel: localModel) options.shouldEnableClassification = true options.maxPerObjectLabelCount = 3 // Multiple object detection in static images let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableMultipleObjects = true options.shouldEnableClassification = true options.maxPerObjectLabelCount = 3
Objective-C
// Live detection and tracking MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.shouldEnableClassification = YES; options.maxPerObjectLabelCount = 3; // Multiple object detection in static images MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableMultipleObjects = YES; options.shouldEnableClassification = YES; options.maxPerObjectLabelCount = 3;
3. Подготовьте входное изображение.
Создайте объект 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];
4. Создайте и запустите детектор объектов.
Создайте новый детектор объектов:
Быстрый
let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
Затем воспользуйтесь детектором:
Асинхронно:
Быстрый
objectDetector.process(image) { objects, error in guard error == nil, let objects = objects, !objects.isEmpty else { // Handle the error. return } // Show results. }
Objective-C
[objectDetector processImage:image completion:^(NSArray
*_Nullable objects, NSError *_Nullable error) { if (objects.count == 0) { // Handle the error. return; } // Show results. }]; Синхронно:
Быстрый
var objects: [Object] do { objects = try objectDetector.results(in: image) } catch let error { // Handle the error. return } // Show results.
Objective-C
NSError *error; NSArray
*objects = [objectDetector resultsInImage:image error:&error]; // Show results or handle the error.
5. Получите информацию об объектах с соответствующими обозначениями.
Если вызов обработчика изображений проходит успешно, он либо передает список
Objectобработчику завершения, либо возвращает этот список, в зависимости от того, был ли вызван асинхронный или синхронный метод.Каждый
Objectсодержит следующие свойства:frameОбъект CGRect, указывающий положение объекта на изображении.trackingIDЦелочисленное значение, идентифицирующее объект на разных изображениях, или `nil` в режиме SINGLE_IMAGE_MODE. labelslabel.textТекстовое описание метки. Возвращается только в том случае, если метаданные модели LiteRT содержат описания меток. label.indexИндекс метки среди всех меток, поддерживаемых классификатором. label.confidenceЗначение достоверности классификации объекта. Быстрый
// objects contains one item if multiple object detection wasn't enabled. for object in objects { let frame = object.frame let trackingID = object.trackingID let description = object.labels.enumerated().map { (index, label) in "Label \(index): \(label.text), \(label.confidence), \(label.index)" }.joined(separator: "\n") }
Objective-C
// The list of detected objects contains one item if multiple object detection // wasn't enabled. for (MLKObject *object in objects) { CGRect frame = object.frame; NSNumber *trackingID = object.trackingID; for (MLKObjectLabel *label in object.labels) { NSString *labelString = [NSString stringWithFormat:@"%@, %f, %lu", label.text, label.confidence, (unsigned long)label.index]; } }
Обеспечение превосходного пользовательского опыта
Для обеспечения наилучшего пользовательского опыта следуйте этим рекомендациям в своем приложении:
- Успешное обнаружение объектов зависит от их визуальной сложности. Для обнаружения объектам с небольшим количеством визуальных признаков может потребоваться занимать большую часть изображения. Необходимо предоставить пользователям инструкции по захвату входных данных, которые хорошо работают с типами объектов, которые вы хотите обнаружить.
- При использовании классификации, если вы хотите обнаружить объекты, которые не попадают точно в поддерживаемые категории, реализуйте специальную обработку для неизвестных объектов.
Также ознакомьтесь с демонстрационным приложением ML Kit Material Design и коллекцией шаблонов Material Design для функций, использующих машинное обучение .
Повышение производительности
Если вы хотите использовать обнаружение объектов в приложении реального времени, следуйте этим рекомендациям для достижения наилучшей частоты кадров:При использовании потокового режима в приложениях реального времени не следует применять обнаружение нескольких объектов одновременно, поскольку большинство устройств не смогут обеспечить достаточную частоту кадров.
- Для обработки видеокадров используйте синхронный API
results(in:)детектора. Вызовите этот метод из функцииcaptureOutput(_, didOutput:from:)вAVCaptureVideoDataOutputSampleBufferDelegate, чтобы синхронно получить результаты из заданного видеокадра. Установите параметрalwaysDiscardsLateVideoFramesвAVCaptureVideoDataOutputв значениеtrue, чтобы ограничить количество вызовов детектора. Если во время работы детектора появится новый видеокадр, он будет отброшен. - Если вы используете выходные данные детектора для наложения графики на входное изображение, сначала получите результат от ML Kit, а затем отрендерите изображение и наложение за один шаг. Таким образом, вы будете отрендеривать изображение на поверхности дисплея только один раз для каждого обработанного входного кадра. Пример можно увидеть в функции updatePreviewOverlayViewWithLastFrame в примере быстрого запуска ML Kit.
Если не указано иное, контент на этой странице предоставляется по лицензии Creative Commons "С указанием авторства 4.0", а примеры кода – по лицензии Apache 2.0. Подробнее об этом написано в правилах сайта. Java – это зарегистрированный товарный знак корпорации Oracle и ее аффилированных лиц.
Последнее обновление: 2026-06-17 UTC.
[[["Прост для понимания","easyToUnderstand","thumb-up"],["Помог мне решить мою проблему","solvedMyProblem","thumb-up"],["Другое","otherUp","thumb-up"]],[["Отсутствует нужная мне информация","missingTheInformationINeed","thumb-down"],["Слишком сложен/слишком много шагов","tooComplicatedTooManySteps","thumb-down"],["Устарел","outOfDate","thumb-down"],["Проблема с переводом текста","translationIssue","thumb-down"],["Проблемы образцов/кода","samplesCodeIssue","thumb-down"],["Другое","otherDown","thumb-down"]],["Последнее обновление: 2026-06-17 UTC."],[],["ML Kit enables detecting and tracking up to five objects in images or video, identified by unique IDs. Models can be bundled locally, increasing app size, or hosted remotely via Firebase, downloaded on demand, and updated without app republishing. Configure object detection via `CustomObjectDetectorOptions`, setting detection mode, multiple object detection, and classification settings. Create a local or remote detector, and process images using synchronous or asynchronous methods. Image orientation is handled with a switch method that is dependent of the camera position. Performance optimizations are given for video frame processing.\n"]]