Android 12 版本中包含多项相机 ITS 变更。本文总结了这些变更,并将其分为四大类:
重构为 Python 3
由于 Python 2.7 已于 2020 年 1 月废弃,因此整个相机 ITS 代码库已重构为 Python 3 代码。在 Android 12 中,需要使用以下 Python 版本和库:
- Python 3.7.9 或 Python 3.7.10
- OpenCV 3.4.2
- Numpy 1.19.2
- Matplotlib 3.3.2
- Scipy 1.5.2
- pySerial 3.5
- Pillow 8.1.0
- PyYAML 5.3.1
主测试启动器 tools/run_all_tests.py
保持与 Android 11 或更低版本相同,并已重构为 Python 3 代码。
各项测试均已重构,并使用 tests/its_base_test.py
中定义的新测试设置类。大多数测试名称和功能保持不变。在 Android 12 中,各项测试现在都会加载其场景。虽然为每项测试加载场景会增加总测试时间,但这样能够单独对各项测试进行调试。
如需详细了解各项测试变更,请参阅测试变更。
以下 Python 模块已重构并更改名称:
pymodules/its/caps.py
→utils/camera_properties_utils.py
pymodules/its/cv2image.py
→utils/opencv_processing_utils.py
pymodules/its/device.py
→utils/its_session_utils.py
pymodules/its/error.py
→utils/error_util.py
pymodules/its/image.py
→utils/image_processing_utils.py
pymodules/its/objects.py
→utils/capture_request_utils.py
pymodules/its/target.py
→utils/target_exposure_utils.py
tools/hw.py
→utils/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 之外,还会在测试类中传递其他参数,例如平板电脑的 brightness
、chart_distance
、debug_mode
、camera_id
和 scene_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
文件的值运行。此外,您还可以在命令行中覆盖 camera
和 scene
的配置文件值,所用的命令与 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_SCENES
或 TEST_BED_MANUAL
完成。不过,如果使用 TEST_BED_TABLET_SCENES
完成测试,必须连接平板电脑且平板电脑序列号必须有效(即便未使用平板电脑),因为测试类设置会分配平板电脑的序列号值。
运行各个测试
您可以仅出于调试目的而运行单个测试,因为系统不会将测试结果报告给 CTS 验证程序。由于无法在命令行中覆盖 config.yml
文件中的 camera
和 scene
值,因此在单个相关测试的 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.txt
和test_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_white
和 test_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 中,系统会针对 FULL
和 LEVEL3
设备运行剪裁测试。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 特征检测之间的区别。提高最低特征要求阈值会导致检测到质量不佳的特征,并对测量结果产生负面影响。
图 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 捕获被设置为完全饱和的 BLACK
、WHITE
、RED
、GREEN
和 BLUE
测试图案。由于测试图案的定义要符合传感器拜尔阵列,因此必须如下表所示为每种颜色设置颜色通道。
颜色 | 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 秒。