Jump to content

Recommended Posts

Posted

Ok, hello folks :)

I was thinking, is that possible to create that kind of program, that takes like 4 snapshots from screen.

Then greyscale them to black/white images.

Then compare, which ones of shots will match eatchothers, like x% (x-definable).

I was thinking it somehow like this:

Dim $image1 = TakeSnapShot( screenx1, screeny1, screenx2, screeny2 )
Dim $image2 = TakeSnapShot( screenx1, screeny1, screenx2, screeny2 )
Dim $image3 = TakeSnapShot( screenx1, screeny1, screenx2, screeny2 )
Dim $image4 = TakeSnapShot( screenx1, screeny1, screenx2, screeny2 )

; Then somehow greyscale them
for $i = 4 to 0 Step -1
   GreyScale( $image + $i )
Next
Compare( $image1, $image2 )     ; Returns how it should say... Match-% of two images, like 0.60
Compare( $image1, $image3 )
Compare( $image1, $image4 )
etc etc.

That very simple show about idea, but hopefully someone understand what I'm looking for :)

Thanks!

Posted

For really cool functions for all kinds of image manipulation, check out prospeed, as for instance described here:

http://www.autoitscript.com/forum/index.php?showtopic=71654

It can greyscale, compare, take snapshots and much, much more. The grayscaling and screenshots works fine for me, I used it, the compare I have never used but it seems to work too, and fast.

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Posted

Looks pretty nice :)

How can I search smaller item from bigger image, and actually return x- and y-cordinates for top left corner of item...?

I copied small 18x17px area from greysquare left corner, and saved it as search.bmp

Now I should search where on the screen that same corner is, at the moment, and return that corners X and Y position.

How could do this...?

Tried with http://www.autoitscript.com/forum/index.php?showtopic=66545

but no perfect matches, and no partial matches. Code is below

#include <prospeed30.au3>
#include<ScreenCapture.au3>

Global Const $mcdir = "C:\Test-Images\"

$start = TimerInit()
$tResult=findBMP($mcdir & "from.bmp",$mcdir & "search.bmp",TRUE)
ConsoleWrite($tResult &  "** Square search totalmatch time elapsed: " & TimerDiff($start) / 1000 & "  seconds" & @LF)
;Again with a partial match
$start = TimerInit()
$tResult=findBMP($mcdir & "from.bmp",$mcdir & "search.bmp",FALSE)
ConsoleWrite($tResult & " ** Square search partial match time elapsed: " & TimerDiff($start) / 1000 & "  seconds" & @LF)

;===============================================================================
; Function Name:    findBMP
; Description:    Finds a bitmap (.BMP) in another BMP file
; Syntax:          findBMP($BMP1, $BMP2, $ExactMatch=TRUE)
;
; Parameter(s):  $BMP1           = Filename of bitmap to search in
;                  $BMP2             = Filename of bitmap to search for
;                  $ExactMatch     = TRUE / FALSE if an exact match is done
;
; Return Value(s):  On Success:   = Returns Array List
;                  On Failure:   = @error 1 (Control was found but there was an error with the DLLCall)
;
; Author(s):        JunkEW
;
; Note(s):        
;               * Its never an exact match even with TRUE as last few bits are disposed in algorithm and lines below
;                are not checked under assumption that those are 99.99% of the time correct       
;
; ** BMP File format documentation http://en.wikipedia.org/wiki/BMP_file_format **
;http://en.wikipedia.org/wiki/Hex_editor
;
; Example(s):
;  
;===============================================================================

Func findBMP($BMP1, $BMP2, $ExactMatch=TRUE)
    Dim $fLine[1];Line number of found line(s), redimmed when second picture size is known
    Dim $BMP1Total = "", $BMP1DataStart=0, $BMP1Size=0, $BMP1Width=0, $BMP1Height=0, $BMP1LineWidth=0;
    Dim $BMP2Total = "", $BMP2DataStart=0, $BMP2Size=0, $BMP2Width=0, $BMP2Height=0, $BMP2LineWidth=0
    Dim $foundAt = "", $matchPossible=FALSE, $matchedLines=0, $foundAtLeft=-1, $foundAtTop=-1
    Dim $bestMatchLine=-1, $HighestMatchingLines=-1; For knowing when no match is found where best area is
    Dim $iPos=0;
    
; Load the bitmap to search in
    loadbmp($BMP1, $BMP1Total, $BMP1DataStart, $BMP1Size, $BMP1Width, $BMP1Height, $BMP1LineWidth)

; Load the bitmap to find
    loadbmp($BMP2, $BMP2Total, $BMP2DataStart, $BMP2Size, $BMP2Width, $BMP2Height, $BMP2LineWidth)

;Make it strings to be able to use string functions for searching
    $BMP1Data = BinaryToString(BinaryMid($BMP1Total, $BMP1DataStart))
    $BMP2Data = BinaryToString(BinaryMid($BMP2Total, $BMP2DataStart))

;For reference of line where in BMP2FindIn a line of BMP2Find was found
    ReDim $fline[$BMP2Height]
    
;If exact match check every 1 line else do it more fuzzy (as most likely other lines are unique)
    if $ExactMatch=true Then
        $iFuzzyAdd = 1
    Else
;Check fuzzy every 10% of lines
        $iFuzzyAdd = ceiling(($bmp2height * 0.1))
    endIf

    $begin = TimerInit()
;Look for each line of the bitmap if it exists in the bitmap to find in
    For $i = 0 To $BMP2Height - 1
;Minus 3 as last bits are padded with unpredictable bytes (24 bits image assumption)
        $searchFor = StringMid($BMP2Data, 1 + ($i * $BMP2lineWidth), ($BMP2lineWidth - 3))
;$iPos = StringInStr($BMP1Data, $searchFor)
; Needs latest beta v3.2.11.5 (beta)
        $iPos = StringInStr($BMP1Data, $searchFor, 2, 1, $iPos+1)

        $fline[$i] = Int($iPos / $BMP1lineWidth)

;Look for all lines above if there is also a match
;Not doing it for the lines below as speed is more important and risk of mismatch on lines below is small
        $iAbove=1
        if $iPos > 0 then
            $bMatchPossible=True
            $matchedLines=1;As first found line is matched we start counting
        Else
            $bMatchPossible=false
            exitloop
        endif
        while (($i+$iAbove) < ($BMP2Height -1)) and ($bMatchPossible=True)
            $searchFor = StringMid($BMP2Data, 1 + (($i + $iAbove) * $BMP2lineWidth), ($BMP2lineWidth - 3))
            $aboveLine = stringmid($BMP1Data,$iPos + ($iAbove * $BMP1LineWidth), ($BMP2LineWidth - 3))

;           consolewrite($searchFor & ";" & $aboveLine & @lf & $i & ";" & ($i+$iAbove) & ";" & ($BMP2Height -1) & @lf)

            if $aboveLine <> $searchFor Then
                $bMatchPossible=False
       ;To remember the area with the best match
                if $matchedLines >= $HighestMatchingLines Then
                    $HighestMatchingLines = $matchedLines
                    
           ;Best guess of location
                    $foundAtTop = $bmp1Height - $fline[$i] - $bmp2height + $i
                    $foundAtLeft =  int(mod($iPos,$bmp1linewidth) / 3)  
                    $bestMatchLine = Int($iPos / $BMP1lineWidth)
                EndIf
                ExitLoop            
            EndIf
            $matchedLines=$matchedLines + 1
            $iAbove=$iAbove+$iFuzzyAdd
        WEnd
;If bMatchPossible is still true most likely we have found the bitmap       
        if $bmatchPossible = True then
            consolewrite("i" & $iPos)
            $foundAtTop = $bmp1Height - $fline[$i] -$bmp2height +$i
            $foundAtLeft =  int(mod($iPos,$bmp1linewidth) / 3)
            
            ConsoleWrite("Could match top: " & $foundAtTop & " left: " & $foundAtLeft & " in " & TimerDiff($begin) / 1000 & "  seconds" & @LF)
            MouseMove($foundatleft,$foundatTop)
            exitloop
        EndIf
    
    Next

    if $bMatchPossible = True Then
        ConsoleWrite("Searching took " & TimerDiff($begin) / 1000 & "  seconds " & @LF)
    Else
        ConsoleWrite("NOT FOUND Searching took " & TimerDiff($begin) / 1000 & "  seconds" & @LF)
    endif

;Return an error if not found else return an array with all information
    if $bMatchPossible = False Then
        SetError(1, 0, 0)
    endif
;   return stringsplit($bMatchPossible & ";" & $matchedLines & ";" & $foundAtLeft & ";" & $foundAtTop & ";" & $bmp2width & ";" & $BMP2Height & ";" & $HighestMatchingLines & ";" & $bestMatchLine,";")
    return $bMatchPossible & ";" & $matchedLines & ";" & $foundAtLeft & ";" & $foundAtTop & ";" & $bmp2width & ";" & $BMP2Height & ";" & $HighestMatchingLines & ";" & $bestMatchLine
EndFunc;==>findBMP

;===============================================================================
; Function Name:    loadBMP
; Description:    Loads the BMP File into a variable
; Syntax:          LoadBMP($BMPFile, byref $BMP, byref $BMPSize, byref $BMPWidth, byRef $BMPHeight, byref $BMPLineWidth)
;
; Parameter(s):  $BMPFile = Filename of bitmap to load
;                  $BMP  = String where bitmap has to be put in
;                  $BMPSize, $BMPWidth, $BMPHeight, $BMPLineWidth are returnvariables with basic information
;
; Return Value(s):  
;
; Author(s):        JunkEW
;
; Note(s):        
;               * It's not a bullet proof loading mechanism. Its main intention is to load BMP files created in "normal" mode
;
; Example(s):
;  
;===============================================================================

func loadBMP($BMPFile, byref $BMP, byref $BMPDataStart, byref $BMPSize, byref $BMPWidth, byRef $BMPHeight, byref $BMPLineWidth)
Const $BMPHDRSize = 54

;   $begin = TimerInit()
    $fHandle = FileOpen($BMPFile, 16)
    $BMP = FileRead($fHandle);Read whole file into memory
    FileClose($fHandle)
;   ConsoleWrite("Loading took " & TimerDiff($begin) & " milliseconds " & @LF)

;All frequently used BMP information out of the header
    $BMPHDR = BinaryMid($BMP, 1, $BMPHDRSize)
    $BMPSize = Dec(StringMid(BinaryMid($BMPHDR, 6, 1) & BinaryMid($BMPHDR, 5, 1) & BinaryMid($BMPHDR, 4, 1) & BinaryMid($BMPHDR, 3, 1), 3))
    $BMPHDRS = Dec(StringMid(BinaryMid($BMPHDR, 18, 1) & BinaryMid($BMPHDR, 17, 1) & BinaryMid($BMPHDR, 16, 1) & BinaryMid($BMPHDR, 15, 1), 3))
    $BMPWidth = Dec(StringMid(BinaryMid($BMPHDR, 22, 1) & BinaryMid($BMPHDR, 21, 1) & BinaryMid($BMPHDR, 20, 1) & BinaryMid($BMPHDR, 19, 1), 3))
    $BMPHeight = Dec(StringMid(BinaryMid($BMPHDR, 26, 1) & BinaryMid($BMPHDR, 25, 1) & BinaryMid($BMPHDR, 24, 1) & BinaryMid($BMPHDR, 23, 1), 3))
    $BMPBitsPP = Dec(StringMid(BinaryMid($BMPHDR, 30, 1) & BinaryMid($BMPHDR, 29, 1), 3))
    $BMPCompression = Dec(StringMid(BinaryMid($BMPHDR, 34, 1) & BinaryMid($BMPHDR, 33, 1) & BinaryMid($BMPHDR, 32, 1) & BinaryMid($BMPHDR, 31, 1), 3))
    $BMPColors = Dec(StringMid(BinaryMid($BMPHDR, 50, 1) & BinaryMid($BMPHDR, 49, 1) & BinaryMid($BMPHDR, 48, 1) & BinaryMid($BMPHDR, 47, 1), 3))

    If $BMPColors=0 Then
        $BMPlineWidth = ($BMPSize - $BMPHDRSize) / $BMPHeight   
        $BMPDataStart = $BMPHDRSize+1
    Else
;Logic seems to be 4 * colors instead of 2^n colors
;~       $BMPlineWidth = ($BMPSize - $BMPHDRSize - (4*(2^$BMPColors))) / $BMPHeight 
;~       $BMPDataStart = $BMPHDRSize+(4*(2^$BMPColors))+1
        $BMPlineWidth = ($BMPSize - $BMPHDRSize - (4*$BMPColors)) / $BMPHeight  
        $BMPDataStart = $BMPHDRSize+(4*$BMPColors)+1
    endif
    Return 0
EndFunc

My example images below.

That code didn't find match from images.

post-28046-1211990502_thumb.gif

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
×
×
  • Create New...