sikuli-driver team mailing list archive
-
sikuli-driver team
-
Mailing list archive
-
Message #31478
Re: [Question #264487]: Help with making some Sikuli image recognition?
Question #264487 on Sikuli changed:
https://answers.launchpad.net/sikuli/+question/264487
RaiMan proposed the following answer:
--- repeat after 5th arrow done
referring to my sample I made for you, I would do it this way:
instead of the final
if not popAsk("repeat?"):
exit()
I would wait for the 5th arrow to change.
For that I would store the arrow, that matched a bit earlier:
if col.exists(Pattern(a).similar(0.8), 0):
print i, a, col.getLastMatch().getScore()
type(arrows[a]) # type the associated key
lastArrow = a # store the match for later use <-----
break # leave the inner loop
now after the loop finished with the 5th arrow, we know, which arrow
matched there and wait for it to vanish:
if reg.getCol(4).exists(Pattern(lastArrow).similar(0.9), 0):
wait(0.5)
as we already experienced with the similarity challenge, again here you
have to set it reasonably to distinguish from the "naked" arrow (usually
it should even be Pattern(lastArrow).exact().
To not get an endless loop here, one should add a max counter, to limit
the wait time and either exit or simply assume it can repeat.
max = 10
if reg.getCol(4).exists(Pattern(lastArrow).similar(0.9), 0):
wait(0.5)
max -= 1
if max == 0:
continue # loop again
# exit() # to terminate in this case (recommended while testing)
BTW:
Modern programming or scripting languages do not have a GOTO anymore. Everything has to be setup in some nested blocks of code. This sometimes make things a bit more complicated depending on the language, but one gets used to it after a while.
This design principal usually leads to the intensive use of modules/functions, to keep the main workflow clear and transparent.
In your case this could be like that:
def handleOneArrow(cell):
global lastArrow # to signal an outside used variable
# loop through the arrow types
for a in arrows:
# check the arrow type in segment
if cell.exists(Pattern(a).similar(0.8), 0):
print i, a, cell.getLastMatch().getScore()
type(arrows[a]) # type the associated key
lastArrow = a
return True # leave the inner loop
return False # no arrow matched
def decideRepeat(reg, pattern):
max = 10
if reg.exists(pattern, 0):
wait(0.5)
max -= 1
if max == 0:
return False # signal wait exceeded
return True
as you might realise here: this approach heavily supports the DRY
principle (don't repeat yourself): implement functions with some
variables, that might be useful in more than one situation.
# all the stuff before the main while loop
while True: # loop until finished
# loop through the segments
for i in range(5):
col = reg.getCol(i)
if not handleOneArrow(col):
pass # here we could handle the situation, that no arrow was found
if not decideRepeat(reg.getCol(4), Pattern(lastArrow).similar(0.9)):
exit() # or some other action in case of vanishing arrow not detected
now the main workflow is clear and rather fixed. adaptions will only be
needed in the functions eventually.
... and now we can see, where we could add some 'whoops code' (nice wording - hope it is not copyrighted ;-)
It does not make sense to check an arrow, when the bar is no longer there:
while True: # loop until finished
barImage = capture(reg) # save the initial state of the bar
# loop through the segments
for i in range(5):
if not barExists(reg, barImage): <---------
pass # decide what to do here
col = reg.getCol(i)
if not handleOneArrow(col):
pass # here we could handle the situation, that no arrow was found
if not decideRepeat(reg.getCol(4), Pattern(lastArrow).similar(0.9)):
exit() # or some other action in case of vanishing arrow not detected
barImage = capture(reg) # save the current state of the bar for next existence check
... and we add another def to the top:
def barExists(reg, barImage):
if not reg.exists(barImage):
return False
return True
now we have the last problem to solve:
after having handled the bar-vanished situation we want to start allover again: but we are on the second loop level and want to proceed with the first level.
Python only knows
continue - instantly go to the current loop head and continue
break - leave the current loop at this point and continue with the next statement after the loop
other scripting languages have a feature like
continue label
to tell what outer loop should be continued and/or
break label
to tell what outer loop level should be left
In Python in doubt we need an indicator and an additional decision, but
in our case when breaking the inner loop, the next statement will be the
While True anyway:
while True: # loop until finished
barImage = capture(reg) # save the initial state of the bar
# loop through the segments
for i in range(5):
if not barExists(reg, barImage):
# do everything needed to start again with while True:
break <---------
col = reg.getCol(i)
if not handleOneArrow(col):
pass # here we could handle the situation, that no arrow was found
if not decideRepeat(reg.getCol(4), Pattern(lastArrow).similar(0.9)):
exit() # or some other action in case of vanishing arrow not detected
barImage = capture(reg) # save the current state of the bar for next existence check
--
You received this question notification because you are a member of
Sikuli Drivers, which is an answer contact for Sikuli.