我正在实现一个应用程序,该应用程序对相机的实时图像使用实时图像处理。使用现在不推荐使用的android.hardware.Camera,它有一定的局限性。为了提高灵活性和性能,我想使用新的android.hardware.camera2 API。但是,我无法获取原始图像数据进行处理。这是在三星Galaxy S5上。(不幸的是,我没有方便的其他Lollipop设备可以在其他硬件上进行测试)。
我得到了整个框架(从“ HdrViewFinder”和“ Camera2Basic”示例中获得灵感),并且通过SurfaceTexture和GLSurfaceView在屏幕上绘制了实时图像。但是,我还需要访问图像数据(至少目前至少可以使用灰度级)进行自定义图像处理。根据StreamConfigurationMap.isOutputSupportedFor(class)的文档,建议直接获取图像数据的表面将是ImageReader(对吗?)。
因此,我将捕获请求设置为:
mSurfaceTexture.setDefaultBufferSize(640, 480);
mSurface = new Surface(surfaceTexture);
...
mImageReader = ImageReader.newInstance(640, 480, format, 2);
...
List<Surface> surfaces = new ArrayList<Surface>();
surfaces.add(mSurface);
surfaces.add(mImageReader.getSurface());
...
mCameraDevice.createCaptureSession(surfaces, mCameraSessionListener, mCameraHandler);
在ImageReader的onImageAvailable回调中,我正在按以下方式访问数据:
Image img = reader.acquireLatestImage();
ByteBuffer grayscalePixelsDirectByteBuffer = img.getPlanes()[0].getBuffer();
...但是在(如前所述)实时图像预览正常工作时,我在这里获得的数据(或我获得数据的方式)存在问题。根据
mCameraInfo.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputFormats();
...应支持以下ImageFormat:NV21,JPEG,YV12,YUV_420_888。我已经尝试了所有方法(为上述“格式”插入了插件),都支持根据设置分辨率getOutputSizes(format)
,但是没有一个能够提供理想的结果:
我在这里想念什么?是什么导致图像被翻转和压扁?如何获得几何上正确的灰度缓冲区?我应该使用其他类型的表面(而不是ImageReader)吗?
任何提示表示赞赏。
我找到了一个解释(尽管不一定是令人满意的解决方案):事实证明,传感器阵列的纵横比为16:9(可通过找到mCameraInfo.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
)。
至少在请求YV12 / YUV_420_888时,拖缆似乎不以任何方式裁剪图像,而是不均匀地缩放图像以达到请求的帧大小。当请求16:9格式(不幸的是,只有两种高分辨率)时,图像具有正确的比例。对我来说似乎有些奇怪-请求JPEG或使用等效的旧相机API函数或静止图像时,似乎不会发生这种情况;而且我不确定非均匀缩放的帧会适合什么。
我觉得这不是一个令人满意的解决方案,因为这意味着您不能依赖输出格式列表,而必须先找到传感器尺寸,找到具有相同长宽比的格式,然后自己对图像进行下采样(如所须)...
我不知道这是这里的预期结果还是S5的“功能”。评论或建议仍然欢迎。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句