Python - 在图像中查找主要/最常见的颜色 [英] Python - Find dominant/most common color in an image

查看:36
本文介绍了Python - 在图像中查找主要/最常见的颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种使用 python 查找图像中最主要的颜色/色调的方法.RGB 中的平均阴影或最常见的阴影都可以.我查看了 Python Imaging 库,但在他们的手册中找不到任何与我正在寻找的内容相关的内容,并且还简要介绍了 VTK.

I'm looking for a way to find the most dominant color/tone in an image using python. Either the average shade or the most common out of RGB will do. I've looked at the Python Imaging library, and could not find anything relating to what I was looking for in their manual, and also briefly at VTK.

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

I did however find a PHP script which does what I need, here (login required to download). The script seems to resize the image to 150*150, to bring out the dominant colors. However, after that, I am fairly lost. I did consider writing something that would resize the image to a small size then check every other pixel or so for it's image, though I imagine this would be very inefficient (though implementing this idea as a C python module might be an idea).

然而,毕竟这一切,我仍然难倒.所以我转向你,所以.有没有一种简单有效的方法可以找到图像中的主色.

However, after all of that, I am still stumped. So I turn to you, SO. Is there an easy, efficient way to find the dominant color in an image.

推荐答案

这里的代码使用了 PillowScipy 的集群包.

Here's code making use of Pillow and Scipy's cluster package.

为简单起见,我将文件名硬编码为image.jpg".调整图像大小是为了速度:如果您不介意等待,请注释掉调整大小调用.当在这个蓝辣椒的示例图像上运行时,它通常说主色是#d8c865,这大致对应于两个辣椒左下方的亮黄色区域.我说通常"是因为所使用的聚类算法具有一定程度的随机性.您可以通过多种方式改变这一点,但就您的目的而言,它可能很适合.(如果您需要确定性结果,请查看 kmeans2() 变体上的选项.)

For simplicity I've hardcoded the filename as "image.jpg". Resizing the image is for speed: if you don't 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

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:
', 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 时,它经常给出偏绿或偏蓝的结果.给定输入图像,这些也是合理的结果......我也无法分辨出该图像中哪种颜色真正占主导地位,所以我不认为算法有问题!

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 can't tell which colour is really dominant in that image either, so I don't fault the algorithm!

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

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')

这篇关于Python - 在图像中查找主要/最常见的颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆