How to get program to capture part of the App.focusedWindow()?

Asked by Winnie Hsu on 2018-09-11

How to decrease the size captured? the app is 1200x720, but I just want to capture 800x600 to compare them, Thanks in advance!

My Code is as Follows:

some_region = App.focusedWindow()
imgabc = capture(some_region)
screenshotsDir = "D:\Sikuli1.1.3\Reports\Screenshot"
shutil.move(imgabc, os.path.join(screenshotsDir, "A.png"))

wait(1)

baseimg = os.path.join(dir, "A.png")

wait(10)
img = os.path.join(dir, "B.png")
shutil.move(capture(some_region), img)

f = Finder(baseimg)

f.find(Pattern(img).similar(0.85))
if f.hasNext():
        print "Image is matching"
else:
        print "Image is not matching"
f.destroy()

Question information

Language:
English Edit question
Status:
Solved
For:
Sikuli Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
2018-09-17
Last query:
2018-09-17
Last reply:
2018-09-14
RaiMan (raimund-hocke) said : #1

Uuups, why so complicated?

some_region = App.focusedWindow()
setBundlePath(dir)
if some_region.has(Pattern("A").similar(0.85)):
        print "Image is matching"
else:
        print "Image is not matching"

Winnie Hsu (winniehsu1993) said : #2

oh, thanks. I don't want to compare entire app, cause a part of area will always change. I want to compare another area to confirm a button is clickable and work well.
My English is bad, hope somebody can understand :(
I try to adjust the similar to ignore the always changed part, but sometimes the result is wrong. I don't use region because can't make sure that the window is always in the same range.

RaiMan (raimund-hocke) said : #3

--- because can't make sure that the window is always in the same range.
exactly for that you have the App.focusedWindow(), because it gives you the region of the app window, wherever it is.

--- cause a part of area will always change
your shots, that you want to find/compare, should be as small as possible concentrating on what is really of interest (in this case your button).
With 1.1.4 you have the masking feature, that allows to ignore parts of the image when searching.

I guess you should go back and try to understand, how SikuliX really works and about the Region concept, which is very flexible.

Winnie Hsu (winniehsu1993) said : #4

sorry, It's hard for me to understand how to specify a specific area in the app, when that area's background has been changed. But thank you so much!
--With 1.1.4 you have the masking feature, that allows to ignore parts of the image when searching.
pImg = Pattern(someOtherImage).mask(ImageOrPattern)
Does this have an example? I try to use, but failed.

Best RaiMan (raimund-hocke) said : #5

--- masking:
I have started a tutorial:
https://sikulix-2014.readthedocs.io/en/latest/tutorials/masking/masking.html

I will add some more explanations, but for now it should already help bit.

Winnie Hsu (winniehsu1993) said : #6

The output makes me confused. Why screenshot Masked matches score max/min below 0.8, the image is same as shotMasked. But shotMasked's score is so higher.

The Output is :
##### searching for: (1536898174.png) original image

found: 1 matches score max/min: 0.7643 / 0.7643

##### searching for: (P(test20180914-1.png) S: 0.7 masked) masked with other image (image-masked)

found: 1 matches score max/min: 0.9995 / 0.9995

##### searching for: (P(D:/Sikuli1.1.3/Reports/Screenshot/test20180914.png) S: 0.7 masked) masked with screen image (image-masked)

found: 1 matches score max/min: 0.7790 / 0.7790
-----------------------------------------------------------------------------------

My Code is as Follows:

some_region = App.focusedWindow()
imgabc = capture(some_region)
screenshotsDir = "D:\Sikuli1.1.3\Reports\Screenshot"
shutil.move(imgabc, os.path.join(screenshotsDir, "test"+ time.strftime('%Y%m%d') +".png"))
wait(1)
#baseimg = os.path.join(screenshotsDir, "test"+ time.strftime('%Y%m%d') +".png")
baseimg = os.path.join(screenshotsDir, "test20180914.png")
wait(1)
shot = "1536898174.png"
shotA = "test20180914-1.png"
# image with black/white parts useable as mask
shotMask = "bbb-1.png"

wait(5)

# Image masked with black/white image shotMask (image-masked)
shotMasked = Pattern("test20180914-1.png").mask(shotMask)
shotMaskedscreen = Pattern(baseimg).mask(shotMask)
# find the search area
# the image shot-tile-small.png must be visible on screen
reg = None
for match in findAllList(shot):
    if reg: reg = reg.union(match)
    else: reg = match
if reg:
    reg = reg.grow(0)
    reg.highlight(2, "green")
else:
    print "search area not visible"
    exit(-1)

# a generalized function for this demonstration
def search(image, descr = ""):
    print "##### searching for: (%s) %s" % (image, descr)
    matches = reg.findAllList(image)
    if len(matches) > 0:
        scoreMax = 0
        scoreMin = 1
        for match in matches:
            match.highlight()
            score = match.getScore()
            if score > scoreMax:
                scoreMax = score
            if score < scoreMin:
                scoreMin = score
        print "found: %d matches score max/min: %.4f / %.4f" % (len(matches), scoreMax, scoreMin)
    else:
        print " found: no matches"
    wait(2)
    highlightOff()

# showcase original image
search(shot, "original image")

# showcase image-masked
search(shotMasked, "masked with other image (image-masked)")
search(shotMaskedscreen, "masked with screen image (image-masked)")

RaiMan (raimund-hocke) said : #7

I cannot tell you, since I cannot "see" your concrete images used.

If you like, you can send me ALL images of a run as zip to my mail sikulix---at---outlook---dot---com.

--- But shotMasked's score is so higher
This is the advantage of masked searches: buzz in the image (background, other changing parts, ...) is ignored, which with unmasked images lead to lower scores.

Winnie Hsu (winniehsu1993) said : #8

Thanks RaiMan, that solved my question.