版權聲明:允許轉載,但轉載必須保留原鏈接;請勿用作商業或者非法用途
此文章來源於項目官方公眾號:“AirtestProject”
1個圖像識別的例子
我們先從1個最簡單的touch(Template())
的語句來看看,Airtest在進行圖片識別的過程中,會用到什么識別算法:
上圖我們截取了執行touch語句的部分日志(截圖不存在於當前設備畫面中),可以看到,在識別圖像的過程中,Airtest嘗試用了SURFMatching
、TemplateMatching
和BRISKMatching
這幾個算法去查找,並且還分別告訴了我們這幾個算法的執行結果是什么。
值得注意的是,在TemplateMatching
算法的執行結果里面,有一個'confidence': 0.4422764182090759
,這個其實就是算法的可信度。 之前我們介紹過如何合理調整闕值來提高圖片識別成功率 ,那個閾值實際上是算法執行成功之后的可信度閾值(默認為0.7),如果算法識別的可信度(也就是confidence
)超過了我們設置的閾值,就會認為識別成功,否則認為失敗。
Airtest圖像識別算法介紹
在airtest框架中集成了不同種類的圖像識別算法。 其中包括模板匹配(也就是上文的TemplateMatching
)、以及基於特征點的圖像識別方法(包含了上文的SURFMatching
和BRISKMatching
)。這兩種識別方法的特點和區別如下:
模板匹配
- 無法跨分辨率識別
- 一定有相對最佳的匹配結果
- 方法名:
"tpl"
特征點匹配
- 跨分辨率識別
- 不一定有匹配結果
- 方法名列表:
["kaze", "brisk", "akaze", "orb", "sift", "surf", "brief"]
在這里我們還需要解釋一下:
1.無法跨分辨率識別,意思是一旦換一台不同分辨率的設備就可能識別失敗;
2.一定有相對最佳的匹配結果,即是不管怎么說也會給你找一個結果出來,雖然可能差別很大。比如上文例子中,我們使用了當前設備不存在的截圖讓程序去查找,屏幕上根本沒有結果,TemplateMatching
算法也找出了一個可信度為0.4的結果。
算法小結
- 模板匹配算法的優點是速度很快,如果分辨率不會改變的話,不妨選擇它作為首選算法
- 在分辨率可能會發生改變的情況下,我們會用特征點匹配的辦法來找圖,這樣跨平台的適應能力會更高,腳本容易適配不同型號的手機
特征點匹配各算法的性能對比
針對單張圖片,不同方法的性能對比
method_list = ["kaze", "brisk", "akaze", "orb", "sift", "surf", "brief"] # 針對一張圖片,繪制該張圖片的CPU和內存使用情況.截屏[2907, 1403] 截圖[1079, 804] search_file, screen_file = "sample\\high_dpi\\tpl1551940579340.png", "sample\\high_dpi\\tpl1551944272194.png" dir_path, file_name = "result", "high_dpi.json" test_and_profile_and_plot(search_file, screen_file, dir_path, file_name, method_list)
注:測試代碼詳見 airtest源碼目錄下的 airtest/benchmark/benchmark.py
- 性能解析:
- 內存:
- 最上方圖為內存曲線
- 內存占用:kaze > sift > akaze > surf > brief > brisk > orb
- CPU:
- 中間圖為CPU曲線
- CPU占用:kaze > surf > akaze > brisk > sift > brief > orb
- 時間:
- 橫軸為時間軸,且程序運行日志中有run tume輸出
- 運行時長:kaze > sift > akaze > surf > brisk > brief > orb
- 特征點對數量:
- 最下方圖為特征點數量圖
- kp_sch為小圖的特征點數量
- kp_src為大圖的特征點數量
- good為匹配成功的特征點對數量
- 點對數量:kaze > akaze > surf > brisk > sift > brief > orb
- 內存:
針對多張圖片的不同方法的性能對比
method_list = ["kaze", "brisk", "akaze", "orb", "sift", "surf", "brief"] # 測試多張圖片,寫入性能測試數據 test_and_profile_all_images(method_list) # 對比繪制多張圖片的結果 plot_profiled_all_images_table(method_list)
- 性能解析:
- 最大內存:
- 最上方圖為內存曲線,橫軸為不同的圖片名
- 最大內存:kaze > sift > akaze > surf > brief > brisk > orb
- 最大CPU:
- 中間圖為CPU曲線
- 最大CPU:kaze > surf > akaze > brisk > sift > brief > orb
- 識別效果:
- sift > surf > kaze > akaze > brisk > brief > orb
- 最大內存:
特征點匹配算法小結
針對單張圖片:
kave識別的效果最好,但同時占用內存和CPU也最多;
相對來說surf和brisk的效果不錯,且占用內存和CPU也處於中等水平;
orb雖然占用內存和CPU最低,但是它的效果也最差;
所以做單圖識別的時候,如果對識別精確度要求很高,且不在乎對內存和CPU的使用率時,可以選擇kave;如果對精確度要求沒那么高時,選擇像surf和brisk這些算法,就不會占用過多的內存和CPU。
針對多張圖片:
sift的識別效果最好,它占用的CPU也比較少,但占用內存較多;
surf的識別效果也很好,它占用的內存也比較少,但占用的CPU很高;
akave和brisk的效果還行,且占用內存和CPU也不是很多;
orb依舊是占用CPU和內存最少,但效果最差的那一個;
所以做多圖識別,對精確度要求高且不在意內存占用率的,可以選擇sift;而對精確度要求高且在意內存占用率的,可以選擇surf;對於精確度要求不是很高的,選用akave和brisk不會占用過多的內存和CPU。
拓展
對性能對比感興趣的同學可以到我們開源項目airtest文件夾里的benchmark目錄下,用benchmark.py
跑一下自己的例子來看看。
Airtest腳本圖像匹配算法的設定方式:
Airtest默認設置的算法是CVSTRATEGY = ["surf", "tpl", "brisk"]
,每次查找圖片的時候,airtest就會按照這個設置好的算法順序去執行,直到找出一個符合設定閾值的識別結果,或者是一直循環查找,直到超時。
當我們執行了1條touch語句(截圖不存在於當前設備畫面中),查找圖片時執行算法的日志如下:
可以看到,airtest按照默認設置的算法順序去執行,從surf
到tpl
再到brisk
,且因為當前設備不存在該截圖,它就一直循環查找,直到超時。
而當要找的截圖存在於當前設備畫面時,日志記錄如下:
airtest按照默認的算法順序,先執行了surf
,然后成功匹配了一個符合設定闕值的結果,程序就認為識別成功了。
那么,當我們想要改變這個算法順序或者自定義我們想要使用的圖像識別算法時該如何做呢?舉個例子:
如果我們使用的都是同樣分辨率的設備,並且想要匹配速度快一些,我們可以將tpl
調整到最前面。設置如下:
from airtest.core.settings import Settings as ST ST.CVSTRATEGY = ["tpl", "sift","brisk"]