【发布时间】:2018-02-23 17:14:52
【问题描述】:
我正在编写一个应用程序,它应该有两个输出表面,一个用于预览,一个用于一些 YUV 处理。对于处理,我想以最少的额外预处理获得图像,因为我知道大多数时候会有 4 倍变焦。因此,我选择从输出尺寸列表(getOutputSizes(ImageFormat.YUV_420_888))中选择Size,它在最小的传感器尺寸中尽可能接近 4 倍变焦(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE 除以 4)。这样,我可以使用 Size 应用“zoom”(CaptureRequest.SCALER_CROP_REGION),因为我知道输出不会受到(额外)插值的影响。
预览大小是根据处理输出的纵横比选择的。
我的问题是我发现输出的质量很大程度上取决于createCaptureSession (List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler) 方法中提供的输出表面。在比较内置相机应用程序的预览图像(相同缩放)和我的处理流(和预览)的图像时,我注意到了这一点。我的重复请求是基于CameraDevice.TEMPLATE_PREVIEW,所以我认为我会得到相同的质量。
文档没有提到任何关于质量的内容,他们只提到了可能的流和目标组合,并提到必须设置管道。
虽然在配置单个输出流时可以使用 getOutputSizes(int) 中的任何尺寸,但当同时配置多个输出时,给定的相机设备可能无法支持尺寸、格式和目标的所有组合.
和
创建会话是一项昂贵的操作,可能需要数百毫秒,因为它需要配置相机设备的内部管道并分配内存缓冲区以将图像发送到所需的目标。
我基本上发现,如果我在会话中添加一个具有最大输出大小(例如 JPEG:MAXIMUM)的虚拟表面(仅用于初始化它),那么我处理图像的质量会好得多。
虽然流配置允许它并且我的特殊上下文(4 倍缩放)适合 PREVIEW 最大尺寸,但我对这种方式感到不舒服。
LEGACY 级别的保证配置
隐私:预览 | YUV:预览 | JPEG:最大 |仍然捕获和应用内处理。
那么有谁知道发生了什么,质量是如何确定的以及如何获得可预测的输出?
- 使用手机:HUAWEI Mate 9
- 传感器有源阵列尺寸:3968x2976
- 裁剪尺寸:1536x863
【问题讨论】:
-
"我基本上发现,如果我在会话中添加一个虚拟表面(仅用于初始化它),并具有最大输出大小(例如 JPEG:MAXIMUM),那么我处理图像的质量好多了。”你能详细说明一下吗?您的意思是您使用 jpeg 图像阅读器创建了一个新请求?
-
@TiagoSantos 我创建了一个 ImageReader (
ImageReader.newInstance(largestJpeg.getWidth(), largestJpeg.getHeight(), ImageFormat.JPEG, 5)),它什么都不做,并在创建捕获会话时将其表面添加到表面列表中。