Identifying image quickly

Asked by Tuna

Hi, new to sikuli!

I'm playing a card game, and am trying to identify which of the 52 cards is in a particular location on my screen.

I attempted to do this by calling range.exists(card) on each of my 52 card images, but this is extremely slow, even though the range is only 15x30 pixels

Is there a better way to go about this?

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
Tuna
Solved:
Last query:
Last reply:
Revision history for this message
RaiMan (raimund-hocke) said :
#1

you have to use range.exists(card, 0)

Then on a not found, the exists returns immediately and not waiting 3 seconds.

In the average you have 25 not founds to get 1 success.

since the search in such a small region should only take some milliseconds, scanning one position should take max 300-500 msec and on average 100-150 msec.

Revision history for this message
Tuna (justinleeturner) said :
#2

Thanks for the response!

Maybe I'm doing something wrong, but it takes around 15 seconds when I run it. Here's what my code looks like:

Settings.MinSimilarity=0.98

r_Top = Region(32,287,15,30)
c_5d = "1384635767085.png"
c_4d = "1384635791739.png"
c_3h = "1384635848632.png"
.... continued for 52 cards ....

print r_Top.exists(c_5d,0)
print r_Top.exists(c_4d,0)
print r_Top.exists(c_3h,0)
... continued for 52 cards ...

Revision history for this message
RaiMan (raimund-hocke) said :
#3

this test script running with version 1.0.1 on a Mac Book Air (2GHz Intel Core I7):

logo = "1384684031942.png" # Sikuli logo on webpage
img = Pattern("1384683797229.png").exact() # a part of it having size 15x30
reg = find(logo)
card = reg.find(img) # card now is the 15x30 region to search in

# now running 52 times
start = time.time()
for i in range(52):
    card.exists(img, 0)
print int((time.time()-start)*1000)

this takes less than 200 msecs

...but then I checked the not found situation and uuups, there is a bug in 1.0.1, which I did not remember, since my daily work is with version 1.1 (under development):
the bug: the minimum time (found or not found) is always given by the WaitScanRate (how many searches per second, which is 3 in the standard and hence 300 msec per search - which leads to your 15 secs).

The workaround:
Use this:
Settings.WaitScanrate=500 # (min wait time = 2 msec)
reg = <define your target region>
Settings.WaitScanrate=3 # reset to normal to not overload your system with normal searches

This is another oddity with 1.0.1:
the region takes the value from the settings at the time when it gets defined and does not look again for changes before a search.

All this is fixed in 1.1 (where it is possible to set theses search influencing values per region)

BTW: It does not make any difference for this timing test, wether you take different images or all the same.

Revision history for this message
Tuna (justinleeturner) said :
#4

Thanks for looking into this!

The Settings.WaitScanrate=500 helped when the card is found (completes 52 calls in 1.1 seconds)
However, when the card is not found, it still takes around 17 seconds

Revision history for this message
RaiMan (raimund-hocke) said :
#5

pls. show your test script.

What version of Sikuli are you using?

Revision history for this message
Tuna (justinleeturner) said :
#6

I'm using 1.0.1. The script is below....thanks!

Settings.MinSimilarity=0.98

Settings.WaitScanrate=500 # (min wait time = 2 msec)
r_small = Region(39,317,10,10)
Settings.WaitScanrate=3

c_spade = "1384724141154.png"
start = time.time()
for i in range(52):
     print r_small.exists(c_spade,0)
print int((time.time()-start)*1000)

Revision history for this message
RaiMan (raimund-hocke) said :
#7

sorry, my fault: the correct option name:
Settings.WaitScanRate

Revision history for this message
Tuna (justinleeturner) said :
#8

Thanks! Runs in about a second now