Bildanalyse

Die Bildanalyse stellt Ihrer App ein CPU-zugängliches Image zur Verfügung, auf dem Sie Bildverarbeitung, maschinelles Sehen oder maschinelles Lernen durchführen. Die in der Anwendung ein analyze() die auf jedem Frame ausgeführt wird.

Informationen zur Integration des ML-Kits von Google in Ihre CameraX-App Siehe ML Kit Analyzer.

Betriebsmodi

Wenn die Analysepipeline der Anwendung nicht mit dem Frame von CameraX mithalten kann kann CameraX so konfiguriert werden, dass Frames gelöscht werden. Dazu gibt es folgende Möglichkeiten:

  • non-blocking (Standardeinstellung): In diesem Modus speichert der Executor immer das Element neuestes Bild in einen Bildpuffer (ähnlich einer Warteschlange mit einer Tiefe von eins) während die Anwendung das vorherige Bild analysiert. Wenn CameraX ein neues Bild erhält, bevor die Anwendung die Verarbeitung beendet hat, neues Bild im selben Zwischenspeicher gespeichert wird, wodurch das vorherige Bild überschrieben wird. Beachten Sie, dass ImageAnalysis.Builder.setImageQueueDepth() keine Auswirkungen auf und der Pufferinhalt wird immer überschrieben. Sie können diesen nicht blockierenden Modus aktivieren, indem Sie setBackpressureStrategy() mit STRATEGY_KEEP_ONLY_LATEST Weitere Informationen zu den Auswirkungen von Executor finden Sie in der Referenz. Dokumentation für STRATEGY_KEEP_ONLY_LATEST

  • blocking: In diesem Modus kann das interne Executor mehrere Images hinzufügen. an die interne Bildwarteschlange gesendet und beginnt erst dann mit dem Verwerfen von Frames, wenn die Warteschlange voll. Die Blockierung gilt für das gesamte Kameragerät: Kamerageräte mehrere gebundene Anwendungsfälle haben, sind diese wird blockiert, während KameraX diese Bilder verarbeitet. Für Beispiel: Wenn sowohl die Vorschau als auch die Bildanalyse an ein Kameragerät gebunden sind, wird die Vorschau auch blockiert, während CameraX die Bilder verarbeitet. Sie können den Blockiermodus aktivieren, indem Sie STRATEGY_BLOCK_PRODUCER bis setBackpressureStrategy() Sie können die Tiefe der Image-Warteschlange auch mithilfe von ImageAnalysis.Builder.setImageQueueDepth() auf.

Mit einem Analysetool mit niedriger Latenz und hoher Leistung, das Analysieren eines Bildes kürzer als die Dauer eines CameraX-Frames ist (z. B. 16 ms für 60 fps) ermöglicht jeder Betriebsmodus eine reibungslose Gesamtwiedergabe Nutzererfahrung. Der Blockiermodus kann in einigen Szenarien weiterhin hilfreich sein, z. B. sehr kurzen Systemjitters bewältigt werden.

Mit einem leistungsstarken Analysetool für hohe Latenz und längere Warteschlange erforderlich ist, um die Latenz auszugleichen. Beachten Sie jedoch, dass der trotzdem alle Frames verarbeiten kann.

Mit einem Analysegerät mit hoher Latenz und einem zeitaufwendigen Analysetool (das Analysegerät kann nicht alle Frames kann ein nicht blockierender Modus da Frames für den Analysepfad entfernt werden müssen, aber gleichzeitig gebundene Anwendungsfälle alle Frames sehen können.

Implementierung

So verwenden Sie die Bildanalyse in Ihrer Anwendung:

Unmittelbar nach der Bindung sendet CameraX die Bilder an das registrierte Analysegerät. Rufen Sie nach Abschluss der Analyse ImageAnalysis.clearAnalyzer() oder heben Sie die Bindung für den Anwendungsfall ImageAnalysis auf, um die Analyse zu beenden.

Anwendungsfall für ImageAnalysis erstellen

ImageAnalysis verbindet Ihrem Analysegerät (einem Bildnutzer) zu CameraX, einem Bildersteller. Anwendungen können ImageAnalysis.Builder um ein ImageAnalysis-Objekt zu erstellen. Mit der ImageAnalysis.Builder kann Folgendes konfigurieren:

Anwendungen können entweder die Auflösung oder das Seitenverhältnis festlegen, aber nicht beides. Die genaue Ausgabeauflösung hängt von der angeforderten Größe der Anwendung ab (oder Seitenverhältnis) und Hardwarefunktionen und können vom angeforderten Wert abweichen. Größe oder Seitenverhältnis. Informationen zum Algorithmus für den Auflösungsabgleich findest du unter die Dokumentation für setTargetResolution()

Eine Anwendung kann die Ausgabebildpixel so konfigurieren, dass sie in YUV (Standardeinstellung) vorliegen. oder RGBA-Farbräume. Bei der Einstellung eines RGBA-Ausgabeformats stellt CameraX intern konvertiert Bilder vom YUV in RGBA und packt Bildbits in den ByteBuffer der ersten Ebene des ImageProxy (die anderen beiden Ebenen werden nicht verwendet) folgende Sequenz:

ImageProxy.getPlanes()[0].buffer[0]: alpha
ImageProxy.getPlanes()[0].buffer[1]: red
ImageProxy.getPlanes()[0].buffer[2]: green
ImageProxy.getPlanes()[0].buffer[3]: blue
...

Bei der Durchführung einer komplizierten Bildanalyse, bei der das Gerät keine können Sie CameraX so konfigurieren, dass Frames mit die im Abschnitt Betriebsmodi dieses Themas beschriebenen Strategien.

Analyseprogramm erstellen

Anwendungen können Analysefunktionen erstellen, indem sie die ImageAnalysis.Analyzer und Überschreiben analyze(ImageProxy image) In jedem Analysator erhalten Anwendungen ein ImageProxy, ein Wrapper für Media.Image. Das Bildformat kann abgefragt werden mit ImageProxy.getFormat() Das Format ist einer der folgenden Werte, mit dem ImageAnalysis.Builder bereitstellt:

  • ImageFormat.RGBA_8888, wenn die App OUTPUT_IMAGE_FORMAT_RGBA_8888 angefordert hat.
  • ImageFormat.YUV_420_888, wenn die App OUTPUT_IMAGE_FORMAT_YUV_420_888 angefordert hat.

Siehe den Anwendungsfall "ImageAnalysis erstellen" für Farbraumkonfigurationen und dazu, wo die Pixelbyte abgerufen werden können.

In einem Analyseprogramm sollte die Anwendung folgende Schritte ausführen:

  1. Analysieren Sie einen bestimmten Frame so schnell wie möglich, am besten innerhalb des eines bestimmten Zeitlimits für die Framerate (z. B. weniger als 32 ms bei 30 fps) Wenn die Anwendung einen Frame nicht schnell genug analysieren kann, einer der unterstützte Frame-Drop-Mechanismen.
  2. Gib ImageProxy an CameraX frei, indem du folgenden Befehl aufrufst: ImageProxy.close() Beachten Sie, dass Sie die Schließfunktion von Media.Image nicht aufrufen sollten. (Media.Image.close())

Anwendungen können die verpackte Media.Image direkt in ImageProxy verwenden. Rufe einfach nicht Media.Image.close() für das umschlossene Bild auf, da dies beschädigt werden würde. den Mechanismus zur Bildfreigabe in CameraX; verwenden Sie stattdessen ImageProxy.close() um die zugrunde liegende Media.Image für CameraX freizugeben.

Analysegerät für ImageAnalysis konfigurieren

Nachdem Sie ein Analysetool erstellt haben, ImageAnalysis.setAnalyzer() um mit der Analyse zu beginnen. Sobald Sie mit der Analyse fertig sind, ImageAnalysis.clearAnalyzer() um das registrierte Analysegerät zu entfernen.

Für die Bildanalyse kann nur ein aktives Analyseprogramm konfiguriert werden. Anrufen ImageAnalysis.setAnalyzer() ersetzt das registrierte Analysegerät, falls es bereits existiert. Anwendungen können jederzeit vor oder nach der Bindung ein neues Analyseprogramm festlegen für den Anwendungsfall.

ImageAnalysis an einen Lebenszyklus binden

Es wird dringend empfohlen, ImageAnalysis an eine vorhandene AndroidX-Lebenszyklus mit dem ProcessCameraProvider.bindToLifecycle() . Beachten Sie, dass die bindToLifecycle()-Funktion die ausgewählten Camera-Gerät, das verwendet werden kann um erweiterte Einstellungen wie die Belichtung und andere Einstellungen zu optimieren. Weitere Informationen zur Steuerung der Kameraausgabe findest du in dieser Anleitung.

Im folgenden Beispiel werden alle Elemente aus den vorherigen Schritten kombiniert, CameraX-Anwendungsfälle für ImageAnalysis und Preview für einen lifeCycle-Inhaber:

Kotlin

val imageAnalysis = ImageAnalysis.Builder()
    // enable the following line if RGBA output is needed.
    // .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
    .setTargetResolution(Size(1280, 720))
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
    .build()
imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer { imageProxy ->
    val rotationDegrees = imageProxy.imageInfo.rotationDegrees
    // insert your code here.
    ...
    // after done, release the ImageProxy object
    imageProxy.close()
})

cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageAnalysis, preview)

Java

ImageAnalysis imageAnalysis =
    new ImageAnalysis.Builder()
        // enable the following line if RGBA output is needed.
        //.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
        .setTargetResolution(new Size(1280, 720))
        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
        .build();

imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
    @Override
    public void analyze(@NonNull ImageProxy imageProxy) {
        int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees();
            // insert your code here.
            ...
            // after done, release the ImageProxy object
            imageProxy.close();
        }
    });

cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, imageAnalysis, preview);

Weitere Informationen

Weitere Informationen zu CameraX finden Sie in den folgenden zusätzlichen Ressourcen.

Codelab

  • <ph type="x-smartling-placeholder"></ph> Erste Schritte mit CameraX
  • Codebeispiel

  • <ph type="x-smartling-placeholder"></ph> Beispiel-Apps für CameraX