OpenCV バージョン4以上に対応したクリックツールを作ってみました
導入方法
http://memo.eightban.com/autoit/autoit-opencv-v4-udf
機能
複数画像対応
画面から画像を登録
指定した画像が見つかるまで待機するしないの選択が可能
画像認識の前と後に処理を追加することが可能
画像認識した後にマウスカーソル移動もしくはクリックすることが可能
画像認識した後にキーを押したりテキストを送信することが可能
処理ごとにフォルダを分けられる

スクリプト
#include <Clipboard.au3>
#include <EditConstants.au3>
#include <MsgBoxConstants.au3>
#include <SendMessage.au3>
#include <WinAPISys.au3>
#Include <ScreenCapture.au3>
#include <GuiStatusBar.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "..\autoit-opencv-com\udf\opencv_udf_utils.au3"
Global $aRect, $iLeft, $iTop, $iWidth, $iHeight
Global $cv
if $CmdLine[0] = 0 Then
Global $idir = ""
Global $Mouse_Move_On_Found = 1
Global $Mouse_Click_On_Found = 0
Global $Wait_mode = 1
Global $Once_mode = 0
Global $Center_mode = 1
Global $Retern_mode = 0
Global $Exemin_mode = 0 ; 0:none,1:exe,2:exemin
Else
Global $idir = "\" & $CmdLine[1]
Global $Mouse_Move_On_Found = $CmdLine[2]*1
Global $Mouse_Click_On_Found = $CmdLine[3]*1
Global $Wait_mode = $CmdLine[4]*1
Global $Once_mode = $CmdLine[5]*1
Global $Center_mode = $CmdLine[6]*1
Global $Retern_mode = $CmdLine[7]*1
Global $Exemin_mode = $CmdLine[8]*1
EndIf
Global Const $fn = @ScriptDir & $idir & "\sendkey" & ".csv"
Global Const $fn2 = @ScriptDir & $idir & "\sendtext" & ".txt"
Global Const $iSleep_Time=500
Global Const $iSleep_Time_On_Found=5000
Global $threshold = 0.95
Global $sCount = 0
Global $mCount = 12
Global $iCount = 0
Global $aCount = 0
Global $fCount = 0
Dim $_Image[$mCount]
Dim $_Image1[$mCount]
Dim $line[$mCount]
For $iz=1 To $mCount Step 1
$_Image[$iz-1] = @ScriptDir & $idir & "\butonimagej" & $iz & ".bmp"
$line[$iz-1] = ""
Next
Global $iMax = 5
Global $iRow = 0
Dim $text[$iMax]
Global Const $textptn="@@text@@"
Global Const $lclkptn="@@Lclick@@"
Global Const $dlclkptn="@@DLclick@@"
Global Const $rclkptn="@@Rclick@@"
Global Const $mclkptn="@@Mclick@@"
Global $iLoop = 1
Global $_msg_0 = " image"
Global $_msg_1 = "* image"
Global $_Image_0 = ""
Global $_tmp_0 = ""
Global $_Pic_0 = 0
Global $ii = 0
Global $kflg = 0
Global $ix=0
dim $_msg[$mCount*2]
For $iz=1 To $mCount*2 Step 1
$_msg[$iz-1] = $_msg_0
Next
$_msg[$mCount] = $_msg_1
Global $_title_1 = "autoimageclosej"
_OpenCV_Open(_OpenCV_FindDLL("opencv_world470*"), _OpenCV_FindDLL("autoit_opencv_com470*"))
;_GDIPlus_Startup()
OnAutoItExitRegister("_OnAutoItExit")
HotKeySet("{Esc}", "_Exit") ; Press ESC for exit
Opt("GUIOnEventMode", 1) ; Change to OnEvent mode
$mainwindow = GUICreate($_title_1, 140,30*$mCount+80,150,50)
;$mainwindow = GUICreate($_title_1, 140,300)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
$msg1="stopping"
$labelx=GUICtrlCreateLabel($msg1, 70, 25)
$StatusBar1 = _GUICtrlStatusBar_Create($mainwindow)
$buttonx = GUICtrlCreateButton("push", 10, 20,50, 25)
GUICtrlSetOnEvent($buttonx, "OKButtonx")
#comments-start
#comments-end
Dim $_Pic[$mCount]
Dim $_label[$mCount]
Dim $_button[$mCount]
For $iz=0 To $mCount-1 Step 1
$_Pic[$iz] = GUICtrlCreatePic($_Image[$iz], 70, 50+30*$iz, 50, 25)
$_label[$iz]=GUICtrlCreateLabel($_msg_0, 65,60+30*$iz)
GUICtrlSetColor($_label[$iz], 0xff0000)
GUICtrlSetBkColor($_label[$iz], $GUI_BKCOLOR_TRANSPARENT)
$_button[$iz] = GUICtrlCreateButton("set"&($iz+1), 10, 50+30*$iz,50, 25)
GUICtrlSetOnEvent($_button[$iz], "OKButton"&($iz+1))
Next
Global $_Pic_0 = 0
Dim $_tmp[$mCount]
GUIRegisterMsg($WM_CLIPBOARDUPDATE, 'WM_CLIPBOARDUPDATE')
GUISetState(@SW_SHOW)
_WinAPI_AddClipboardFormatListener($mainwindow)
_SendMessage($mainwindow, $WM_CLIPBOARDUPDATE)
WinWait($_title_1)
WinActivate($_title_1)
WinSetOnTop($_title_1, "", 1)
If $Exemin_mode Then
if WinWait($_title_1, "",3) Then
sleep(50)
ControlClick ($_title_1,"","Button1")
sleep(50)
If $Exemin_mode = 2 Then GUISetState(@SW_MINIMIZE)
EndIf
EndIf
_csvread()
_txtread()
$pos = MouseGetPos()
$xx2 = $pos[0]
$yy2 = $pos[1]
$cv = _OpenCV_get()
If Not IsObj($cv) Then Exit
_Initialize()
While 1
If $fCount = 0 Then Sleep(1000)
if $kflg = 2 Then
ConsoleWrite($_Pic_0 & $_Image_0 & @CRLF )
Sleep(3000)
_Initialize()
if $_Pic_0 = 0 Then
$_Pic[$ii] = GUICtrlCreatePic($_Image[$ii], 70, 50+30*$ii, 50, 25)
GUISetState(@SW_HIDE )
GUISetState(@SW_SHOW)
Else
GUICtrlSetImage ($_Pic_0,$_Image_0)
EndIf
$kflg = 0
EndIf
if $msg1="stopping" Then
Else
_GUICtrlStatusBar_SetText ($StatusBar1,$iLoop & " - " & $ix+1 & " -txt("&$iRow&")")
For $iz=0 To $mCount-1 Step 1
GUICtrlSetData ($_label[$iz], $_msg[$ix+$mCount-$iz])
Next
_osu()
EndIf
if $ix > $mCount-1 Then
$ix = 0
$iLoop += 1
EndIf
If $_Image1[$ix]<>"" Then Sleep($iSleep_Time)
WEnd
Func OKButtonx()
if $msg1="stopping" Then
$msg1="executing"
Else
$msg1="stopping"
$ix+=1
EndIf
GUICtrlSetData ($labelx, $msg1)
EndFunc
Func OKButton1()
$ii=0
_imageget($ii)
EndFunc
Func OKButton2()
$ii=1
_imageget($ii)
EndFunc
Func OKButton3()
$ii=2
_imageget($ii)
EndFunc
Func OKButton4()
$ii=3
_imageget($ii)
EndFunc
Func OKButton5()
$ii=4
_imageget($ii)
EndFunc
Func OKButton6()
$ii=5
_imageget($ii)
EndFunc
Func OKButton7()
$ii=6
_imageget($ii)
EndFunc
Func OKButton8()
$ii=7
_imageget($ii)
EndFunc
Func OKButton9()
$ii=8
_imageget($ii)
EndFunc
Func OKButton10()
$ii=9
_imageget($ii)
EndFunc
Func OKButton11()
$ii=10
_imageget($ii)
EndFunc
Func OKButton12()
$ii=11
_imageget($ii)
EndFunc
Func _imageget($ic=0)
$_Image_0 = $_Image[$ic]
$_Pic_0 = $_Pic[$ic]
$kflg = 1
Send("#+S")
Sleep(2000)
EndFunc
Func _opt($ia=0)
Switch Int($ia+0)
Case 0 To 3
Case 4 To 5
Sleep(3000)
Send("{END}")
Sleep(1000)
Case Else
EndSwitch
EndFunc
Func _opt2($ib=0)
Switch Int($ib+0)
Case 0 To 3
Case 4 To 5
Sleep(3000)
Send("!{LEFT}")
Sleep(1000)
Case Else
EndSwitch
EndFunc
;===========================
Func _osu()
$pos = MouseGetPos()
If $_Image1[$ix]<>"" Then
; _opt($ix)
$sCount += 1
ConsoleWrite("Rect: [" & $iWidth & " x " & $iHeight & " from (" & $iLeft & ", " & $iTop & ")]" & @CRLF)
; The higher the value, the higher the match is exact
; Local $threshold = 0.95
$img = _OpenCV_GetDesktopScreenMat($aRect)
if $iCount=0 Then
; Ignore the alpha channel when matching the template => $CV_COLOR_BGRA2BGR
; Only consider gray scale colors when matching the template => $CV_COLOR_BGRA2GRAY
; using cveCanny and/or gray scale can significantly reduce the matching time but also reduce the matching accuracy
$aMatches = 0
Global $aMatches = _OpenCV_FindTemplate($img, $_tmp[$ix], $threshold, Default, Default, Default, $CV_COLOR_BGRA2GRAY)
Local $iMatches = UBound($aMatches)
ConsoleWrite("Number of matches: " & $iMatches & $_Image[$ix] & " "&$ix&@CRLF)
If $Once_mode Then
if $iMatches<>0 Then $iMatches = 1
EndIf
$iCount = $iMatches
$aCount = $iMatches
$_tmp_0 = $_tmp[$ix]
if $iMatches <>0 Then $ix+=1
EndIf
ConsoleWrite('- [' & $_tmp_0 & '] IX=' & $ix & @CRLF)
if $iCount<>0 Then
Local $ixx = $aCount - $iCount
$iCount -=1
Local $aMatchRect = _OpenCV_Rect(0, 0, $_tmp_0.width, $_tmp_0.height)
$aMatchRect[0] = $aMatches[$ixx][0]
$aMatchRect[1] = $aMatches[$ixx][1]
ConsoleWrite('- [' & $sCount & '] Image found:' & " X=" & $aMatchRect[0] & " Y=" & $aMatchRect[1] & @CRLF)
If $Center_mode Then
Local $posx = $aMatchRect[0] + $_tmp_0.width/2
Local $posy = $aMatchRect[1] + $_tmp_0.height/2
Else
Local $posx = $aMatchRect[0]
Local $posy = $aMatchRect[1]
EndIf
If $Mouse_Move_On_Found Then
MouseMove($posx, $posy)
Sleep($iSleep_Time_On_Found)
EndIf
If $Mouse_Click_On_Found Then MouseClick("left", $posx, $posy)
If $Retern_mode Then
MouseMove($xx2, $yy2)
Sleep(2000)
EndIf
; ToolTip('(' & $sCount & "] Image found:" & " X=" & $aMatchRect[0] & " Y=" & $aMatchRect[1], 1, 1)
;_opt2($ix)
if $ix>0 Then _sendky($ix-1)
Else
If Not $Wait_mode Then $ix+=1
EndIf
Sleep(2000)
Else
$ix+=1
EndIf
if $pos[0]=$xx2 AND $pos[1]=$yy2 Then
Else
$xx2 = $pos[0]
$yy2 = $pos[1]
; Beep(900, 100)
EndIf
EndFunc
Func WM_CLIPBOARDUPDATE($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam, $lParam
if $kflg = 1 Then
Sleep(200)
_ClipBoard_Open(0)
$hBmp = _ClipBoard_GetDataEx ($CF_BITMAP )
_ScreenCapture_SaveImage ($_Image_0, $hBmp)
_ClipBoard_Close()
ConsoleWrite(" Save image: " & $_Image_0 & @CRLF )
$kflg = 2
EndIf
Return 0
EndFunc ;==>
Func _Initialize()
$fCount = 0
For $iz=0 To $mCount-1 Step 1
If FileExists($_Image[$iz]) Then
$_tmp[$iz] = $cv.imread($_Image[$iz])
$_Image1[$iz] = $_Image[$iz]
$fCount += 1
Else
$_tmp[$iz] = ""
$_Image1[$iz] = ""
EndIf
; $_tmp[$iz] = $cv.imread(_OpenCV_FindFile("samples\data\mario_coin.png"))
Next
; Search on the first screen. Leave empty to search on all screens
; Reducing the search area improves the search time
$aRect = _OpenCV_GetDesktopScreenRect(1)
$iLeft = $aRect[0]
$iTop = $aRect[1]
$iWidth = $aRect[2]
$iHeight = $aRect[3]
EndFunc ;==>_Initialize
Func _sendky($mx)
; if $mx-1<0 Then MsgBox(4096,"err", $mx,5)
if $line[$mx]<> "" Then
Sleep(3000)
$array2 = StringSplit($line[$mx], ",")
For $cx = 1 to UBound($array2)-1
if $array2[$cx]<> "" Then
if $array2[$cx] == $textptn then
Send($text[$iRow])
$iRow +=1
if $iRow > $iMax -1 Then $iRow =0
ElseIf StringCompare(StringLeft ( $array2[$cx],StringLen ( $textptn)), $textptn, 1) then
Switch $array2[$cx]
Case $lclkptn
MouseClick("left")
Case $dlclkptn
MouseClick("left")
MouseClick("left")
Case $rclkptn
MouseClick("right")
Case $mclkptn
MouseClick("middle")
Case Else
Send($array2[$cx])
EndSwitch
Else
$tx = StringTrimLeft ( $array2[$cx],StringLen ( $textptn))
if StringIsDigit ( $tx -1) Then
; MsgBox(4096,"Array Contents0", $text[$tx],5)
; Send("{END}")
Send($text[$tx-1])
EndIf
EndIf
EndIf
Sleep(2000)
_GUICtrlStatusBar_SetText ($StatusBar1,$iLoop & " - " & $ix+1 & " -k(" & $cx & "/" &UBound($array2)-1&") -txt("&$iRow&")")
Next
EndIf
EndFunc
Func _csvread()
$mm = 0
$file = FileOpen($fn, 0)
;ファイルが読み込みモードで開かれたかどうかチェック
If $file = -1 Then
Else
;EOFに達するまで1文字づつ読み込む。
While 1
$line[$mm] = FileReadLine($file)
If @error = -1 Then ExitLoop
$mm=$mm+1
If $mm > $mCount -1 Then ExitLoop
Wend
FileClose($file)
EndIf
EndFunc
Func _txtread()
$mm = 0
$file2 = FileOpen($fn2, 0)
;ファイルが読み込みモードで開かれたかどうかチェック
If $file2 = -1 Then
Else
;EOFに達するまで1文字づつ読み込む。
While 1
$text[$mm] = FileReadLine($file2)
If @error = -1 Then ExitLoop
$mm=$mm+1
If $mm > $iMax -1 Then
$iMax +=1
ReDim $text[$iMax]
EndIf
Wend
FileClose($file2)
EndIf
;_ArrayDisplay($text)
EndFunc
Func _Release()
#comments-start
#comments-end
$cv.destroyAllWindows()
EndFunc ;==>_Release
Func _OnAutoItExit()
; _GDIPlus_Shutdown()
_OpenCV_Close()
EndFunc ;==>_OnAutoItExit
Func CLOSEClicked()
_Release()
Exit
EndFunc
Func _Exit()
_Release()
Exit 0
EndFunc ;==>_Exit
説明
OpenCV の画像認識を使ってマウスカーソルを動かしたりクリックしたりします。Windows の機能を使って画面をクリップボード経由でキャプチャーしています
使い方
スクリプトのパラメータ(有効:1, 無効:0)を変更しプログラムを起動してください。
セットボタンで画像を登録し,その後 PUSH ボタンで画像認識を開始してください。
$Mouse_Move_On_Found
画像が見つかった時にマウスカーソルを動かすかどうか
$Mouse_Click_On_Found
画像が見つかった時にクリックするかどうか
$Wait_mode
目的の画像が見つかるまで待ち続けるかどうか
プッシュボタンで次の画像を検索します
$Once_mode
複数画像を見つけた時に最初の画像だけ処理するかどうか
$Center_mode
見つかった画像の中心に移動するかどうか
通常は見つかった画像の左上
$Retern_mode
マウスが動いた後元に戻るか
$Exemin_mode
起動後実行して最小化するかどうか
$iSleep_Time_On_Found
マウスカーソルが動いた後の待ち時間
$threshold
画像認識の曖昧さ
_opt
画像検索する前に行う処理
コメントアウトしています。使用する場合はコメント[;]を取ってください
_opt2
画像検索後に行う処理
コメントアウトしています。使用する場合はコメント[;]を取ってください
バッチファイル
C:\autoit3\AutoIt3_x64.exe C:\autoit3\autoit-opencv-com\samples\00_autoimgeclosej.au3 #windows 1 0 0 1 1 1 1
sendkey.csv
キーボードを押したりテキストを送信するためのファイルです。カンマ区切りで複数指定が可能です。
行番号がボタンの番号に対応しています
----------------------------------------------
@@text@@1
@@text@@2,@@text@@3
@@Rclick@@
@@text@@
D:\data2\03.jpg,{ENTER},{TAB 4},{END}
{END}
----------------------------------------------
@@text@@を指定すると長い文やカンマを指定することができます。行番号がない場合は上から順番にセットします
キーの設定はオートイットと同じですのでサイトを参考にしてください
https://open-shelf.appspot.com/AutoIt3.3.6.1j/html/functions/Send.htm
マウスクリックをすることができます。
@@Lclick@@ 左クリック
@@DLclick@@ ダブルクリック
@@Rclick@@ 右クリック
@@Mclick@@ ミドルクリック
sendtext.txt
@@text@@に対応した文を設定するファイルです。数字は行番号に対応しています。
----------------------------------------------
おはようございます。
こんにちは
おやすみなさい,また明日。
----------------------------------------------
その他
コピペした後は下にある文字は次のように変更してください
[ [
& &
< <
> >
シンプルなスクリプト
自分でスクリプトを作られる場合はこちらを参考にしてください
http://memo.eightban.com/autoit/autoit-opencv-v4-button