Python-在imag中查找主要/最常见的颜色

2024-04-28 04:23:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种使用python在图像中找到最主要颜色/色调的方法。无论是平均阴影或最常见的出RGB将做。我查看了Python映像库,在他们的手册中找不到任何与我所要查找的内容相关的内容,也没有简要介绍VTK。

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

然而,在这一切之后,我仍然感到困惑。所以我转向你,所以。有没有一种简单有效的方法来找到图像的主色。


Tags: 模块方法图像脚本内容here颜色rgb
3条回答

如果你还在寻找答案,下面是对我有用的,尽管效率不高:

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)

下面是使用PillowScipy's cluster package的代码。

为了简单起见,我将文件名硬编码为“image.jpg”。调整图像大小是为了提高速度:如果您不介意等待,请注释掉resize调用。当在这个{a3}上运行时,它通常说主色是{d8c865,它大致相当于两个辣椒左下角的亮黄色区域。我之所以说“通常”,是因为使用的clustering algorithm具有一定程度的随机性。有多种方法可以改变这一点,但对于你的目的,它可能很适合。(如果需要确定的结果,请查看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')

Python图像库在图像对象上有getcolors方法:

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

我想你还是可以尝试在这之前调整图像的大小,看看它是否有更好的表现。

相关问题 更多 >