Android 12 相机图像测试套件版本说明

Android 12 版本中包含多项相机 ITS 变更。本文总结了这些变更,并将其分为四大类:

重构为 Python 3

由于 Python 2.7 已于 2020 年 1 月废弃,因此整个相机 ITS 代码库已重构为 Python 3 代码。在 Android 12 中,需要使用以下 Python 版本和库:

主测试启动器 tools/run_all_tests.py 保持与 Android 11 或更低版本相同,并已重构为 Python 3 代码。

各项测试均已重构,并使用 tests/its_base_test.py 中定义的新测试设置类。大多数测试名称和功能保持不变。在 Android 12 中,各项测试现在都会加载其场景。虽然为每项测试加载场景会增加总测试时间,但这样能够单独对各项测试进行调试。

如需详细了解各项测试变更,请参阅测试变更

以下 Python 模块已重构并更改名称:

  • pymodules/its/caps.pyutils/camera_properties_utils.py
  • pymodules/its/cv2image.pyutils/opencv_processing_utils.py
  • pymodules/its/device.pyutils/its_session_utils.py
  • pymodules/its/error.pyutils/error_util.py
  • pymodules/its/image.pyutils/image_processing_utils.py
  • pymodules/its/objects.pyutils/capture_request_utils.py
  • pymodules/its/target.pyutils/target_exposure_utils.py
  • tools/hw.pyutils/sensor_fusion_utils.py

采用 Mobly 测试框架

Mobly 是一个基于 Python 的测试框架,支持需要多台设备并采用自定义硬件设置的测试用例。相机 ITS 使用 Mobly 测试基础架构来更好地控制测试并改善测试日志记录。

相机 ITS 使用 Mobly 测试基础架构来更好地控制测试并改善测试日志记录。Mobly 是一个基于 Python 的测试框架,支持需要多台设备并采用自定义硬件设置的测试用例。如需详细了解 Mobly,请参阅 google/mobly

config.yml 文件

使用 Mobly 框架,您可以在 its_base_test 类中设置一部被测设备 (DUT) 和一台图表平板电脑。config.yml (YAML) 文件用于创建 Mobly 测试平台。可以在此配置文件中配置多个测试平台,例如一个平板电脑测试平台和一个传感器融合测试平台。在每个测试平台的控制器部分,您可以指定 device_ids 来向测试运行程序标识相应的 Android 设备。除了设备 ID 之外,还会在测试类中传递其他参数,例如平板电脑的 brightnesschart_distancedebug_modecamera_idscene_id。常用的测试参数值包括:

brightness: 192  (all tablets except Pixel C)
chart_distance: 31.0  (rev1/rev1a box for FoV < 90° cameras)
chart_distance: 22.0 (rev2 test rig for FoV > 90° cameras)

基于平板电脑的测试

如果测试基于平板电脑,那么测试平台名称中必须包含关键字 TABLET。在初始化期间,Mobly 测试运行程序会初始化 TestParams 并将其传递给各项测试。

以下是用于运行基于平板电脑的测试的 config.yml 文件示例。

TestBeds:
  - Name: TEST_BED_TABLET_SCENES
    # Test configuration for scenes[0:4, 6, _change]
    Controllers:
        AndroidDevice:
          - serial: 8A9X0NS5Z
            label: dut
          - serial: 5B16001229
            label: tablet

    TestParams:
      brightness: 192
      chart_distance: 22.0
      debug_mode: "False"
      chart_loc_arg: ""
      camera: 0
      scene: <scene-name>  # if <scene-name> runs all scenes

您可以使用 tools/run_all_tests.py 调用测试平台。如果没有命令行值,测试将使用 config.yml 文件的值运行。此外,您还可以在命令行中覆盖 camerascene 的配置文件值,所用的命令与 Android 11 或更低版本类似。

例如:

python tools/run_all_tests.py
python tools/run_all_tests.py camera=1
python tools/run_all_tests.py scenes=2,1,0
python tools/run_all_tests.py camera=1 scenes=2,1,0

传感器融合测试

如果是传感器融合测试,那么测试平台名称中必须包含关键字 SENSOR_FUSION。正确的测试平台依测试的场景而定。Android 12 支持 Arduino 和 Canakit 这两种用于传感器融合的控制器

以下是用于运行传感器融合测试的 config.yml 文件示例。

Testbeds
  - Name: TEST_BED_SENSOR_FUSION
    # Test configuration for sensor_fusion/test_sensor_fusion.py
    Controllers:
        AndroidDevice:
          - serial: 8A9X0NS5Z
            label: dut

    TestParams:
      fps: 30
      img_size: 640,480
      test_length: 7
      debug_mode: "False"
      chart_distance: 25
      rotator_cntl: arduino         # cntl can be arduino or canakit
      rotator_ch: 1
      camera: 0

如需使用传感器融合测试装置运行传感器融合测试,请使用以下命令:

python tools/run_all_tests.py scenes=sensor_fusion
python tools/run_all_tests.py scenes=sensor_fusion camera=0

多个测试平台

配置文件中可以包含多个测试平台。最常见的组合是平板电脑测试平台和传感器融合测试平台的组合。

以下是同时包含平板电脑测试平台和传感器融合测试平台的 config.yml 文件示例。

Testbeds
  - Name: TEST_BED_TABLET_SCENES
    # Test configuration for scenes[0:4, 6, _change]
    Controllers:
        AndroidDevice:
          - serial: 8A9X0NS5Z
            label: dut
          - serial: 5B16001229
            label: tablet

    TestParams:
      brightness: 192
      chart_distance: 22.0
      debug_mode: "False"
      chart_loc_arg: ""
      camera: 0
      scene: <scene-name>  # if <scene-name> runs all scenes

  - Name: TEST_BED_SENSOR_FUSION
    # Test configuration for sensor_fusion/test_sensor_fusion.py
    Controllers:
        AndroidDevice:
          - serial: 8A9X0NS5Z
            label: dut

    TestParams:
      fps: 30
      img_size: 640,480
      test_length: 7
      debug_mode: "False"
      chart_distance: 25
      rotator_cntl: arduino         # cntl can be arduino or canakit
      rotator_ch: 1
      camera: 0

手动测试

Android 12 继续支持手动测试。但是,测试平台必须在测试平台名称中使用关键字 MANUAL 对测试进行相应的标识。此外,该测试平台不能包含平板电脑 ID。

以下是用于手动测试的 config.yml 文件示例。

TestBeds:
  - Name: TEST_BED_MANUAL
    Controllers:
        AndroidDevice:
          - serial: 8A9X0NS5Z
            label: dut

    TestParams:
      debug_mode: "False"
      chart_distance: 31.0
      camera: 0
      scene: scene1

不使用平板电脑的测试场景

场景 0 和场景 5 的测试可以使用 TEST_BED_TABLET_SCENESTEST_BED_MANUAL 完成。不过,如果使用 TEST_BED_TABLET_SCENES 完成测试,必须连接平板电脑且平板电脑序列号必须有效(即便未使用平板电脑),因为测试类设置会分配平板电脑的序列号值。

运行各个测试

您可以仅出于调试目的而运行单个测试,因为系统不会将测试结果报告给 CTS 验证程序。由于无法在命令行中覆盖 config.yml 文件中的 camerascene 值,因此在单个相关测试的 config.yml 文件中,这些参数必须准确无误。此外,如果配置文件中有多个测试平台,必须使用 --test_bed 标志指定测试平台。例如:

python tests/scene1_1/test_black_white.py --config config.yml --test_bed TEST_BED_TABLET_SCENES

测试工件

在 Android 12 中,相机 ITS 测试工件的存储与 Android 11 或更低版本类似,但存在以下变更:

  • 为清楚起见,测试工件 /tmp 目录在 8 字符随机字符串前面附加了 CameraITS_
  • 每项测试的测试输出和错误都存储在 test_log.DEBUG 中,而不是存储在 test_name_stdout.txttest_name_stderr.txt 中。
  • 每一项测试的 DUT 和平板电脑 logcat 都存储在 /tmp/CameraITS_######## 目录中,这简化了调试,因为调试 3A 问题所需的全部信息都记录了下来。

测试变更

在 Android 12 中,平板电脑场景是 PNG 文件而非 PDF 文件。使用 PNG 文件可以让更多型号的平板电脑正确显示场景。

scene0/test_jitter.py

在 Android 12 中,test_jitter 测试针对实体隐藏式相机运行。

scene1_1/test_black_white.py

在 Android 12 中,test_black_white 兼具 test_black_whitetest_channel_saturation 的功能。

下表介绍了 Android 11 中的这两项单独的测试。

测试名称 初始 API 级别 断言
scene1_1/test_black_white.py 全部 短曝光、低增益 RGB 值 ~[0, 0, 0]
长曝光、高增益 RGB 值 ~[255, 255, 255]
scene1_1/test_channel_saturation.py 29 减少了对 [255, 255, 255] 色差的容差,以消除白色图像中的色调。

下表介绍了 Android 12 中将二者合并后的测试 scene1_1/test_black_white.py。

测试名称 初始 API 级别 断言
scene1_1/test_black_white.py 全部 短曝光、低增益 RGB 值 ~[0, 0, 0]
长曝光、高增益 RGB 值 ~[255, 255, 255] 并减少这两个值之间的容差,以消除白色图像中的色调。

scene1_1/test_burst_sameness_manual.py

在 Android 12 中,test_burst_sameness_manual 测试针对实体隐藏式相机运行。

scene1_2/test_tonemap_sequence.py

在 Android 12 中,test_tonemap_sequence 测试针对 LIMITED 相机运行。

scene1_2/test_yuv_plus_raw.py

在 Android 12 中,test_yuv_plus_raw 测试针对实体隐藏式相机运行。

scene2_a/test_format_combos.py

在 Android 12 中,test_format_combos 测试针对 LIMITED 相机运行。

scene3/test_flip_mirror.py

在 Android 12 中,test_flip_mirror 测试针对 LIMITED 相机运行。

scene4/test_aspect_ratio_and_crop.py

在 Android 12 中,对 scene4/test_aspect_ratio_and_crop.py 中的查找圆形操作进行了重构。

较低版本的 Android 使用的方法需要通过大小和颜色过滤器查找父轮廓(方形)内的子轮廓(圆形)。Android 12 使用的方法则是先查找所有轮廓,然后通过查找最“接近圆形”的特征进行过滤。为了过滤掉屏幕上的假圆形,需要设置最小轮廓面积,并且所找的圆形轮廓必须为黑色。

轮廓及其选择条件如下图所示。

轮廓和选择条件概念图

图 1. 轮廓和选择条件概念图

Android 12 的方法更简单,可以有效解决某些画面平板电脑中的边界框裁剪问题。系统会记录所有候选圆形以用于调试目的。

在 Android 12 中,系统会针对 FULLLEVEL3 设备运行剪裁测试。Android 11 或更低版本则会跳过 FULL 设备的剪裁测试断言。

下表列出了与给定设备级别和初始 API 级别相对应的 test_aspect_ratio_and_crop.py 断言。

设备级别 初始 API 级别 断言
LIMITED 全部 宽高比
4:3、16:9、2:1 格式的视野
FULL < 31 宽高比
4:3、16:9、2:1 格式的视野
FULL ≥ 31 剪裁
宽高比
4:3、16:9、2:1 格式的视野
LEVEL3 全部 剪裁
宽高比
4:3、16:9、2:1 格式的视野

scene4/test_multi_camera_alignment.py

scene4/test_multi_camera_alignment.py 中用于 YUV 捕获的方法 undo_zoom() 已重构,以便更准确地说明在与捕获宽高比不匹配的传感器上如何剪裁。

Android 11 Python 2 代码

zoom_ratio = min(1.0 * yuv_w / cr_w, 1.0 * yuv_h / cr_h)
circle[i]['x'] = cr['left'] + circle[i]['x'] / zoom_ratio
circle[i]['y'] = cr['top'] + circle[i]['y'] / zoom_ratio
circle[i]['r'] = circle[i]['r'] / zoom_ratio

Android 12 Python 3 代码

yuv_aspect = yuv_w / yuv_h
relative_aspect = yuv_aspect / (cr_w/cr_h)
if relative_aspect > 1:
  zoom_ratio = yuv_w / cr_w
  yuv_x = 0
  yuv_y = (cr_h - cr_w / yuv_aspect) / 2
else:
  zoom_ratio = yuv_h / cr_h
  yuv_x = (cr_w - cr_h * yuv_aspect) / 2
  yuv_y = 0
circle['x'] = cr['left'] + yuv_x + circle['x'] / zoom_ratio
circle['y'] = cr['top'] + yuv_y + circle['y'] / zoom_ratio
circle['r'] = circle['r'] / zoom_ratio

sensor_fusion/test_sensor_fusion.py

在 Android 12 中,针对传感器融合测试新增了一个方法,用于检测图像中的特征。

在低于 Android 12 的版本中,使用整张图像来查找 240 项最佳特征,然后遮住中心周围 20% 范围内的特征以防果冻效应,最低特征要求是符合 30 项特征。

如果此方法找到的特征不足,Android 12 会先遮住中心周围 20% 范围内的特征检测区域,然后将最大特征数限制为最低特征要求的两倍。

下图显示了 Android 11 和 Android 12 特征检测之间的区别。提高最低特征要求阈值会导致检测到质量不佳的特征,并对测量结果产生负面影响。

Android 11 和 Android 12 之间在特征检测方面的区别
sensor_fusion 特征检测

图 2. Android 11 和 Android 12 之间在特征检测方面的区别

新测试

scene0/test_solid_color_test_pattern.py

Android 12 启用了一项新测试:test_solid_color_test_pattern。这项测试针对所有相机启用,下表对其进行了说明。

场景 测试名称 初始 API 级别 说明
0 test_solid_color_test_pattern 31 确认纯色图像输出和图像颜色的可编程性。

必须启用纯色测试图案才能支持相机隐私模式。test_solid_color_test_pattern 测试用于确认纯色 YUV 图像是以所选图案定义的颜色输出的,并且图像颜色能够根据说明发生变化。

参数

  • cameraPrivacyModeSupport:确定相机是否支持隐私模式。
  • android.sensor.testPatternMode:设置测试图案模式。此测试使用 SOLID_COLOR
  • android.sensor.testPatternData:为测试图案模式设置 R、Gr、Gb、G 测试图案值。

有关纯色测试图案的说明,请参阅 SENSOR_TEST_PATTERN_MODE_SOLID_COLOR

方法

系统会针对设置的参数捕获 YUV 帧并验证图像内容。测试图案直接从图像传感器输出,因此不需要特定场景。如果支持 PER_FRAME_CONTROL,系统会针对测试的每项设置捕获一个 YUV 帧。如果不支持 PER_FRAME_CONTROL,系统会捕获四个帧但只分析最后一个帧,以便在 LIMITED 相机中最大限度地扩大测试覆盖范围。

YUV 捕获被设置为完全饱和的 BLACKWHITEREDGREENBLUE 测试图案。由于测试图案的定义要符合传感器拜尔阵列,因此必须如下表所示为每种颜色设置颜色通道。

颜色 testPatternData (RGGB)
黑色 (0, 0, 0, 0)
白色 (1, 1, 1, 1)
红色 (1, 0, 0, 0)
绿色 (0, 1, 1, 0)
蓝色 (0, 0, 0, 1)

断言表

下表介绍了 test_solid_color_test_pattern.py 的测试断言。

相机
初始 API 级别
相机类型 断言的颜色
31 拜尔 黑色、白色、红色、绿色、蓝色
31 单色 黑色、白色
< 31 拜尔/黑白 黑色

性能等级测试

scene2_c/test_camera_launch_perf_class.py

验证在 scene2_c 人脸场景中,前置和后置主摄像头的摄像头启动时间是否都不到 500 毫秒。

scene2_c/test_jpeg_capture_perf_class.py

验证在 scene2_c 人脸场景中,前置和后置主摄像头的 1080p JPEG 拍摄延迟时间是否都不到 1 秒。