image found, but region location wrong

Asked by Beth Griffin

I have been trying to clean up some image matching issues.

I have a sikuli script that observes MS Visual Studio until a breakpoint is hit:

if exists("BreakpointArrow.png", 300):
    m = getLastMatch()
    m.highlight()

I expected the highlight to show up around the yellow arrow on the screen. Instead, it shows up anywhere but the right location, and not always is the same place.

I need this match to be in the correct location, so I can do

n = m.right()
if n.exists("Line of code"):
    # breakpoint at correct location
else:
    # breakpoint at wrong location

I'm trying:

myArrow = Pattern("BreakpointArrow.png").exact()
if exists(myArrow):
  ...

Whether I use onAppear() or exists, the X and Y of the found image is never correct. What is wrong?

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
Beth Griffin
Solved:
Last query:
Last reply:

This question was reopened

Revision history for this message
Beth Griffin (beth-griffin) said :
#1

So it looks like in the event handler, the event.region location is correct, but any time I "find" the image outside the event handler, the location is wrong.

So I am working around this (since everyone is a class member) by setting self.myRegion = event.region in the handler, and using that after the observe.

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

--- exact() does not work correctly
seems to be a bug. use .similar(0.99) instead

--- match in different locations
It seems, you are searching the whole screen. If yes: this generally does not make sense: bad speed and accuracy.
narrow the region for the search of the BP-symbol to the column in the VS window, where it should appear.
Since the VS window is somehow structured, it is rather easy to search/calculate a region for that.

so this should work as you want:

col = <some-calculated-region>
with col:
    if exists("BreakpointArrow.png", 300):
        m = getLastMatch()
        m.highlight()

or

col = <some-calculated-region>
if col.exists("BreakpointArrow.png", 300):
    m = col.getLastMatch()
    m.highlight()

Revision history for this message
Beth Griffin (beth-griffin) said :
#3

1. While the BP symbol is in a column, the column itself may be in a different location based on user/machine settings (like language). It isn't always easy to find the correct location with one algorithm. While it is usually relevant to the source editor, it is not always visible until AFTER the breakpoint has been hit, and I am using the existence of the BPArrow symbol to tell me the breakpoint is hit.

On that note:

2. The following code example show the really strange behavior:

def SobelFilterTest (unittest.TestCase):

    def setUp(self):
        ...
        self.BPRegion = None
        ...

    def BPArrowAppearHandler(self, event):
        self.BPRegion = event.region
        # or self.BPRegion = getLastMatch()
        event.region.stopObserver

    def test_SobelFilter(self)
        # open a solution in MS VS
        ...
        nArrow = Pattern("BPArrow.png")
        onAppear(nArrow, self.BPArrowAppearHandler)
        observe(300)
        self.BPRegion.highlight()
        wait(30)
        self.BPRegion.highlight()

I run the script using

mySobelFilterTest = unittest.TestLoader().loadTestsFromTestCase(SobelFilterTest)
unittest.TextTestRunner(verbosity=2).run(mySobelFilterTest)

If BPRegion = event.region: region = point, highlight shows nothing
If BPRegion = getLastMatch(): region = rectangle (larger than image), and highlight appears in the wrong location

I tried doing

myVSRegion = App.focusedWindow()
# to really narrow down:
# mySolExpRegion = myVSRegion.find("SolExpTitleBar.png").below()
# Start debugging (solution explorer can move from left side to right side or vice versa
# At break, which I am waiting for by waiting for the BPArrow.png, so already there is a catch 22
myVSRegion.onAppear("BPArrow.png", BPArrowAppearHandler)

I get an error trying to assign the 2nd argument of onAppear.

So, using a smaller region seems broken, using the full screen is broken too.

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

This runs perfectly (on my Mac, adapt it to Windows and your situation):

- have the Sikuli Q&A page open
- start the script
- open one of the answers
- the yellow beast appears and is matched

download source if you want: https://files.me.com/rhocke/6emk0r

I think it always makes sense to narrow the search region and it is worth the coding effort, that might be necessary.

BTW: event.region is the observed region, a found match is event.match
(http://sikuli.org/docx/region.html#SikuliEvent)

-------------------------------

import unittest

myVSRegion = App.focusedWindow()
# to really narrow down:
# mySolExpRegion = myVSRegion.find("SolExpTitleBar.png").below()
# Start debugging (solution explorer can move from left side to right side or vice versa
# At break, which I am waiting for by waiting for the BPArrow.png, so already there is a catch 22
#myVSRegion.onAppear("BPArrow.png", BPArrowAppearHandler)

ab = App("Safari")
ab.focus()
aw = ab.window()
reg = aw.find("siklogo.png").below()
# a column region below the top left Sikuli logo

class SobelFilterTest (unittest.TestCase):

    def setUp(self):
        print "in setUp:"
        reg.highlight(2)
        #self.BPRegion = None # not really needed

    def BPArrowAppearHandler(self, event):
        print "target appeared"
        self.BPRegion = event.match
        event.region.stopObserver()

    def test_SobelFilter1(self):
        print "in Test1"
        # nArrow = Pattern("BPArrow.png")
        nArrow = Pattern("circle.png") # the yellow round edit button
        reg.onAppear(nArrow, self.BPArrowAppearHandler)
        reg.observe(300)
        self.BPRegion.highlight(3)

mySobelFilterTest = unittest.TestLoader().loadTestsFromTestCase(SobelFilterTest)
unittest.TextTestRunner(verbosity=2).run(mySobelFilterTest)

Revision history for this message
Beth Griffin (beth-griffin) said :
#5

What is the difference between event.region and event.match?

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

--- event.region
is the region you are observing
observe() # observes Screen(0)
reg.observe() # observes the region defined with reg

--- event.match
just from the docs:

match
In an APPEAR event, match saves the top Match object that appeared in the observed region.

In a VANISH event, match saves the last Match object that was in the observed region but vanished.

This attribute is not valid in a CHANGE event.

Revision history for this message
Beth Griffin (beth-griffin) said :
#7

Thanks RaiMan, that solved my question.

Revision history for this message
Beth Griffin (beth-griffin) said :
#8

Ok, I spoke too soon.

Sikuli says, yeah, found match, so I set self.BPRegion = event.match

I then highlight the match, and it is nowhere near the image on the screen. Narrowing down the search region doesn't seem to help (image not found even though it is in the smaller region). It's like even though the image is specific, graphics only, 3 different colors(grey, blue, yellow), sikuli always picks a match that is all one color (white).

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

could you send me a screenshot with the wrong highlight and the narrowed region highlighted too.
(mail at https://launchpad.net/~raimund-hocke)

Revision history for this message
Beth Griffin (beth-griffin) said :
#10

I just sent an e-mail with the requested images.

Revision history for this message
Beth Griffin (beth-griffin) said :
#11

I just tried with rc3 and other script modifications. I now set the onAppear to use an image containing the gDEBugger Explorer title bar and the SobelFilter.cpp file tab, then create a search region from there (as well as making the arrow image just the yellow arrow with the grey background, no little blue edge). Hopefully, the assumption that this new image will be valid on other machines is correct.