Gdip_Imagesearch exclude found zones for correct result Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Riki81
Posts: 7
Joined: 27 Jun 2017, 11:58

Gdip_Imagesearch exclude found zones for correct result

27 Jun 2017, 12:38

I need to count the number of images with Gdip_Imagesearch.
The problem is when I work with simple one-color images, the function does not exclude previous found zone in next instances-loop search...
There are significantly more hits in the result (61 hits instead of the correct 3, in example) and greatly reduced performance.

I found a temporary partial solution by changing the search stepY (or stepX) in Gdip_MultiLockedBitsSearch:

Code: Select all

iX := 1, stepX := 1, iY := 1, stepY := nHeight
But result still not correct in most situations. I'm looking for better solution.

Test example: https://mega.nz/#!L99CWCaR!b_V9GI74duBK ... qF-SImufs8

I will be gracious if someone helps me.
User avatar
noname
Posts: 516
Joined: 19 Nov 2013, 09:15

Re: Gdip_Imagesearch exclude found zones for correct result

28 Jun 2017, 06:20

Image


You could change the haystack to exclude found images , it does not have to much of added search time and in principle will always work .

Code: Select all



SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1

#Include *i Gdip_All.ahk
#Include *i Gdip_ImageSearch.ahk


If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}

pneedle :=Gdip_CreateBitmapFromFile("needle.png")
  Gdip_GetImageDimensions(pneedle , wn, hn)
phaystack:=pBitmap :=Gdip_CreateBitmapFromFile("haystack.png")
  Gdip_GetImageDimensions(phaystack , wh, hh)
pGraphics:=Gdip_GraphicsFromImage(phaystack)

pBrush:=Gdip_BrushCreateSolid(0xff000000)

t:=a_tickcount

loop 40 ;just to be safe
{
    Gdip_ImageSearch(phaystack ,pneedle,list,0,0,wh,hh,,,,1)
    
    if !regexmatch(list,"\d")
      break
    
    l .=list "`n"
    pos:=strsplit(list,",")
    
    Gdip_FillRectangle(pGraphics, pBrush, pos.1,pos.2, wn, hn)
   ;  Gdip_SaveBitmapToFile(phaystack,"t.png")
    
   ; Gui, add,picture,,t.png
   ; Gui, show,autosize
   ; sleep 500
   ; Gui, destroy
}

msgbox % "time= " a_tickcount-t "ms`n" l



Gdip_DisposeImage(phaystack)
Gdip_DisposeImage(pneedle)
Gdip_Shutdown(pToken)


Riki81
Posts: 7
Joined: 27 Jun 2017, 11:58

Re: Gdip_Imagesearch exclude found zones for correct result

28 Jun 2017, 07:54

Great solution, That's exactly what I wanted. Thank you, noname!
Riki81
Posts: 7
Joined: 27 Jun 2017, 11:58

Re: Gdip_Imagesearch exclude found zones for correct result  Topic is solved

28 Jun 2017, 12:54

Found another solution. It do same but inside Gdip_MultiLockedBitsSearch function. Now I can use ImageSearch with Instances=0 parameter as usual.
With big haystack this method ~15x faster.

Code: Select all

Gdip_MultiLockedBitsSearch(hStride,hScan,hWidth,hHeight,nStride,nScan,nWidth,nHeight
,ByRef OutputList="",OuterX1=0,OuterY1=0,OuterX2=0,OuterY2=0,Variation=0
,SearchDirection=1,Instances=0,LineDelim="`n",CoordDelim=",")
{
    OutputList := ""
    OutputCount := !Instances
    InnerX1 := OuterX1 , InnerY1 := OuterY1
    InnerX2 := OuterX2 , InnerY2 := OuterY2

    ; The following part is a rather ugly but working hack that I
    ; came up with to adjust the variables and their increments
    ; according to the specified Haystack Search Direction
    /*
    Mod(SD,4) = 0 --> iX = 2 , stepX = +0 , iY = 1 , stepY = +1
    Mod(SD,4) = 1 --> iX = 1 , stepX = +1 , iY = 1 , stepY = +1
    Mod(SD,4) = 2 --> iX = 1 , stepX = +1 , iY = 2 , stepY = +0
    Mod(SD,4) = 3 --> iX = 2 , stepX = +0 , iY = 2 , stepY = +0
    SD <= 4   ------> Vertical preference
    SD > 4    ------> Horizontal preference
    */
    ; Set the index and the step (for both X and Y) to +1
    iX := 1, stepX := 1, iY := 1, stepY := 1
    ; Adjust Y variables if SD is 2, 3, 6 or 7
    Modulo := Mod(SearchDirection,4)
    If ( Modulo > 1 )
        iY := 2, stepY := 0
    ; adjust X variables if SD is 3, 4, 7 or 8
    If !Mod(Modulo,3)
        iX := 2, stepX := 0
    ; Set default Preference to vertical and Nonpreference to horizontal
    P := "Y", N := "X"
    ; adjust Preference and Nonpreference if SD is 5, 6, 7 or 8
    If ( SearchDirection > 4 )
        P := "X", N := "Y"
    ; Set the Preference Index and the Nonpreference Index
    iP := i%P%, iN := i%N%

    While (!(OutputCount == Instances) && (0 == Gdip_LockedBitsSearch(hStride,hScan,hWidth,hHeight,nStride
    ,nScan,nWidth,nHeight,FoundX,FoundY,OuterX1,OuterY1,OuterX2,OuterY2,Variation,SearchDirection)))
    {
        OutputCount++
        OutputList .= LineDelim FoundX CoordDelim FoundY
        Outer%P%%iP% := Found%P%+step%P%
        Inner%N%%iN% := Found%N%+step%N%
        Inner%P%1 := Found%P%
        Inner%P%2 := Found%P%+1
        While (!(OutputCount == Instances) && (0 == Gdip_LockedBitsSearch(hStride,hScan,hWidth,hHeight,nStride
        ,nScan,nWidth,nHeight,FoundX,FoundY,InnerX1,InnerY1,InnerX2,InnerY2,Variation,SearchDirection)))
        {
            OutputCount++
			
			; Fill found region for exlude from next instances =================
			x := FoundX
			y := FoundY
			FillColor := "0xff000000"
			Loop, %nHeight%
			{            
				Loop, %nWidth%
				{
					Gdip_SetLockBitPixel(FillColor, hScan, x, y, hStride)
					x++
				}
				x := FoundX
				y++
			}
			;===================================================================
			
            OutputList .= LineDelim FoundX CoordDelim FoundY
            Inner%N%%iN% := Found%N%+step%N%
        }
    }
    OutputList := SubStr(OutputList,1+StrLen(LineDelim))
    OutputCount -= !Instances
    Return OutputCount
}
Last edited by Riki81 on 29 Jun 2017, 14:23, edited 1 time in total.
User avatar
noname
Posts: 516
Joined: 19 Nov 2013, 09:15

Re: Gdip_Imagesearch exclude found zones for correct result

29 Jun 2017, 12:12

Image

Very nice integrated! Your adaptation makes it a lot easier to use but after playing with it I cannot find a big speed advantage,the haystack is a screengrab about 1380x768 pixels the needle is the same as you used.

fullscreengrab with needle images and larger colour area
Image

I am quite surprised by this result :eh:
Riki81
Posts: 7
Joined: 27 Jun 2017, 11:58

Re: Gdip_Imagesearch exclude found zones for correct result

29 Jun 2017, 13:32

Yes, the difference is only with a large amount of hits. Stress-test with one color 1920x1200 haystack and same 30x30 needle:
ImageImage

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], gabelynn1, Google [Bot] and 317 guests