小编典典

Python-查找图像中的主要/最常见颜色

python

我正在寻找一种使用python查找图像中最主要的颜色/色调的方法。普通的阴影或最普通的RGB都可以。我看过Python
Imaging库,找不到任何与我在他们的手册中所寻找的内容有关的内容,也没有对VTK进行过简短的了解。

但是,我确实找到了可以满足我需要的PHP脚本(在此处需要登录才能下载)。该脚本似乎将图像大小调整为150 * 150,以显示主要颜色。但是,在那之后,我相当失落。我确实考虑过编写一些可以将图像调整为较小尺寸,然后检查其他每个像素的图像的方法,尽管我认为这样做效率不高(尽管将这种想法实现为C
python模块可能是一种想法)。

但是,尽管如此,我还是很困惑。所以,我转向你。是否有一种简单有效的方法来查找图像中的主色。


阅读 281

收藏
2020-12-20

共1个答案

小编典典

这是使用PillowScipy的cluster软件包的代码。

为简单起见,我将文件名硬编码为“
image.jpg”。调整图像大小是为了提高速度:如果您不介意等待,请注释一下调整大小调用。当在此蓝胡椒样本图像上运行时,通常会说主要颜色是#d8c865,它大致对应于两个胡椒左下角的浅黄色区域。我说“通常”是因为所使用的聚类算法具有一定程度的随机性。您可以通过多种方式更改此设置,但出于您的目的,它可能非常适合。(如果需要确定的结果,请检查kmeans2()变体上的选项。)

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

print('reading image')
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[2]).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))

注意:当我将聚类的数量从5扩展到10或15时,结果通常是绿色或蓝色。给定输入图像,这些结果也是合理的……我也无法确定哪种颜色在该图像中真正占主导地位,因此我也不会对算法提出批评!

还有一点好处:仅使用N种最常用的颜色保存缩小尺寸的图像:

# 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')
2020-12-20