【问题标题】:Android camera2 preview image disorder when saved using ImageReader使用ImageReader保存时Android camera2预览图像混乱
【发布时间】:2019-03-25 08:29:39
【问题描述】:

我正在使用 Android Camera2 API 拍摄一系列照片,用于实时姿势估计和环境重建(SLAM 问题)。目前我只是将所有这些图片保存在我的 SD 卡中以供离线处理。

我根据 google 的 Camera2Basic 使用 TextureViewImageReader 设置处理管道,它们都被设置为重复预览请求的目标表面。

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();
                    }
                }
            }
        });

按下按钮时会添加/删除ImageReaderImageReaderOnImageAvailableListener 实现如下:

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)丢弃旧帧,还检查了图像的时间戳以确保它们单调增加。

阅读器确实以可接受的速率(大约 25fps)接收图像。然而,仔细查看保存的图像序列表明它们不是 始终按时间顺序保存。

以下图片来自程序拍摄的长序列(抱歉无法直接发图:():

图片1:

图 2:

图 3:

这种紊乱并不经常发生,但它们随时可能发生,而且似乎不是初始化问题。我想这与ImageReader 的缓冲区大小有关,因为缓冲区越大,“闪回”就越少。有人有同样的问题吗?

【问题讨论】:

    标签: java android android-camera2


    【解决方案1】:

    当您启用 ImageReader 时,您是使用 TEMPLATE_STILL_CAPTURE 来处理捕获请求,还是仅使用 TEMPLATE_PREVIEW?您发现哪些设备存在问题?

    如果您使用的是 STILL_CAPTURE,请确保检查设备是否支持 ENABLE_ZSL 标志,并将其设置为 false。当它设置为 true 时(通常是支持它的设备上的默认设置,对于 STILL_CAPTURE 模板),由于相机设备中存在一个零快门延迟队列,因此图像可能会乱序返回。

    【讨论】:

    • 感谢您的申请!但是我正在使用 TEMPLATE_PREVIEW 并开始重复捕获会话。
    【解决方案2】:

    我终于发现,当在其构造函数中将ImageReader 的格式设置为YUV_420_888 时,这种混乱消失了。最初我将此字段设置为JPEG

    使用JPEG 格式不仅会导致较大的处理延迟,而且会导致混乱。我猜从图像传感器数据到所需格式的转换利用了其他硬件,例如 DSP 或 GPU,它们不能保证时间顺序。

    【讨论】:

      猜你喜欢
      • 2017-01-06
      • 1970-01-01
      • 2023-03-12
      • 2017-09-09
      • 2012-07-04
      • 1970-01-01
      • 2016-08-19
      • 1970-01-01
      • 2014-10-17
      相关资源
      最近更新 更多