Puoi utilizzare ML Kit per rilevare i volti nelle immagini e nei video.
Prova
- Prova l'app di esempio per vedere un utilizzo di esempio di questa API.
- Prova a utilizzare il codice autonomamente con il codelab.
Prima di iniziare
- Includi i seguenti pod ML Kit nel podfile:
pod 'GoogleMLKit/FaceDetection', '3.2.0'
- Dopo aver installato o aggiornato i pod del progetto, apri il progetto Xcode utilizzando il relativo
.xcworkspace
. ML Kit è supportato in Xcode versione 12.4 o successiva.
Linee guida per l'immagine di input
Per il riconoscimento facciale, devi utilizzare un'immagine di almeno 480 x 360 pixel. Affinché ML Kit possa rilevare con precisione i volti, le immagini di input devono contenere volti rappresentati da sufficienti dati di pixel. In generale, ogni volto da rilevare in un'immagine deve essere di almeno 100 x 100 pixel. Se vuoi rilevare i contorni dei volti, ML Kit richiede un input di risoluzione più elevato: ogni faccia deve essere di almeno 200 x 200 pixel.
Se rilevi i volti in un'applicazione in tempo reale, puoi anche considerare le dimensioni complessive delle immagini di input. Le immagini più piccole possono essere elaborate più velocemente, quindi per ridurre la latenza, acquisisci immagini a risoluzioni più basse, ma tieni presente i requisiti di accuratezza sopra indicati e assicurati che il volto del soggetto occupi la maggior parte dell'immagine possibile. Consulta anche i suggerimenti per migliorare il rendimento in tempo reale.
Anche una scarsa messa a fuoco dell'immagine può influire sulla precisione. Se non ottieni risultati accettabili, chiedi all'utente di acquisire nuovamente l'immagine.
Anche l'orientamento del volto rispetto alla videocamera può influire sulle caratteristiche facciali rilevate da ML Kit. Consulta i concetti del rilevamento facciale.
1. Configura il rilevatore di volti
Prima di applicare il rilevamento dei volti a un'immagine, se vuoi modificare una qualsiasi delle impostazioni predefinite del rilevatore di volti, specifica queste impostazioni con un oggettoFaceDetectorOptions
. Puoi modificare le seguenti impostazioni:
Impostazioni | |
---|---|
performanceMode |
fast (valore predefinito) | accurate
Favorire la velocità o la precisione durante il rilevamento dei volti. |
landmarkMode |
none (valore predefinito) | all
Indica se tentare di rilevare i "punti di riferimento" facciali (occhi, orecchie, naso, guance, bocca) di tutti i volti rilevati. |
contourMode |
none (valore predefinito) | all
Indica 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
Indica se classificare o meno i volti in categorie come "sorridente" e "occhi aperti". |
minFaceSize |
CGFloat (valore predefinito: 0.1 )
Imposta le dimensioni minime del volto, espresse come rapporto tra la larghezza della testa e la larghezza dell'immagine. |
isTrackingEnabled |
false (valore predefinito) | true
Indica se assegnare o meno un ID per i volti, che può essere utilizzato per tracciare i volti nelle immagini. Tieni presente che quando è abilitato 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 sia il rilevamento dei contorni che il rilevamento dei volti. |
Ad esempio, crea un oggetto FaceDetectorOptions
come in uno dei seguenti esempi:
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 UIImage
o CMSampleBuffer
.
Se usi un UIImage
, segui questi passaggi:
- Crea un oggetto
VisionImage
con ilUIImage
. Assicurati di specificare il valore.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 usi un CMSampleBuffer
, segui questi passaggi:
-
Specifica l'orientamento dei dati 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'oggettoCMSampleBuffer
e l'orientamento: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 l'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. Ricevere informazioni sui volti rilevati
Se il rilevamento dei volti ha esito positivo, il rilevatore passa un array di oggettiFace
al gestore del completamento. Ogni oggetto Face
rappresenta un volto rilevato nell'immagine. Per ogni volto, puoi ottenere le coordinate di delimitazione nell'immagine di input, nonché qualsiasi altra informazione trovata dal rilevatore di volti. 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 è attivo il rilevamento dei contorni del volto, viene visualizzato un elenco di punti per ogni caratteristica del volto rilevata. Questi punti rappresentano la forma dell'elemento. Per informazioni dettagliate su come vengono rappresentati i contorni, consulta la sezione Concetti di rilevamento facciale.
L'immagine seguente illustra come questi punti vengano 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 le frequenze fotogrammi ottimali:
Configura il rilevatore di volti in modo che utilizzi il rilevamento o la classificazione dei volti e il rilevamento dei punti di riferimento, ma non entrambi:
Rilevamento dei contorni
Rilevamento dei punti di riferimento
Classificazione
Rilevamento e classificazione dei punti di riferimento
Rilevamento e rilevamento dei punti di riferimento
Rilevamento e classificazione dei contorni
Rilevamento e classificazione dei punti di riferimento
Rilevamento dei contorni, rilevamento e classificazione dei punti di riferimentoAttiva la modalità
fast
(attivata per impostazione predefinita).Valuta la possibilità di acquisire immagini a una risoluzione più bassa. Tuttavia, tieni presente anche i requisiti di dimensione delle immagini di questa API.
- Per elaborare i fotogrammi 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. Mantieni il valoretrue
peralwaysDiscardsLateVideoFrames
diAVCaptureVideoDataOutput
per limitare le chiamate al rilevatore. Se un nuovo frame video diventa disponibile mentre il rilevatore è in esecuzione, questo verrà eliminato. - Se utilizzi l'output del rilevatore per sovrapporre gli elementi grafici all'immagine di input, recupera prima il risultato da ML Kit, quindi esegui il rendering dell'immagine e dell'overlay in un solo passaggio. In questo modo, esegui il rendering sulla piattaforma di visualizzazione solo una volta per ogni frame di input elaborato. Per un esempio, vedi updatePreviewOverlayViewWithLastFrame nell'esempio della guida rapida di ML Kit.