2

Using Pillow

im = Image.open("GameShot.png");
pix = im.load();
PixelColor = pix[x,y]
if PixelColor == green:
    # do stuff

My Issue

pix[x,y] returns an RGB value and in my image the colour that I'm looking for doesn't stay the same.

  • Either I need to find a new way to do this.
  • Or I need a way to generalise colors.
Jacob Ritchie
  • 1,261
  • 11
  • 22
Nicholas
  • 37
  • 1
  • 10

1 Answers1

4

You need some kind of function to classify a RGB value as belonging to a particular color.

One simple way to get close to this is to define a specific value for each color you want to consider (in your case, red and green, as you say in your comment below) and then calculate the manhattan distance between your RGB value and each of those points. Then you can pick the point that is the smallest distance away and say your pixel belongs to that color.

This will work for any number of colors that you specify and though it may not always be 100% accurate, it's good enough as a first approximation.

Note: I don't have access to Pillow, so I'm not sure what data structure im.load() returns. I'm using (R,G,B) tuples to give a rough idea.

def classify(rgb_tuple):
    # eg. rgb_tuple = (2,44,300)

    # add as many colors as appropriate here, but for
    # the stated use case you just want to see if your
    # pixel is 'more red' or 'more green'
    colors = {"red": (255, 0, 0),
              "green" : (0,255,0),
              }

    manhattan = lambda x,y : abs(x[0] - y[0]) + abs(x[1] - y[1]) + abs(x[2] - y[2]) 
    distances = {k: manhattan(v, rgb_tuple) for k, v in colors.items()}
    color = min(distances, key=distances.get)
    return color
Jacob Ritchie
  • 1,261
  • 11
  • 22
  • Well I need to find a tank in shellshock but every time a take a new screenshot the tank seems to be a slightly different color – Nicholas Apr 06 '16 at 00:45
  • All i need to do is find the color red but it could be many different RGB values of red – Nicholas Apr 06 '16 at 00:50
  • So you're trying to differentiate between a green tank and a red tank? This function should probably be good enough to differentiate between red/green, looking at the color scheme of that game. – Jacob Ritchie Apr 06 '16 at 00:51
  • No i'm trying to find the x,y position of my green tank and then the x,y position of the red tank i found a pixel on the red tank that seems to stay the same but i can't find one on the green tank. p.s i'm not sure how to use your code. – Nicholas Apr 06 '16 at 00:53
  • I put this is classify((36, 144, 60)) and got this File "C:/Users/nicho/Desktop/clasify rgb.py", line 10, in classify distances = {k: manhattan(v, rgb_tuple) for k, v in my_dictionary.iteritems()} NameError: name 'my_dictionary' is not defined – Nicholas Apr 06 '16 at 00:58
  • Try it again with my updated code? There was a misnamed variable in my code. – Jacob Ritchie Apr 06 '16 at 01:01
  • I put in classify((36, 144, 60)) and got this Traceback (most recent call last): File "", line 1, in classify((36, 144, 60)) File "C:/Users/nicho/Desktop/clasify rgb.py", line 12, in classify distances = {k: manhattan(v, rgb_tuple) for k, v in colors.iteritems()} AttributeError: 'dict' object has no attribute 'iteritems' – Nicholas Apr 06 '16 at 01:07
  • For python 3 the method is .items(), not .iteritems(). My bad - I didn't see the tag. http://stackoverflow.com/questions/30418481/error-dict-object-has-no-attribute-iteritems-when-trying-to-use-networkx – Jacob Ritchie Apr 06 '16 at 01:09
  • So how would I add more colours to this assuming this code works by finding the closest colour match from the given list of colours – Nicholas Apr 06 '16 at 01:18
  • That is how it works, yes. You can add entries to the `colors` dictionary with a color name and an RGB tuple that's representative of that color. For example a bright purple would be (255,0,255), white would be (255,255,255), etc. No matter what the length of the dictionary, the function will always return the name of the color that is the closest match to rgb_tuple. – Jacob Ritchie Apr 06 '16 at 01:22
  • 1
    Thanks you win the accepted answer award jk but rly thanks for the help man – Nicholas Apr 06 '16 at 01:26
  • And fyi I think that im.load returns some kind of list – Nicholas Apr 06 '16 at 01:31
  • And if I add more colours will it get more accurate – Nicholas Apr 06 '16 at 01:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/108347/discussion-between-nicholas-and-jacob-ritchie). – Nicholas Apr 06 '16 at 02:41