AutoItでImageSearch、画面内の画像認識

autoit 画面内画像検索imagesearch AutoIT

ゲーム自動化などのキーワードでよく使われるのが画像認識らしく、AutoItでもImageSearch UDF+ImageSearch.dllがあります。画面をキャプチャ(スクリーンショット)して、指定した画像があるかマッチングを行うもののようです。
なので、Win+Shift+S的な画面キャプチャした画像から対象画像があるかのマッチングですね。

スポンサーリンク

1. ImageSearch UDFを取得する

下記 urlでCenrrally氏が提供しています。トピック1番目の最後にダウンロードリンクがあるので、ダウンロードしrarを解凍します。

ImageSearch Usage Explanation
After having lot of issues myself with getting ImageSearch to work I decided to make topic with explanation how to proper use this script.Here is link of origin...

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で保存しました。

google analyticsのアイコン

見つけたらマウスをアイコンに移動するスクリプトです。

#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の画像認識を用いた画面内マッチングの記事を書きました。

コメント

タイトルとURLをコピーしました