Sie können ML Kit verwenden, um Gesichter in Bildern und Videos zu erkennen.
Hinweis
- Falls noch nicht geschehen, Fügen Sie Firebase zu Ihrem Android-Projekt hinzu.
- Abhängigkeiten für die ML Kit-Android-Bibliotheken zu Ihrem Modul hinzufügen
Gradle-Datei auf App-Ebene (in der Regel
app/build.gradle
):apply plugin: 'com.android.application' apply plugin: 'com.google.gms.google-services' dependencies { // ... implementation 'com.google.firebase:firebase-ml-vision:24.0.3' // If you want to detect face contours (landmark detection and classification // don't require this additional model): implementation 'com.google.firebase:firebase-ml-vision-face-model:20.0.1' }
-
Optional, aber empfohlen: Konfigurieren Sie die App für den automatischen Download.
das ML-Modell auf das Gerät übertragen,
nachdem Ihre App aus dem Play Store installiert wurde.
Fügen Sie dazu die folgende Deklaration im
AndroidManifest.xml
-Datei: Wenn Sie den Download von Modellen bei der Installation nicht aktivieren, wird das Modell beim ersten Ausführen des Detektors heruntergeladen. Anfragen, die Sie vor dem wenn der Download abgeschlossen ist, keine Ergebnisse liefert.<application ...> ... <meta-data android:name="com.google.firebase.ml.vision.DEPENDENCIES" android:value="face" /> <!-- To use multiple models: android:value="face,model2,model3" --> </application>
Richtlinien für Eingabebilder
Damit ML Kit Gesichter richtig erkennen kann, müssen die eingegebenen Bilder Gesichter enthalten die durch ausreichende Pixeldaten dargestellt werden. Jedes Gesicht, das Sie sehen möchten, die in einem Bild erkannt werden sollen, mindestens 100 × 100 Pixel groß sein. Wenn Sie herausfinden möchten, Konturen von Flächen erfordert ML Kit eine Eingabe mit höherer Auflösung: jede Fläche sollte mindestens 200 x 200 Pixel groß sein.
Wenn Sie Gesichter in einer Echtzeitanwendung erkennen, um die Gesamtabmessungen der eingegebenen Bilder zu berücksichtigen. Kleinere Bilder können werden schneller verarbeitet. Um die Latenz zu verringern, nehmen Sie Bilder daher mit geringerer Auflösung auf. (unter Berücksichtigung der oben genannten Anforderungen an die Genauigkeit) und stellen Sie sicher, dass das Gesicht der Person so weit wie möglich einnimmt. Siehe auch Tipps zum Verbessern der Leistung in Echtzeit
Ein zu niedriger Bildfokus kann die Genauigkeit beeinträchtigen. Wenn Sie keine akzeptablen Ergebnisse erhalten, versuchen Sie, das Bild erneut aufzunehmen.
Auch die Ausrichtung eines Gesichts relativ zur Kamera kann sich darauf auswirken, welche Gesichtszüge Funktionen, die ML Kit erkennt. Weitere Informationen finden Sie unter Gesichtserkennung Konzepte.
1. Gesichtserkennung konfigurieren
Bevor Sie die Gesichtserkennung auf ein Bild anwenden, wenn Sie eine der Gesichtserkennung verwenden, legen Sie diese Einstellungen mit einemFirebaseVisionFaceDetectorOptions
-Objekt.
Sie können die folgenden Einstellungen ändern:
Einstellungen | |
---|---|
Leistungsmodus |
FAST (Standard)
| ACCURATE
Bevorzugen Sie bei der Gesichtswiedererkennung Geschwindigkeit oder Genauigkeit. |
Sehenswürdigkeiten erkennen |
NO_LANDMARKS (Standardeinstellung)
| ALL_LANDMARKS
Ob es um Gesichtsmerkmale wie Augen, Ohren, Nase, Wangen, Mund usw. |
Konturen erkennen |
NO_CONTOURS (Standardeinstellung)
| ALL_CONTOURS
Gibt an, ob die Konturen von Gesichtszügen erkannt werden sollen. Konturen sind nur für das auffälligste Gesicht im Bild erkannt wurde. |
Gesichter klassifizieren |
NO_CLASSIFICATIONS (Standardeinstellung)
| ALL_CLASSIFICATIONS
ob Gesichter in Kategorien wie "Lächeln", und „Augen geöffnet“. |
Minimale Gesichtsgröße |
float (Standardeinstellung: 0.1f )
Die Mindestgröße der zu erkennenden Gesichter im Verhältnis zum Bild. |
Gesichtserkennung aktivieren |
false (Standard) | true
Gibt an, ob Gesichtern eine ID zugewiesen werden soll, anhand derer die Gesichter in unterschiedlichen Bildern. Beachten Sie, dass bei aktivierter Konturerkennung nur eine Fläche erkannt. Die Gesichtserkennung liefert daher keine hilfreichen Ergebnisse. In diesem Fall Um die Erkennungsgeschwindigkeit zu verbessern, sollten Sie nicht beide Gesichtserkennung und Gesichtserkennung. |
Beispiel:
Java
// High-accuracy landmark detection and face classification FirebaseVisionFaceDetectorOptions highAccuracyOpts = new FirebaseVisionFaceDetectorOptions.Builder() .setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE) .setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS) .setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS) .build(); // Real-time contour detection of multiple faces FirebaseVisionFaceDetectorOptions realTimeOpts = new FirebaseVisionFaceDetectorOptions.Builder() .setContourMode(FirebaseVisionFaceDetectorOptions.ALL_CONTOURS) .build();
Kotlin+KTX
// High-accuracy landmark detection and face classification val highAccuracyOpts = FirebaseVisionFaceDetectorOptions.Builder() .setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE) .setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS) .setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS) .build() // Real-time contour detection of multiple faces val realTimeOpts = FirebaseVisionFaceDetectorOptions.Builder() .setContourMode(FirebaseVisionFaceDetectorOptions.ALL_CONTOURS) .build()
2. Gesichtserkennung ausführen
Wenn Sie Gesichter in einem Bild erkennen möchten, erstellen Sie einFirebaseVisionImage
-Objekt aus einem Bitmap
-, media.Image
-, ByteBuffer
-, Byte-Array oder einer Datei auf dem Gerät. Übergeben Sie dann das FirebaseVisionImage
-Objekt an die
Die Methode detectInImage
von FirebaseVisionFaceDetector
.
Für die Gesichtserkennung sollten Sie ein Bild mit mindestens den Abmessungen 480 x 360 Pixel. Wenn Sie Gesichter in Echtzeit erkennen, kann die Aufnahme von Frames mit dieser Mindestauflösung die Latenz verringern.
Erstellen Sie ein
FirebaseVisionImage
-Objekt aus Ihrem Bild.-
Um ein
FirebaseVisionImage
-Objekt aus einemmedia.Image
-Objekt, z. B. beim Aufnehmen eines Bildes von einem des Geräts an und übergib dasmedia.Image
-Objekt und die Rotation aufFirebaseVisionImage.fromMediaImage()
.Wenn Sie die Methode CameraX-Bibliothek, den
OnImageCapturedListener
undImageAnalysis.Analyzer
-Klassen berechnen den Rotationswert Sie müssen also nur die Rotation in eine der ML Kit-ModelleROTATION_
-Konstanten vor dem AufrufFirebaseVisionImage.fromMediaImage()
:Java
private class YourAnalyzer implements ImageAnalysis.Analyzer { private int degreesToFirebaseRotation(int degrees) { switch (degrees) { case 0: return FirebaseVisionImageMetadata.ROTATION_0; case 90: return FirebaseVisionImageMetadata.ROTATION_90; case 180: return FirebaseVisionImageMetadata.ROTATION_180; case 270: return FirebaseVisionImageMetadata.ROTATION_270; default: throw new IllegalArgumentException( "Rotation must be 0, 90, 180, or 270."); } } @Override public void analyze(ImageProxy imageProxy, int degrees) { if (imageProxy == null || imageProxy.getImage() == null) { return; } Image mediaImage = imageProxy.getImage(); int rotation = degreesToFirebaseRotation(degrees); FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation); // Pass image to an ML Kit Vision API // ... } }
Kotlin+KTX
private class YourImageAnalyzer : ImageAnalysis.Analyzer { private fun degreesToFirebaseRotation(degrees: Int): Int = when(degrees) { 0 -> FirebaseVisionImageMetadata.ROTATION_0 90 -> FirebaseVisionImageMetadata.ROTATION_90 180 -> FirebaseVisionImageMetadata.ROTATION_180 270 -> FirebaseVisionImageMetadata.ROTATION_270 else -> throw Exception("Rotation must be 0, 90, 180, or 270.") } override fun analyze(imageProxy: ImageProxy?, degrees: Int) { val mediaImage = imageProxy?.image val imageRotation = degreesToFirebaseRotation(degrees) if (mediaImage != null) { val image = FirebaseVisionImage.fromMediaImage(mediaImage, imageRotation) // Pass image to an ML Kit Vision API // ... } } }
Wenn Sie keine Kamerabibliothek verwenden, die Ihnen die Rotation des Bildes anzeigt, anhand der Drehung des Geräts und der Ausrichtung der Kamera Sensor im Gerät:
Java
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 0); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 180); } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private int getRotationCompensation(String cameraId, Activity activity, Context context) throws CameraAccessException { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int rotationCompensation = ORIENTATIONS.get(deviceRotation); // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE); int sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION); rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360; // Return the corresponding FirebaseVisionImageMetadata rotation value. int result; switch (rotationCompensation) { case 0: result = FirebaseVisionImageMetadata.ROTATION_0; break; case 90: result = FirebaseVisionImageMetadata.ROTATION_90; break; case 180: result = FirebaseVisionImageMetadata.ROTATION_180; break; case 270: result = FirebaseVisionImageMetadata.ROTATION_270; break; default: result = FirebaseVisionImageMetadata.ROTATION_0; Log.e(TAG, "Bad rotation value: " + rotationCompensation); } return result; }
Kotlin+KTX
private val ORIENTATIONS = SparseIntArray() init { ORIENTATIONS.append(Surface.ROTATION_0, 90) ORIENTATIONS.append(Surface.ROTATION_90, 0) ORIENTATIONS.append(Surface.ROTATION_180, 270) ORIENTATIONS.append(Surface.ROTATION_270, 180) } /** * Get the angle by which an image must be rotated given the device's current * orientation. */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Throws(CameraAccessException::class) private fun getRotationCompensation(cameraId: String, activity: Activity, context: Context): Int { // Get the device's current rotation relative to its "native" orientation. // Then, from the ORIENTATIONS table, look up the angle the image must be // rotated to compensate for the device's rotation. val deviceRotation = activity.windowManager.defaultDisplay.rotation var rotationCompensation = ORIENTATIONS.get(deviceRotation) // On most devices, the sensor orientation is 90 degrees, but for some // devices it is 270 degrees. For devices with a sensor orientation of // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees. val cameraManager = context.getSystemService(CAMERA_SERVICE) as CameraManager val sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION)!! rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360 // Return the corresponding FirebaseVisionImageMetadata rotation value. val result: Int when (rotationCompensation) { 0 -> result = FirebaseVisionImageMetadata.ROTATION_0 90 -> result = FirebaseVisionImageMetadata.ROTATION_90 180 -> result = FirebaseVisionImageMetadata.ROTATION_180 270 -> result = FirebaseVisionImageMetadata.ROTATION_270 else -> { result = FirebaseVisionImageMetadata.ROTATION_0 Log.e(TAG, "Bad rotation value: $rotationCompensation") } } return result }
Übergeben Sie dann das
media.Image
-Objekt und den Drehwert anFirebaseVisionImage.fromMediaImage()
:Java
FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);
Kotlin+KTX
val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
- Wenn Sie ein
FirebaseVisionImage
-Objekt aus einem Datei-URI erstellen möchten, übergeben Sie den App-Kontext und den Datei-URI anFirebaseVisionImage.fromFilePath()
. Dies ist nützlich, wenn Sie Verwenden Sie den IntentACTION_GET_CONTENT
, um den Nutzer zur Auswahl aufzufordern ein Bild aus ihrer Galerie-App.Java
FirebaseVisionImage image; try { image = FirebaseVisionImage.fromFilePath(context, uri); } catch (IOException e) { e.printStackTrace(); }
Kotlin+KTX
val image: FirebaseVisionImage try { image = FirebaseVisionImage.fromFilePath(context, uri) } catch (e: IOException) { e.printStackTrace() }
- Um ein
FirebaseVisionImage
-Objekt aus einemByteBuffer
oder einem Byte-Array, berechnen Sie zuerst das Bild Rotation wie oben für diemedia.Image
-Eingabe beschrieben.Erstellen Sie dann ein
FirebaseVisionImageMetadata
-Objekt. die die Höhe, Breite, Farbcodierung, und Rotation:Java
FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build();
Kotlin+KTX
val metadata = FirebaseVisionImageMetadata.Builder() .setWidth(480) // 480x360 is typically sufficient for .setHeight(360) // image recognition .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build()
Verwenden Sie den Zwischenspeicher oder das Array und das Metadatenobjekt, um einen Objekt
FirebaseVisionImage
:Java
FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata); // Or: FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);
Kotlin+KTX
val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata) // Or: val image = FirebaseVisionImage.fromByteArray(byteArray, metadata)
- Um ein
FirebaseVisionImage
-Objekt aus einemBitmap
-Objekt:Java
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
Kotlin+KTX
val image = FirebaseVisionImage.fromBitmap(bitmap)
Bitmap
dargestellte Bild muss aufrecht und ohne zusätzliche Drehung aufrecht.
-
Rufen Sie eine
FirebaseVisionFaceDetector
-Instanz ab:Java
FirebaseVisionFaceDetector detector = FirebaseVision.getInstance() .getVisionFaceDetector(options);
Kotlin+KTX
val detector = FirebaseVision.getInstance() .getVisionFaceDetector(options)
Übergeben Sie zuletzt das Bild an die Methode
detectInImage
:Java
Task<List<FirebaseVisionFace>> result = detector.detectInImage(image) .addOnSuccessListener( new OnSuccessListener<List<FirebaseVisionFace>>() { @Override public void onSuccess(List<FirebaseVisionFace> faces) { // Task completed successfully // ... } }) .addOnFailureListener( new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } });
Kotlin+KTX
val result = detector.detectInImage(image) .addOnSuccessListener { faces -> // Task completed successfully // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
3. Informationen zu erkannten Gesichtern erhalten
Wenn der Vorgang der Gesichtserkennung erfolgreich war, wird dem Erfolgsempfänger eine Liste vonFirebaseVisionFace
-Objekten übergeben. Jedes FirebaseVisionFace
-Objekt steht für ein Gesicht, das erkannt wurde
auf dem Bild. Für jedes Fläche können Sie die Begrenzungskoordinaten in der Eingabe abrufen,
sowie alle anderen Informationen, für die Sie die Gesichtserkennung konfiguriert haben.
finden. Beispiel:
Java
for (FirebaseVisionFace face : faces) { Rect bounds = face.getBoundingBox(); float rotY = face.getHeadEulerAngleY(); // Head is rotated to the right rotY degrees float rotZ = face.getHeadEulerAngleZ(); // Head is tilted sideways rotZ degrees // If landmark detection was enabled (mouth, ears, eyes, cheeks, and // nose available): FirebaseVisionFaceLandmark leftEar = face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR); if (leftEar != null) { FirebaseVisionPoint leftEarPos = leftEar.getPosition(); } // If contour detection was enabled: List<FirebaseVisionPoint> leftEyeContour = face.getContour(FirebaseVisionFaceContour.LEFT_EYE).getPoints(); List<FirebaseVisionPoint> upperLipBottomContour = face.getContour(FirebaseVisionFaceContour.UPPER_LIP_BOTTOM).getPoints(); // If classification was enabled: if (face.getSmilingProbability() != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) { float smileProb = face.getSmilingProbability(); } if (face.getRightEyeOpenProbability() != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) { float rightEyeOpenProb = face.getRightEyeOpenProbability(); } // If face tracking was enabled: if (face.getTrackingId() != FirebaseVisionFace.INVALID_ID) { int id = face.getTrackingId(); } }
Kotlin+KTX
for (face in faces) { val bounds = face.boundingBox val rotY = face.headEulerAngleY // Head is rotated to the right rotY degrees val rotZ = face.headEulerAngleZ // Head is tilted sideways rotZ degrees // If landmark detection was enabled (mouth, ears, eyes, cheeks, and // nose available): val leftEar = face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR) leftEar?.let { val leftEarPos = leftEar.position } // If contour detection was enabled: val leftEyeContour = face.getContour(FirebaseVisionFaceContour.LEFT_EYE).points val upperLipBottomContour = face.getContour(FirebaseVisionFaceContour.UPPER_LIP_BOTTOM).points // If classification was enabled: if (face.smilingProbability != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) { val smileProb = face.smilingProbability } if (face.rightEyeOpenProbability != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) { val rightEyeOpenProb = face.rightEyeOpenProbability } // If face tracking was enabled: if (face.trackingId != FirebaseVisionFace.INVALID_ID) { val id = face.trackingId } }
Beispiel für Gesichtskonturen
Wenn Sie die Gesichtskonturerkennung aktiviert haben, wird eine Liste mit Punkten jedes erkannte Gesichtsmerkmal. Diese Punkte stellen die Form des . Das Gesicht erkennen lassen Übersicht über die Erkennungskonzepte. Dort finden Sie weitere Informationen zu Konturen. repräsentiert werden.
In der folgenden Abbildung sehen Sie, wie diese Punkte einem Gesicht zugeordnet werden (klicken Sie auf das Bild zum Vergrößern):
Gesichtserkennung in Echtzeit
Wenn Sie die Gesichtserkennung in einer Echtzeitanwendung verwenden möchten, gehen Sie so vor: um optimale Framerates zu erzielen:
Konfigurieren Sie die Gesichtserkennung, um entweder Gesichtskonturerkennung oder -klassifizierung und Erkennung von Sehenswürdigkeiten, aber nicht beides:
Konturerkennung
Erkennung von Sehenswürdigkeiten
Klassifizierung
Erkennung und Klassifizierung von Sehenswürdigkeiten
Konturerkennung und Erkennung von Sehenswürdigkeiten
Konturerkennung und Klassifizierung
Konturerkennung, Erkennung von Sehenswürdigkeiten und KlassifizierungAktivieren Sie den
FAST
-Modus (standardmäßig aktiviert).Nehmen Sie Bilder mit einer niedrigeren Auflösung auf. Beachten Sie jedoch auch, Anforderungen an die Bildabmessungen dieser API.
- Aufrufe an den Detektor drosseln Wenn ein neuer Videoframe wenn der Detektor ausgeführt wird, lassen Sie den Frame weg.
- Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken auf das Eingabebild zu legen, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern Sie dann das Bild und das Overlay in einem einzigen Schritt. Dadurch rendern Sie auf der Anzeigeoberfläche für jeden Eingabe-Frame nur einmal.
-
Wenn Sie die Camera2 API verwenden, nehmen Sie Bilder in
ImageFormat.YUV_420_888
-Format.Wenn Sie die ältere Camera API verwenden, nehmen Sie Bilder in
ImageFormat.NV21
-Format.