# Python – Find dominant/most common color in an image

## Python – Find dominant/most common color in an image

Heres code making use of Pillow and Scipys cluster package.

For simplicity Ive hardcoded the filename as image.jpg. Resizing the image is for speed: if you dont mind the wait, comment out the resize call. When run on this sample image of blue peppers it usually says the dominant colour is #d8c865, which corresponds roughly to the bright yellowish area to the lower left of the two peppers. I say usually because the clustering algorithm used has a degree of randomness to it. There are various ways you could change this, but for your purposes it may suit well. (Check out the options on the kmeans2() variant if you need deterministic results.)

``````from __future__ import print_function
import binascii
import struct
from PIL import Image
import numpy as np
import scipy
import scipy.misc
import scipy.cluster

NUM_CLUSTERS = 5

im = Image.open(image.jpg)
im = im.resize((150, 150))      # optional, to reduce time
ar = np.asarray(im)
shape = ar.shape
ar = ar.reshape(scipy.product(shape[:2]), shape).astype(float)

print(finding clusters)
codes, dist = scipy.cluster.vq.kmeans(ar, NUM_CLUSTERS)
print(cluster centres:n, codes)

vecs, dist = scipy.cluster.vq.vq(ar, codes)         # assign codes
counts, bins = scipy.histogram(vecs, len(codes))    # count occurrences

index_max = scipy.argmax(counts)                    # find most frequent
peak = codes[index_max]
colour = binascii.hexlify(bytearray(int(c) for c in peak)).decode(ascii)
print(most frequent is %s (#%s) % (peak, colour))
``````

Note: when I expand the number of clusters to find from 5 to 10 or 15, it frequently gave results that were greenish or bluish. Given the input image, those are reasonable results too… I cant tell which colour is really dominant in that image either, so I dont fault the algorithm!

Also a small bonus: save the reduced-size image with only the N most-frequent colours:

``````# bonus: save image using only the N most common colours
import imageio
c = ar.copy()
for i, code in enumerate(codes):
c[scipy.r_[scipy.where(vecs==i)],:] = code
imageio.imwrite(clusters.png, c.reshape(*shape).astype(np.uint8))
print(saved clustered image)
``````

Try Color-thief. It is based on `Pillow` and works awesome.

Installation

`pip install colorthief`

Usage

``````from colorthief import ColorThief
color_thief = ColorThief(/path/to/imagefile)
# get the dominant color
dominant_color = color_thief.get_color(quality=1)
``````

It can also find color pallete

``````palette = color_thief.get_palette(color_count=6)
``````

#### Python – Find dominant/most common color in an image

Python Imaging Library has method getcolors on Image objects:

im.getcolors() => a list of (count,
color) tuples or None

I guess you can still try resizing the image before that and see if it performs any better.