Puoi utilizzare ML Kit per rilevare i volti nelle immagini e nel video.
Prova subito
- Prova l'app di esempio per vedere un esempio di utilizzo di questa API.
- Prova il codice autonomamente con il codelab.
Prima di iniziare
- Includi i seguenti pod di ML Kit nel tuo podfile:
pod 'GoogleMLKit/FaceDetection', '3.2.0'
- Dopo aver installato o aggiornato i pod del progetto, apri il progetto Xcode utilizzando
.xcworkspace
. ML Kit è supportato in Xcode versione 12.4 o successiva.
Linee guida sull'immagine di input
Per il riconoscimento dei volti, devi utilizzare un'immagine di dimensioni di almeno 480 x 360 pixel. Affinché ML Kit possa rilevare con precisione i volti, le immagini di input devono contenere volti rappresentati da dati Pixel sufficienti. In generale, ogni volto che vuoi rilevare in un'immagine deve essere di almeno 100x100 pixel. Se vuoi rilevare i contorni dei volti, ML Kit richiede un input di risoluzione più elevata: ogni volto deve essere di almeno 200x200 pixel.
Se rilevi i volti in un'applicazione in tempo reale, puoi anche prendere in considerazione le dimensioni complessive delle immagini di input. Le immagini più piccole possono essere elaborate più rapidamente, quindi per ridurre la latenza, acquisisci immagini a risoluzioni inferiori, ma tieni presente i requisiti di accuratezza sopra riportati e assicurati che il volto del soggetto occupi la maggiore quantità possibile di immagini. Consulta anche i suggerimenti per migliorare le prestazioni in tempo reale.
Una messa a fuoco dell'immagine scadente può anche influire sulla precisione. Se non ottieni risultati accettabili, chiedi all'utente di riprendere l'immagine.
L'orientamento di un volto rispetto alla fotocamera può influire sulle caratteristiche del viso rilevate da ML Kit. Consulta Concetti sul rilevamento dei volti.
1. Configura il rilevatore del volto
Prima di applicare il rilevamento dei volti a un'immagine, se vuoi modificare le impostazioni predefinite del rilevatore del volto, specificale con un oggettoFaceDetectorOptions
. Puoi modificare le seguenti impostazioni:
Impostazioni | |
---|---|
performanceMode |
fast (valore predefinito) | accurate
Favorisci la velocità o l'accuratezza nel rilevamento dei volti. |
landmarkMode |
none (valore predefinito) | all
Consente di specificare se cercare o meno di rilevare i "segnali" facciali (occhio, orecchie, naso, guance, bocca) di tutti i volti rilevati. |
contourMode |
none (valore predefinito) | all
Consente di stabilire se rilevare i contorni delle caratteristiche del viso. I contorni vengono rilevati solo per il volto più in evidenza in un'immagine. |
classificationMode |
none (valore predefinito) | all
Consente di specificare se classificare o meno i volti in categorie quali "sorriso" e "occhio aperto". |
minFaceSize |
CGFloat (valore predefinito: 0.1 )
Consente di impostare la dimensione minima del volto, espressa come rapporto tra la larghezza della testa e la larghezza dell'immagine. |
isTrackingEnabled |
false (valore predefinito) | true
Consente di specificare se assegnare o meno i volti a un ID, che può essere utilizzato per monitorare i volti nelle immagini. Tieni presente che quando viene attivato il rilevamento dei contorni, viene rilevato un solo volto, quindi il monitoraggio dei volti non produce risultati utili. Per questo motivo e per migliorare la velocità di rilevamento, non attivare il rilevamento dei contorni e il monitoraggio dei volti. |
Ad esempio, crea un oggetto FaceDetectorOptions
come nel seguente esempio:
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. Prepara l'immagine di input
Per rilevare i volti in un'immagine, passa l'immagine comeUIImage
o
CMSampleBufferRef
a FaceDetector
utilizzando il metodo
process(_:completion:)
o results(in:)
:
Crea un oggetto VisionImage
utilizzando un UIImage
o un
CMSampleBuffer
.
Se utilizzi un UIImage
, segui questi passaggi:
- Crea un oggetto
VisionImage
con ilUIImage
. Assicurati di specificare il.orientation
corretto.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Se utilizzi un CMSampleBuffer
, segui questi passaggi:
-
Specifica l'orientamento dei dati dell'immagine contenuti in
CMSampleBuffer
.Per ottenere l'orientamento dell'immagine:
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; } }
- Crea un oggetto
VisionImage
utilizzando l'oggetto e l'orientamentoCMSampleBuffer
: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. Ottieni un'istanza di FaceDetector
Ottieni un'istanza di FaceDetector
:
Swift
let faceDetector = FaceDetector.faceDetector(options: options)
Objective-C
MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
4. Elabora immagine
Quindi, passa l'immagine al metodoprocess()
:
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. Visualizzare le informazioni sui volti rilevati
Se l'operazione di rilevamento dei volti ha esito positivo, il rilevatore trasmette un array di oggettiFace
al gestore di completamento. Ogni oggetto Face
rappresenta un volto rilevato nell'immagine. Per ogni volto, puoi visualizzarne le coordinate di delimitazione nell'immagine di input, nonché eventuali altre informazioni che hai configurato per il rilevamento del volto. Ad esempio:
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; } }
Esempio di contorni del volto
Se hai attivato il rilevamento dei contorni del volto, ricevi un elenco di punti per ogni caratteristica del viso che è stata rilevata. Questi punti rappresentano la forma della funzionalità. Consulta la pagina Concetti sul rilevamento dei volti per maggiori dettagli su come vengono rappresentati i contorni.
La seguente immagine illustra come questi punti vengono mappati a un volto, fai clic sull'immagine per ingrandirla:
Rilevamento dei volti in tempo reale
Se vuoi utilizzare il rilevamento dei volti in un'applicazione in tempo reale, segui queste linee guida per ottenere la migliore frequenza fotogrammi:
Configura il rilevatore del volto in modo che utilizzi il rilevamento o la classificazione dei contorni del volto e il rilevamento dei punti di riferimento, ma non entrambi:
Rilevamento del profilo
Rilevamento del punto di riferimento
Classificazione
Rilevamento e classificazione del profilo
Rilevamento del profilo e rilevamento del punto di riferimento
Rilevamento e classificazione del profilo
Rilevamento del profilo, rilevamento del punto di riferimento e classificazioneAttiva la modalità
fast
(attiva per impostazione predefinita).Potresti acquisire immagini a una risoluzione inferiore. Tuttavia, tieni presente anche i requisiti per le dimensioni delle immagini di questa API.
- Per l'elaborazione dei frame video, utilizza l'API sincrona
results(in:)
del rilevatore. Richiama questo metodo dalla funzionecaptureOutput(_, didOutput:from:)
diAVCaptureVideoDataOutputSampleBufferDelegate
per ottenere in modo sincrono i risultati dal frame video specificato. MantienialwaysDiscardsLateVideoFrames
diAVCaptureVideoDataOutput
cometrue
per limitare le chiamate al rilevatore. Se un nuovo video diventa disponibile mentre il rilevatore è in esecuzione, viene eliminato. - Se utilizzi l'output del rilevatore per sovrapporre la grafica all'immagine di input, prima ottieni il risultato da ML Kit, quindi visualizza l'immagine e l'overlay in un solo passaggio. In questo modo, visualizzerai nella piattaforma display solo una volta per ogni frame di input elaborato. Guarda un esempio di updateAnteprimaOverlayViewWithLastFrame nell'esempio della guida rapida di ML Kit.