Jump to content

My method extremly slow ( MultiPixelSearch )


Jex
 Share

Recommended Posts

My Pixel Search method trying find my first color in fullscreen and if found my color, looking for second color for check first color is my true result or not ( Example : My first color red but if im do normal pixel search i cant find my true result because my screen will be have too many red pixels but if im look for +5 pixel right and +50 pixel down for second color and if second color true then my first color coordinate result will be big chance true result. If second color not true continue pixel searching... ) My problem is normal pixel search code or function will search 1,296,000 pixel ( 1440x900 ) in 30ms ! Example :

Global $Width = @DesktopWidth, $Height = @DesktopHeight
$Begin = TimerInit()
PixelSearch(1, 1, $Width, $Height, 0x636B6D)
$Result = TimerDiff($Begin)
MsgBox("","",($Width * $Height) & " Pixel Searched in " & Round($Result,0) & "ms !")oÝ÷ Ù»­)®Ø©¥±æ«r(uçÇ­ÈvÇ]½çM4¦,^)þÖ.®e´Ì¡×º[b>,^'­Èt߬u

Sorry for my bad English i hope im explained my problem enough understandable <_<

Link to comment
Share on other sites

My Pixel Search method trying find my first color in fullscreen and if found my color, looking for second color for check first color is my true result or not ( Example : My first color red but if im do normal pixel search i cant find my true result because my screen will be have too many red pixels but if im look for +5 pixel right and +50 pixel down for second color and if second color true then my first color coordinate result will be big chance true result. If second color not true continue pixel searching... ) My problem is normal pixel search code or function will search 1,296,000 pixel ( 1440x900 ) in 30ms ! Example :

Sorry for my bad English i hope im explained my problem enough understandable <_<

Didn't understand your math. If you want to search the whole screen, then why pass any coordinates as inputs, especially odd numbers like "1142, 745, 1276, 774" which defines a box of 134 by 29 pixels. Also, your $Color1 value was invalid ("0x0777C90") so I assumed it just had too many 7's.

This technique should be much faster. It uses the native PixelSearch function, and adds the logic to continue the search if the first color is found but the second isn't. Continuation is done in two stages: first finish the rest of the line, then continue with the rest of the box (from next line on down).

$FirstColor = 0x077C90
$SecondColor = 0x0776C8
$Left = 1142
$Top = 745
$Right = 1276
$Bottom = 774

$avReturn = _MultiPixelSearch($Left, $Top, $Right, $Bottom, $FirstColor, $SecondColor)
If @error Then
    MsgBox(16, "Error", "Match not found.")
Else
    MsgBox(64, "Match!", "Found matching pixels:" & @CRLF & _
            @TAB & "First color: 0x" & Hex($FirstColor, 6) & " found at: x = " & $avReturn[0] & "  y = " & $avReturn[1] & @CRLF & _
            @TAB & "Second color: 0x" & Hex($SecondColor, 6) & " found at: x = " & $avReturn[0] + 5 & "  y = " & $avReturn[1] + 50)
EndIf

; -------------------------------------------------------------------------------
; Function _MultiPixelSearch
; Search for $Color1, but only match if $Color2 is also found at +5/+50
; If match is found, returns array coordinates of $Color1 ($avPixel[0] = x, $avPixel[1] = y)
;   $Color2, of course, will be at $avPixel[0] + 5/$avPixel[1] + 50
; -------------------------------------------------------------------------------
Func _MultiPixelSearch($x1, $y1, $x2, $y2, $Color1, $Color2)
    While 1
        Local $avPixel = PixelSearch($x1, $y1, $x2, $y2, $Color1)
        If @error Then
            Return SetError(@error, 0, 0)
        Else
            ; First color found, check for second at +5/+50
            If PixelGetColor($avPixel[0] + 5, $avPixel[1] + 50) = $Color2 Then
                ; Found second color
                Return $avPixel
            Else
                ; Second color not found, finish this line
                While 1
                    $avPixel = PixelSearch($avPixel[0] + 1, $avPixel[1], $x2, $avPixel[1], $Color1)
                    If @error Then
                        ; First color not found on remainder of line
                        ExitLoop
                    Else
                        ; First color found again, check second
                        If PixelGetColor($avPixel[0] + 5, $avPixel[1] + 50) = $Color2 Then
                            ; Found second color
                            Return $avPixel
                        ElseIf $avPixel[0] = $x2 Then
                            ; Don't continue if end of line
                            ExitLoop
                        Else
                            ; No match, continue finishing the line
                            ContinueLoop
                        EndIf
                    EndIf
                WEnd
            EndIf
        EndIf
        
        If $avPixel[1] = $y2 Then
            ; That was the last line, don't continue
            Return SetError(1, 0, 0)
        Else
            ; Continue search from next line
            $y1 = $avPixel[1] + 1
        EndIf
    WEnd
EndFunc   ;==>_MultiPixelSearch

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

PsaltyDS very thanks for your help, before im saw your post im found solution <_< :

Global $Width = @DesktopWidth, $Height = @DesktopHeight, $Pixel[5], $Found = False, $Result, $Var = 0, $Begin

Sleep(3000)
MultiPixelSearch(1, 1, $Width, $Height, "0x0777C9", "0x0776C8", 134, 29)

If $Found = True Then
    ToolTip("Found! Color:" & $Pixel[0] & " X:" & $Pixel[1] & " Y:" & $Pixel[2])
    MouseMove($Pixel[1], $Pixel[2], 0)
    Sleep(3000)
EndIf

ToolTip("Search completed in " & Round($Result, 0) & "ms !")
Sleep(2000)

Func MultiPixelSearch($x, $y, $x2, $y2, $Color1, $Color2, $x3, $y3)
    $Begin = TimerInit()
    While 1
        $Pixel1 = PixelSearch($x, $y, $x2, $y2, $Color1)
        If Not @error Then
            $Pixel2 = PixelSearch($Pixel1[0] + $x3, $Pixel1[1] + $y3, $Pixel1[0] + $x3, $Pixel1[1] + $y3, $Color2)
            If Not @error Then
                $Pixel[0] = $Color1
                $Pixel[1] = $Pixel1[0]
                $Pixel[2] = $Pixel1[1]
                $Pixel[3] = $Pixel2[0]
                $Pixel[4] = $Pixel2[1]
                $Found = True
                ExitLoop
            Else
                $x = $Pixel1[0] + 1
                $y = $Pixel1[1]
            EndIf
        Else
            ExitLoop
        EndIf
    WEnd
    $Result = TimerDiff($Begin)
EndFunc   ;==>MultiPixelSearchoÝ÷ Øýz-µë-yÙ²ì&zØhuÚ'ßÛdjwâÛk¹ç(¢·b«^¢¹è´­k^²×±æ«r§Ê^yÖ§v·¬º[yÒk(®W¬²
Úvæ­yÐr¶°k*®¢Ýuãnøç]»ë¾øªê-¶­±ú+q©ºV­{MúÇv§wMúËx¦y©ß¢·âÚ®¢ßµßþÛÚ®¢Öî·*.j·«mièµìi¨§yק¢è!²¨¹Ú'ßÛn׫²Ö§vÊ+¯*®¢Ø-Ø­6"z-Ç'(uéè¶Ç­Èm®ç~׫±ç(ÚbÅélyªÜýø±x'£Òj}ýµø±+âaj׫®ÀºÚ·Ov2émø±zTj·!Ý«·çoÝ÷ ØûÜIÊy«­¢+ØÀÌØí]¥Ñ ôͭѽÁ]¥Ñ (ÀÌØí!¥¡ÐôͭѽÁ!¥¡Ð(ÀÌØí¥ÉÍÑ
½±½ÈôÁàÀÜÜÝä(ÀÌØíM½¹
½±½ÈôÁàÀÜÜÙà(ÀÌØí1ÐôÄ(ÀÌØíQ½ÀôÄ(ÀÌØíI¥¡ÐôÀÌØí]¥Ñ (ÀÌØí ½Ñѽ´ôÀÌØí!¥¡Ð()M±À ÌÀÀÀ¤(ÀÌØíÙIÑÕɸô}5ձѥA¥á±MÉ  ÀÌØí1аÀÌØíQ½À°ÀÌØíI¥¡Ð°ÀÌØí  ½Ñѽ´°ÀÌØí¥ÉÍÑ
½±½È°ÀÌØíM½¹
½±½È¤)%ÉɽÈQ¡¸(5Í   ½à ÄØ°ÅÕ½ÐíÉɽÈÅÕ½Ðì°ÅÕ½Ðí5Ñ ¹½Ð½Õ¹¸ÅÕ½Ðì¤)±Í(5Í  ½à ØаÅÕ½Ðí5Ñ ÌÌìÅÕ½Ðì°ÅÕ½Ðí½Õ¹µÑ¡¥¹Á¥á±ÌèÅÕ½ÐìµÀì
I1µÀì|(QµÀìÅÕ½Ðí¥ÉÍн±½ÈèÁàÅÕ½ÐìµÀì!à ÀÌØí¥ÉÍÑ
½±½È°Ø¤µÀìÅÕ½Ðì½Õ¹ÐèàôÅÕ½ÐìµÀìÀÌØíÙIÑÕɹlÁtµÀìÅÕ½ÐìäôÅÕ½ÐìµÀìÀÌØíÙIÑÕɹlÅtµÀì
I1µÀì|(QµÀìÅÕ½ÐíM½¹½±½ÈèÁàÅÕ½ÐìµÀì!à ÀÌØíM½¹
½±½È°Ø¤µÀìÅÕ½Ðì½Õ¹ÐèàôÅÕ½ÐìµÀìÀÌØíÙIÑÕɹlÁt¬ÔµÀìÅÕ½ÐìäôÅÕ½ÐìµÀìÀÌØíÙIÑÕɹlÅt¬ÔÀ¤)¹%((ì´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´(ìչѥ½¸}5ձѥA¥á±MÉ (ìMÉ ½ÈÀÌØí
½±½ÈÄ°Õн¹±äµÑ ¥ÀÌØí
½±½Èȥ̱ͼ½Õ¹Ð¬Ô¼¬ÔÀ(ì%µÑ ¥Ì½Õ¹°ÉÑÕɹÌÉÉ佽ɥ¹Ñ̽ÀÌØí
½±½ÈÄ ÀÌØíÙA¥á±lÁtôà°ÀÌØíÙA¥á±lÅtôä¤(ìÀÌØí
½±½ÈÈ°½½ÕÉÍ°Ý¥±°ÐÀÌØíÙA¥á±lÁt¬Ô¼ÀÌØíÙA¥á±lÅt¬ÔÀ(ì´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´´)Õ¹}5ձѥA¥á±MÉ  ÀÌØíàÄ°ÀÌØíäÄ°ÀÌØíàÈ°ÀÌØíäÈ°ÀÌØí
½±½ÈÄ°ÀÌØí
½±½ÈȤ(]¡¥±Ä(1½°ÀÌØíÙA¥á°ôA¥á±MÉ  ÀÌØíàÄ°ÀÌØíäÄ°ÀÌØíàÈ°ÀÌØíäÈ°ÀÌØí
½±½ÈĤ(%ÉɽÈQ¡¸(IÑÕɸMÑÉɽȡÉɽȰÀ°À¤(±Í(ì¥ÉÍн±½È½Õ¹°¡¬½Èͽ¹Ð¬Ô¼¬ÔÀ(%A¥á±Ñ
½±½È ÀÌØíÙA¥á±lÁt¬Ô°ÀÌØíÙA¥á±lÅt¬ÔÀ¤ôÀÌØí
½±½ÈÈQ¡¸(ì½Õ¹Í½¹½±½È(IÑÕɸÀÌØíÙA¥á°(±Í(ìM½¹½±½È¹½Ð½Õ¹°¥¹¥Í Ñ¡¥Ì±¥¹(]¡¥±Ä(ÀÌØíÙA¥á°ôA¥á±MÉ  ÀÌØíÙA¥á±lÁt¬Ä°ÀÌØíÙA¥á±lÅt°ÀÌØíàÈ°ÀÌØíÙA¥á±lÅt°ÀÌØí
½±½ÈĤ(%ÉɽÈQ¡¸(ì¥ÉÍн±½È¹½Ð½Õ¹½¸Éµ¥¹È½±¥¹(á¥Ñ1½½À(±Í(ì¥ÉÍн±½È½Õ¹¥¸°¡¬Í½¹(%A¥á±Ñ
½±½È ÀÌØíÙA¥á±lÁt¬ÄÌаÀÌØíÙA¥á±lÅt¬Èä¤ôÀÌØí
½±½ÈÈQ¡¸(ì½Õ¹Í½¹½±½È(IÑÕɸÀÌØíÙA¥á°(±Í%ÀÌØíÙA¥á±lÁtôÀÌØíàÈQ¡¸(콸Ìäíн¹Ñ¥¹Õ¥¹½±¥¹(á¥Ñ1½½À(±Í(ì9¼µÑ °½¹Ñ¥¹Õ¥¹¥Í¡¥¹Ñ¡±¥¹(
½¹Ñ¥¹Õ1½½À(¹%(¹%(]¹(¹%(¹%((%ÀÌØíÙA¥á±lÅtôÀÌØíäÈQ¡¸(ìQ¡ÐÝÌÑ¡±Íб¥¹°½¸Ìäíн¹Ñ¥¹Õ(IÑÕɸMÑÉÉ½È Ä°À°À¤(±Í(ì
½¹Ñ¥¹ÕÍÉ É½´¹áб¥¹(ÀÌØíäÄôÀÌØíÙA¥á±lÅt¬Ä(¹%(]¹)¹Õ¹ìôôÐí}5ձѥA¥á±MÉ
Edited by Jex
Link to comment
Share on other sites

I can't edit my last post, because if im press "Full Edit" have like that things = ÀÌØíäÄôÀÌØíÙA¥á±lÅt¬Ä(¹%(]¹)¹Õ¹ìôôÐí}5ձѥA¥á±M

Now my code working without problem and find true coordinate but in 2000ms <_<

Global $Width = @DesktopWidth, $Height = @DesktopHeight, $Begin, $Result, $Pixel[2], $x2, $y2, $Color1, $Color2, $x3, $y3, $Pos[2]

Sleep(2000)
$Pos = MultiPixelSearch(1, 1, $Width, $Height, "0x0777C9", "0x0776C8", 134, 29)

If Not @error Then
    $Result = TimerDiff($Begin)
    ToolTip("Found! X:" & $Pos[0] & " Y:" & $Pos[1] & @CRLF & "Search completed in " & Round($Result, 0) & "ms!")
    MouseMove($Pos[0], $Pos[1], 0)
Else
    $Result = TimerDiff($Begin)
    ToolTip("Search completed in " & Round($Result, 0) & "ms!")
EndIf

Sleep(5000)

Func MultiPixelSearch($x, $y, $x2, $y2, $Color1, $Color2, $x3, $y3)
    $Begin = TimerInit()
    While 1
        $Pixel = PixelSearch($x, $y, $x2, $y2, $Color1)
        If @error Then
            Return SetError(@error, 0, 0)
        Else
            If PixelGetColor($Pixel[0] + $x3, $Pixel[1] + $y3) = $Color2 Then
                Return $Pixel
            Else
                CompleteLine()
            EndIf
        EndIf
        If $Pixel[1] = $y2 Then
            Return SetError(1, 0, 0)
        Else
            $y = $Pixel[1] + 1
        EndIf
    WEnd
EndFunc   ;==>MultiPixelSearch

Func CompleteLine()
    While 1
        $Pixel2 = PixelSearch($Pixel[0] + 1, $Pixel[1], $x2, $Pixel[1], $Color1)
        If @error Then
            ExitLoop
        Else
            If PixelGetColor($Pixel2[0] + $x3, $Pixel2[1] + $y3) = $Color2 Then
                Return $Pixel
            ElseIf $Pixel2[0] = $x2 Then
                ExitLoop
            EndIf
        EndIf
    WEnd
EndFunc   ;==>CompleteLine
Edited by Jex
Link to comment
Share on other sites

I'm changed my code little and added gui for test :

Posted Image

#include <GUIConstants.au3>

Global $Width = @DesktopWidth, $Height = @DesktopHeight, $Pixel[9], $Found = False, $Result, $Var = 0, $Begin

$Form = GUICreate("MultiPixelSearch Test", 315, 122, 200, 150)
$Input1 = GUICtrlCreateInput("", 32, 8, 49, 21)
$Input2 = GUICtrlCreateInput("", 112, 8, 49, 21)
$Input3 = GUICtrlCreateInput("", 208, 8, 73, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$Input4 = GUICtrlCreateInput("", 32, 32, 49, 21)
$Input5 = GUICtrlCreateInput("", 112, 32, 49, 21)
$Input6 = GUICtrlCreateInput("", 208, 32, 73, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$Input7 = GUICtrlCreateInput("", 32, 56, 49, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$Input8 = GUICtrlCreateInput("", 112, 56, 49, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$Input9 = GUICtrlCreateInput("", 280, 8, 25, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$Input10 = GUICtrlCreateInput("", 280, 32, 25, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$Label1 = GUICtrlCreateLabel("X :", 8, 8, 17, 17)
$Label2 = GUICtrlCreateLabel("Y :", 88, 8, 17, 17)
$Label3 = GUICtrlCreateLabel("Color1 :", 168, 8, 40, 17)
$Label4 = GUICtrlCreateLabel("+X :", 8, 32, 23, 17)
$Label5 = GUICtrlCreateLabel("+Y :", 88, 32, 23, 17)
$Label6 = GUICtrlCreateLabel("Color2 :", 168, 32, 40, 17)
$Label7 = GUICtrlCreateLabel("<--- Color2 Coordinates", 168, 56, 111, 17)
$Label8 = GUICtrlCreateLabel("Y :", 88, 56, 17, 17)
$Label9 = GUICtrlCreateLabel("X :", 8, 56, 17, 17)
$Button1 = GUICtrlCreateButton("Check", 8, 88, 75, 25, 0)
$Button2 = GUICtrlCreateButton("Fullscreen MultiPixelSearch Test", 88, 88, 211, 25, 0)
GUISetState(@SW_SHOW)

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            GUICtrlSetData($Input3, "0x" & Hex(PixelGetColor(GUICtrlRead($Input1), GUICtrlRead($Input2)), 6))
            GUICtrlSetBkColor($Input9, GUICtrlRead($Input3))
            GUICtrlSetData($Input7, GUICtrlRead($Input1) + GUICtrlRead($Input4))
            GUICtrlSetData($Input8, GUICtrlRead($Input2) + GUICtrlRead($Input5))
            GUICtrlSetData($Input6, "0x" & Hex(PixelGetColor(GUICtrlRead($Input7), GUICtrlRead($Input8)), 6))
            GUICtrlSetBkColor($Input10, GUICtrlRead($Input6))
        Case $Button2
            If GUICtrlRead($Input3) <> "" Then
                GUISetState(@SW_HIDE)
                Sleep(2000)
                MultiPixelSearch(1, 1, $Width, $Height, GUICtrlRead($Input3), GUICtrlRead($Input6), GUICtrlRead($Input4), GUICtrlRead($Input5))
                GUISetState(@SW_SHOW)
                Test()
            Else
                MsgBox("", "", 'Fill boxs and later press "Check" button before test!')
            EndIf
    EndSwitch
WEnd

Func MultiPixelSearch($x, $y, $x2, $y2, $Color1, $Color2, $x3, $y3)
    $Begin = TimerInit()
    While 1
        $Pixel1 = PixelSearch($x, $y, $x2, $y2, $Color1)
        If Not @error Then
            $Var += 1
            $Pixel2 = PixelSearch($Pixel1[0] + $x3, $Pixel1[1] + $y3, $Pixel1[0] + $x3, $Pixel1[1] + $y3, $Color2)
            If Not @error Then
                $Found = True
                ExitLoop
            Else
                While 1
                    $Pixel3 = PixelSearch($Pixel1[0] + 1, $Pixel1[1], $x2, $Pixel1[1], $Color1)
                    If Not @error Then
                        $Var += 1
                        $Pixel2 = PixelSearch($Pixel3[0] + $x3, $Pixel3[1] + $y3, $Pixel3[0] + $x3, $Pixel3[1] + $y3, $Color2)
                        If Not @error Then
                            $Found = True
                            ExitLoop 2
                        ElseIf $Pixel3[0] = $x2 Then
                            ExitLoop
                        Else
                            $Pixel1[0] = $Pixel3[0]
                        EndIf
                    Else
                        ExitLoop
                    EndIf
                WEnd
                If $Pixel1[1] = $x2 Then
                    ExitLoop
                Else
                    $y = $Pixel1[1] + 1
                EndIf
            EndIf
        Else
            ExitLoop
        EndIf
    WEnd
    If $Found = True Then
        $Pixel[0] = $Var
        $Pixel[1] = $Pixel1[0]
        $Pixel[2] = $Pixel1[1]
        $Pixel[3] = $Pixel2[0]
        $Pixel[4] = $Pixel2[1]
        $Pixel[5] = $Color1
        $Pixel[6] = $Color2
        $Pixel[7] = $x3
        $Pixel[8] = $y3
    EndIf
    $Result = TimerDiff($Begin)
EndFunc   ;==>MultiPixelSearch

Func Test()
    If $Found = True Then
        MsgBox("", "", "First color ( " & $Pixel[5] & " ) found " & $Pixel[0] & " times and final result X: " & $Pixel[1] & " Y: " & $Pixel[2] & @CRLF & "Second color ( " & $Pixel[6] & " ) found in X: " & $Pixel[3] & " Y: " & $Pixel[4] & " ( +X: " & $Pixel[7] & " +Y: " & $Pixel[8] & " )" & @CRLF & "Search completed in " & Round($Result, 0) & "ms.")
        ;If $Pixel[1] = GUICtrlRead($Input1) And $Pixel[2] = GUICtrlRead($Input2) Then MsgBox("","","True coordinates found!!!")
    Else
        MsgBox("", "", "Search completed in " & Round($Result, 0) & "ms.")
    EndIf
EndFunc   ;==>Test
Edited by Jex
Link to comment
Share on other sites

  • Moderators

I'm curious if you found this faster (or easier) than the PixelSearchEx() I provided the link for?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

To be honest im didn't understand your code for what or doing what. My code not fast but basic for understand i mean <_<

Maybe you are trying to find multiple colors?

PixelSearchEx finds the same color (with shade variance if wanted), but instead of stopping at the first instance found, it continues throughout the entire region you selected.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Posted Image

Example you want click that red box but if you search blue, red or pink pixels you cant find true position because have too many red, blue and pink pixels.

But if you search like that: If you find blue pixel look +x52 and +y18 and if found pink pixel then first blue pixel true result else continue searching until find true blue. So if red box and on box pink and blue dots move another position that no problem because that method can find true position. I hope im explained enough understandable :)

"but instead of stopping at the first instance found, it continues throughout the entire region you selected." <-- But that true my method doing that.

Again sorry for my bad English <_<

Edited by Jex
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...