Jeya Kumar
Jeya Kumar

Reputation: 1102

How to find the dominant color in images using Python?

I am trying to find top 2 colors from my image to process them accordingly For example if image has blue and white i apply one rule, if it is green and red i apply some other rule.I am trying below code which work for some and not for all.

Main goal : every image has top 2 dominant visible color as shown below and i need to get those color.

Expected result :

image1 : blue and yellow shade

image2 : green shade and blue shade

code :

from PIL import Image

import numpy as np
import scipy
import scipy.misc
import scipy.cluster

NUM_CLUSTERS = 5

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

print('find clus')
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 = ''.join(chr(int(c)) for c in peak).encode("utf-8").hex()
print ('most frequent is %s (#%s)' % (peak, colour))

For this image

enter image description here

I am getting most frequent is [ 1.84704063 1.59035213 252.29132127] (#0101c3bc) As per this link https://www.w3schools.com/colors/colors_picker.asp?color=80ced6 It is detecting blue that is true.

For green image : instead of green shade it is detecting light pink

enter image description here

Detected coloe : most frequent is [142.17271615 234.99711606 144.77187718] (#c28ec3aac290) this is wrong prediction

Upvotes: 0

Views: 2227

Answers (1)

Joe
Joe

Reputation: 7121

There seems to be an error in the line

colour = ''.join(chr(int(c)) for c in peak).encode("utf-8").hex()

Try to add this

for i in peak:
    print(hex(int(i)))

It will print the correct hex characters.

Try the following line:

colour = ''.join([hex(int(c))[2:].zfill(2) for c in peak])

No need for chr as hex() returns the string you are looking for, you just have to drop the digits 0x is puts at the start.

Upvotes: 1

Related Questions