Za pomocą pakietu ML Kit możesz wykrywać twarze na obrazach i w filmach.
Zanim zaczniesz
- Jeśli nie masz jeszcze w aplikacji dodanej Firebase, wykonaj czynności podane w przewodniku dla początkujących.
- Umieść biblioteki ML Kit w pliku Podfile:
Po zainstalowaniu lub zaktualizowaniu podów projektu otwórz Xcode projektu korzystającego z: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'
.xcworkspace
. - W aplikacji zaimportuj Firebase:
Swift
import Firebase
Objective-C
@import Firebase;
Wytyczne dotyczące obrazu wejściowego
Aby ML Kit mógł precyzyjnie wykrywać twarze, obrazy wejściowe muszą zawierać twarze które są reprezentowane przez wystarczającą ilość danych pikseli. Ogólnie rzecz biorąc, każda twarz, którą chcesz pokazać, powinna mieć rozmiar co najmniej 100 x 100 pikseli. Jeśli chcesz wykrywać aby określić kontury twarzy, ML Kit wymaga wyższej rozdzielczości: powinien wynosić co najmniej 200 x 200 pikseli.
Jeśli wykrywasz twarze w aplikacji działającej w czasie rzeczywistym, możesz też aby wziąć pod uwagę ogólne wymiary obrazów wejściowych. Mniejsze obrazy szybsze przetwarzanie, a więc aby zmniejszyć opóźnienie, można robić zdjęcia w niższej rozdzielczości. (pamiętając o powyższych wymaganiach dotyczących dokładności) i upewnij się, że twarz obiektu zajmuje jak najwięcej miejsca na obrazie. Zobacz też Wskazówki, jak zwiększyć skuteczność w czasie rzeczywistym.
Słaba ostrość obrazu może negatywnie wpływać na dokładność. Jeśli nie uzyskujesz akceptowalnych wyników, poproś użytkownika o ponowne zrobienie zdjęcia.
Położenie twarzy w odniesieniu do aparatu może też wpływać na jej wygląd. wykrywanych przez ML Kit. Zobacz Wykrywanie twarzy Pojęcia.
1. Konfigurowanie wykrywania twarzy
Zanim zastosujesz wykrywanie twarzy na zdjęciu, możesz zmienić domyślnych ustawień wykrywania twarzy, określ je za pomocąVisionFaceDetectorOptions
. Możesz zmienić
te ustawienia:
Ustawienia | |
---|---|
performanceMode |
fast (domyślna) | accurate
Większa szybkość lub dokładność podczas wykrywania twarzy. |
landmarkMode |
none (domyślna) | all
Czy próbować wykryć „punkty orientacyjne” — oczy, uszu, nosa, policzków, ust – wszystkich wykrytych twarzy. |
contourMode |
none (domyślna) | all
Określa, czy wykrywać kontury rysów twarzy. Kontury są tylko dla najbardziej widocznej twarzy na zdjęciu. |
classificationMode |
none (domyślna) | all
Możliwość sklasyfikowania twarzy w kategoriach, takich jak „uśmiech”, i „oczy otwarte”. |
minFaceSize |
CGFloat (domyślnie: 0.1 )
Minimalny rozmiar twarzy do wykrycia w odniesieniu do obrazu. |
isTrackingEnabled |
false (domyślna) | true
Określa, czy przypisywać twarzom identyfikator, który może służyć do śledzenia i twarze na zdjęciach. Pamiętaj, że przy włączonym wykrywaniu kontur tylko jedna twarz więc śledzenie twarzy nie da żadnych przydatnych wyników. Do tego celu i aby zwiększyć szybkość wykrywania, nie włączaj obu konturów wykrywaniem oraz śledzeniem twarzy. |
Na przykład utwórz VisionFaceDetectorOptions
.
jak jeden z następujących przykładów:
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. Włącz wykrywanie twarzy
Aby wykrywać twarze na zdjęciu, przekaż je jakoUIImage
lub
CMSampleBufferRef
na: detect(in:)
: VisionFaceDetector
:
- Pobierz instancję
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];
-
Utwórz obiekt
VisionImage
za pomocąUIImage
lubCMSampleBufferRef
.Aby użyć karty
UIImage
:- W razie potrzeby obróć zdjęcie, tak by jego
imageOrientation
właściwość to.up
. - Utwórz obiekt
VisionImage
przy użyciu prawidłowo wykonanej rotacjiUIImage
Nie określaj żadnych metadanych rotacji – są to metadane domyślne..topLeft
.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Aby użyć karty
CMSampleBufferRef
:-
Utwórz obiekt
VisionImageMetadata
, który określa orientacji danych zdjęć zawartych w BuforCMSampleBufferRef
.Aby sprawdzić orientację obrazu:
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; } }
Następnie utwórz obiekt metadanych:
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];
- Utwórz obiekt
VisionImage
za pomocą ObiektCMSampleBufferRef
i metadane rotacji:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- W razie potrzeby obróć zdjęcie, tak by jego
-
Następnie przekaż obraz do metody
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. Uzyskiwanie informacji o wykrytych twarzy
Jeśli operacja wykrywania twarzy się powiedzie, czujnik twarzy przekaże tablicę zVisionFace
obiektów do modułu obsługi uzupełniania. Każdy
VisionFace
obiekt reprezentuje twarz wykrytą na obrazie. Dla:
można sprawdzić współrzędne ograniczające na obrazie wejściowym,
wszelkie inne informacje skonfigurowane przez Ciebie w celu wykrywania twarzy. Przykład:
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; } }
Przykład konturu twarzy
Gdy włączysz wykrywanie konturu twarzy, zobaczysz listę punktów za wszystkie wykryte cechy twarzy. Te punkty odpowiadają kształtowi funkcji. Zobacz twarz Omówienie pojęć związanych z wykrywaniem, aby uzyskać szczegółowe informacje o konturach reprezentowanych.
Na poniższym obrazie przedstawiono mapowanie tych punktów na twarz (kliknij obraz do powiększenia):
Wykrywanie twarzy w czasie rzeczywistym
Jeśli chcesz używać wykrywania twarzy w aplikacjach działających w czasie rzeczywistym, postępuj zgodnie z tymi instrukcjami wytycznych dotyczących uzyskiwania najlepszej liczby klatek na sekundę:
Skonfiguruj wykrywacz twarzy, aby używał jednej wykrywanie kontur lub klasyfikacja twarzy i wykrywanie punktów orientacyjnych, ale nie oba te rodzaje naraz:
Wykrywanie konturów
Wykrywanie punktów orientacyjnych
Klasyfikacja
Wykrywanie i klasyfikacja punktów orientacyjnych
Wykrywanie konturów i wykrywanie punktów orientacyjnych
Wykrywanie i klasyfikacja kontur
Wykrywanie konturów, wykrywanie punktów orientacyjnych i klasyfikacjaWłącz tryb
fast
(domyślnie włączony).Rozważ robienie zdjęć w niższej rozdzielczości. Pamiętaj jednak, wymagania dotyczące wymiarów obrazów w tym interfejsie API.
- Ogranicz wywołania do detektora. Jeśli nowa klatka wideo dostępnych, gdy detektor jest uruchomiony, upuść ramkę.
- Jeśli używasz danych wyjściowych detektora do nakładania grafiki na obrazu wejściowego, najpierw pobierz wynik z ML Kit, a następnie wyrenderuj obraz i nakładanie nakładek w jednym kroku. W ten sposób renderowanie na powierzchni tylko raz na każdą ramkę wejściową. Zobacz previewOverlayView. i FIRDetectionOverlayView w aplikacji z funkcją prezentacji.