Region.right(): unexpected result --- means right of right border of Region --- docs rewritten

Asked by Petr Fejfar

Hi all,

I've tried to extend a found region to the right, but I got a result which seems to be a strange to me. Let assume code snipet:

 w = find(image)
 print 'Found: %s' % w
 w = find(image).left(10)
 print 'Left: %s' % w
 w = find(image).right(10)
 print 'Right: %s' % w

and printed output:

        Found: Match[720,395 211x26] score=1,00, target=center
        Left: Region[710,395 10x26]@Screen(0) E:Y, T:3,0
        Right: Region[931,395 10x26]@Screen(0) E:Y, T:3,0

I'd expect, that setting right border of region should result in

        Right: Region[720,395 10x26]@Screen(0) E:Y, T:3,0

and I've no no idea where the value 931 came from. On the top of it, when I extend the region to the right, the X value is always 931 regarding a value of the argument passed to right() method.

Please, could somebody shed light on?

Thx, pf

Question information

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

since each find() starts a new search, your approach is risky.

you should operate on the saved first match, to avoid new find operations (the world might have turned ;-)

w = find(image)
print 'Found: %s' % w
wl = w.left(10)
print 'Left: %s' % wl
wr = w.right(10)
print 'Right: %s' % wr

and these left(), right() and other spatial operators mean outside of the base region.
so right in your case is
Match[720,395 211x26].right(10) -> Region[(720+211=931),395 10x26]

Revision history for this message
Petr Fejfar (pf1957) said :
#2

> and these left(), right() and other spatial operators mean outside of the base region.
> so right in your case is
> Match[720,395 211x26].right(10) -> Region[(720+211=931),395 10x26]

I'm not a native english speaker, hence it is possible I do not understand the description in the dox:

    The new region is constructed by extending the current region from its right border by range
    number of pixels towards the right boundary of the screen.
    The new region will also include the current region.

I'd say, that this description corresponds to

    r.setW(min(r.getW,r.getW+range))

Revision history for this message
Petr Fejfar (pf1957) said :
#3

Sorry, it should be:

    r.setW(max(r.getW,r.getW+range))

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

You are right: "extending the current region" is not correct (It was written by a "not native english speaker" --- called RaiMan ;-), so I will change the doc accordingly (but the picture is correct and marvelous --- isn't it :-))

But: the spatial operators do not change the current region, they always return a new one - that might be assigned again to the region variable.

In X 1.0 rc2 there will be Region.moveTo(Location) and Region.morphTo(Region) that might be used for that.

On top I requested an Region.inside(left, right, top, bottom) (bug 702291)

Have fun with Sikuli

Revision history for this message
Petr Fejfar (pf1957) said :
#5

> "extending the current region" is not correct

probably as well as "The new region will also include the current region"... It is excluded actually

> But: the spatial operators do not change the current region, they always return a new one - that might be assigned again to the > region variable.

Yes, I know. The code was for demonstration only. FYI, I've written utility function for my purpose:

def extendRegion(orgRegion,dx,dy,dw,dh):
 newRegion = Region(orgRegion)
 newRegion.setX(newRegion.getX()+dx)
 newRegion.setY(newRegion.getY()+dy)
 newRegion.setW(newRegion.getW()+dw-dx)
 newRegion.setH(newRegion.getH()+dh-dy)
 return newRegion

Thx for your support, pf

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

Oh yes, we Sikulist's need a bunch of these utility functions in our daily Sikuli life ;-)

Your utility function:
your intention seems to be, to stay with the modified region inside the borders of the old one (the left and top borders are moved, but the right and bottom stay fixed).

You are running the risk to get a negative width and or height in cases where (whatever reason) dx is greater than w+dw (same for h).

I have a similar function and always prefer to create a new region (more flexible in usage).

def regInside(reg, left, right, top=0, bottom=0):
 return Region(max(reg.x, reg.x+left), max(reg.y, reg.y+top), max(1,reg.w-left-right), max(1,reg.h-top-bottom))

I mainly use it to cut off left and right portion of a region in text recognition cases (therefor the top and bottom 0 default)

Normally you only need to change the region itself, if you have attached attributes like error handling and observers that you want to keep or in some looping constructions.

Revision history for this message
Petr Fejfar (pf1957) said :
#7

> your intention seems to be, to stay with the modified region inside the borders of the old one
> (the left and top borders are moved, but the right and bottom stay fixed).

No, my intention is to just create a new region extended the old onew in required direction, e.g.

    extendRegion(-10,0,0,0) will produce region extended in left direction (x=x-10, w=x+10)
    extendRegion(0,0,10,0) will produce region extended in right direction (x=x, w=x+10)
    extendRegion(-10,0,10,0) will produce region extended in both horizontal directions (x=x-10, w=x+20)
    etc...

> You are running the risk to

You are right: but I'm still in evaluation process

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

Sure, sorry for being blind :-(

But rewriting the docs and finally understanding your intention, I will request
extendAbove()
extendBelow()
extendRight()
extendLeft()

as the including version of the spatial operators, so you can use the more verbose approach (your cases):
reg.extendLeft(10)
reg.extendRight(10)
reg.extendLeft(10).extendRight(10)

... I love these dotted method worms ;-)