Get pixel color in region and compare to Color

Asked by HjalmarSn

Hi! I'm trying to find colored pixels in a region with this code, but no luck :(
Can someone tell me whats wrong?

def findItemsOfColor():
    area = Region(playground.x + 75,playground.y + 90,600,400)
    area.highlight(1)
    wait(1)
    x = area.x
    y = area.y
    i=0
    while i==0:
        x = x+1
        p = Location(x,y)
        aColor = Color(0x6969FF)
        if myRobot.getPixelColor(p.x, p.y) == aColor:
            print "FOUND ITEM!!!"
            click(x+4,y+4)
            wait(1)
        if x > area.x + area.w:
            print "Searched row"
            x = area.x
            y = y + 1
            if y > area.y + area.h:
                i = 1
                break

Question information

Language:
English Edit question
Status:
Answered
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
j (j-the-k) said :
#1

aColor = Color(0x6969FF)
Here you are creating an Object of the class Color.

myRobot.getPixelColor(p.x, p.y)
Here you are creating another Object of the class Color (I guess).

if myRobot.getPixelColor(p.x, p.y) == aColor:
Here you are comparing the objects and since they are not the same object (do not have the same memory address) the comparison will always fail.

In Python and Java you can only compare primitive datatypes with == to check if they have the same value. Not primitive objects like Color are normally compared by their address in memory if no special behaviour is implemented. I do not know the Color-class but I guess they cannot be compared like this. If this is the case, you have to get the raw color value as a float or string from the two color objects and then you can compare them like you did.

If I'm wrong and the Color class does indeed implement the == functionality, I don't know why your code does not work, sorry.

Revision history for this message
HjalmarSn (hjalmarsn) said :
#2

Tried string-comparison instead, but the whole script freezes if this code is enabled.. Is there a better way to loop through a region's pixels and compare them to a color? This is what my codes looks like now:

def findItemsOfColor():
    area = Region(playground.x + 75,playground.y + 90,600,400)
    area.highlight(1)
    wait(1)
    x = area.x
    y = area.y
    i=0
    while i==0:
        x = x+1
        p = Location(x,y)
        aColor = Color(0x6969FF)
        bColor = myRobot.getPixelColor(p.x, p.y)
        if bColor.toString() == aColor.toString():
            print "FOUND ITEM!!!"
            click(x+4,y+4)
            wait(1)
        if x > area.x + area.w:
            x = area.x
            y = y + 1
            if y > area.y + area.h:
                i = 1
                break

Revision history for this message
j (j-the-k) said :
#3

can you tell us what Color is?
Is it a python class or a java class?
how is it imported?

Revision history for this message
HjalmarSn (hjalmarsn) said :
#4

Thanks for the quick reply! It's a Java function imported at the top of the file using

import java.awt.Color as Color

Tried to comment out some lines to see what was causing the freeze and the script works if I comment out this line

bColor = myRobot.getPixelColor(p.x,p.y)

Also instansiated the object myRobot above but still nothing..

Revision history for this message
HjalmarSn (hjalmarsn) said :
#5

Robot is imported at the top of the file using

import java.awt.Robot as JRobot

And instansiated in the function mentioned above using myRobot = JRobot()

Still freezes :/

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

-- the Color class is not needed in this case
-- c = myRobot.getPixelColor(p.x,p.y).getRGB() returns a 32Bit integer value
-- if c == 0x6969FF: should work (as j-the-k mentioned: you can only compare primitive datatypes with == )

BTW:
myRobot.getPixelColor()
is a rather "slow" feature: checking 1000 pixels (a region of 33x33 pixels !) might last some seconds. So it is not really applicable for searching pixels. Verifications of single pixels after a find() operation can be done though.

Having this in mind, it is vital to have in the loop only the things, that are really needed.
using a loop with for should be more efficient to.

x = area.x
w = area.w
y = area.y
h = area.h

color = 0x6969FF

# run through pixel rows
for r in range(y, h+1):
    for c in range (x, w+1):
        if myRobot.getPixelColor(p.x,p.y).getRGB() = color:
            # do what should be done

Revision history for this message
j (j-the-k) said :
#7

Your second version runs on my system and the colors are found.
Unfortunately it takes a long time, on my PC, it took about 4 seconds for a 600px line to scan, so the process would take 400*4s= ~26 minutes to finish a 400*600 pixel area.

Revision history for this message
obiwan-92 (obiwan-92) said :
#8

Hello.

Sorry for my late answer but it can help other people who have the same problem.
You need to use a bufferImage to accelerate your Java process.

Regards.

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

@obiwan-92
This is a good point.
I will add this to the new version, which has a new Image class anyway, that caches its buffered images.

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

The current version 1.0.1 at least has
Location.getColor()
which internally uses the very slow Robot feature.

This is sufficient for checking a few pixels on the screen.

Revision history for this message
obiwan-92 (obiwan-92) said :
#11

-- @RaiMan
Hello !
Look a the linked bug Bug #810301: [request] get color of one pixel very fast
I put a function with the bufferedImage, in Jython. It's fast enough, I think.

Continue your great job !
Regards.

Can you help with this problem?

Provide an answer of your own, or ask HjalmarSn for more information if necessary.

To post a message you must log in.