Airtest 特征点匹配基类 KeypointMatching 深度解析:KAZE 识别框架与源码级原理
测试质量保障计算机视觉【免费下载链接】AirtestUI Automation Framework for Games and Apps项目地址https://gitcode.com/gh_mirrors/ai/Airtest点击查看免费下载导读本文围绕 Airtest 图像识别体系中的特征点匹配基类KeypointMatching源码位于 airtest/aircv/keypoint_base.pyAPI 文档见 docs/all_module/airtest.aircv.keypoint_base.rst展开。它承载了 KAZE、AKAZE、BRISK、ORB、SIFT、SURF、BRIEF 等全部特征点匹配算法的公共识别流程。读完本文你将掌握特征点匹配的完整调用链检测 → 描述 → 匹配 → 区域映射 → 置信度计算 → 结果校验、KeypointMatching对外提供的全部方法与参数含义并能看懂 Airtest 的CVSTRATEGY识别策略中kaze/brisk/akaze/orb等算法是如何被调度执行的。一、KeypointMatching 在 Airtest 图像识别体系中的定位Airtest 的识别核心位于 airtest/core/cv.py其中定义了一张算法注册表MATCHING_METHODSMATCHING_METHODS { tpl: TemplateMatching, mstpl: MultiScaleTemplateMatchingPre, gmstpl: MultiScaleTemplateMatching, kaze: KAZEMatching, brisk: BRISKMatching, akaze: AKAZEMatching, orb: ORBMatching, sift: SIFTMatching, surf: SURFMatching, brief: BRIEFMatching, }其中kaze/brisk/akaze/orb四个算法类定义在 airtest/aircv/keypoint_matching.pysift/surf/brief定义在 airtest/aircv/keypoint_matching_contrib.py。这些类全部继承自KeypointMatching基类只需要覆写init_detector()以及个别场景下的get_keypoints_and_descriptors()/match_keypoints()即可复用基类中整套“找最优结果”的识别管线。KeypointMatching与同目录下的模板匹配类template_matching.py是 Airtest 两条并行的识别技术路线模板匹配基于滑窗相关度计算特征点匹配基于局部特征点keypoint的提取与配对。在 tests/test_aircv.py 的注释里可以看到该团队对不同算法内存与效果的经验结论内存占用 kaze(2GB) sift akaze surf brisk brief orb tpl单纯效果推荐 tpl surf ≈ sift kaze brisk akaze brief orb。二、类定义与核心参数基类KeypointMatching的构造签名如下class KeypointMatching(object): METHOD_NAME KAZE # 日志中的方法名 FILTER_RATIO 0.59 # SIFT 优秀特征点过滤比例值0-1 范围建议 0.4-0.6 ONE_POINT_CONFI 0.5 # 只找出一对相似特征点时的置信度 def __init__(self, im_search, im_source, threshold0.8, rgbTrue): self.im_source im_source # 大图通常是设备截图 self.im_search im_search # 小图要查找的目标图片 self.threshold threshold # 置信度阈值低于该值视为未匹配 self.rgb rgb # 是否使用 RGB 三通道校验置信度各参数与类属性说明参数 / 属性默认值含义与建议im_search必传待搜索的目标小图如游戏中的某个按钮/图标截图im_source必传被搜索的大图通常是设备实时截图threshold0.8匹配置信度阈值范围 [0,1]最终结果confidence threshold才返回否则返回NonergbTrue为True时用 RGB 三通道 HSV 方式计算置信度为False时用灰度TM_CCOEFF_NORMED方式计算METHOD_NAMEKAZE日志与调试信息中显示的方法名子类各自覆写如 BRISK、AKAZE、ORBFILTER_RATIO0.59knnMatch 初筛比例只有最近距离 FILTER_RATIO * 次近距离的匹配对才被保留用于剔除不“独特优秀”的特征点ONE_POINT_CONFI0.5预留常量用于描述仅一对匹配点时的置信度参考值三、识别主流程 find_best_result()四步管线find_best_result()keypoint_base.py是整个基类对外最核心的入口用print_run_time装饰器包装utils.py 中的print_run_time会记录耗时并把耗时time字段注入返回的 dict。其执行分四步第一步校验图像是否正常。调用check_image_valid(self.im_source, self.im_search)定义于 utils.py只要任一图像为None或全零not img.any()即返回None。第二步获取特征点集并匹配出特征点对。调用_get_key_points()返回kp_sch, kp_src, good搜索图特征点、源图特征点、筛选后的优秀匹配对。第三步按匹配对数分三种策略提取识别区域len(good) in [0, 1]0 对无法提取区域1 对无法确定矩形直接返回Nonelen(good) in [2, 3]分别走_handle_two_good_points()或_handle_three_good_points()基于两/三个匹配点计算缩放比例与目标矩形len(good) 4走_many_good_pts()通过单应矩阵homography映射出目标区域的四个角点。第四步计算置信度并返回。先从w_h_range解出x_min, x_max, y_min, y_max, w, h用cv2.resize把源图目标区域缩放到与搜索图一致调用_cal_confidence(resize_img)求置信度最后调用generate_result(middle_point, pypts, confidence)utils.py生成统一格式的结果 dict。返回结果格式{ result: (x, y), # 目标中心点在 im_source 中的坐标 rectangle: [(x0, y0), (x1, y1), (x2, y2), (x3, y3)], # 目标矩形四角左上-左下-右下-右上 confidence: 0.85, # 匹配置信度 time: 0.32, # 仅通过 print_run_time 装饰器调用时存在单位秒 }只有在confidence self.threshold时才会返回该 dict否则返回None——这正是 Airtest 识别“找不到目标”时返回空、进而触发TargetNotFoundError的底层机制。四、特征点提取与匹配_get_key_points() 的实现细节_get_key_points()keypoint_base.py完成“检测 → 描述 → 匹配 → 初筛 → 去重”五个环节初始化算子调用init_detector()。基类默认实现为cv2.KAZE_create()cv2.BFMatcher(cv2.NORM_L1)各子类覆写为不同的检测器与匹配距离度量KAZEMatchingcv2.KAZE_create()cv2.BFMatcher(cv2.NORM_L1)即默认实现子类为空实现BRISKMatchingcv2.BRISK_create()cv2.BFMatcher(cv2.NORM_HAMMING)AKAZEMatchingcv2.AKAZE_create()cv2.BFMatcher(cv2.NORM_L1)ORBMatchingcv2.ORB_create()cv2.BFMatcher(cv2.NORM_HAMMING)SIFTMatchingcv2.SIFT_create(edgeThreshold10)OpenCV ≥3.4.12 或 ≥4.5.0 时直接可用否则回退cv2.xfeatures2d.SIFT_create匹配器为cv2.FlannBasedMatcher({algorithm: FLANN_INDEX_KDTREE, trees: 5}, dict(checks50))SURFMatchingcv2.xfeatures2d.SURF_create(HESSIAN_THRESHOLD400, upright0)同样使用 FLANNBRIEFMatching使用cv2.xfeatures2d.StarDetector_create()cv2.xfeatures2d.BriefDescriptorExtractor_create()需要 opencv-contrib 模块。提取特征点与描述符对im_search与im_source分别调用get_keypoints_and_descriptors()即detector.detectAndCompute(image, None)BRIEF 是 STAR 检测 BRIEF 描述两步。数量下限校验若任一图特征点数 2抛出NoMatchPointError(Not enough feature points in input images !)异常类定义于 error.py。kNN 匹配初筛matcher.knnMatch(des_sch, des_src, k2)为每个特征点取前 2 个最近邻仅当m.distance self.FILTER_RATIO * n.distance时保留该点即“最近距离显著优于次近距离”的点才算优秀匹配这是 Lowe 提出的经典 ratio testAirtest 取 0.59。匹配对去重以源图特征点的整数坐标(x, y)为判据去除重复点——允许搜索图一个点对应源图多个点一对多但不允许源图一个点对应搜索图多个点多对一。去重后的匹配对列表即为good。五、识别区域求解的三种策略5.1 两对匹配点_handle_two_good_points()取出两对匹配点各自的坐标调用_get_origin_result_with_two_points()keypoint_base.py完成中点计算先取两个源图点的中点作为初始middle_point同轴退化处理若搜索图两点同 x 或同 y 轴或源图两点同轴无法构成矩形返回None缩放比例x_scale |(pts_src2[0]-pts_src1[0]) / (pts_sch2[0]-pts_sch1[0])|y_scale同理——本质是用匹配点对的几何关系推断目标在源图中的缩放中点校正由于中点是映射矩阵的中点而非特征点中点需按sch_middle_point - (w/2, h/2)的偏移乘以缩放比例进行修正边界裁剪将middle_point与矩形四角裁剪到源图边界[0, w_s-1] × [0, h_s-1]内截图左上角坐标为 (0,0)。5.2 三对匹配点_handle_three_good_points()取第 1 个点与第 2、3 个点的中点构成两对“虚拟点”再复用_get_origin_result_with_two_points()的逻辑从而在点数不足 4 时依然能用两点法估算目标区域。5.3 四对及以上匹配点_many_good_pts()当匹配对 ≥ 4 时keypoint_base.py采用更稳健的单应矩阵方案将匹配点对组织为np.float32(...).reshape(-1, 1, 2)调用_find_homography()内部cv2.findHomography(sch_pts, src_pts, cv2.RANSAC, 5.0)失败时抛出HomographyError见 error.py用 RANSAC 的mask过滤出内点selected再基于内点重算更精确的变换矩阵M将搜索图四角[[0,0],[0,h-1],[w-1,h-1],[w-1,0]]通过cv2.perspectiveTransform(pts, M)映射到源图得到目标区域四角pypts取左上角与右下角的中点作为middle_point并把四个角点按“左上→左下→右下→右上”点序整理后做边界裁剪越界置为边界值。六、置信度计算 _cal_confidence() 与结果校验6.1 两种置信度算法_cal_confidence(resize_img)keypoint_base.py把源图目标区域缩放cv2.resize到与搜索图同尺寸后rgbTrue时调用cal_rgb_confidence(resize_img, self.im_search)rgbFalse时调用cal_ccoeff_confidence(resize_img, self.im_search)。两种算法都定义在 cal_confidence.pycal_ccoeff_confidence先将图像转灰度用cv2.matchTemplate(im_source, im_search, cv2.TM_CCOEFF_NORMED)取最大响应值计算前用copyMakeBorder(..., 10, BORDER_REPLICATE)扩展 10 像素计算区域并在角落写入 0/255 干扰值防止算法放大微小差异。cal_rgb_confidence把两图np.clip(..., 10, 245)削掉极端像素后转 HSV强化颜色影响再扩展边界然后对 B、G、R 三个通道分别做TM_CCOEFF_NORMED匹配取三个通道置信度的最小值——保证识别结果在三个颜色通道上都足够相似。无论哪种方式最终都会做一次修正confidence (1 confidence) / 2把TM_CCOEFF_NORMED的 [-1, 1] 取值范围映射到更符合直觉的 [0, 1] 区间该方法在TemplateMatching的置信度计算中同样使用。6.2 结果合理性校验 _target_error_check()在计算置信度之前find_best_result()会调用_target_error_check(w_h_range)keypoint_base.py做物理合理性校验异常时抛出MatchResultCheckErrorerror.py识别区域的宽或高 5 像素 → 判定识别失效截图区域不可能小于 5 像素识别区域的宽或高小于搜索图对应尺寸的 0.2 倍或大于 5 倍 → 判定识别错误屏幕像素差不可能达到 5 倍。这一校验有效拦截了特征点误匹配导致的“夸张”目标框是保证 UI 自动化点击坐标可靠性的重要防线。七、调试辅助show_match_image() 可视化匹配连线show_match_image()keypoint_base.py用于直观展示特征点匹配关系内部调用一次find_best_result()触发匹配流程新建一张高度取两图最大高度、宽度为w_sch w_src的空白图左侧放搜索图、右侧放源图对good中每个匹配对用随机颜色在“搜索图特征点 → 源图特征点横坐标偏移 w_sch”之间画一条连线。该函数返回拼接后的可视化图像矩阵适合在调试阶段核对特征点匹配质量也可以结合 aircv.py 中的show()窗口函数直接展示。八、在 Airtest 上层 API 中的调度与使用8.1 CVSTRATEGY 策略链Airtest 的全局配置 airtest/core/settings.py 定义了默认识别策略CVSTRATEGY [mstpl, tpl, sift, brisk] # OpenCV 版本介于 3.4.2 与 4.4.0 之间时SIFT 尚未移入主仓库 CVSTRATEGY [mstpl, tpl, brisk]Template._cv_match()airtest/core/cv.py会按CVSTRATEGY顺序依次尝试每种算法一旦某个算法返回非空结果就break。_try_match()会捕获NoModuleError例如未安装 opencv-contrib 时使用surf/sift/brief与BaseError并返回None从而优雅地降级到下一个策略。这也解释了为什么特征点匹配类必须与模板匹配类保持统一的“构造后调用find_best_result()”接口约定——这正是基类把识别管线抽象出来的工程价值。8.2 上层调用示例直接使用特征点匹配进行图像识别的典型写法与 tests/test_aircv.py 中test_find_kaze等用例一致from airtest.aircv.imread import imread # 注意实际应从 airtest.aircv 导入 imread from airtest.aircv.keypoint_matching import KAZEMatching, BRISKMatching, AKAZEMatching, ORBMatching # 读取图片imread 定义于 airtest/aircv/aircv.py im_search imread(keypoint_search.png) # 目标小图 im_source imread(keypoint_screen.png) # 截图大图 result KAZEMatching(im_search, im_source, threshold0.7, rgbTrue).find_best_result() if result: print(result[result]) # 目标中心点 print(result[rectangle]) # 目标矩形四角 print(result[confidence]) # 置信度 else: print(未找到目标)imread()支持中文路径Python3 下通过np.fromfilecv2.imdecode解码定义于 aircv.py。8.3 多目标识别与预测区域需要注意基类mask_kaze()与find_all_results()目前是raise NotImplementedError的占位实现keypoint_base.py即特征点匹配路线在 Airtest 中只提供“找最优结果”的能力多目标查找由模板匹配的find_all_template()template.py承担。此外Predictorairtest/core/cv.py会在录制了record_pos时预测目标在屏幕上的候选区域并裁剪后做特征点匹配_find_keypoint_result_in_predict_area可显著缩小匹配范围、提升速度。九、小结KeypointMatching是 Airtest 特征点识别家族唯一的公共基类它把“图像校验 → 特征点检测/描述 → kNN 匹配初筛与去重 → 两点/三点/单应矩阵三种区域求解 → 灰度或 RGB 置信度 → 物理合理性校验”封装为固定管线子类只需声明检测器与匹配器即可接入新的特征点算法。理解该基类就等于同时理解了kaze/brisk/akaze/orb/sift/surf/brief七种算法的公共识别原理也能更精准地调试CVSTRATEGY策略与threshold阈值相关的识别问题。相关实现均可直接在 airtest/aircv/keypoint_base.py、airtest/aircv/keypoint_matching.py、airtest/aircv/keypoint_matching_contrib.py 与 airtest/core/cv.py 中继续研读。赞分享测试质量保障计算机视觉【免费下载链接】AirtestUI Automation Framework for Games and Apps项目地址https://gitcode.com/gh_mirrors/ai/Airtest点击查看免费下载相关推荐OpenCV AKAZE 局部特征匹配实战基于 KAZE 特征的检测、2-NN 匹配与单应内点校验OpenCV AKAZE 局部特征匹配实战基于 KAZE 特征的检测、2 NN 匹配与单应内点校验 AKAZEAccelerated KAZE是一种基于非计算机视觉图像处理深度学习机器学习Airtest 图像识别算法性能基准测试指南特征点匹配方法对比与 benchmark 工具实战Airtest 图像识别算法性能基准测试指南特征点匹配方法对比与 benchmark 工具实战 本文以 benchmark/README.md https:/测试质量保障计算机视觉OpenCvSharp特征匹配从关键点检测到物体识别OpenCvSharp特征匹配从关键点检测到物体识别 一、特征匹配技术栈解析 在计算机视觉领域特征匹配是实现物体识别、图像拼接和三维重建的核心技术。Open计算机视觉图像处理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考