ImageSearch, 120+images, too slow

Ask gaming related questions (AHK v1.1 and older)
TooNoobToScript
Posts: 3
Joined: 14 Oct 2017, 09:27

ImageSearch, 120+images, too slow

14 Oct 2017, 10:05

Hello, I`m very new in scripting, can you help me with this issue please?

Script task: find image and click on it, there are 120+ images, every of them potentially can be on screen, but only 5-6 actually appears.

I made a very primitive script with ImageSearch, it works, but too slow - about 30 sec to check screen for all possible images.

So the question is it possible to make this script faster?

Code: Select all

Numpad1::

loop, 1

{    
ImageSearch, xp, yp, 0, 0, 793, 726,  Image1.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}

ImageSearch, xp, yp, 0, 0, 793, 726, *50 Image2.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}

...
...
...
...

ImageSearch, xp, yp, 0, 0, 793, 726, *50 Image125.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}
}
Return

f5::pause
f10::exitapp
User avatar
Reloaded
Posts: 283
Joined: 25 Aug 2017, 08:48

Re: ImageSearch, 120+images, too slow

14 Oct 2017, 11:27

Try to add
SetBatchLines -1
this make your Script faster, but idk it work on ImageSearch, just try it.#


And you need to add
Coordmode, mouse, screen
this make the Script better work.
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: ImageSearch, 120+images, too slow

14 Oct 2017, 11:56

I don't think there's really a way to make it work faster. Comparing images simply takes a lot of time.

However, that doesn't mean your code can't be faster. You need a new approach. I recommend some way to group together "competing" images, and when something in common amongst those images is identified, search specifically for those images instead of all 120+.

If 20 images have a red pixel in their top left corner, use PixelGetColor or PixelSearch if the image can be anywhere on screen (and not just in a grid arrangement), and depending on those results then conduct an ImageSearch with those 20 images.

Alternatively, if nothing else, you can make your code much shorter:

Code: Select all

Loop, 125
{
ImageSearch, xp, yp, 0, 0, 793, 726, *50 Image%A_Index%.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}
}
User avatar
Xtra
Posts: 2750
Joined: 02 Oct 2015, 12:15

Re: ImageSearch, 120+images, too slow

14 Oct 2017, 13:42

Make the most commonly found images found first with the lowest numbers ie: image1 - image6 etc.
Once an image is found (ErrorLevel = 0) break the inner loop and start the search from the beginning again (Loop within a Loop).
This way you are not searching through all images every time one is found.

Based on above examples it would look like this:

Code: Select all

SetBatchLines -1
Coordmode, Pixel, screen
Coordmode, Mouse, screen

Loop
{
    Loop, 125
    {
        ImageSearch, xp, yp, 0, 0, 793, 726, *50 Image%A_Index%.png
        If (ErrorLevel = 0)
        {
            MouseMove, xp, yp, 0
            send {LButton}
            break
        }
    }
}
HTH

Note: If you need it faster use GDIP imagesearch instead.
TooNoobToScript
Posts: 3
Joined: 14 Oct 2017, 09:27

Re: ImageSearch, 120+images, too slow

15 Oct 2017, 06:36

Thank you for your advices, I used it and now the script is 30% faster, but still too slow - in ideal it must be 4-5 sec, not 20. Looks like the only way is Gdip_ImageSearch. Tried to find some manual, but all links are outdated, this for example https://autohotkey.com/board/topic/6594 ... nual-v143/. Maybe someone know where to find actual link to manual?
User avatar
Xtra
Posts: 2750
Joined: 02 Oct 2015, 12:15

Re: ImageSearch, 120+images, too slow

15 Oct 2017, 15:41

Having the variation set to 50 is going to take a lot longer to search.
Try lowering that number if you need 50 most likely your screen is changing and not matching the image exactly every time.
I would also reduce the search area to the minimum size to find all the images.

The gdip tutorial does not cover image searching it was not a part of the original lib.

HTH
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: ImageSearch, 120+images, too slow

15 Oct 2017, 15:54

If Gdip_ImageSearch is still not fast enough. One possible solution would be to convert the images to hex and search the text, in case that's faster.

[Note: the lines are retrieved upside down, so the order of those lines has to be reversed.]
Gdip: image binary data to hex string for OCR - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=35339

[Some other code related to image to hex.]
Use Gdip to split a single image into multiple images - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 05#p175705

An obvious point to make, just because I didn't see mentioned yet, would be to make the haystack/needle images as small as possible.

[Gdip_ImageSearch was not an original part of the Gdip library, and there are different versions of it.]
[This was the better version that I found and it explains the parameters at the beginning.]
AutoHotkey/Gdip_ImageSearch.ahk at master · MasterFocus/AutoHotkey · GitHub
https://github.com/MasterFocus/AutoHotk ... Search.ahk
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Spawnova
Posts: 554
Joined: 08 Jul 2015, 00:12
Contact:

Re: ImageSearch, 120+images, too slow

15 Oct 2017, 23:47

One other thing that can drastically speed up imagesearch is to disable aero if it's enabled.
User avatar
Brazolek123
Posts: 187
Joined: 06 Jun 2016, 16:02

Re: ImageSearch, 120+images, too slow

16 Oct 2017, 04:18

1) Place at begining of script, it reduced imagesearch speed from 60ms to 0-1ms (literally zero to one miliseconds, in my case)

Code: Select all

SetBatchLines, -1
DllCall("dwmapi\DwmEnableComposition", "uint", 0)
2) Try compile both x32 and x64 and check whats faster (in my case x32 is two times faster than x64)
(warning, gdip.ahk need to have modified numget functions in order to work on x64)

3) Simple imagesearch works faster in my case than gdip, but gdip has its advantages.

4) Search only desired area, not whole screen.

5) If you are using gdip imagesearch on one area to find many objects do as below:

Code: Select all

      pToken := Gdip_Startup()
      bmpArea := Gdip_BitmapFromHWnd(hWindow) ; you only obtain main window once, you can aswell use gbfromScreen()

      bmpObject1 := Gdip_CreateBitmapFromFile(file1)
      RET1 := Gdip_ImageSearch(bmpArea,bmpObject1,OutputList,reg1,reg2,reg3,reg4,Variation,Trans,SearchDirection) ;  scan multiple images
      Gdip_DisposeImage(bmpObject1) ; always dispose to avoid ram leak

      bmpObject2 := Gdip_CreateBitmapFromFile(file2)
      RET2 := Gdip_ImageSearch(bmpArea,bmpObject2,OutputList,reg1,reg2,reg3,reg4,Variation,Trans,SearchDirection)
      Gdip_DisposeImage(bmpObject2)

      Gdip_DisposeImage(bmpArea)
      Gdip_Shutdown(pToken) ; always shut it down
Last edited by Brazolek123 on 16 Oct 2017, 06:10, edited 1 time in total.
TooNoobToScript
Posts: 3
Joined: 14 Oct 2017, 09:27

Re: ImageSearch, 120+images, too slow

16 Oct 2017, 06:09

Thank you all for your help, now it scans almost 150 images for 3 sec, and it is simple ImageSearch.
Here is the code is case someone got same problem.

Code: Select all


#NoEnv
#MaxHotkeysPerInterval 99000000
#HotkeyInterval 99000000
#KeyHistory 0
ListLines Off
Process, Priority, , A
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
SetWinDelay, -1
SetControlDelay, -1
SendMode Input

Numpad1::
CoordMode, mouse, Window

SetBatchLines, -1
DllCall("dwmapi\DwmEnableComposition", "uint", 0)



loop, 1

{    
ImageSearch, xp, yp, 0, 0, 793, 726, *50  Fish.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}

ImageSearch, xp, yp, 0, 0, 793, 726, *50 Stone.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}

...
...
...
...

ImageSearch, xp, yp, 0, 0, 793, 726, *50 Wall.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}
}
Return
And another small question. I tried to write script using Gdip_ImageSearch function, but definetly made something wrong: it must make screenshot of active window, search image Needle.png within and click on it.
Gdip.ahk consist MasterFocus`s functions and placed in Autohotkey/Lib directory, so it works fine.
Can you please explain me whats wrong whit this code?

Code: Select all

#Include Gdip.ahk

Numpad1::

pToken := Gdip_Startup()
   
pBitmapHayStack := Gdip_BitmapFromScreen()

pBitmapNeedle := Gdip_CreateBitmapFromFile (Needle.png)
     
loop, 1
{
Gdip_ImageSearch(pBitmapHayStack, pBitmapNeedle, x, y)
if ErrorLevel=0
   MouseClick, Right, x,  y,
}

Gdip_DisposeImage(pBitmapNeedle)
Gdip_DisposeImage(pBitmapHayStack)
Gdip_Shutdown(pToken)
return
User avatar
Brazolek123
Posts: 187
Joined: 06 Jun 2016, 16:02

Re: ImageSearch, 120+images, too slow

16 Oct 2017, 06:18

Code: Select all

#Include Gdip.ahk
Numpad1::
pToken := Gdip_Startup()
pBitmapHayStack := Gdip_BitmapFromScreen()
loop, 1
{
	pBitmapNeedle := Gdip_CreateBitmapFromFile(Needle.png)    	    ;it rather should be inside loop if you would like in future to scan more than 1 img in signle thread
	RET := Gdip_ImageSearch(pBitmapHayStack,pBitmapNeedle,OutputList)
	if (RET > 0){                                                                               				    ;ret=negative if error, 0 if no found on screen or 1 if found
	   temppos := StrSplit(OutputList, ",")              	                  			        ; open your gdip.ahk and read what output list is and whats 'instances' option, might help you
	   x := temppos[1]
	   y := temppos[2]
	   temppos := ""                                                                            			    ; clear array
	   MouseClick, Right, %x%,  %y%,
	}
	Gdip_DisposeImage(pBitmapNeedle)                                 			    ; dispose inside the loop in case you would like in future to scan more than 1 img in signle thread
}

Gdip_DisposeImage(pBitmapHayStack)
Gdip_Shutdown(pToken)
return
braveknightrs
Posts: 6
Joined: 04 Jun 2023, 22:58

Re: ImageSearch, 120+images, too slow

25 Nov 2023, 21:31

TooNoobToScript wrote:
16 Oct 2017, 06:09
Thank you all for your help, now it scans almost 150 images for 3 sec, and it is simple ImageSearch.
Here is the code is case someone got same problem.

Code: Select all


#NoEnv
#MaxHotkeysPerInterval 99000000
#HotkeyInterval 99000000
#KeyHistory 0
ListLines Off
Process, Priority, , A
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
SetWinDelay, -1
SetControlDelay, -1
SendMode Input

Numpad1::
CoordMode, mouse, Window

SetBatchLines, -1
DllCall("dwmapi\DwmEnableComposition", "uint", 0)



loop, 1

{    
ImageSearch, xp, yp, 0, 0, 793, 726, *50  Fish.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}

ImageSearch, xp, yp, 0, 0, 793, 726, *50 Stone.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}

...
...
...
...

ImageSearch, xp, yp, 0, 0, 793, 726, *50 Wall.png
If ErrorLevel=0
{
MouseMove, xp, yp, 0
send {LButton}
}
}
Return
And another small question. I tried to write script using Gdip_ImageSearch function, but definetly made something wrong: it must make screenshot of active window, search image Needle.png within and click on it.
Gdip.ahk consist MasterFocus`s functions and placed in Autohotkey/Lib directory, so it works fine.
Can you please explain me whats wrong whit this code?

Code: Select all

#Include Gdip.ahk

Numpad1::

pToken := Gdip_Startup()
   
pBitmapHayStack := Gdip_BitmapFromScreen()

pBitmapNeedle := Gdip_CreateBitmapFromFile (Needle.png)
     
loop, 1
{
Gdip_ImageSearch(pBitmapHayStack, pBitmapNeedle, x, y)
if ErrorLevel=0
   MouseClick, Right, x,  y,
}

Gdip_DisposeImage(pBitmapNeedle)
Gdip_DisposeImage(pBitmapHayStack)
Gdip_Shutdown(pToken)
return
Oh man i was trying soo many different things to speed up image searching. I tried making my functions compute faster, reduce lines of code, tried different imagesearching classes and the thing that worked was adding those directives in. Image searching for a single small image went from 47-78 ms to 0-16ms! amazing

Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: No registered users and 150 guests