ゲーム自動化などのキーワードでよく使われるのが画像認識らしく、AutoItでもImageSearch UDF+ImageSearch.dllがあります。画面をキャプチャ(スクリーンショット)して、指定した画像があるかマッチングを行うもののようです。
なので、Win+Shift+S的な画面キャプチャした画像から対象画像があるかのマッチングですね。
1. ImageSearch UDFを取得する
下記 urlでCenrrally氏が提供しています。トピック1番目の最後にダウンロードリンクがあるので、ダウンロードしrarを解凍します。
32bit用、64bit用でdllが違うのでそれぞれ環境に合わせてダウンロードします。
2. 関数は2つ。全体から検索か、エリア内検索か
画面全体から_ImageSearch()か、画面の一部から_ImageSearchArea()です。
_ImageSearch()は内部で_ImageSearchArea()呼んでいるだけですね。なので自分の使い方に合わせて関数を更に簡略化してもいいかと。
引数は以下のようになっています。
- $findImage マッチングしたい画像 ファイル名か、画像データのポインタ
ファイル名: target.bmp
画像データのポインタ - $resultPosition 返ってくるxy座標が画像の中心=1か、左上=0か
- $x, $y 返ってくる座標
- $tolerance 0~255
0は色完全マッチ、255にすると左上にあるごみ箱を探すなど変。
JPEGは非可逆圧縮なので、0だと当然マッチしなく100でマッチする(かなり遅い)
可逆圧縮のBMPかPNGを使うほうが良い - $HBMP $findImageと、どう組み合わせるのかわからない
- $x1,$y1,$right, $bottom 画面のどこを対象にするか
2.1 まずは動作確認
OSが64bitならSciTEのビルドオプション(Ctrl+F7)で64bitにチェックしてから。
今回はgoogle analyticsのアイコンを探してみます。キャプチャをPNGで保存しました。

見つけたらマウスをアイコンに移動するスクリプトです。
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include "ImageSearch.au3" Local $x1 Local $y1 Local $ret = _ImageSearch(@ScriptDir & "\target.png", 1, $x1,$y1,0) If $ret Then MsgBox(0,"found", "found") MouseMove($x1,$y1) EndIf ConsoleWrite("x="& $x1 & ", y=" & $y1)
Google Analyticsをブラウザで立ち上げてアイコンが見えるようにして、このスクリプトを実行すると、見つかればマウスが移動します。
3. 特定のアプリ内画像検索はまずアプリの矩形を取得
Citrixのような一見ウィンドウだけど実は画像となるとUIAutomationなどではコントロール取得できないので、ImageSearchAreaの出番になりますね。
その為にもまずはウィンドウを取得して、その矩形をImageSearchArea()に渡すことが必要になります。
Citrix持っていないので、ChromeウィンドウをUIAutomationで取得し、それを渡すことでそのウィンドウ矩形を取得します。UIAutomationでコントロールなど取得するには下記記事を参考に。
ウィンドウ矩形を取得し、ImageSearchAreaに渡せば速度も速くなり、他アプリのコントロールを取得するような誤動作減る期待が持てますね。
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <Array.au3> #include "UIA_Constants.au3" #include "ImageSearch.au3" Opt( "MustDeclareVars", 1) Global $b_box = _get_chrome_rect() If Not IsArray($b_box) Then Exit EndIf Func _get_chrome_rect() ; UIAutomation オブジェクト生成 Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation8, $sIID_IUIAutomation6, $dtag_IUIAutomation6 ) If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF ) ConsoleWrite( "$oUIAutomation OK" & @CRLF ) ; デスクトップ 取得 Local $pDesktop, $oDesktop $oUIAutomation.GetRootElement( $pDesktop ) $oDesktop = ObjCreateInterface( $pDesktop, $sIID_IUIAutomationElement9, $dtag_IUIAutomationElement9 ) If Not IsObj( $oDesktop ) Then Return ConsoleWrite( "$oDesktop ERR" & @CRLF ) ConsoleWrite( "$oDesktop OK" & @CRLF ) Local $pCondition $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, "アナリティクス - Google Chrome", $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pChrome, $oChrome $oDesktop.FindFirst($TreeScope_Children, $pCondition, $pChrome) $oChrome = ObjCreateInterface( $pChrome, $sIID_IUIAutomationElement9, $dtag_IUIAutomationElement9) If Not IsObj( $oChrome ) Then Return ConsoleWrite( "$oChrome ERR" & @CRLF ) ConsoleWrite( "$oChrome OK" & @CRLF ) Local $bbox ;l,t,w,h $oChrome.GetCurrentPropertyValue( $UIA_BoundingRectanglePropertyId, $bbox) ; _ArrayDisplay($bbox) ConsoleWrite("bbox l=" & $bbox[0] & " t=" & $bbox[1] & " w=" & $bbox[2] & " h=" & $bbox[3] & @CRLF) Return $bbox EndFunc Global $x1 Global $y1 ;Local $ret = _ImageSearch(@ScriptDir & "\target.png", 1, $x1,$y1,0) Global $ret = _ImageSearchArea(@ScriptDir & "\target.png", 1, $b_box[0],$b_box[1],$b_box[2],$b_box[3],$x1,$y1,0) If $ret Then MsgBox(0,"found", "found") MouseMove($x1,$y1) EndIf ConsoleWrite("x=" & $x1 & ", y=" & $y1)
4. マスク画像も認識出来るか
先ほどのGoogle Analyticsのアイコンの白背景をマスキングしたPNGを用意し、これを画面内から検索します。
画面も背景を青に変更したものを用意しました。


ChromeにもAnalytics表示(背景白)していたのですが、うまく認識されません。
マスキングにコツがあるのでしょうか。ImageSearch.dllではちょっと厳しいようです。
5. OpenCVを使ったほうが良い
AutoItでOpenCVの画像認識を用いた画面内マッチングの記事を書きました。
コメント