Puoi utilizzare ML Kit per rilevare i volti nelle immagini e nei video.
Prima di iniziare
- Se non hai già aggiunto Firebase alla tua app, fallo seguendo i passaggi nella guida introduttiva .
- Includi le librerie ML Kit nel tuo 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'
Dopo aver installato o aggiornato i Pod del tuo progetto, assicurati di aprire il tuo progetto Xcode utilizzando il relativo.xcworkspace
. - Nella tua app, importa Firebase:
Veloce
import Firebase
Obiettivo-C
@import Firebase;
Inserisci le linee guida per l'immagine
Affinché ML Kit rilevi con precisione i volti, le immagini di input devono contenere volti rappresentati da dati pixel sufficienti. In generale, ogni volto che desideri rilevare in un'immagine dovrebbe essere di almeno 100x100 pixel. Se desideri rilevare i contorni dei volti, ML Kit richiede un input con una risoluzione più elevata: ogni volto deve essere di almeno 200x200 pixel.
Se stai rilevando volti in un'applicazione in tempo reale, potresti anche voler considerare le dimensioni complessive delle immagini di input. Le immagini più piccole possono essere elaborate più velocemente, quindi per ridurre la latenza, acquisire immagini a risoluzioni inferiori (tenendo presente i requisiti di precisione di cui sopra) e garantire che il volto del soggetto occupi la maggior parte possibile dell'immagine. Vedi anche Suggerimenti per migliorare le prestazioni in tempo reale .
Una scarsa messa a fuoco dell'immagine può compromettere la precisione. Se non ottieni risultati accettabili, prova a chiedere all'utente di acquisire nuovamente l'immagine.
Anche l'orientamento di un volto rispetto alla fotocamera può influenzare le caratteristiche facciali rilevate da ML Kit. Vedere Concetti di rilevamento dei volti .
1. Configura il rilevatore di volti
Prima di applicare il rilevamento dei volti a un'immagine, se desideri modificare una qualsiasi delle impostazioni predefinite del rilevatore di volti, specifica tali impostazioni con un oggettoVisionFaceDetectorOptions
. È possibile modificare le seguenti impostazioni:Impostazioni | |
---|---|
performanceMode | fast (predefinito) | accurate Privilegia la velocità o la precisione nel rilevamento dei volti. |
landmarkMode | none (predefinito) | all Se tentare di rilevare i "punti di riferimento" facciali (occhi, orecchie, naso, guance, bocca) di tutti i volti rilevati. |
contourMode | none (predefinito) | all Se rilevare i contorni dei tratti del viso. I contorni vengono rilevati solo per il volto più prominente in un'immagine. |
classificationMode | none (predefinito) | all Se classificare o meno i volti in categorie come "sorridente" e "occhi aperti". |
minFaceSize | CGFloat (predefinito: 0.1 )La dimensione minima, relativa all'immagine, dei volti da rilevare. |
isTrackingEnabled | false (predefinito) | true Se assegnare o meno ai volti un ID, che può essere utilizzato per tracciare i volti nelle immagini. Tieni presente che quando il rilevamento dei contorni è abilitato, viene rilevato solo un volto, quindi il rilevamento dei volti non produce risultati utili. Per questo motivo, e per migliorare la velocità di rilevamento, non abilitare sia il rilevamento dei contorni che il tracciamento del volto. |
Ad esempio, crea un oggetto VisionFaceDetectorOptions
come uno dei seguenti esempi:
Veloce
// 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
Obiettivo-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. Eseguire il rilevatore di volti
Per rilevare i volti in un'immagine, passa l'immagine comeUIImage
o CMSampleBufferRef
al metodo detect(in:)
di VisionFaceDetector
:- Ottieni un'istanza di
VisionFaceDetector
:Veloce
lazy var vision = Vision.vision() let faceDetector = vision.faceDetector(options: options)
Obiettivo-C
FIRVision *vision = [FIRVision vision]; FIRVisionFaceDetector *faceDetector = [vision faceDetector]; // Or, to change the default settings: // FIRVisionFaceDetector *faceDetector = // [vision faceDetectorWithOptions:options];
Crea un oggetto
VisionImage
utilizzandoUIImage
oCMSampleBufferRef
.Per utilizzare un'immagine
UIImage
:- Se necessario, ruotare l'immagine in modo che la relativa proprietà
imageOrientation
sia.up
. - Crea un oggetto
VisionImage
utilizzandoUIImage
ruotato correttamente. Non specificare alcun metadato di rotazione: è necessario utilizzare il valore predefinito,.topLeft
.Veloce
let image = VisionImage(image: uiImage)
Obiettivo-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Per utilizzare un
CMSampleBufferRef
:Crea un oggetto
VisionImageMetadata
che specifica l'orientamento dei dati dell'immagine contenuti nel bufferCMSampleBufferRef
.Per ottenere l'orientamento dell'immagine:
Veloce
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 } }
Obiettivo-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; } }
Quindi, crea l'oggetto metadati:
Veloce
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Obiettivo-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];
- Crea un oggetto
VisionImage
utilizzando l'oggettoCMSampleBufferRef
e i metadati di rotazione:Veloce
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Obiettivo-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Se necessario, ruotare l'immagine in modo che la relativa proprietà
- Quindi, passa l'immagine al metodo
detect(in:)
:Veloce
faceDetector.process(visionImage) { faces, error in guard error == nil, let faces = faces, !faces.isEmpty else { // ... return } // Faces detected // ... }
Obiettivo-C
[faceDetector detectInImage:image completion:^(NSArray<FIRVisionFace *> *faces, NSError *error) { if (error != nil) { return; } else if (faces != nil) { // Recognized faces } }];
3. Ottieni informazioni sui volti rilevati
Se l'operazione di rilevamento dei volti ha esito positivo, il rilevatore di volti passa una serie di oggettiVisionFace
al gestore di completamento. Ogni oggetto VisionFace
rappresenta un volto rilevato nell'immagine. Per ciascun volto, puoi ottenere le coordinate di delimitazione nell'immagine di input, nonché qualsiasi altra informazione che hai configurato per trovare il rilevatore di volti. Per esempio: Veloce
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 } }
Obiettivo-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; } }
Esempio di contorni del viso
Quando hai abilitato il rilevamento del contorno del viso, ottieni un elenco di punti per ciascuna caratteristica del viso rilevata. Questi punti rappresentano la forma dell'elemento. Consulta la panoramica sui concetti di rilevamento dei volti per i dettagli su come vengono rappresentati i contorni.
L'immagine seguente illustra come questi punti vengono mappati su una faccia (fare clic sull'immagine per ingrandirla):
Rilevamento dei volti in tempo reale
Se desideri utilizzare il rilevamento dei volti in un'applicazione in tempo reale, segui queste linee guida per ottenere i migliori framerate:
Configura il rilevatore di volti per utilizzare il rilevamento dei contorni dei volti o la classificazione e il rilevamento dei punti di riferimento, ma non entrambi:
Rilevamento dei contorni
Rilevamento dei punti di riferimento
Classificazione
Individuazione e classificazione dei punti di riferimento
Rilevamento dei contorni e rilevamento dei punti di riferimento
Rilevamento e classificazione dei contorni
Rilevamento dei contorni, rilevamento dei punti di riferimento e classificazioneAbilita la modalità
fast
(abilitata per impostazione predefinita).Considera l'idea di acquisire immagini con una risoluzione inferiore. Tuttavia, tieni presente anche i requisiti relativi alla dimensione dell'immagine di questa API.
- Limita le chiamate al rilevatore. Se un nuovo fotogramma video diventa disponibile mentre il rilevatore è in funzione, rilasciare il fotogramma.
- Se si utilizza l'output del rilevatore per sovrapporre la grafica all'immagine in input, ottenere prima il risultato da ML Kit, quindi eseguire il rendering dell'immagine e sovrapporre in un unico passaggio. In questo modo, viene eseguito il rendering sulla superficie di visualizzazione solo una volta per ciascun fotogramma di input. Per un esempio, vedi le classi PreviewOverlayView e FIRDetectionOverlayView nell'app di esempio vetrina.