Android Things - Создание сеанса предварительного просмотра камеры завершается неудачно, и предварительный просмотр не отображается - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь развернуть пример Android TensorFlow-Lite, в частности, активность детектора.

Мне удалось развернуть его на планшете. Приложение прекрасно работает, оно способно обнаруживать объекты, помещать ограничивающий прямоугольник вокруг него, с меткой и уровнем достоверности.

Затем я установил плату Raspberry Pi 3 Model B, установил в нее Android Things, подключил через ADB, а затем развернул ту же программу из Android Studio. Однако экран, который я использовал для своей платы Rπ, был пустым.

После проверки демонстрации камеры для вещей Android у меня возникла идея включить аппаратное ускорение для поддержки предварительного просмотра камеры. Я добавил в:

android:hardwareAccelerated="true"

в теге application Манифеста.

Я также добавил следующее в тег приложения:

<uses-library android:name="com.google.android.things" />

И фильтр намерений в моем теге активности:

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.IOT_LAUNCHER" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Чтобы приложение TensorFlow запускалось после загрузки.

Я снова развернул приложение, но та же ошибка сохраняется - я не могу настроить сеанс экрана предварительного просмотра.

Вот следующий код, который был включен в пример TensorFlow:

private void createCameraPreviewSession() {
    try {
        final SurfaceTexture texture = textureView.getSurfaceTexture();
        assert texture != null;

        // We configure the size of default buffer to be the size of camera preview we want.
        texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());

        // This is the output Surface we need to start preview.
        final Surface surface = new Surface(texture);

        // We set up a CaptureRequest.Builder with the output Surface.
        previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        previewRequestBuilder.addTarget(surface);

        LOGGER.e("Opening camera preview: " + previewSize.getWidth() + "x" + previewSize.getHeight());

        // Create the reader for the preview frames.
        previewReader =
                ImageReader.newInstance(
                        previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);

        previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);
        previewRequestBuilder.addTarget(previewReader.getSurface());

        // Here, we create a CameraCaptureSession for camera preview.
        cameraDevice.createCaptureSession(
                Arrays.asList(surface, previewReader.getSurface()),
                new CameraCaptureSession.StateCallback() {

                    @Override
                    public void onConfigured(final CameraCaptureSession cameraCaptureSession) {
                        // The camera is already closed
                        if (null == cameraDevice) {
                            return;
                        }

                        // When the session is ready, we start displaying the preview.
                        captureSession = cameraCaptureSession;
                        try {
                            // Auto focus should be continuous for camera preview.
                            previewRequestBuilder.set(
                                    CaptureRequest.CONTROL_AF_MODE,
                                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                            // Flash is automatically enabled when necessary.
                            previewRequestBuilder.set(
                                    CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

                            // Finally, we start displaying the camera preview.
                            previewRequest = previewRequestBuilder.build();
                            captureSession.setRepeatingRequest(
                                    previewRequest, captureCallback, backgroundHandler);
                        } catch (final CameraAccessException e) {
                            LOGGER.e(e, "Exception!");
                            LOGGER.e("camera access exception!");
                        }
                    }

                    @Override
                    public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {
                        showToast("Failed");
                        LOGGER.e("configure failed!!");
                    }
                },
                null);
    } catch (final CameraAccessException e) {
        LOGGER.e("camera access exception!");
        LOGGER.e(e, "Exception!");
    }
}

Журнал ошибок - это тот, который находится в методе переопределения onConfigureFailed, и соответствующие журналы ошибок, ведущие к этому оператору:

11-12 14:02:40.677 1991-2035/org.tensorflow.demo E/CameraCaptureSession: Session 0: Failed to create capture session; configuration failed
11-12 14:02:40.679 1991-2035/org.tensorflow.demo E/tensorflow: CameraConnectionFragment: configure failed!!

Однако я не смог отследить трассировку стека Session 0:.

Кроме включения аппаратного ускорения и добавления нескольких других тегов в манифест, я ничего не пробовал.

Я провел свое исследование и видел другие примеры, но они фотографируют только одним нажатием кнопки. Мне нужна рабочая камера.

У меня также есть пример CameraDemoForAndroidThings, но я боюсь, что не знаю, как Котлин может догадаться, как он работает.

Если есть кто-то, кому удалось запустить Java-версию TensorFlow Detection Activity на Raspberry Pi Android Things, просим внести свой вклад и сообщить нам, как вы это сделали.

UPDATE:

Очевидно, что камера может поддерживать только одну конфигурацию потока одновременно. Я также смог сделать вывод, что мне нужно изменить функцию createCaptureSession(), чтобы использовать только одну поверхность, теперь моя функция выглядит так:

cameraDevice.createCaptureSession(
//                    Arrays.asList(surface, previewReader.getSurface()),
        Arrays.asList(surface),
        new CameraCaptureSession.StateCallback() {

            @Override
            public void onConfigured(final CameraCaptureSession cameraCaptureSession) {
                // The camera is already closed
                if (null == cameraDevice) {
                    return;
                }

                // When the session is ready, we start displaying the preview.
                captureSession = cameraCaptureSession;
                try {
                    // Auto focus should be continuous for camera preview.
//                                previewRequestBuilder.set(
//                                        CaptureRequest.CONTROL_AF_MODE,
//                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                    // Flash is automatically enabled when necessary.
//                                previewRequestBuilder.set(
//                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

                    // Finally, we start displaying the camera preview.
                    previewRequest = previewRequestBuilder.build();
                    captureSession.setRepeatingRequest(
                            previewRequest, captureCallback, backgroundHandler);

                    previewRequestBuilder.addTarget(previewReader.getSurface());

                } catch (final CameraAccessException e) {
                    LOGGER.e("exception hit while configuring camera!");
                    LOGGER.e(e, "Exception!");
                }
            }

            @Override
            public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {
                LOGGER.e("Configure failed!");
                showToast("Failed");
            }
        },
        null);

Это позволяет мне получить предварительный просмотр в реальном времени. Однако код не отправляет изображение из предварительного просмотра в блок processImage().

Кто-нибудь успешно реализовал примеры TensorFlow-Lite, включающие предварительные просмотры с камер на Android-вещи?

...