Use o Kit de ML para detectar rostos em imagens e vídeos.
Antes de começar
- Se você ainda não adicionou o Firebase ao seu app, siga as etapas no guia de iniciação.
- Inclua as bibliotecas do Kit de ML no seu Podfile:
pod 'Firebase/MLVision', '6.25.0' # If you want to detect face contours (landmark detection and classification # don't require this additional model): pod 'Firebase/MLVisionFaceModel', '6.25.0'
Depois de instalar ou atualizar os pods do projeto, abra o projeto do Xcode usando o.xcworkspace
. - Importe o Firebase para seu app:
Swift
import Firebase
Objective-C
@import Firebase;
Diretrizes de imagem de entrada
Para que o Kit de ML detecte rostos com precisão, as imagens de entrada devem conter rostos representados por dados de pixel suficientes. Em geral, cada rosto que você quiser detectar em uma imagem deverá ter pelo menos 100x100 pixels. Se você quiser detectar os contornos dos rostos, o Kit de ML precisará de uma entrada de resolução mais alta: cada rosto deverá ter pelo menos 200x200 pixels.
Se você estiver fazendo a detecção facial em um aplicativo em tempo real, considere as dimensões gerais das imagens de entrada. Já que as imagens menores podem ser processadas mais rapidamente, reduza a latência capturando imagens em resoluções menores (lembrando os requisitos de precisão acima) e faça o rosto da pessoa ocupar o máximo possível da imagem. Consulte também Dicas para melhorar o desempenho em tempo real.
Uma imagem com foco inadequado pode prejudicar a precisão. Se os resultados não forem aceitáveis, peça para o usuário recapturar a imagem.
A orientação de um rosto em relação à câmera também pode afetar os atributos faciais que o Kit de ML detecta. Veja Conceitos de detecção facial.
1. Configurar o detector facial
Antes de aplicar a detecção facial a uma imagem, especifique essas configurações com um objetoVisionFaceDetectorOptions
se quiser alterar qualquer uma delas. É possível alterar
as seguintes configurações:
Configurações | |
---|---|
performanceMode |
fast (padrão) | accurate
Favoreça a velocidade ou a precisão durante a detecção facial. |
landmarkMode |
none (padrão) | all
Para tentar detectar "pontos de referência" faciais de todos os rostos detectados: olhos, orelhas, nariz, bochechas ou boca. |
contourMode |
none (padrão) | all
Para detectar os contornos dos atributos faciais. São detectados apenas os contornos do rosto mais proeminente de uma imagem. |
classificationMode |
none (padrão) | all
Se é necessário classificar faces em categorias como "sorrindo" e "olhos abertos". |
minFaceSize |
CGFloat (padrão: 0.1 )
O tamanho mínimo, relativo à imagem, de rostos a serem detectados. |
isTrackingEnabled |
false (padrão) | true
Atribuir ou não IDs, que podem ser usados para rastrear rostos em imagens. Quando a detecção de contorno está ativada, apenas um rosto é detectado, portanto, o rastreamento facial não produz resultados úteis. Por esse motivo, e para melhorar a velocidade de detecção, não ative a detecção de contorno simultaneamente com o rastreamento facial. |
Por exemplo, crie um objeto VisionFaceDetectorOptions
como um dos seguintes exemplos:
Swift
// High-accuracy landmark detection and face classification let options = VisionFaceDetectorOptions() options.performanceMode = .accurate options.landmarkMode = .all options.classificationMode = .all // Real-time contour detection of multiple faces let options = VisionFaceDetectorOptions() options.contourMode = .all
Objective-C
// High-accuracy landmark detection and face classification FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init]; options.performanceMode = FIRVisionFaceDetectorPerformanceModeAccurate; options.landmarkMode = FIRVisionFaceDetectorLandmarkModeAll; options.classificationMode = FIRVisionFaceDetectorClassificationModeAll; // Real-time contour detection of multiple faces FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init]; options.contourMode = FIRVisionFaceDetectorContourModeAll;
2. Executar o detector facial
Para detectar rostos em uma imagem, transmita a imagem comoUIImage
ou CMSampleBufferRef
para o método detect(in:)
do VisionFaceDetector
:
- Consiga uma instância de
VisionFaceDetector
:Swift
lazy var vision = Vision.vision() let faceDetector = vision.faceDetector(options: options)
Objective-C
FIRVision *vision = [FIRVision vision]; FIRVisionFaceDetector *faceDetector = [vision faceDetector]; // Or, to change the default settings: // FIRVisionFaceDetector *faceDetector = // [vision faceDetectorWithOptions:options];
-
Crie um objeto
VisionImage
usando umUIImage
ou umCMSampleBufferRef
.Para usar um
UIImage
:- Se necessário, gire a imagem para que a propriedade
imageOrientation
seja.up
. - Crie um objeto
VisionImage
usando aUIImage
com a rotação correta. Não especifique metadados de rotação: o valor padrão,.topLeft
, precisa ser usado.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Para usar um
CMSampleBufferRef
:-
Crie um objeto
VisionImageMetadata
que especifique a orientação dos dados da imagem contidos no bufferCMSampleBufferRef
.Para ver a orientação da imagem:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> VisionDetectorImageOrientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftTop : .rightTop case .landscapeLeft: return cameraPosition == .front ? .bottomLeft : .topLeft case .portraitUpsideDown: return cameraPosition == .front ? .rightBottom : .leftBottom case .landscapeRight: return cameraPosition == .front ? .topRight : .bottomRight case .faceDown, .faceUp, .unknown: return .leftTop } }
Objective-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
Em seguida, crie o objeto de metadados:
Swift
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objective-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
- Crie um objeto
VisionImage
usando o objetoCMSampleBufferRef
e os metadados de rotação:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Se necessário, gire a imagem para que a propriedade
-
Em seguida, transmita a imagem para o método
detect(in:)
:Swift
faceDetector.process(visionImage) { faces, error in guard error == nil, let faces = faces, !faces.isEmpty else { // ... return } // Faces detected // ... }
Objective-C
[faceDetector detectInImage:image completion:^(NSArray<FIRVisionFace *> *faces, NSError *error) { if (error != nil) { return; } else if (faces != nil) { // Recognized faces } }];
3. Receber informações sobre rostos detectados
Se a operação de detecção facial for bem-sucedida, o detector facial transmitirá uma matriz de objetosVisionFace
para o gerenciador de conclusão. Cada
objeto VisionFace
representa um rosto detectado na imagem. Para
cada rosto, é possível receber as coordenadas delimitadoras na imagem de entrada, além de
qualquer outra informação configurada no detector facial a ser encontrada. Por exemplo:
Swift
for face in faces { let frame = face.frame if face.hasHeadEulerAngleY { let rotY = face.headEulerAngleY // Head is rotated to the right rotY degrees } if face.hasHeadEulerAngleZ { let rotZ = face.headEulerAngleZ // Head is rotated upward 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 (FIRVisionFace *face in faces) { // Boundaries of face in image CGRect frame = face.frame; 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): FIRVisionFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar]; if (leftEar != nil) { FIRVisionPoint *leftEarPosition = leftEar.position; } // If contour detection was enabled: FIRVisionFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom]; if (upperLipBottomContour != nil) { NSArray<FIRVisionPoint *> *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 traço facial detectado. Esses pontos representam a forma do traço. Consulte a Visão geral dos conceitos de detecção facial para ver detalhes sobre como os contornos são representados.
A imagem a seguir ilustra como esses pontos mapeiam um rosto. Clique nela para ampliar:
Detecção facial em tempo real
Se você quiser usar a detecção facial em um aplicativo em tempo real, siga estas diretrizes para conseguir as melhores taxas de frames:
Configure o detector facial para usar a detecção de contorno facial ou a classificação e a detecção de pontos de referência, mas não os dois:
Detecção de contornos
Detecção de pontos de referência
Classificação
Detecção e classificação de pontos de referência
Detecção de contornos e detecção de pontos de referência
Detecção e classificação de contornos
Detecção de contornos, detecção de pontos de referência e classificaçãoAtive o modo
fast
(ativado por padrão).Capture imagens em uma resolução menor. No entanto, lembre-se também dos requisitos de dimensão de imagem da API.
- Limite as chamadas ao detector. Se um novo frame de vídeo ficar disponível durante a execução do detector, descarte esse frame.
- Se você estiver usando a saída do detector para sobrepor elementos gráficos na imagem de entrada, primeiro acesse o resultado do Kit de ML. Em seguida, renderize a imagem e faça a sobreposição de uma só vez. Ao fazer isso, você renderiza a superfície de exibição apenas uma vez para cada frame de entrada. Consulte as classes previewOverlayView e FIRDetectionOverlayView no app de exemplo da demonstração.