Você pode usar o Kit de ML para detectar rostos em imagens e vídeos.
Faça um teste
- Teste o app de exemplo para um exemplo de uso dessa API.
- Experimente o código com a codelab.
Antes de começar
- Inclua os seguintes pods do kit de ML no seu Podfile:
pod 'GoogleMLKit/FaceDetection', '15.5.0'
- Depois de instalar ou atualizar os pods do seu projeto, abra o projeto Xcode usando o
.xcworkspace
: O Kit de ML é compatível com a versão 12.4 ou mais recente do Xcode.
Diretrizes de imagens de entrada
Para reconhecimento facial, você deve usar uma imagem com dimensões de pelo menos 480 x 360 pixels. Para que o Kit de ML detecte rostos com precisão, as imagens de entrada precisam conter rostos representados por dados de pixel suficientes. Em geral, cada rosto que você quer para detectar em uma imagem deve ter pelo menos 100 x 100 pixels. Se você quiser detectar os contornos dos rostos, o kit de ML exige uma entrada de resolução mais alta: cada rosto deve ter pelo menos 200 x 200 pixels.
Se você detectar rostos em um aplicativo em tempo real, também pode querer considere as dimensões gerais das imagens de entrada. Imagens menores podem ser processados mais rapidamente, por isso, para reduzir a latência, capture imagens em resoluções mais baixas, mas os requisitos de precisão acima e garantir que os o rosto da pessoa ocupa o máximo possível da imagem. Consulte também dicas para melhorar o desempenho em tempo real.
Uma imagem com foco inadequado também pode afetar a precisão. Caso o conteúdo não seja aceito peça ao usuário para recapturar a imagem.
A orientação de um rosto em relação à câmera também pode afetar características de atributos que o kit de ML detecta. Consulte Conceitos de detecção facial.
1. Configurar o detector facial
Antes de aplicar a detecção facial a uma imagem, se você quiser alterar padrão do detector facial, especifique essas configurações com uma ObjetoFaceDetectorOptions
. É possível mudar
as seguintes configurações:
Configurações | |
---|---|
performanceMode |
fast (padrão) | accurate
Favoreça a velocidade ou a precisão ao detectar rostos. |
landmarkMode |
none (padrão) | all
Para tentar detectar os "pontos de referência" faciais, como olhos, orelhas, nariz, bochechas, boca — de todos os rostos detectados. |
contourMode |
none (padrão) | all
Para detectar os contornos das características faciais. Contornos são detectado apenas no rosto mais proeminente da imagem. |
classificationMode |
none (padrão) | all
Se é necessário classificar rostos em categorias como "sorrindo" e "de olhos abertos". |
minFaceSize |
CGFloat (padrão: 0.1 )
Define o menor tamanho facial desejado, expresso como a proporção do largura da cabeça com a largura da imagem. |
isTrackingEnabled |
false (padrão) | true
Se deve ou não atribuir um ID aos rostos, que pode ser usado para rastrear rostos nas imagens. Quando a detecção de contorno está ativada, apenas um rosto detectado. Por isso, o rastreamento facial não produz resultados úteis. Para isso e, para melhorar a velocidade de detecção, não ative as duas opções detecção e rastreamento facial. |
Por exemplo, crie um objeto FaceDetectorOptions
como um dos seguintes exemplos:
Swift
// High-accuracy landmark detection and face classification let options = FaceDetectorOptions() options.performanceMode = .accurate options.landmarkMode = .all options.classificationMode = .all // Real-time contour detection of multiple faces // options.contourMode = .all
Objective-C
// High-accuracy landmark detection and face classification MLKFaceDetectorOptions *options = [[MLKFaceDetectorOptions alloc] init]; options.performanceMode = MLKFaceDetectorPerformanceModeAccurate; options.landmarkMode = MLKFaceDetectorLandmarkModeAll; options.classificationMode = MLKFaceDetectorClassificationModeAll; // Real-time contour detection of multiple faces // options.contourMode = MLKFaceDetectorContourModeAll;
2. Preparar a imagem de entrada
Para detectar rostos em uma imagem, transmita a imagem comoUIImage
ou
CMSampleBufferRef
para FaceDetector
usando o
Método process(_:completion:)
ou results(in:)
:
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. Receber uma instância do FaceDetector
Receba uma instância de FaceDetector
:
Swift
let faceDetector = FaceDetector.faceDetector(options: options)
Objective-C
MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
4. Processar a imagem
Em seguida, transmita a imagem para o métodoprocess()
:
Swift
weak var weakSelf = self faceDetector.process(visionImage) { faces, error in guard let strongSelf = weakSelf else { print("Self is nil!") return } guard error == nil, let faces = faces, !faces.isEmpty else { // ... return } // Faces detected // ... }
Objective-C
[faceDetector processImage:image completion:^(NSArray<MLKFace *> *faces, NSError *error) { if (error != nil) { return; } if (faces.count > 0) { // Recognized faces } }];
5. Receber informações sobre rostos detectados
Se a operação de detecção facial for bem-sucedida, o detector vai transmitir uma matriz. de objetosFace
para o gerenciador de conclusão. Cada
O objeto Face
representa um rosto que foi detectado na imagem. Para
cada rosto, é possível obter as coordenadas delimitadoras na imagem de entrada, bem como
qualquer outra informação configurada para ser encontrada pelo detector facial. Exemplo:
Swift
for face in faces { let frame = face.frame if face.hasHeadEulerAngleX { let rotX = face.headEulerAngleX // Head is rotated to the uptoward rotX degrees } if face.hasHeadEulerAngleY { let rotY = face.headEulerAngleY // Head is rotated to the right rotY degrees } if face.hasHeadEulerAngleZ { let rotZ = face.headEulerAngleZ // Head is tilted sideways rotZ degrees } // If landmark detection was enabled (mouth, ears, eyes, cheeks, and // nose available): if let leftEye = face.landmark(ofType: .leftEye) { let leftEyePosition = leftEye.position } // If contour detection was enabled: if let leftEyeContour = face.contour(ofType: .leftEye) { let leftEyePoints = leftEyeContour.points } if let upperLipBottomContour = face.contour(ofType: .upperLipBottom) { let upperLipBottomPoints = upperLipBottomContour.points } // If classification was enabled: if face.hasSmilingProbability { let smileProb = face.smilingProbability } if face.hasRightEyeOpenProbability { let rightEyeOpenProb = face.rightEyeOpenProbability } // If face tracking was enabled: if face.hasTrackingID { let trackingId = face.trackingID } }
Objective-C
for (MLKFace *face in faces) { // Boundaries of face in image CGRect frame = face.frame; if (face.hasHeadEulerAngleX) { CGFloat rotX = face.headEulerAngleX; // Head is rotated to the upward rotX degrees } if (face.hasHeadEulerAngleY) { CGFloat rotY = face.headEulerAngleY; // Head is rotated to the right rotY degrees } if (face.hasHeadEulerAngleZ) { CGFloat rotZ = face.headEulerAngleZ; // Head is tilted sideways rotZ degrees } // If landmark detection was enabled (mouth, ears, eyes, cheeks, and // nose available): MLKFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar]; if (leftEar != nil) { MLKVisionPoint *leftEarPosition = leftEar.position; } // If contour detection was enabled: MLKFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom]; if (upperLipBottomContour != nil) { NSArray<MLKVisionPoint *> *upperLipBottomPoints = upperLipBottomContour.points; if (upperLipBottomPoints.count > 0) { NSLog("Detected the bottom contour of the subject's upper lip.") } } // If classification was enabled: if (face.hasSmilingProbability) { CGFloat smileProb = face.smilingProbability; } if (face.hasRightEyeOpenProbability) { CGFloat rightEyeOpenProb = face.rightEyeOpenProbability; } // If face tracking was enabled: if (face.hasTrackingID) { NSInteger trackingID = face.trackingID; } }
Exemplo de contornos faciais
Quando a detecção de contorno facial está ativada, você recebe uma lista de pontos para cada característica facial que foi detectada. Esses pontos representam a forma . Ver Rosto de detecção para detalhes sobre como os contornos representados.
A imagem a seguir ilustra como esses pontos mapeiam um rosto. Clique no imagem para ampliá-la:
Detecção facial em tempo real
Se você quiser usar a detecção facial em um aplicativo em tempo real, siga estas diretrizes para obter as melhores taxas de quadros:
Configure o detector facial para usar detecção de contorno facial ou classificação e detecção de pontos de referência, mas não os dois:
Detecção de contorno
Detecção de pontos de referência
Classificação
Detecção e classificação de pontos de referência
Detecção de contorno e detecção de pontos de referência
Detecção e classificação de contorno
Detecção de contorno, detecção de pontos de referência e classificaçãoAtive o modo
fast
(ativado por padrão).Capture imagens em uma resolução mais baixa. No entanto, também tenha em mente os requisitos de dimensão de imagem dessa API.
- Para processar frames de vídeo, use a API síncrona
results(in:)
do detector. Ligação esse método daAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
para receber resultados do vídeo fornecido de forma síncrona frame. Manter deAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
comotrue
para limitar as chamadas ao detector. Se um novo frame 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 a imagem de entrada, primeiro acesse o resultado do Kit de ML e, em seguida, renderize a imagem e 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. Veja a classe updatePreviewOverlayViewWithLastFrame na amostra do guia de início rápido do Kit de ML.