Airtest的图像识别算法
2.1 Airtest图像识别的基本原理
以一个touch的动作为例,分析执行的日志:
在识别图像的过程中,Airtest尝试用了SURFMatching、TemplateMatching和BRISKMatching这几个算法去查找,并且还分别告诉了我们这几个算法的执行结果是什么?
TemplateMatching算法的执行结果里面,有一个’confidence’:0.4586929976940155,这个其实就是算法的可信度;如果算法识别的可信度(也就是confidence)超过了我们设置的阈值(默认0.7),就会认为识别成功,否则认为失败。
这里图像识别使用了开源的opencv库,默认设置的算法是CVSTRATEGY = [“surf”, “tpl”, “brisk”],每次查找图片的时候,airtest就会按照这个设置好的算法顺序去执行,直到找出一个符合设定阈值的识别结果,或者是一直循环查找,直到超时。
2.2 Airtest图像识别算法分类
Airtest支持opencv3里面的8种图像识别算法:
MATCHING_METHODS = {
"tpl":TemplateMatching,
"kaze":KAZEMatching,
"brisk":BRISKMatching,
"akaze":AKAZEMatching,
"orb": ORBMatching,
"sift": SIFTMatching,
"surf": SURFMatching,
"brief": BRIEFMatching,
}
以上8种算法可以分为两类:
-
模板匹配(TemplateMatching)
-
基于特征点的图像识别
2.2.1 模板匹配(TemplateMatching)
模板匹配是一种最原始、最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题。它是图像处理中最基本、最常用的匹配方法。模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。
模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域
2.2.2 基于特征点的图像识别
以下图像识别算法都基于lena.png进行测试
2.2.2.1 sift
尺度不变特征转换(Scale-invariant feature transform或SIFT)
SIFT是目前应用最广泛的关键点检测和描述算法,SITF算法首先被David.G.Lowe提出并发表在文章 “Distinctive Image Features from Scale-Invariant Keypoints”中,其中Scale-Invariant的意思是尺度不变性。
SIFT特征提取充分利用了图像局部信息,它包含以下优点:
⑴SIFT特征具有旋转、尺度、平移、视角及亮度不变性,有利于对目标特征信息进行有效表达。
⑵SIFT特征对参数调整鲁棒性好,在进行特征描述时,根据场景需要可调整适宜的特征点数量,以便进行特征分析。
SIFT特征算法对图像局部特征点的提取主要包括4个步骤:
疑似特征点检测、去除伪特征点、特征点梯度与方向匹配及特征描述向量生成。
测试代码:
import cv2
import numpy
def surf_test():
img = cv2.imread("lena.png")
cv2.imshow('Input Image', img)
cv2.waitKey(0)
# 检测
surf = cv2.xfeatures2d.SURF_create()
keypoints = surf.detect(img, None)
# 显示
# 必须要先初始化img2
img2 = img.copy()
img2 = cv2.drawKeypoints(img, keypoints, img2, color=(0, 255, 0))
cv2.imshow('Detected SURF keypoints', img2)
cv2.waitKey(0)
if name == ‘main’:
surf_test()
测试图像:
2.2.2.2 surf
SURF特征描述算子:speeded-Up Robust Features
SURF特征描述子是Herbert Bay等人在2006年发表的论文“SURF:Speeded Up Robust Features”中提出的。
SURF主要是把SIFT中的某些运算作了简化。SURF把SIFT中的高斯二阶微分的模板进行了简化,使得卷积平滑操作仅需要转换成加减运算, 这样使得SURF算法的鲁棒性好且时间复杂度低。SURF最终成生的特征点特征向量的维度为64维。
可能要向原作者给版权费
测试代码:
import cv2
import numpy
def surf_test():
img = cv2.imread("lena.png")
cv2.imshow('Input Image', img)
cv2.waitKey(0)
# 检测
surf = cv2.xfeatures2d.SURF_create()
keypoints = surf.detect(img, None)
# 显示
# 必须要先初始化img2
img2 = img.copy()
img2 = cv2.drawKeypoints(img, keypoints, img2, color=(0, 255, 0))
cv2.imshow('Detected SURF keypoints', img2)
cv2.waitKey(0)
if name == ‘main’:
surf_test()
测试图像:
2.2.2.3 brisk
Binary Robust Invariant Scalable Keypoints, 2011
测试代码:
import cv2
import numpy
def brisk_test():
img = cv2.imread("lena.png")
cv2.imshow('Input Image', img)
cv2.waitKey(0)
brisk = cv2.BRISK_create()
keypoints = brisk.detect(img, None)
# 必须要先初始化img2
img2 = img.copy()
img2 = cv2.drawKeypoints(img, keypoints, img2, color=(0,255,0))
cv2.imshow('Detected BRISK keypoints', img2)
cv2.waitKey(0)
if name == ‘main’:
brisk_test()
测试图像:
2.2.2.4 kaze
KAZE(AKAZE)是基于非线性插值的方法,这一点在图像处理方面来说确实比SURF和SIFT要好,毕竟图像大多是不连续的
与SIFT/SURF比较
更加稳定
非线性尺度空间
KAZE是日语音译过来的 , KAZE与SIFT、SURF最大的区别在于构造尺度空间,KAZE是利用非线性方式构造,得到的关键点也就更准确
测试代码:
import cv2
import numpy
def kaze_test():
img = cv2.imread("lena.png")
cv2.imshow('Input Image', img)
cv2.waitKey(0)
# 检测
kaze = cv2.KAZE_create()
keypoints = kaze.detect(img, None)
# 显示
# 必须要先初始化img2
img2 = img.copy()
img2 = cv2.drawKeypoints(img, keypoints, img2, color=(0,255,0))
cv2.imshow('Detected KAZE keypoints', img2)
cv2.waitKey(0)
if name == ‘main’:
kaze_test()
测试图像:
2.2.2.5 akaze
AKAZE速度更加快,比较新的算法,只有在opencv新版本中才有
测试代码:
import cv2
import numpy
def akaze_test():
img = cv2.imread("lena.png")
cv2.imshow('Input Image', img)
cv2.waitKey(0)
# 检测
akaze = cv2.AKAZE_create()
keypoints = akaze.detect(img, None)
# 显示
# 必须要先初始化img2
img2 = img.copy()
img2 = cv2.drawKeypoints(img, keypoints, img2, color=(0,255,0))
cv2.imshow('Detected AKAZE keypoints', img2)
cv2.waitKey(0)
if name == ‘main’:
akaze_test()
测试图像:
2.2.2.6 orb
Oriented FAST and Rotated BRIEF
ORB特征描述算法的运行时间远优于SIFT与SURF,可用于实时性特征检测。
ORB特征基于FAST角点的特征点检测与描述技术, 该算法是Ethan Rubleed 在论文“ORB:An efficient alternative to SIFT or SURF”中提出的。
ORB特征具有尺度与旋转不变性,同时对噪声及透视仿射也具有不变性,良好的性能使得得用ORB在进行特征描述时的应用场景十分广泛。
测试代码:
import cv2
import numpy
def orb_test():
img = cv2.imread("lena.png")
cv2.imshow('Input Image', img)
cv2.waitKey(0)
# 检测
orb = cv2.ORB_create()
keypoints = orb.detect(img, None)
# 显示
# 必须要先初始化img2
img2 = img.copy()
img2 = cv2.drawKeypoints(img, keypoints, img2, color=(0, 255, 0))
cv2.imshow('Detected ORB keypoints', img2)
cv2.waitKey(0)
if name == ‘main’:
orb_test()
测试图像:
2.2.2.7 brief
BRIEF是一个效率很高的提取特征描述子的方法,同时,当图像发生很大的平面内的旋转,它有着很好的识别率
测试代码:
import cv2
import numpy
def brief_test():
img = cv2.imread("lena.png")
cv2.imshow('Input Image', img)
cv2.waitKey(0)
# OpenCV3.x
# 注意由star计算特征点,brief进行简化
star = cv2.xfeatures2d.StarDetector_create()
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create()
"""获取图像特征点和描述符."""
# find the keypoints with STAR
keypoints = star.detect(img, None)
# compute the descriptors with BRIEF
keypoints, descriptors = brief.compute(img,keypoints)
# 必须要先初始化img2
img2 = img.copy()
img2 = cv2.drawKeypoints(img, keypoints, img2, color=(0, 255, 0))
cv2.imshow('Detected brief keypoints', img2)
cv2.waitKey(0)
if name == ‘main’:
brief_test()
测试图像:
2.3 修改默认识别算法
from airtest.core.settings import Settings as ST ST.CVSTRATEGY = [“tpl”, “sift”,“brisk”]
2.4 图像识别算法小结
2.4.1 性能解析
单张性能:
多张性能:
最大内存:
最上方图为内存曲线,横轴为不同的图片名
最大内存:kaze > sift > akaze > surf > brief > brisk > orb
最大CPU:
中间图为CPU曲线
最大CPU:kaze > surf > akaze > brisk > sift > brief > orb
识别效果:
sift > surf > kaze > akaze > brisk > brief > orb
2.4.2 总结
1.模板匹配算法的优点是速度很快,如果分辨率不会改变的话,不妨选择它作为首选算法
-
在分辨率可能会发生改变的情况下,更适合用特征点匹配的办法来找图,这样跨平台的适应能力会更高,脚本容易适配不同型号的手机
-
sift和surf一直提供了较高的准确率,并且结果比较稳定;sift较surf更准一些,但是也有brisk最好的时候
-
orb的速度非常快,但是最容易出现问题,AKAZE也很容易出现问题
-
其他算法,包括AKAZE,速度的差别都不是很大