#java #android #android-camera2
#java #Android #android-camera2
Вопрос:
Я делаю серию снимков, используя Android Camera2 API для оценки позы в реальном времени и реконструкции окружающей среды (проблема SLAM). В настоящее время я просто сохраняю все эти снимки на своей SD-карте для автономной обработки.
Я настраиваю конвейер обработки в соответствии с тем, что Google Camera2Basic
использует TextureView
, а также ImageReader
, где они оба заданы в качестве целевых поверхностей для повторного запроса предварительного просмотра.
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mIsShooting){
try {
mCaptureSession.stopRepeating();
mPreviewRequestBuilder.removeTarget(mImageReader.getSurface());
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
mIsShooting = false;
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
else{
try {
mCaptureSession.stopRepeating();
mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
mIsShooting = true;
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
});
ImageReader
Добавляется / удаляется при нажатии кнопки. ImageReader
‘s OnImageAvailableListener
реализован следующим образом:
private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image img = reader.acquireLatestImage();
if(null == img){
return;
}
if(img.getTimestamp() <= mLatestFrameTime){
Log.i(Tag, "disorder detected!");
return;
}
mLatestFrameTime = img.getTimestamp();
ImageSaver saver = new ImageSaver(img, img.getTimestamp());
saver.run();
}
};
Я использую acquireLatestImage
(с размером буфера, установленным на 2) для удаления старых кадров, а также проверил временную метку изображения, чтобы убедиться, что они монотонно увеличиваются.
Считыватель действительно получает изображения с приемлемой скоростью (около 25 кадров в секунду). Однако более пристальный взгляд на сохраненную последовательность изображений показывает, что они не всегда сохраняются в хронологическом порядке.
Следующие изображения взяты из длинной последовательности, снятой программой (извините, что не могу опубликовать изображения напрямую : ( ):
Изображение 1:
Изображение 2:
Изображение 3:
Такой беспорядок возникает не очень часто, но он может возникнуть в любое время и, похоже, не является проблемой инициализации. Я полагаю, это как-то связано с ImageReader
размером буфера, поскольку при большем буфере происходит меньше «обратных вспышек». У кого-нибудь такая же проблема?
Ответ №1:
Я, наконец, обнаружил, что такой беспорядок исчезает при установке ImageReader
формата YUV_420_888
в его конструкторе. Изначально я установил это поле как JPEG
.
Использование JPEG
формата приводит не только к большой задержке обработки, но и к беспорядку. Я предполагаю, что для преобразования данных датчика изображения в желаемый формат используется другое оборудование, такое как DSP или графический процессор, что не гарантирует хронологический порядок.
Ответ №2:
Используете ли вы TEMPLATE_STILL_CAPTURE для запросов на захват при включении ImageReader или просто TEMPLATE_PREVIEW? С какими устройствами вы видите проблемы?
Если вы используете STILL_CAPTURE, обязательно проверьте, поддерживает ли устройство флаг ENABLE_ZSL, и установите для него значение false. Когда для параметра установлено значение true (обычно по умолчанию на устройствах, которые его поддерживают, для шаблона STILL_CAPTURE), изображения могут быть возвращены не по порядку, поскольку на устройстве камеры установлена очередь с нулевой задержкой затвора.
Комментарии:
1. Спасибо за вашу заявку! Однако я использую TEMPLATE_PREVIEW и запускаю повторный сеанс захвата.