输出流、裁剪和缩放

输出流

相机子系统仅在基于 ANativeWindow 的管道上运行,适用于所有分辨率和输出格式。可以一次配置多个流以将单个帧发送到多个目标,例如 GPU、视频编码器、 RenderScript或应用程序可见的缓冲区(RAW Bayer、已处理的 YUV 缓冲区或 JPEG 编码的缓冲区)。

作为优化,必须提前配置这些输出流,并且一次只能存在有限的数量。这允许预先分配内存缓冲区和配置相机硬件,以便在提交请求时列出多个或不同的输出管道,在完成请求时不会出现延迟或延迟。

有关取决于支持的硬件级别的保证流输出组合的更多信息,请参阅createCaptureSession()

裁剪

通过 ANDROID_SCALER_CROP_REGION 设置传达全像素阵列的裁剪(用于数字变焦和其他需要较小 FOV 的用例)。这是一个按请求设置,可以根据每个请求进行更改,这对于实现流畅的数字变焦至关重要。

该区域被定义为一个矩形 (x, y, width, height),其中 (x, y) 描述了矩形的左上角。矩形在传感器有源像素阵列的坐标系上定义,(0,0) 是有源像素阵列的左上角像素。因此,宽度和高度不能大于 ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY 静态信息字段中报告的尺寸。 HAL 通过 ANDROID_SCALER_MAX_DIGITAL_ZOOM 静态信息字段报告允许的最小宽度和高度,该字段描述了支持的最大缩放系数。因此,最小裁剪区域宽度和高度为:

  {width, height} =
   { floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[0] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM),
     floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[1] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM) }

如果裁剪区域需要满足特定要求(例如,它需要从偶数坐标开始,并且它的宽度/高度需要是偶数),HAL 必须进行必要的舍入并写出输出中使用的最终裁剪区域结果元数据。同样,如果 HAL 实现了视频稳定,它必须调整结果裁剪区域以描述应用视频稳定后实际包含在输出中的区域。一般来说,使用相机的应用程序必须能够根据裁剪区域、图像传感器的尺寸和镜头焦距来确定它正在接收的视野。

由于裁剪区域适用于所有流,其纵横比可能与裁剪区域不同,因此用于每个流的确切传感器区域可能小于裁剪区域。具体来说,每个流应通过最小程度地进一步裁剪定义的裁剪区域来保持方形像素及其纵横比。如果流的纵横比比裁剪区域宽,则应进一步垂直裁剪流,如果流的纵横比比裁剪区域窄,则应进一步水平裁剪流。

在所有情况下,流裁剪必须在完整裁剪区域内居中,并且每个流仅相对于完整裁剪区域进行水平或垂直裁剪,而不是两者。

例如,如果定义了两个流,一个 640x480 流(4:3 纵横比)和一个 1280x720 流(16:9 纵横比),下面展示了几个样本作物区域的每个流的预期输出区域,假设为 3 MP(2000 x 1500 像素阵列)传感器。

裁剪区域:(500、375、1000、750)(4:3 纵横比)
640x480 流式裁剪:(500、375、1000、750)(等于裁剪区域)
1280x720 流式裁剪:(500、469、1000、562)

作物区域 43 比率

图 1. 4:3 纵横比

裁剪区域:(500、375、1333、750)(16:9 纵横比)
640x480 流式裁剪:(666、375、1000、750)
1280x720 流式裁剪:(500、375、1333、750)(等于裁剪区域)

作物区域 169 比率

图 2. 16:9 纵横比

裁剪区域:(500、375、750、750)(1:1 纵横比)
640x480 流式裁剪:(500、469、750、562)
1280x720 流式裁剪:(500、543、750、414)

作物区域 11 比率

图 3. 1:1 纵横比

最后一个示例,一个 1024x1024 方形纵横比流而不是 480p 流:
裁剪区域:(500、375、1000、750)(4:3 纵横比)
1024x1024 流式作物:(625、375、750、750)
1280x720 流式裁剪:(500、469、1000、562)

裁剪区域 43 平方比

图 4. 4:3 纵横比,正方形

再加工

通过对 RAW Bayer 数据的重新处理支持提供对原始图像文件的额外支持。此支持允许相机管道处理先前捕获的 RAW 缓冲区和元数据(先前记录的整个帧),以生成新的渲染 YUV 或 JPEG 输出。

飞涨

对于运行 Android 11 或更高版本的设备,应用可以通过ANDROID_CONTROL_ZOOM_RATIO设置使用相机的缩放(数字和光学)。

缩放比率定义为浮点因子。除了使用ANDROID_SCALER_CROP_REGION进行裁剪和缩放,应用程序可以使用ANDROID_CONTROL_ZOOM_RATIO来控制缩放级别,并使用ANDROID_SCALER_CROP_REGION进行水平和垂直裁剪以实现与原生相机传感器不同的纵横比。

多相机系统可能包含多个不同焦距的镜头,用户可以通过在镜头之间切换来使用光学变焦。使用ANDROID_CONTROL_ZOOM_RATIO在以下场景中具有优势:

  • 从广角镜头放大到远摄镜头:与ANDROID_SCALER_CROP_REGION的整数值相比,浮点比率提供了更好的精度。
  • 从广角镜头缩小到超广角镜头: ANDROID_CONTROL_ZOOM_RATIO支持缩小 (<1.0f),而ANDROID_SCALER_CROP_REGION不支持。

为了说明,这里有几个不同缩放比例、裁剪区域和输出流的场景,使用上一节中定义的相同假设相机。

缩放比例:2.0;原始视野的 1/4
裁剪区域:(0、0、2000、1500)(4:3 纵横比)
640x480 流裁剪:(0, 0, 2000, 1500)(等于裁剪区域)
1280x720 流式裁剪:(0、187、2000、1125)

缩放比例 2-crop-43

图 5. 2.0 缩放,4:3 纵横比

缩放比例:2.0;原始视野的 1/4
裁剪区域:(0、187、2000、1125)(16:9 纵横比)
640x480 流式裁剪:(250、187、1500、1125)(邮筒)
1280x720 流式裁剪:(0, 187, 2000, 1125)(等于裁剪区域)

缩放比例 2-crop-169

图 6. 2.0 缩放,16:9 纵横比

缩放比例:0.5; 4 倍原始视野(从广角镜头切换到超广角镜头)
裁剪区域:(250、0、1500、1500)(1:1 纵横比)
640x480 流式裁剪:(250、187、1500、1125)(信箱)
1280x720 流式裁剪:(250、328、1500、844)(信箱)

图像/缩放比例-0.5-crop-11

图 7. 0.5 缩放,1:1 纵横比

从上图可以看出,裁剪区域的坐标系变为缩放后的有效视野,并由具有以下尺寸的矩形表示:( 0 , 0 , activeArrayWith , activeArrayHeight )。这同样适用于 AE/AWB/AF 区域和面。此坐标系更改不适用于 RAW 捕获及其相关元数据,例如intrinsicCalibrationlensShadingMap

使用上面相同的假设示例,并假设输出流#1 (640x480) 是取景器流,可以通过以下两种方式之一实现 2.0 倍缩放:

  • zoomRatio = 2.0 , scaler.cropRegion = (0, 0, 2000, 1500)
  • zoomRatio = 1.0 (默认), scaler.cropRegion = (500, 375, 1000, 750)

对于将android.control.aeRegions设置为取景器视野左上角四分之一的应用,请将android.control.aeRegions设置为(0, 0, 1000, 750)并将android.control.zoomRatio设置为2.0 。或者,应用程序可以将android.control.aeRegions设置为1.0android.control.zoomRatio的等效区域(500, 375, 1000, 750)