O Kit de ML fornece dois SDKs otimizados para detecção de poses.
Nome do SDK | PoseDetection | PoseDetectionAccurate |
---|---|---|
Implementação | Os recursos do detector de base são vinculados estaticamente ao app no tempo de build. | Os recursos para um detector preciso são vinculados estaticamente ao app no tempo de build. |
Tamanho do app | Até 29,6 MB | Até 33,2 MB |
Desempenho | iPhone X: ~45 QPS | iPhone X: ~29 QPS |
Faça um teste
- Teste o app de exemplo para um exemplo de uso dessa API.
Antes de começar
Inclua os seguintes pods do kit de ML no seu Podfile:
# If you want to use the base implementation: pod 'GoogleMLKit/PoseDetection', '3.2.0' # If you want to use the accurate implementation: pod 'GoogleMLKit/PoseDetectionAccurate', '3.2.0'
Depois de instalar ou atualizar os pods do seu projeto, abra o projeto do Xcode usando o
xcworkspace
. O Kit de ML é compatível com o Xcode versão 13.2.1 ou mais recente.
1. Criar uma instância de PoseDetector
Para detectar uma pose em uma imagem, primeiro crie uma instância de PoseDetector
e
você pode especificar as configurações do detector.
PoseDetector
opções
Modo de detecção
O PoseDetector
opera em dois modos de detecção. Escolha aquela que corresponde
seu caso de uso.
stream
(padrão)- O detector de poses primeiro detectará as pessoa proeminente na imagem e, em seguida, executar a detecção de pose. Nos frames subsequentes, a etapa de detecção de pessoa não será realizada, a menos que a pessoa fique obscurecidas ou não são mais detectadas com alta confiança. O detector de poses tentam rastrear a pessoa mais proeminente e voltar a pose em cada a inferência. Isso reduz a latência e suaviza a detecção. Use esse modo quando quiser detectar a pose em um stream de vídeo.
singleImage
- O detector de poses detectará uma pessoa e executará a pose detecção de ameaças. A etapa de detecção de pessoa será executada para cada imagem, portanto, a latência ser maior e não há rastreamento de pessoas. Usar este modo ao usar a pose detecção em imagens estáticas ou em que o rastreamento não é desejado.
Especifique as opções do detector de poses:
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;
Por fim, receba uma instância de PoseDetector
. Transmita as opções especificadas:
Swift
let poseDetector = PoseDetector.poseDetector(options: options)
Objective-C
MLKPoseDetector *poseDetector = [MLKPoseDetector poseDetectorWithOptions:options];
2. Preparar a imagem de entrada
Para detectar poses, faça o seguinte para cada imagem ou frame de vídeo.
Se você tiver ativado o modo de stream, precisará criar objetos VisionImage
a partir de
CMSampleBuffer
.
Crie um objeto VisionImage
usando um UIImage
ou um
CMSampleBuffer
.
Se você usa um UIImage
, siga estas etapas:
- Crie um objeto
VisionImage
com oUIImage
. Especifique o.orientation
correto.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Se você usa um CMSampleBuffer
, siga estas etapas:
-
Especifique a orientação dos dados da imagem contidos no
CMSampleBuffer
:Para saber qual é a orientação da imagem:
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; } }
- Crie um objeto
VisionImage
usando o Objeto e orientaçãoCMSampleBuffer
: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. Processar a imagem
Transmita VisionImage
para um dos métodos de processamento de imagem do detector de poses. É possível usar o método assíncrono process(image:)
ou o síncrono results()
.
Para detectar objetos de maneira síncrona:
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.
Para detectar objetos de forma assíncrona:
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. Receber informações sobre a pose detectada
Se uma pessoa for detectada na imagem, a API de detecção de pose vai transmitir um
matriz de objetos Pose
para o gerenciador de conclusão ou retorna a matriz,
dependendo se você chamou o método assíncrono ou síncrono.
Se a pessoa não estava totalmente dentro da imagem, o modelo atribui as coordenadas de pontos de referência ausentes fora do frame e a baixa InFrameConfidence.
Se nenhuma pessoa for detectada, a matriz vai estar vazia.
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; } }
Dicas para melhorar o desempenho
A qualidade dos resultados depende da qualidade da imagem de entrada:
- Para que o Kit de ML detecte a pose com precisão, a pessoa na imagem deve ser representada por dados de pixel suficientes; para obter o melhor desempenho, o assunto deve ter pelo menos 256 x 256 pixels.
- Se você detectar a pose em um aplicativo em tempo real, também pode considerar as dimensões gerais das imagens de entrada. Imagens menores podem ser processadas mais rápido, portanto, para reduzir a latência, capture imagens em resoluções mais baixas, mas mantenha os requisitos de resolução acima e garantir que o assunto ocupe o máximo o máximo possível da imagem.
- Uma imagem com foco inadequado também pode afetar a precisão. Se você não receber resultados aceitáveis, peça ao usuário para recapturar a imagem.
Se você quiser usar a detecção de pose em um aplicativo em tempo real, siga estas diretrizes para ter as melhores taxas de frames:
- Usar o SDK do PoseDetection básico e o modo de detecção
stream
. - Capture imagens em uma resolução mais baixa. No entanto, lembre-se também dos requisitos de dimensão de imagem dessa API.
- Para processar frames de vídeo, use a API síncrona
results(in:)
do detector. Chame esse método no objeto AVCaptureVideoDataOutputSampleBufferDelegate. Função captureOutput(_, didOutput:from:) para receber os resultados do frame de vídeo de forma síncrona. Mantenha o alwaysDiscardsLateVideoFrames de AVCaptureVideoDataOutput como verdadeiro para limitar as chamadas ao detector. Se um novo quadro de vídeo ficar disponível enquanto o detector estiver em execução, ele será descartado. - Se você usar a saída do detector para sobrepor elementos gráficos na imagem de entrada, primeiro acesse o resultado do kit de ML e, em seguida, renderize a imagem e a sobreposição em uma única etapa. Ao fazer isso, você renderiza a superfície de exibição apenas uma vez para cada frame de entrada processado. Consulte a previewOverlayView e MLKDetectionOverlayView no app de exemplo da demonstração.
Próximas etapas
- Para aprender a usar pontos de referência de poses para classificar poses, consulte Dicas de classificação de posições.
- Consulte a amostra do guia de início rápido do Kit de ML no GitHub para ver um exemplo dessa API em uso.