← Back to team overview

sikuli-driver team mailing list archive

[Question #685952]: customizing how an observer finds an event

 

New question #685952 on Sikuli:
https://answers.launchpad.net/sikuli/+question/685952

Hi, I would like to use observer to find images based on color. I am using the java code from user aguelle for finding a match by color and the example java code from RaiMan for observers. Code for both methods is below.

The custom class MinSimColoredScreen from aguelle that extends Screen overrides the following methods:
<PatternOrString> Match wait(PatternOrString target, double timeout)
Observer getObserver()

I assumed when I called onAppear and observeInBackground from a MinSimColoredScreen instance, that observe would use the wait method from MinSimColoredScreen. This doesn't happen though. How does observe work exactly and is it possible to customize the way it finds and records events?

btw, Sikuli is great, thanks RaiMan!

Josh
---

/**
 * This class implements support for colored pattern matching if similarity has
 * to be quite low.
 *
 * @author aguelle
 *
 */
public class MinSimColoredScreen extends Screen {

    public MinSimColoredScreen() {
        super();
    }

    /**
     * Constructor
     *
     * @param searchRegion
     *            The search region
     */
    public MinSimColoredScreen(Region searchRegion) {
        setSearchRegion(searchRegion);
    }

    static Logger log = Logger.getLogger(MinSimColoredScreen.class.getName());

    private final double MAX_COLOR_DIFFERENCE = 0.07;
    private Region searchRegion;

    @Override
    public <PatternOrString> Match wait(PatternOrString target, double timeout)
            throws FindFailed {
        System.out.println("in MinSim");
        long startingTime = System.currentTimeMillis();
        long timeoutMS = (long) (timeout * 1000);

        boolean found = false;
        Match match = null;
        long usedTime = 0;
        Color colorFoundImage = null;
        Color colorTargetImage = null;
        double colorDifference = -1;

        while (usedTime < timeoutMS && found == false) {

            match = super.wait(target, timeout);
            Rectangle targetRect = match.getRect();
            BufferedImage targetImage = match.getImage().get();

            try {
                Thread.sleep(10);
            } catch (InterruptedException e1) {
                log.error("Thread Sleep failed.", e1);
            }

            // take screenshot of found region
            BufferedImage foundImage = null;
            try {
                foundImage = new Robot().createScreenCapture(new Rectangle(
                        targetRect));
            } catch (AWTException e) {
                log.error("Creating screen capture failed.", e);
            }

            // compare average colors of target image and screenshot of the
            // found region
            colorFoundImage = new Color(ImageUtils.getAverageColor(foundImage));
            colorTargetImage = new Color(
                    ImageUtils.getAverageColor(targetImage));

            colorDifference = ImageUtils.getColorDifference(colorFoundImage,
                    colorTargetImage);

            if (colorDifference <= MAX_COLOR_DIFFERENCE) {
                found = true;
            }

            usedTime = System.currentTimeMillis() - startingTime;
        }

        if (!found) {
            throw new FindFailed("Color does not match");
        }

        log.debug(target + " found!");
        return match;
    }

    /**
     * Sets the search region for the screen
     *
     * @param searchRegion
     *            The search region
     */
    public void setSearchRegion(Region searchRegion) {
        this.searchRegion = searchRegion;
        setH(searchRegion.h);
        setW(searchRegion.w);
        this.setLocation(new Location(searchRegion.x, searchRegion.y));
    }

    public Region getSearchRegion() {
        return searchRegion;
    }

    @Override
    public Observer getObserver() {
        return super.getObserver();
    }
}

---

public class Example {

    public Example() {}

    //a helper for the formatted printout:
    private static void p(String msg, Object... args) {
        System.out.println(String.format(msg, args));
    }

    //the example:
    private void findColor() {
        String orange = "orange.png";
        Region reg = new Region(0, 0, 880, 580); // define the observed region
        MinSimColoredScreen minSimColoredScreen = new MinSimColoredScreen(reg);
        minSimColoredScreen.getSearchRegion().highlight(2);
        minSimColoredScreen.onAppear(orange, new ObserverCallBack() { // define the handler
            @Override
            public void appeared(ObserveEvent evt) {
                if (evt.isAppear()) {
                    evt.getMatch().highlight(1);
                    evt.stopObserver();
                } else {
                    p("im handler: match nicht gefunden");
                }
            }
        });
        minSimColoredScreen.observeInBackground(); // start observation in background forever
        int n = 0;
        while (minSimColoredScreen.isObserving()) { // do something while observe is running
            p("%d - observing", n);
            reg.wait(1.0);
            n++;
        }
    }

    public static void main(String args[]) {
        Example example = new Example();
        example.findColor();
    }
}

-- 
You received this question notification because your team Sikuli Drivers
is an answer contact for Sikuli.