Android ImageReader运动检测

时间:2016-02-21 01:57:57

标签: java android image-processing image-formats android-camera2

我正在开发一款必须能够基于机器人camera2 API进行运动检测的应用程序。所以我正在使用ImageReader和相应的OnImageAvailableListener。我有两个目标曲面用于CameraCaptureSession的Frames,UI SurfaceTexture,我在其中显示相机的预览,以及ImageReaders表面。

我有点“强迫”使用ImageFormat.YUV_420_88,原因与此问题中提到的相同:

ImageReader makes Camera lag

我对这种格式有点新意,我需要实现运动检测。

我的想法是以像素方式遍历Image.getPlanes()[i] .getBuffer()并根据特定阈值比较两个图像。

我有两个问题:

  1. 这是个好主意吗?是否有更好/更有效的方式?

  2. 格式YUV_420_88中哪一个平面最适合这种运动检测?

1 个答案:

答案 0 :(得分:0)

  
      
  1. 这是个好主意吗?有没有更好/更有效的方法?
  2.   

是的。 然后,没有其他方法可以比较连续的帧以检测运动事件。

  
      
  1. YUV_420_88格式的哪个平面最适合这种运动检测?
  2.   

我认为是Planes()[0]。

我的示例代码:

mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader imageReader) {
            Image image = null;
            try {
                image = imageReader.acquireLatestImage();
                if (null == image) {
                    return;
                }
                ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                byte[] bytes = new byte[buffer.capacity()];
                buffer.get(bytes);

                detectMotion(bytes);
            } finally {
                if (image != null) {
                    image.close();
                }
            }
        }

        private void detectMotion(byte[] frame) {
            if (null == frame) {
                return;
            }

            int ret = NativeUtil.detectMotion(frame);
            if (ret == 1) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mIvMotion.setVisibility(View.VISIBLE);
                    }
                });
                Log.d(TAG, "Detected motion event");
            } else {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mIvMotion.setVisibility(View.INVISIBLE);
                    }
                });
            }
        }
    };