我正在编写一个应该有两个输出表面的应用程序,一个用于预览,另一个用于某些YUV处理。对于处理,我想获得具有最少额外预处理的图像,知道大多数时间将有4倍变焦。因此,我选择从输出尺寸列表(getOutputSizes(ImageFormat.YUV_420_888)
)中选择尽可能接近4倍变焦(Size
除以4)的CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE
。最小传感器尺寸。这样,我就可以应用" zoom " (CaptureRequest.SCALER_CROP_REGION
)使用此Size
知道输出不受(附加)插值的影响。
预览大小是根据处理输出的宽高比选择的。
我的问题是我发现输出的质量高度依赖于createCaptureSession (List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler)
方法中提供的输出表面。在比较内置相机应用程序(相同缩放)的预览图像和处理流(和预览)的图像时,我注意到了这一点。我的重复请求基于CameraDevice.TEMPLATE_PREVIEW
,所以我假设我会得到相同的质量。
文档没有提及有关质量的任何内容,他们只提到了可能的流和目标组合,并提到必须设置管道。
虽然配置单个输出流时可以使用getOutputSizes(int)中的任何大小,但是当一次配置多个输出时,给定的摄像头设备可能无法支持所有大小,格式和目标的组合。
和
创建会话是一项昂贵的操作,可能需要几百毫秒,因为它需要配置摄像机设备的内部管道并分配内存缓冲区以将图像发送到所需目标。
我基本上发现,如果我在会话中添加一个虚拟表面(仅用于初始化它),并且输出大小最大(例如JPEG:MAXIMUM),那么处理图像的质量要好得多。
虽然流配置允许它和我的特殊上下文(4倍缩放)符合PREVIEW最大尺寸,但我对这种做法感到不舒服。
LEGACY级保证配置
PRIV:预览| YUV:预览| JPEG:MAXIMUM |仍然捕获加上应用内处理。
所以有人知道发生了什么,如何确定质量以及如何获得可预测的输出?
答案 0 :(得分:1)
幕后的逻辑是复杂的,特定于设备的,因此我通常只提供一些指导原则:
如果您为会话请求的最大分辨率远低于相机支持的最大分辨率,相机通常会尝试选择更节能的模式进行操作 - 基本上,只读取二次采样图像关闭传感器,而不是全分辨率。这节省了大量功率,这对于视频聊天应用,视频录制以及不需要完全分辨率的类似长时间运行任务非常重要。
如果相机设备选择二次采样传感器模式,则数码变焦的质量将大幅下降。不幸的是,没有办法告诉相机您将要求最大数字变焦以及低分辨率输出以获得1:1的传感器窗口。
从实际情况来说,如果你真的想要裁剪区域的1:1图像质量,并且你没有将它绘制到屏幕上,你可能最好拍摄全分辨率图像然后剪裁自己。或者,如果您需要显示预览,配置您从不使用的全分辨率JPEG输出(例如),强制相机选择全尺寸传感器输出模式。
有关传感器模式配置的详细信息很难实现,因为对可用传感器模式和各种带宽/功率限制的限制很难用简单的方式来描述,所以现在保证就是获得像素您要求进行流式配置 - 如果您没有配置完整分辨率输出,则无法保证数码变焦无论如何都能提供相同的质量。