Search code examples
pythonimagecomputer-visionpython-imaging-library

How to get set of colours in an image using python PIL


After importing an image using python's PIL module I would like to get the set of colours in the image as a list of rgb tuples.

What If I know before hand that there will only be 2 colours and the image will be very small, maybe 20x20 pixels? However, I will be running this algorithm over a lot of images. Will It be more effiient to loop through all pixels until I see 2 unique colours? Because I understand loops are very slow in python.


Solution

  • First, let's make an image. I'll just use ImageMagick to make a blue background with magenta writing:

    convert -size 300x120 -background blue -fill magenta -gravity center -font AppleChancery label:"StackOverflow" PNG24:image.png
    

    enter image description here

    As you can see, I only specified two colours - magenta and blue, but the PNG image actually contains 200+ colours and the JPEG image contains 2,370 different colours!

    So, if I want to get the two main colours, I can do this:

    from PIL import Image
    
    # Open the image
    im = Image.open('image.png') 
    
    # Quantize down to 2 colour palettised image using *"Fast Octree"* method:
    q = im.quantize(colors=2,method=2)
    
    # Now look at the first 2 colours, each 3 RGB entries in the palette:
    print(q.getpalette()[:6])
    

    Sample Result

    [0, 0, 255, 247, 0, 255]
    

    If you write that out as 2 RGB triplets, you get:

    RGB 0/0/255   = blue
    RGB 247/0/255 = magenta
    

    The best way to do this for lots of images is to use multithreading or multiprocessing if you want them done fast!