Я пытаюсь развернуть пример 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-вещи?