一、背景
目前国内/国际大型互联网公司已经有了很多的APP或游戏遍历测试工具,公司内部每天也有很多UI自动化的任务在跑。随着自动化遍历工具的逐渐成熟和日常任务的进行,每次任务都会产生大量的遍历过程截图,对于这大量的截图,很难有人力逐张检查是否存在异常,人力成本过大,但也许花了很多人力去检查,但实际可以看到的图像异常问题却很少。针对这个问题,显然需要图像异常的自动断言能力进行判断自动化任务截图是否存在某种异常。
通过提供多种图像异常检测能力,期望探索解决各类UI自动化任务中的UI图像异常自动断言。并提供接入简单,接入方式多样的工具或服务。
二、整体方案
方案主要由算法能力接入、算法训练框架以及图像数据库三个部分组成。
方案主要提供两种接入方式:SDK和服务的方式。目前SDK主要提供Python SDK,SDK的方式主要适用于保密项目或不希望相关截图流出生产环境的业务和项目。为每个图像质量检测算法提供了单独的API供接入方自定义选择。服务方式主要是HTTP服务,提供了通用的服务端接入方式。同时还可以通过自动化任务插件方式接入图像异常检测,在自动化Case跑完之后,对过程截图进行图像质量异常断言。
训练框架部分目前只用到了图像分类相关的框架,包括图像预处理、图像增强、图像对抗样本生成、模型训练等。后续会加入更多的图像算法相关的框架,例如图像分割、目标检测等。
图像数据库中的数据来源主要由业务异常数据以及异常图像生成器组成,由于真实异常图片的本身就很少,我们需要在异常图片的基础上通过某些算法生成一些人造的异常图片。同时,也可以由业务同学,通过损坏某些图像资源,来得到。
检测的流程主要有三个部分组成:通用质量检测算法、场景分类、场景定制算法。之所以需要场景分类,是因为很多APP对于不同的APP场景(比如详情页、视频页等)对于某些图像质量异常的定义各不相同,使得需要根据场景适配不同的算法。
三、核心算法
由于异常检测的数据通常是长尾分布,针对大部分算法,我们都采取了传统图像处理的方式来解决,而针对图像处理解决不了的情况,我们使用异常图片生成+深度学习的方式来解决。
传统图像处理的优势在于对数据量的要求相对较低,但泛化性较差,随着时间和异常数据的逐步积累,会逐渐转换为传统方法召回+深度学习方法精确分类的模式。
3.1 核心指标
对于图像异常检测算法,我们除了精确率和召回率(Precision,Recall)以外,定义了两个指标来评估算法的好坏:检出率、误检率。设图片总数为x,异常图片总数为y,正确检出异常数为c,错误检出异常数为w
检出率
误检率
其中检出率用来评估算法能从海量图片中识别出存在异常图片的能力;误检率用来评估检出图片中真实存在异常的概率。对于图像异常检测来说,我们对检出率的要求更高,而对误检率相对要求较宽松。原因是我们不希望漏掉任何的异常图像,但少量的错误识别Case可以在人工Review的时候筛掉。
3.2 黑白屏检测
(1) 概述
用于检测当前界面截图是否为黑屏白屏异常。示例如下:
(2) 原理
将界面分割成由上到下的若干个区域,通过计算区域内所有32 * 32灰度图像的像素区域的像素均值和标准差的均值来检测当前界面是否存在黑屏或者白屏的异常出现。根据不同业务定义的黑白屏情况,支持按业务定制不同的黑白屏标准。
3.3 损坏检测
损坏检测会根据不同的业务场景会出现的不同的损坏异常进行检测,业务方可以自定义调用哪些检测算法。比较常见的损坏异常有紫色块异常、白色块异常和花屏异常。
3.3.1 紫色块异常
(1) 概述
紫色块异常通常出现在游戏场景中,配合UI自动化在遍历或者是执行Case的过程中检测是否有紫色块异常。通常造成紫色块异常的原因是贴图或者模型图片的损坏或者丢失。
(2) 原理
通过计算截图中判定为紫色像素的占比来确定是否有紫色块异常。由于贴图或模型图像损坏时的紫色块也会受到阴影的效果影响,所以判断为紫色块的RGB值范围限制在R >= 220, G <= 60, B >= 220。
3.3.2 白色块异常
(1) 概述
白色块异常通常出现在游戏场景中,配合UI自动化在遍历或者是执行Case的过程中检测是否有白色块异常。通常造成白色块异常的原因是UI图片的损坏或者丢失。
(2) 原理
通过检测画面中的白色矩形区域来判断是否存在白色块异常。具体原理见上图。其中计算像素均值的时候可以适当放宽像素均值的阈值以检测下图这种白色矩形异常。
(3) 效果
测试集效果检出率 99.8% (4826/4836),误检率 0.1% (209/15w), Precision 96%, Recall 99.8%
3.3.3 花屏
(1) 概述
检测游戏或视频中的花屏异常。
(2) 原理
通过异常图片生成的方式(主要为图像处理和人工收集)构建分类数据集,利用训练二分类CNN模型。
(3) 效果
测试集准确率98.7% (961/974),其中异常图片准确率99.4%(484/487),正常图片98.1%(478/487)。CPU单张图片预测时长约42ms。模型大小4 MB
3.4 屏幕黑框检测
(1) 概述
检测图像是否有黑框
(2) 原理
判断图片四周是否有超过阈值宽度的黑色区域
3.5 过曝检测
(1) 概述
检测图像中特效是否出现过曝
(2) 原理
- 通过二值化保留高亮区域
- 利用形态学开操作去除噪点
- 通过高亮区域的面积和形状进行过滤
3.6 文字重叠检测
(1) 概述
检测页面中的文字区域是否存在文字重叠异常
(2) 异常数据构建
实际场景中,正常样本的图片数量是非常多的,我们通过OCR 对文字区域进行定位,通过算法将背景和文字颜色提取出来后,叠加上特定大小、特定字体、特定颜色的错位字体构建文字重叠的异常图像。通过这种方法,我们构建了文字重叠区域的数据集,其中异常区域量级2w+
(3) 原理
由于文字区域的尺寸太小,从整图维度作为输入做检测的方式经过实验后都认为不可行,最后采取了当前的方案:
通过OCR 提取文字区域的位置,将文字区域送入训练好的文字重叠分类器当中,判断是否存在文字重叠。测试集准确率Precision 88%,Recall 62%
3.7 无监督场景聚类
(1) 概述
在图像异常检测的场景下,对于每个不同的场景,需要应用的检测算法及相同算法的检测标准都不同,所以需要智能算法对同一个APP的多个场景进行场景聚类后进行不同场景的定制化检测。在这里我们可以通过无监督的方式,从海量的自动化产生的截图中获取一个自动的场景划分,避免了监督学习中对海量数据的人工标注工作和长时间的模型训练和调优过程。
(2) 原理
- 通过Sift + Spatial Pyramid Pooling 提取多尺度下的Sift 特征点及特征向量,这里选择了3个尺度下的Sift特征。
- 对整个数据集所有的图片所提取的所有尺度下的特征向量进行KMeans聚类,获得一个codebook。
- 根据codebook,对每个图片的的Sift特征进行计算直方图向量,并拼接3个尺度1+4+9 共14个直方图向量作为图片的全局表述
- 使用Bisecting KMeans对全局向量做自适应聚类,无需人工指定簇的个数。
- 对最终的聚类结果做可视化后挑选相同场景的簇做合并,得到最终的场景分类器。
(3) 效果
四、技术难点
4.1 数据
对于所有异常检测的任务来说,异常数据的获取都是最困难的。为了解决这种数据获取的困难,我们采取了三种手动制造异常图片的方式——GrabCut算法(紫块异常)、随机叠加图片(花屏异常)和文字区域叠加(文字重叠异常)的方式。
GrabCut算法是基于GMM和图算法对图片中的前景和背景进行分割的算法,通过GrabCut算法我们提取了前景图片之后,对前景物体利用紫色色块填充后形成了人造的异常图片。
随机叠加图片的方式主要用来生成游戏中的花屏图片。通过少数的几张真实的花屏图片,我们发现花屏异常通常都是由前后几帧的图片混合出现的。通过随机叠加生成了一批和真实异常图十分接近的异常图。
在文字区域叠加的方式中,我们通过OCR 对文字区域进行定位,通过算法将背景和文字颜色提取出来后,叠加上特定大小、特定字体、特定颜色的错位字体构建文字重叠的异常图像。通过这种方法,我们构建了文字重叠区域的数据集,其中异常区域量级2w+
4.2 Over Confident
由于人造的异常图片进行分类任务对于深度卷积神经网络来说过于简单,最终的得到的模型的预测结果的Score 通常都接近1,通常在0.99 左右,这对实际任务十分不利。在这里我们引入了标签平滑(Label Smoothing)的正则方式,以缓解模型Over Confident的问题。
4.2.1 标签平滑(Label Smoothing)
标签平滑简单来说就是将计算Loss时候的Hard One Hot Label (一个类别为 1 其余为0)替换成Soft One Hot Label (一个类别接近1,其余接近0)的方式,来缓解Over Confident问题。
这种正则方式在大多数分类任务中都被证明有效。
4.3 样本过于简单
对于人造样本过于简单的问题,会发现一些明显是无异常图片的Case被错分到有异常这一类。我们尝试对人造的样本及真实的正常图片,加入一些对抗样本(Adversarial Examples)来使得分类的边界更加的清晰鲁棒。
4.3.1 对抗样本(Adversarial Examples)
在分类任务中,有时候我们会发现,一张预测正确的图片,加入了一些非常小的肉眼看不出的噪声后,会使得分类器完全预测错误,虽然肉眼看起来完全没有差别。这些样本就是对抗样本。
通过加入对抗样本,使得分类器学到的数据分布的边界更加清晰,防止模型学习到一些我们观察不到的未知的视觉信息。
4.4 计算资源
测试过程中,图像分析的请求数量大,对算法的实时性要求比较高。在上述提到的算法中,花屏检测算法对计算资源的要求最高,通过选择适合移动端的轻量级网络MobileNet 加上Tensorflow提供的TF Lite Uint8量化,可以在精度损失不大的情况下,获得极大的速度提升和计算资源的节省。
五、落地效果
这里只针对落地游戏场景的三种算法做了落地效果的实验
5.1 测试集效果
检出率 | 误检率 | |
---|---|---|
紫色块 | 96.4%(53/55) | 0%(0/15w) |
白色块 | 99.8% (4826/4836) | 0.1% (209/15w) |
花屏算法测试集准确率98.7% (961/974),其中异常图片准确率99.4%(484/487),正常图片98.1%(478/487)。CPU单张图片预测时长约42ms。模型大小4 MB
5.2 落地效果
总数 | 异常图片 | 无异常图片 | |
---|---|---|---|
总数 | 13856 | 1 | 13855 |
紫块 | 1 | 1 | 0 |
白块 | 70 | 0 | 70 |
花屏 | 140 | 0 | 140 |
紫块
预测是否存在异常 | |||
---|---|---|---|
实际是否存在异常 | Yes | No | |
Yes | 1 | 0 | |
No | 0 | 13855 |
白块
预测是否存在异常 | |||
---|---|---|---|
实际是否存在异常 | Yes | No | |
Yes | 0 | 0 | |
No | 70 | 13786 |
花屏
预测是否存在异常 | |||
---|---|---|---|
实际是否存在异常 | Yes | No | |
Yes | 0 | 0 | |
No | 140 | 13716 |
可以看出,通过图像质量检测插件,大大降低需要做断言的截图数量(13856->211)。就算法效果而言,紫块算法已经无需优化,白块和花屏算法需要后续收集误检图片做进一步的调优。