Posen mit ML Kit für Android erkennen

ML Kit bietet zwei optimierte SDKs für die Körperhaltungserkennung.

SDK-Namepose-detectionpose-detection-accurate
ImplementierungCode und Assets werden bei der Build-Phase statisch mit Ihrer App verknüpft.Code und Assets werden bei der Build-Phase statisch mit Ihrer App verknüpft.
Auswirkungen auf die App-Größe (einschließlich Code und Assets)~10,1 MB~13,3 MB
LeistungGoogle Pixel 3 XL: ca. 30 fpsGoogle Pixel 3 XL: ca. 23 fps mit CPU, ca. 30 fps mit GPU

Jetzt ausprobieren

Hinweis

  1. In die Datei build.gradle auf Projektebene muss das Maven-Repository von Google in die Abschnitte buildscript und allprojects aufgenommen werden.
  2. Fügen Sie der Gradle-Datei Ihres Moduls auf App-Ebene (in der Regel app/build.gradle) die Abhängigkeiten für die ML Kit-Android-Bibliotheken hinzu:

    dependencies {
      // If you want to use the base sdk
      implementation 'com.google.mlkit:pose-detection:18.0.0-beta5'
      // If you want to use the accurate sdk
      implementation 'com.google.mlkit:pose-detection-accurate:18.0.0-beta5'
    }
    

1. Instanz von PoseDetector erstellen

Optionen für PoseDetector

Wenn Sie eine Pose in einem Bild erkennen möchten, erstellen Sie zuerst eine Instanz von PoseDetector und geben Sie optional die Einstellungen für den Detector an.

Erkennungsmodus

Der PoseDetector kann in zwei Erkennungsmodi betrieben werden. Achten Sie darauf, die Option auszuwählen, die zu Ihrem Anwendungsfall passt.

STREAM_MODE (Standard)
Die Positionserkennung erkennt zuerst die am stärksten hervortretende Person im Bild und führt dann die Positionserkennung durch. In den nachfolgenden Frames wird der Schritt zur Personenerkennung nur ausgeführt, wenn die Person verdeckt ist oder nicht mehr mit hoher Wahrscheinlichkeit erkannt wird. Der Körperhaltungs-Detektor versucht, die am stärksten hervortretende Person zu verfolgen und ihre Körperhaltung bei jeder Erkennung zurückzugeben. Dadurch wird die Latenz verringert und die Erkennung optimiert. Verwenden Sie diesen Modus, wenn Sie die Körperhaltung in einem Videostream erkennen möchten.
SINGLE_IMAGE_MODE
Der Haltungsdetektor erkennt eine Person und führt dann die Haltungserkennung aus. Der Schritt zur Personenerkennung wird für jedes Bild ausgeführt. Daher ist die Latenz höher und es erfolgt kein Personen-Tracking. Verwenden Sie diesen Modus, wenn Sie die Körperhaltungserkennung auf statischen Bildern verwenden oder wenn kein Tracking gewünscht ist.

Hardwarekonfiguration

Der PoseDetector unterstützt mehrere Hardwarekonfigurationen zur Leistungsoptimierung:

  • CPU: den Detektor nur mit der CPU ausführen
  • CPU_GPU: den Detector sowohl mit der CPU als auch mit der GPU ausführen

Beim Erstellen der Detektoroptionen können Sie die Hardwareauswahl mit der APIsetPreferredHardwareConfigs steuern. Standardmäßig sind alle Hardwarekonfigurationen als bevorzugt festgelegt.

ML Kit berücksichtigt Verfügbarkeit, Stabilität, Korrektheit und Latenz der einzelnen Konfigurationen und wählt die beste aus den bevorzugten Konfigurationen aus. Wenn keine der bevorzugten Konfigurationen zutrifft, wird die CPU-Konfiguration automatisch als Fallback verwendet. ML Kit führt diese Prüfungen und die zugehörige Vorbereitung nicht blockierend durch, bevor die Beschleunigung aktiviert wird. Wenn der Nutzer den Detector also zum ersten Mal ausführt, wird höchstwahrscheinlich CPU verwendet. Nach Abschluss der Vorbereitung wird die beste Konfiguration bei den folgenden Ausführungen verwendet.

Anwendungsbeispiele für setPreferredHardwareConfigs:

  • Wenn ML Kit die beste Konfiguration auswählen soll, rufen Sie diese API nicht auf.
  • Wenn Sie keine Beschleunigung aktivieren möchten, geben Sie nur CPU an.
  • Wenn Sie die GPU verwenden möchten, um die CPU zu entlasten, auch wenn die GPU langsamer sein könnte, geben Sie nur CPU_GPU ein.

Geben Sie die Optionen für die Körperhaltungserkennung an:

Kotlin

// Base pose detector with streaming frames, when depending on the pose-detection sdk
val options = PoseDetectorOptions.Builder()
    .setDetectorMode(PoseDetectorOptions.STREAM_MODE)
    .build()

// Accurate pose detector on static images, when depending on the pose-detection-accurate sdk
val options = AccuratePoseDetectorOptions.Builder()
    .setDetectorMode(AccuratePoseDetectorOptions.SINGLE_IMAGE_MODE)
    .build()

Java

// Base pose detector with streaming frames, when depending on the pose-detection sdk
PoseDetectorOptions options =
   new PoseDetectorOptions.Builder()
       .setDetectorMode(PoseDetectorOptions.STREAM_MODE)
       .build();

// Accurate pose detector on static images, when depending on the pose-detection-accurate sdk
AccuratePoseDetectorOptions options =
   new AccuratePoseDetectorOptions.Builder()
       .setDetectorMode(AccuratePoseDetectorOptions.SINGLE_IMAGE_MODE)
       .build();

Erstellen Sie abschließend eine Instanz von PoseDetector. Übergeben Sie die von Ihnen angegebenen Optionen:

Kotlin

val poseDetector = PoseDetection.getClient(options)

Java

PoseDetector poseDetector = PoseDetection.getClient(options);

2. Eingabebild vorbereiten

Wenn Sie Posen in einem Bild erkennen möchten, erstellen Sie ein InputImage-Objekt aus einem Bitmap-, media.Image-, ByteBuffer-, Byte-Array oder einer Datei auf dem Gerät. Übergeben Sie dann das InputImage-Objekt an das PoseDetector.

Für die Körperhaltungserkennung sollten Sie ein Bild mit den Abmessungen 480 x 360 Pixel verwenden. Wenn Sie Posen in Echtzeit erkennen, kann die Aufnahme von Frames mit dieser Mindestauflösung die Latenz verringern.

Sie können ein InputImage-Objekt aus verschiedenen Quellen erstellen. Im Folgenden werden die einzelnen Quellen erläutert.

Mit einem media.Image

Wenn Sie ein InputImage-Objekt aus einem media.Image-Objekt erstellen möchten, z. B. wenn Sie ein Bild mit der Kamera eines Geräts aufnehmen, übergeben Sie das media.Image-Objekt und die Drehung des Bildes an InputImage.fromMediaImage().

Wenn Sie die CameraX-Bibliothek verwenden, wird der Drehwert von den Klassen OnImageCapturedListener und ImageAnalysis.Analyzer berechnet.

Kotlin

private class YourImageAnalyzer : ImageAnalysis.Analyzer {

    override fun analyze(imageProxy: ImageProxy) {
        val mediaImage = imageProxy.image
        if (mediaImage != null) {
            val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
            // Pass image to an ML Kit Vision API
            // ...
        }
    }
}

Java

private class YourAnalyzer implements ImageAnalysis.Analyzer {

    @Override
    public void analyze(ImageProxy imageProxy) {
        Image mediaImage = imageProxy.getImage();
        if (mediaImage != null) {
          InputImage image =
                InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
          // Pass image to an ML Kit Vision API
          // ...
        }
    }
}

Wenn Sie keine Kamerabibliothek verwenden, die den Drehwinkel des Bildes angibt, können Sie ihn anhand des Drehwinkels des Geräts und der Ausrichtung des Kamerasensors im Gerät berechnen:

Kotlin

private val ORIENTATIONS = SparseIntArray()

init {
    ORIENTATIONS.append(Surface.ROTATION_0, 0)
    ORIENTATIONS.append(Surface.ROTATION_90, 90)
    ORIENTATIONS.append(Surface.ROTATION_180, 180)
    ORIENTATIONS.append(Surface.ROTATION_270, 270)
}

/**
 * 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, isFrontFacing: Boolean): 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)

    // Get the device's sensor orientation.
    val cameraManager = activity.getSystemService(CAMERA_SERVICE) as CameraManager
    val sensorOrientation = cameraManager
            .getCameraCharacteristics(cameraId)
            .get(CameraCharacteristics.SENSOR_ORIENTATION)!!

    if (isFrontFacing) {
        rotationCompensation = (sensorOrientation + rotationCompensation) % 360
    } else { // back-facing
        rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360
    }
    return rotationCompensation
}

Java

private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
    ORIENTATIONS.append(Surface.ROTATION_0, 0);
    ORIENTATIONS.append(Surface.ROTATION_90, 90);
    ORIENTATIONS.append(Surface.ROTATION_180, 180);
    ORIENTATIONS.append(Surface.ROTATION_270, 270);
}

/**
 * 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, boolean isFrontFacing)
        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);

    // Get the device's sensor orientation.
    CameraManager cameraManager = (CameraManager) activity.getSystemService(CAMERA_SERVICE);
    int sensorOrientation = cameraManager
            .getCameraCharacteristics(cameraId)
            .get(CameraCharacteristics.SENSOR_ORIENTATION);

    if (isFrontFacing) {
        rotationCompensation = (sensorOrientation + rotationCompensation) % 360;
    } else { // back-facing
        rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360;
    }
    return rotationCompensation;
}

Übergeben Sie dann das media.Image-Objekt und den Wert für den Drehungsgrad an InputImage.fromMediaImage():

Kotlin

val image = InputImage.fromMediaImage(mediaImage, rotation)

Java

InputImage image = InputImage.fromMediaImage(mediaImage, rotation);

Datei-URI verwenden

Wenn du ein InputImage-Objekt aus einem Datei-URI erstellen möchtest, übergebe den App-Kontext und den Datei-URI an InputImage.fromFilePath(). Das ist nützlich, wenn Sie mit einer ACTION_GET_CONTENT-Intent den Nutzer auffordern, ein Bild aus seiner Galerie-App auszuwählen.

Kotlin

val image: InputImage
try {
    image = InputImage.fromFilePath(context, uri)
} catch (e: IOException) {
    e.printStackTrace()
}

Java

InputImage image;
try {
    image = InputImage.fromFilePath(context, uri);
} catch (IOException e) {
    e.printStackTrace();
}

Mit einem ByteBuffer oder ByteArray

Wenn Sie ein InputImage-Objekt aus einem ByteBuffer oder ByteArray erstellen möchten, berechnen Sie zuerst den Drehwinkel des Bildes, wie oben für die media.Image-Eingabe beschrieben. Erstellen Sie dann das InputImage-Objekt mit dem Puffer oder Array sowie der Höhe, Breite, Farbcodierung und dem Drehgrad des Bilds:

Kotlin

val image = InputImage.fromByteBuffer(
        byteBuffer,
        /* image width */ 480,
        /* image height */ 360,
        rotationDegrees,
        InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12
)
// Or:
val image = InputImage.fromByteArray(
        byteArray,
        /* image width */ 480,
        /* image height */ 360,
        rotationDegrees,
        InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12
)

Java

InputImage image = InputImage.fromByteBuffer(byteBuffer,
        /* image width */ 480,
        /* image height */ 360,
        rotationDegrees,
        InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12
);
// Or:
InputImage image = InputImage.fromByteArray(
        byteArray,
        /* image width */480,
        /* image height */360,
        rotation,
        InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12
);

Mit einem Bitmap

Wenn Sie ein InputImage-Objekt aus einem Bitmap-Objekt erstellen möchten, verwenden Sie die folgende Deklaration:

Kotlin

val image = InputImage.fromBitmap(bitmap, 0)

Java

InputImage image = InputImage.fromBitmap(bitmap, rotationDegree);

Das Bild wird durch ein Bitmap-Objekt zusammen mit den Drehgraden dargestellt.

3. Bild verarbeiten

Übergeben Sie das vorbereitete InputImage-Objekt an die Methode process von PoseDetector.

Kotlin

Task<Pose> result = poseDetector.process(image)
       .addOnSuccessListener { results ->
           // Task completed successfully
           // ...
       }
       .addOnFailureListener { e ->
           // Task failed with an exception
           // ...
       }

Java

Task<Pose> result =
        poseDetector.process(image)
                .addOnSuccessListener(
                        new OnSuccessListener<Pose>() {
                            @Override
                            public void onSuccess(Pose pose) {
                                // Task completed successfully
                                // ...
                            }
                        })
                .addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                // Task failed with an exception
                                // ...
                            }
                        });

4. Informationen zur erkannten Pose abrufen

Wenn im Bild eine Person erkannt wird, gibt die API für die Haltungserkennung ein Pose-Objekt mit 33 PoseLandmarks zurück.

Wenn die Person nicht vollständig im Bild ist, weist das Modell den fehlenden Markierungen Koordinaten außerhalb des Bildes zu und gibt ihnen niedrige Werte für die Konfidenz im Bild.

Wenn im Frame keine Person erkannt wurde, enthält das Pose-Objekt keine PoseLandmark.

Kotlin

// Get all PoseLandmarks. If no person was detected, the list will be empty
val allPoseLandmarks = pose.getAllPoseLandmarks()

// Or get specific PoseLandmarks individually. These will all be null if no person
// was detected
val leftShoulder = pose.getPoseLandmark(PoseLandmark.LEFT_SHOULDER)
val rightShoulder = pose.getPoseLandmark(PoseLandmark.RIGHT_SHOULDER)
val leftElbow = pose.getPoseLandmark(PoseLandmark.LEFT_ELBOW)
val rightElbow = pose.getPoseLandmark(PoseLandmark.RIGHT_ELBOW)
val leftWrist = pose.getPoseLandmark(PoseLandmark.LEFT_WRIST)
val rightWrist = pose.getPoseLandmark(PoseLandmark.RIGHT_WRIST)
val leftHip = pose.getPoseLandmark(PoseLandmark.LEFT_HIP)
val rightHip = pose.getPoseLandmark(PoseLandmark.RIGHT_HIP)
val leftKnee = pose.getPoseLandmark(PoseLandmark.LEFT_KNEE)
val rightKnee = pose.getPoseLandmark(PoseLandmark.RIGHT_KNEE)
val leftAnkle = pose.getPoseLandmark(PoseLandmark.LEFT_ANKLE)
val rightAnkle = pose.getPoseLandmark(PoseLandmark.RIGHT_ANKLE)
val leftPinky = pose.getPoseLandmark(PoseLandmark.LEFT_PINKY)
val rightPinky = pose.getPoseLandmark(PoseLandmark.RIGHT_PINKY)
val leftIndex = pose.getPoseLandmark(PoseLandmark.LEFT_INDEX)
val rightIndex = pose.getPoseLandmark(PoseLandmark.RIGHT_INDEX)
val leftThumb = pose.getPoseLandmark(PoseLandmark.LEFT_THUMB)
val rightThumb = pose.getPoseLandmark(PoseLandmark.RIGHT_THUMB)
val leftHeel = pose.getPoseLandmark(PoseLandmark.LEFT_HEEL)
val rightHeel = pose.getPoseLandmark(PoseLandmark.RIGHT_HEEL)
val leftFootIndex = pose.getPoseLandmark(PoseLandmark.LEFT_FOOT_INDEX)
val rightFootIndex = pose.getPoseLandmark(PoseLandmark.RIGHT_FOOT_INDEX)
val nose = pose.getPoseLandmark(PoseLandmark.NOSE)
val leftEyeInner = pose.getPoseLandmark(PoseLandmark.LEFT_EYE_INNER)
val leftEye = pose.getPoseLandmark(PoseLandmark.LEFT_EYE)
val leftEyeOuter = pose.getPoseLandmark(PoseLandmark.LEFT_EYE_OUTER)
val rightEyeInner = pose.getPoseLandmark(PoseLandmark.RIGHT_EYE_INNER)
val rightEye = pose.getPoseLandmark(PoseLandmark.RIGHT_EYE)
val rightEyeOuter = pose.getPoseLandmark(PoseLandmark.RIGHT_EYE_OUTER)
val leftEar = pose.getPoseLandmark(PoseLandmark.LEFT_EAR)
val rightEar = pose.getPoseLandmark(PoseLandmark.RIGHT_EAR)
val leftMouth = pose.getPoseLandmark(PoseLandmark.LEFT_MOUTH)
val rightMouth = pose.getPoseLandmark(PoseLandmark.RIGHT_MOUTH)

Java

// Get all PoseLandmarks. If no person was detected, the list will be empty
List<PoseLandmark> allPoseLandmarks = pose.getAllPoseLandmarks();

// Or get specific PoseLandmarks individually. These will all be null if no person
// was detected
PoseLandmark leftShoulder = pose.getPoseLandmark(PoseLandmark.LEFT_SHOULDER);
PoseLandmark rightShoulder = pose.getPoseLandmark(PoseLandmark.RIGHT_SHOULDER);
PoseLandmark leftElbow = pose.getPoseLandmark(PoseLandmark.LEFT_ELBOW);
PoseLandmark rightElbow = pose.getPoseLandmark(PoseLandmark.RIGHT_ELBOW);
PoseLandmark leftWrist = pose.getPoseLandmark(PoseLandmark.LEFT_WRIST);
PoseLandmark rightWrist = pose.getPoseLandmark(PoseLandmark.RIGHT_WRIST);
PoseLandmark leftHip = pose.getPoseLandmark(PoseLandmark.LEFT_HIP);
PoseLandmark rightHip = pose.getPoseLandmark(PoseLandmark.RIGHT_HIP);
PoseLandmark leftKnee = pose.getPoseLandmark(PoseLandmark.LEFT_KNEE);
PoseLandmark rightKnee = pose.getPoseLandmark(PoseLandmark.RIGHT_KNEE);
PoseLandmark leftAnkle = pose.getPoseLandmark(PoseLandmark.LEFT_ANKLE);
PoseLandmark rightAnkle = pose.getPoseLandmark(PoseLandmark.RIGHT_ANKLE);
PoseLandmark leftPinky = pose.getPoseLandmark(PoseLandmark.LEFT_PINKY);
PoseLandmark rightPinky = pose.getPoseLandmark(PoseLandmark.RIGHT_PINKY);
PoseLandmark leftIndex = pose.getPoseLandmark(PoseLandmark.LEFT_INDEX);
PoseLandmark rightIndex = pose.getPoseLandmark(PoseLandmark.RIGHT_INDEX);
PoseLandmark leftThumb = pose.getPoseLandmark(PoseLandmark.LEFT_THUMB);
PoseLandmark rightThumb = pose.getPoseLandmark(PoseLandmark.RIGHT_THUMB);
PoseLandmark leftHeel = pose.getPoseLandmark(PoseLandmark.LEFT_HEEL);
PoseLandmark rightHeel = pose.getPoseLandmark(PoseLandmark.RIGHT_HEEL);
PoseLandmark leftFootIndex = pose.getPoseLandmark(PoseLandmark.LEFT_FOOT_INDEX);
PoseLandmark rightFootIndex = pose.getPoseLandmark(PoseLandmark.RIGHT_FOOT_INDEX);
PoseLandmark nose = pose.getPoseLandmark(PoseLandmark.NOSE);
PoseLandmark leftEyeInner = pose.getPoseLandmark(PoseLandmark.LEFT_EYE_INNER);
PoseLandmark leftEye = pose.getPoseLandmark(PoseLandmark.LEFT_EYE);
PoseLandmark leftEyeOuter = pose.getPoseLandmark(PoseLandmark.LEFT_EYE_OUTER);
PoseLandmark rightEyeInner = pose.getPoseLandmark(PoseLandmark.RIGHT_EYE_INNER);
PoseLandmark rightEye = pose.getPoseLandmark(PoseLandmark.RIGHT_EYE);
PoseLandmark rightEyeOuter = pose.getPoseLandmark(PoseLandmark.RIGHT_EYE_OUTER);
PoseLandmark leftEar = pose.getPoseLandmark(PoseLandmark.LEFT_EAR);
PoseLandmark rightEar = pose.getPoseLandmark(PoseLandmark.RIGHT_EAR);
PoseLandmark leftMouth = pose.getPoseLandmark(PoseLandmark.LEFT_MOUTH);
PoseLandmark rightMouth = pose.getPoseLandmark(PoseLandmark.RIGHT_MOUTH);

Tipps zur Leistungsverbesserung

Die Qualität der Ergebnisse hängt von der Qualität des Eingabebilds ab:

  • Damit ML Kit die Körperhaltung genau erkennen kann, muss die Person auf dem Bild durch ausreichend Pixeldaten dargestellt werden. Für eine optimale Leistung sollte das Motiv mindestens 256 × 256 Pixel groß sein.
  • Wenn Sie die Körperhaltung in einer Echtzeitanwendung erkennen, sollten Sie auch die Gesamtabmessungen der Eingabebilder berücksichtigen. Kleinere Bilder können schneller verarbeitet werden. Um die Latenz zu verringern, sollten Sie Bilder mit niedrigerer Auflösung aufnehmen. Beachten Sie dabei jedoch die oben genannten Auflösungsanforderungen und achten Sie darauf, dass das Motiv möglichst viel Platz auf dem Bild einnimmt.
  • Auch ein unscharfer Bildfokus kann sich auf die Genauigkeit auswirken. Wenn Sie keine zufriedenstellenden Ergebnisse erhalten, bitten Sie den Nutzer, das Bild noch einmal aufzunehmen.

Wenn Sie die Körperhaltungserkennung in einer Echtzeitanwendung verwenden möchten, beachten Sie die folgenden Richtlinien, um die beste Framerate zu erzielen:

  • Verwenden Sie das Base Pose Detection SDK und STREAM_MODE.
  • Sie können auch Bilder mit niedrigerer Auflösung aufnehmen. Beachten Sie jedoch auch die Anforderungen an die Bildabmessungen dieser API.
  • Wenn Sie die Camera- oder camera2-API verwenden, begrenzen Sie die Aufrufe an den Detektor. Wenn während der Laufzeit des Detektors ein neuer Videoframe verfügbar wird, legen Sie ihn ab. Ein Beispiel finden Sie in der Klasse VisionProcessorBase in der Beispiel-App für die Schnellstartanleitung.
  • Wenn Sie die CameraX API verwenden, muss die Backpressure-Strategie auf den Standardwert ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST festgelegt sein. So wird sichergestellt, dass immer nur ein Bild zur Analyse gesendet wird. Wenn mehr Bilder erstellt werden, während der Analyser beschäftigt ist, werden sie automatisch gelöscht und nicht für die Übermittlung in die Warteschlange gestellt. Sobald das analysierte Bild durch Aufrufen von ImageProxy.close() geschlossen wurde, wird das nächste aktuelle Bild gesendet.
  • 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. Dieser wird nur einmal pro Eingabeframe auf der Displayoberfläche gerendert. Eines dieser Beispiele finden Sie in der Beispiel-App für den Schnellstart in den Klassen CameraSourcePreview und GraphicOverlay.
  • Wenn Sie die Camera2 API verwenden, sollten Sie Bilder im ImageFormat.YUV_420_888-Format aufnehmen. Wenn Sie die ältere Camera API verwenden, nehmen Sie Bilder im ImageFormat.NV21-Format auf.

Nächste Schritte