Rilevamento dei volti con ML Kit su iOS

Puoi utilizzare ML Kit per rilevare i volti nelle immagini e nei video.

Prova

  • Prova l'app di esempio per per vedere un esempio di utilizzo di questa API.
  • Prova a utilizzare il codice utilizzando codelab.

Prima di iniziare

  1. Includi i seguenti pod ML Kit nel podfile:
    pod 'GoogleMLKit/FaceDetection', '3.2.0'
    
  2. Dopo aver installato o aggiornato i pod del progetto, apri il progetto Xcode utilizzando la relativa .xcworkspace. ML Kit è supportato in Xcode versione 12.4 o successiva.

Linee guida per l'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 accuratamente i volti, le immagini di input devono contenere volti rappresentate da dati pixel sufficienti. In generale, ogni volto che vuoi da rilevare in un'immagine devono essere di almeno 100 x 100 pixel. Se vuoi rilevare i contorni delle facce, ML Kit richiede un input di risoluzione più alta: ogni faccia deve essere di almeno 200 x 200 pixel.

Se rilevi i volti in un'applicazione in tempo reale, potresti anche per considerare le dimensioni complessive delle immagini di input. Le immagini più piccole possono essere elaborati più velocemente. In questo modo, per ridurre la latenza, acquisire immagini a risoluzioni più basse, tenendo conto dei requisiti di accuratezza di cui sopra e accertati che il volto del soggetto occupa la maggior quantità possibile dell'immagine. Vedi anche suggerimenti per migliorare il rendimento in tempo reale.

Anche una scarsa messa a fuoco dell'immagine può influire sulla precisione. Se non accetti risultati, chiedi all'utente di recuperare l'immagine.

L'orientamento di un volto rispetto alla fotocamera può influire anche sul viso rileva le funzionalità di ML Kit. Consulta Concetti relativi al rilevamento facciale.

1. Configurare il rilevatore di volti

Prima di applicare il rilevamento dei volti a un'immagine, se vuoi modificare una delle impostazioni predefinite del rilevatore di volti, specifica tali impostazioni con un FaceDetectorOptions. Puoi modificare le seguenti impostazioni:

Impostazioni
performanceMode fast (predefinito) | accurate

Prediligi 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 sono rilevato solo per il volto più in evidenza in un'immagine.

classificationMode none (predefinito) | all

Se classificare o meno i volti in categorie come "sorriso" e "con gli occhi aperti".

minFaceSize CGFloat (valore predefinito: 0.1)

Imposta la dimensione minima del volto desiderata, espressa come rapporto tra della testa alla larghezza dell'immagine.

isTrackingEnabled false (predefinito) | true

Indica se assegnare o meno ai volti un ID, che può essere utilizzato per il tracciamento volti attraverso le immagini.

Tieni presente che quando il rilevamento del contorno è attivo, viene selezionato un solo volto viene rilevato, quindi il rilevamento dei volti non produce risultati utili. Per questo e per migliorare la velocità di rilevamento, non abilitare entrambi rilevamento e rilevamento dei volti.

Ad esempio, crea una 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, passala come UIImage o come CMSampleBufferRef a FaceDetector utilizzando Metodo process(_:completion:) o results(in:):

Crea un oggetto VisionImage utilizzando un UIImage o un CMSampleBuffer.

Se usi un UIImage, segui questi passaggi:

  • Crea un oggetto VisionImage con UIImage. 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 dell'immagine contenuti nei 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 il metodo CMSampleBuffer oggetto e 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. Recupera un'istanza di FaceDetector

Recupera 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 metodo process():

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 oggetti Face al gestore del completamento. Ciascuna L'oggetto Face rappresenta un volto rilevato nell'immagine. Per per ogni faccia, puoi ottenere le coordinate di delimitazione nell'immagine di input, 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

Quando il rilevamento del contorno del volto è attivo, viene visualizzato un elenco di punti per ogni caratteristica del volto rilevata. Questi punti rappresentano la forma funzionalità. Vedi Volto Detection Concepts per i dettagli sui contorni rappresentato.

Nell'immagine di seguito puoi vedere come questi punti mappano a un volto, fai clic sull'icona immagine per ingrandirla:

esempio rilevato mesh contorno viso

Rilevamento dei volti in tempo reale

Se vuoi utilizzare il rilevamento dei volti in un'applicazione in tempo reale, segui queste istruzioni linee guida per ottenere le migliori frequenze fotogrammi:

  • Configura il rilevatore di volti per usare uno dei seguenti dispositivi rilevamento o classificazione del contorno del volto e rilevamento dei punti di riferimento, ma non entrambi:

    Rilevamento contorno
    Rilevamento dei punti di riferimento
    Classificazione
    Rilevamento e classificazione dei punti di riferimento
    Rilevamento dei contorni e dei punti di riferimento
    Rilevamento e classificazione del contorno
    Rilevamento contorni, rilevamento dei punti di riferimento e classificazione

  • Attiva la modalità fast (attiva per impostazione predefinita).

  • Prova ad acquisire immagini a una risoluzione inferiore. Tuttavia, tieni presente requisiti per le dimensioni immagine di questa API.

  • Per elaborare i fotogrammi video, utilizza l'API sincrona results(in:) del rilevatore. Chiama questo metodo dal di AVCaptureVideoDataOutputSampleBufferDelegate captureOutput(_, didOutput:from:) per ottenere in modo sincrono i risultati dal video specificato frame. Mantieni di AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames come true per limitare le chiamate al rilevatore. Se un nuovo il fotogramma video diventa disponibile mentre il rilevatore è in esecuzione, quindi verrà eliminato.
  • Se utilizzi l'output del rilevatore per sovrapporre elementi grafici l'immagine di input, occorre prima ottenere il risultato da ML Kit, quindi eseguire il rendering dell'immagine e la sovrapposizione in un solo passaggio. In questo modo, visualizzi la pagina solo una volta per ogni frame di input elaborato. Vedi la pagina updatePreviewOverlayViewWithLastFrame. nell'esempio della guida rapida di ML Kit.