В ML Kit есть два оптимизированных SDK для обнаружения поз.
| Название SDK | PoseDetection | PoseDetectionAccurate |
|---|---|---|
| Реализация | Объекты для базового детектора статически связаны с приложением во время сборки. | Объекты для точного детектора статически связываются с приложением во время сборки. |
| Размер приложения | до 29,6 МБ; | до 33,2 МБ; |
| Эффективность | iPhone X: ~45 кадров/с | iPhone X: ~29 кадров/с |
Попробовать
- Попробуйте пример приложения, чтобы увидеть, как используется этот API.
Подготовка
Добавьте в Podfile следующие поды ML Kit:
# If you want to use the base implementation: pod 'GoogleMLKit/PoseDetection', '8.0.0' # If you want to use the accurate implementation: pod 'GoogleMLKit/PoseDetectionAccurate', '8.0.0'После установки или обновления модулей проекта откройте проект Xcode, используя файл
xcworkspace. ML Kit поддерживается в Xcode версии 13.2.1 или выше.
1. Как создать экземпляр PoseDetector
Чтобы обнаружить позу на изображении, сначала создайте экземпляр PoseDetector и при необходимости укажите настройки детектора.
PoseDetector варианта
Режим обнаружения
PoseDetector работает в двух режимах обнаружения. Выберите подходящий вариант.
stream(по умолчанию)- Сначала детектор позы определяет самого заметного человека на изображении, а затем распознает его позу. На последующих кадрах обнаружение человека не будет выполняться, если только он не будет скрыт или не будет обнаружен с высокой степенью достоверности. Детектор поз будет пытаться отслеживать наиболее заметного человека и возвращать его позу в каждом инференсе. Это позволяет снизить задержку и повысить точность обнаружения. Используйте этот режим, если вам нужно обнаружить позу в видеопотоке.
singleImage- Детектор позы обнаружит человека, а затем определит его позу. Обнаружение людей будет выполняться для каждого изображения, поэтому задержка будет выше, а отслеживание людей не будет выполняться. Используйте этот режим при использовании позы обнаружение на статических изображениях или там, где отслеживание нежелательно.
Укажите настройки детектора поз:
Swift
// Base pose detector with streaming, when depending on the PoseDetection SDK let options = PoseDetectorOptions() options.detectorMode = .stream // Accurate pose detector on static images, when depending on the // PoseDetectionAccurate SDK let options = AccuratePoseDetectorOptions() options.detectorMode = .singleImage
Objective-C
// Base pose detector with streaming, when depending on the PoseDetection SDK MLKPoseDetectorOptions *options = [[MLKPoseDetectorOptions alloc] init]; options.detectorMode = MLKPoseDetectorModeStream; // Accurate pose detector on static images, when depending on the // PoseDetectionAccurate SDK MLKAccuratePoseDetectorOptions *options = [[MLKAccuratePoseDetectorOptions alloc] init]; options.detectorMode = MLKPoseDetectorModeSingleImage;
Наконец, получите экземпляр PoseDetector. Передайте указанные параметры:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Как подготовить входное изображение
Чтобы обнаружить позы, выполните следующие действия для каждого изображения или кадра видео.
Если вы включили режим потоковой передачи, то должны создать объекты VisionImage из CMSampleBuffer.
Создайте объект VisionImage, используя UIImage или CMSampleBuffer.
Если вы используете UIImage, выполните следующие действия:
- Создайте объект
VisionImageсUIImage. Убедитесь, что вы указали правильное значение параметра.orientation.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Если вы используете CMSampleBuffer, выполните следующие действия:
-
Укажите ориентацию данных изображения, содержащихся в элементе
CMSampleBuffer.Чтобы получить ориентацию изображения:
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; } }
- Создайте объект
VisionImage, используя объектCMSampleBufferи ориентацию: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. Обработка изображения
Передайте VisionImage в один из методов обработки изображений детектора поз. Вы можете использовать асинхронный метод process(image:) или синхронный метод results().
Чтобы распознавать объекты синхронно:
Swift
var results: [Pose] do { results = try poseDetector.results(in: image) } catch let error { print("Failed to detect pose with error: \(error.localizedDescription).") return } guard let detectedPoses = results, !detectedPoses.isEmpty else { print("Pose detector returned no results.") return } // Success. Get pose landmarks here.
Objective-C
NSError *error; NSArray*poses = [poseDetector resultsInImage:image error:&error]; if (error != nil) { // Error. return; } if (poses.count == 0) { // No pose detected. return; } // Success. Get pose landmarks here.
Чтобы обнаружить объекты асинхронно:
Swift
poseDetector.process(image) { detectedPoses, error in guard error == nil else { // Error. return } guard !detectedPoses.isEmpty else { // No pose detected. return } // Success. Get pose landmarks here. }
Objective-C
[poseDetector processImage:image completion:^(NSArray* _Nullable poses, NSError * _Nullable error) { if (error != nil) { // Error. return; } if (poses.count == 0) { // No pose detected. return; } // Success. Get pose landmarks here. }];
4. Как получить информацию об обнаруженной позе
Если на изображении обнаружен человек, API распознавания позы передает массив объектов Pose обработчику завершения или возвращает массив в зависимости от того, какой метод вы вызвали – асинхронный или синхронный.
Если человек не полностью попал в кадр, модель присваивает отсутствующим контрольным точкам координаты за пределами кадра и низкие значения InFrameConfidence.
Если человек не обнаружен, массив пуст.
Swift
for pose in detectedPoses { let leftAnkleLandmark = pose.landmark(ofType: .leftAnkle) if leftAnkleLandmark.inFrameLikelihood > 0.5 { let position = leftAnkleLandmark.position } }
Objective-C
for (MLKPose *pose in detectedPoses) { MLKPoseLandmark *leftAnkleLandmark = [pose landmarkOfType:MLKPoseLandmarkTypeLeftAnkle]; if (leftAnkleLandmark.inFrameLikelihood > 0.5) { MLKVision3DPoint *position = leftAnkleLandmark.position; } }
Советы по повышению эффективности
Качество результатов зависит от качества исходного изображения:
- Чтобы ML Kit мог точно определить позу, человек на изображении должен быть представлен достаточным количеством пикселей. Для оптимальной работы размер объекта должен быть не менее 256 x 256 пикселей.
- Если вы определяете позу в приложении, работающем в реальном времени, вам также следует учитывать общие размеры входных изображений. Небольшие изображения обрабатываются быстрее, поэтому, чтобы уменьшить задержку, снимайте с более низким разрешением. При этом учитывайте указанные выше требования к разрешению и следите за тем, чтобы объект занимал как можно большую часть изображения.
- Точность также может снизиться из-за плохого фокуса. Если результаты вас не устроят, попросите пользователя сделать снимок ещё раз.
Если вы хотите использовать обнаружение поз в приложении, работающем в реальном времени, следуйте приведенным ниже рекомендациям, чтобы достичь наилучшей частоты кадров.
- Используйте базовый SDK PoseDetection и режим обнаружения
stream. - Попробуйте снимать с более низким разрешением. Однако также учитывайте требования к размеру изображений в этом API.
- Для обработки кадров видео используйте синхронный API детектора
results(in:). Вызовите этот метод из функции captureOutput(_, didOutput:from:) протокола AVCaptureVideoDataOutputSampleBufferDelegate, чтобы синхронно получить результаты для заданного видеокадра. Для свойства alwaysDiscardsLateVideoFrames объекта AVCaptureVideoDataOutput должно быть задано значение true, чтобы ограничить количество вызовов детектора. Если во время работы детектора станет доступен новый кадр видео, он будет пропущен. - Если вы используете результаты работы детектора для наложения графики на входное изображение, сначала получите результат от ML Kit, а затем отрисуйте изображение и наложение за один шаг. Таким образом, вы выполняете рендеринг на поверхности отображения только один раз для каждого обработанного входного кадра. Пример можно найти в классах previewOverlayView и MLKDetectionOverlayView в примере приложения.
Дальнейшие действия
- Чтобы узнать, как использовать ориентиры позы для классификации поз, ознакомьтесь с советами по классификации поз.
- Пример использования этого API можно найти в образце быстрого запуска ML Kit на GitHub.