Frage Android camera2 Capture Burst ist zu langsam


Ich versuche, den android-Camera2Basic-Code zu ändern, um einen Ausbruch von Bildern zu erfassen. Allerdings kann ich die Verzögerung zwischen Bildern nicht schneller als 200-300ms auf meinem Nexus 5 mit L 5.0.1 erreichen.

Ich habe eine Menge Dinge ausprobiert, aber das ist das grundlegendste. Dies ist der einzige Teil des Camera2Basic-Codes, den ich geändert habe. Meine Vorschau TexturView ist nur 50x50dp, aber das sollte egal sein, oder?

Für was es wert ist, hat dieser Code nur Verzögerungen um 50-100ms auf meinem Nexus 6, mit L 5.1.

private void captureStillPicture() {
    try {
        List<CaptureRequest> captureList = new ArrayList<CaptureRequest>();
        mPreviewRequestBuilder.addTarget(mImageReader.getSurface());

        for (int i=0;i<10;i++) {
            captureList.add(mPreviewRequestBuilder.build());
        }

        mCaptureSession.stopRepeating();
        mCaptureSession.captureBurst(captureList, cameraCaptureCallback, null);
        mPreviewRequestBuilder.removeTarget(mImageReader.getSurface());
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

CameraCaptureSession.CaptureCallback cameraCaptureCallback = new CameraCaptureSession.CaptureCallback() {
    @Override
    public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
            TotalCaptureResult result) {
        Log.d("camera","saved");
        mPictureCounter++;
        if (mPictureCounter >= 10)
            unlockFocus();
    }
};

9
2018-03-25 19:47


Ursprung


Antworten:


Das Problem, auf das Sie stoßen, ist ein Artefakt des von Ihnen angeforderten Bildausgabeformats. Der JPEG-Kodierungsprozess stellt eine große Stallzeit in der Kamerapipeline dar, so dass es zwischen dem Ende einer Belichtung und der nächsten, während dieser Kodierung eine große Ausfallzeit gibt.

Die 30fps-Rate, die angegeben wird, kann erreicht werden, indem das Ausgabebildformat auf der ImageReader als YUV, da das eine "native" Ausgabe für die Kamera ist. Auf diese Weise können Sie die Bilder so speichern, wie sie aufgenommen wurden. Anschließend müssen Sie die JPEG-Codierung separat von der Inline-Verarbeitung der Kamera durchführen.

Zum Beispiel auf dem Nexus 5 die Ausgabe Stallzeit für JPEG Kodierung ist 243ms, die Sie beobachtet haben. Zum YUV_420_888 Ausgabe ist es 0ms. Ebenso wegen ihrer großen Größe, RAW_SENSOR Encoding führt eine Stallzeit von 200ms ein.

Beachten Sie auch, dass selbst wenn Sie das Zeitlimit für Hindernisse entfernen, indem Sie ein "schnelleres" Format wählen, immer noch eine minimale Bildzeit, abhängig von der Ausgabebildgröße. Aber für die volle Auflösung des Nexus 5 ist dies 33ms, was Sie erwartet haben.

Die relevanten Informationen sind in den Metadaten der Kamera enthalten StreamConfigurationMap Objekt, Hier. Besuche die getOutputStallDuration(int format, Size size) und getOutputMinFrameDuration(int format, Size size) Methoden zur Bestätigung.


16
2018-03-27 17:31



Versuchen Sie, die folgenden Parameter für die Aufnahmeanforderung festzulegen

requestBuilder = camDevice
        .createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);

requestBuilder.set(CaptureRequest.EDGE_MODE,
        CaptureRequest.EDGE_MODE_OFF);
requestBuilder.set(
        CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE,
        CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON);
requestBuilder.set(
        CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE,
        CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_OFF);
requestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
        CaptureRequest.NOISE_REDUCTION_MODE_OFF);
requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
        CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);

requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);

Ich bin mir nicht sicher, wie schnell Informationen in CameraCaptureSession.CaptureCallback kommen. Es hat keine Bilddaten und kann vor oder nach ImageReader.OnImageAvailableListener aufgerufen werden. Versuchen Sie, die Zeit zwischen ImageReader.OnImageAvailableListener-Aufrufen zu messen. Vergessen Sie nicht, Bilder zu lesen und zu veröffentlichen, da neue Bilder nicht verfügbar sind, wenn der Puffer voll ist und Bilder nicht freigegeben werden. Beispielsweise:

private class imageAvailableListener implements
            ImageReader.OnImageAvailableListener {
        @Override
        public void onImageAvailable(ImageReader ir) {
            Log.i(TAG, "Time = " + System.currentTimeMillis());
            Image im = ir.acquireNextImage();
            im.close();
        }
    }

ImageReader mImageReader = ImageReader.newInstance(imageReaderWidth,
                    imageReaderHeight, ImageFormat.YUV_420_888, 2);
mImageReader.setOnImageAvailableListener(
                    new imageAvailableListener(), null);

5
2018-03-26 17:15



Basierend auf diesem PcMag-Artikel: http://www.pcmag.com/article2/0,2817,2428017,00.asp Mit dem Nexus 5-Serienbildmodus können Sie 3 Bilder pro Sekunde aufnehmen. Es ist sehr unwahrscheinlich, dass zwischen den Fotos weniger als 333ms liegen.

Haben Sie eine Quelle für Informationen, die darauf hindeuten, dass der Nexus 5-Burst schneller sein sollte?


-2
2018-03-25 20:36