← Back to team overview

sikuli-driver team mailing list archive

Re: [Question #200247]: Using findAll(), a 1 pixel image with 1 minSimilarity gives infinite duplicate matches at the same location?

 

Question #200247 on Sikuli changed:
https://answers.launchpad.net/sikuli/+question/200247

    Status: Open => Answered

RaiMan proposed the following answer:
--1. confirmed
My tests on my Mac showed the same behavior (newest version r930/r931, locally built as 64-Bit)
I tested with one red pixel in the Sikuli logo on the launchpad page having color (180, 37, 28) (some red).
find() and findAll() matched the same pixel (findAll() 100-times the same), but one with a slightly different color (java.awt.Color[r=179,g=37,b=26]).
This behavior is constant in different runs and even when restricting the search region to the logo area.
Since I do not have a test screen, that only contains pixels with the exact color, I guess it would have found one of that in Abel's situation.
BTW: similar(1.0) does not work for me (no matches at all), I have to use similar(0.99), to get matches.

I guess this has to be posted as a bug (but not because of the color,
but the one pixel situation)

--2. workaround (special for your situation)

I played around with the following script, which might help, to solve
your problem:

import java.awt.Robot as JR
rob = JR()

def findPixel(p, r):
    print r
    start = time.time()
    m = r.exists(p,0)
    print "#### find:", time.time()-start
    if not m: return None
    print "(%d, %d)"%(m.x, m.y), rob.getPixelColor(m.x, m.y)
    return m

switchApp("Safari")
# Sikuli Logo visible ?
if not exists("siklogo.png", 0): exit()
pixel = Pattern("Bildschirmfoto 2012-06-13 um 10.28.26.png").similar(0.99) # one reddish pixel

total = time.time()

r = Region(SCREEN)
m = findPixel(pixel, r)
if not m: exit()

rl = Region(SCREEN)
rl.setW(m.x)
findPixel(pixel, rl)

rl = Region(SCREEN)
rl.setX(m.x+1)
rl.setW(rl.w - m.x)
findPixel(pixel, rl)

ra = m.above()
findPixel(pixel, ra)

rb = m.below()
findPixel(pixel, rb)

print "#### total time:", time.time()-total

The idea is, to look in screen regions one after the other, excluding the pixels already found.
Depending on which of the 3 pixels is found as the first one, the approach has to be adapted, since as far as I know, Sikuli's find operation does not guarantee, that the match is the leftmost or uppermost of possible matches.
My example assumes, that the middle one is found with the first find.

-- 
You received this question notification because you are a member of
Sikuli Drivers, which is an answer contact for Sikuli.