Python – 在图像中find主导/最常见的颜色

我正在寻找一种方法来find使用Python的图像中最主要的颜色/色调。 无论是平均阴影还是最常见的RGB都可以。 我已经看了Python的图像库,并找不到任何有关我正在寻找的手册,也简要在VTK。

但是我find了一个PHP脚本,它可以完成我所需要的工作(login需要下载)。 脚本似乎将图像调整为150 * 150,以显示主色调。 不过之后呢,我还是输了。 我曾考虑过写一些将图像大小调整为小尺寸的图像,然后检查每个像素的图像,但是我想这样做效率很低(尽pipe将这个想法作为一个C python模块来实现也许是一个想法)。

然而,毕竟,我仍然难倒了。 所以我转向你,所以 有没有一种简单而有效的方式来find图像中的主色。

这里是使用PIL和Scipy的集群包的代码。

为了简单起见,我将文件名硬编码为“image.jpg”。 调整图像大小是为了提高速度:如果您不介意等待,请将resize调出注释。 当在这个蓝色辣椒的样品图像上运行时,它通常表示主色是#d8c865,大致对应于两个辣椒左下angular的亮黄色区域。 我说“通常”是因为所用的聚类algorithm对它有一定程度的随机性。 有多种方法可以改变这种情况,但为了您的目的,这可能会适合。 (如果需要确定性结果,请查看kmeans2()变体上的选项。)

import struct import Image 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 = scipy.misc.fromimage(im) shape = ar.shape ar = ar.reshape(scipy.product(shape[:2]), shape[2]) 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 = ''.join(chr(c) for c in peak).encode('hex') print 'most frequent is %s (#%s)' % (peak, colour) 

注意:当我扩大从5到10或15的聚类数量时,经常给出绿色或蓝色的结果。 鉴于input图像,这些也是合理的结果…我也不知道哪个颜色真的在这个图像中占主导地位,所以我不算错误的algorithm!

还有一个小小的好处:只用N个最常用的颜色保存缩小图像:

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

Python Imaging Library在Image对象上有方法getcolors:

im.getcolors() =>(count,color)元组列表或None

我猜你还可以尝试在此之前调整图像大小,看看它是否有更好的performance。

您可以使用PIL在每个维度上将图像重复resize2倍,直到达到1×1。 我不知道PIL使用什么algorithm来降低大尺寸因素,所以直接在1×1中调整尺寸可能会丢失信息。 它可能不是最高效的,但它会给你的图像的“平均”的颜色。

要添加到彼得的答案,如果PIL给你一个模式“P”的图像或几乎不是“RGBA”的任何模式,那么你需要应用一个alpha蒙版将其转换为RGBA。 你可以很容易地做到这一点:

 if im.mode == 'P': im.putalpha(0) 

下面是一个基于c + + Qt的例子来猜测主要的图像颜色。 您可以使用PyQt并将其转换为Python等效。

 #include <Qt/QtGui> #include <Qt/QtCore> #include <QtGui/QApplication> int main(int argc, char** argv) { QApplication app(argc, argv); QPixmap pixmap("logo.png"); QImage image = pixmap.toImage(); QRgb col; QMap<QRgb,int> rgbcount; QRgb greatest = 0; int width = pixmap.width(); int height = pixmap.height(); int count = 0; for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { col = image.pixel(i, j); if (rgbcount.contains(col)) { rgbcount[col] = rgbcount[col] + 1; } else { rgbcount[col] = 1; } if (rgbcount[col] > count) { greatest = col; count = rgbcount[col]; } } } qDebug() << count << greatest; return app.exec(); } 

如果你仍然在寻找答案,这是对我有用,尽pipe不是非常有效的:

 from PIL import Image def compute_average_image_color(img): width, height = img.size r_total = 0 g_total = 0 b_total = 0 count = 0 for x in range(0, width): for y in range(0, height): r, g, b = img.getpixel((x,y)) r_total += r g_total += g b_total += b count += 1 return (r_total/count, g_total/count, b_total/count) img = Image.open('image.png') #img = img.resize((50,50)) # Small optimization average_color = compute_average_image_color(img) print(average_color)