【问题标题】:how to generate color histogram of RGB image?如何生成RGB图像的颜色直方图?
【发布时间】:2018-07-13 21:00:59
【问题描述】:

我在网上搜索了一些资源,但它们并不是我想要的。

所以对于一组图像。我想生成一个形式为 {color1: p1, color2: p2,..... color100: p100} 的颜色直方图,其中 colorxxx 表示来自 RGB 图像的颜色。 p 表示该颜色的概率。

有没有简单的方法在 python 中做这些事情?

谢谢

【问题讨论】:

  • 您没有找到 PIL 的函数 histogram,还是您认为它不适合您的目的,因为它不适用于 set 图像?跨度>
  • 它返回一个长度为 256*3 的列表。但它只计算每个频道的频率并将它们连接在一起。它与我需要的不同,因为我需要的实际上是将颜色聚类成一组颜色并计算聚类的频率。在一维中,只需要设置每个bin的间隔和计数频率的bin,但是对于3通道的图像呢?
  • @jack 如果您可以通过指定您搜索的哪些在线资源以及确切原因它们不是您要查找的内容来增强您的问题,我认为 usr256 和其他人(包括我自己)会更容易回答你的问题
  • 您可以使用 PIL 访问图像的各个 RGB 像素,并使用 collections.Counter 实例来计算每种颜色的数量,只需将它们发送到 tuple 即可组成三个颜色通道值。这将起作用,因为这些元组将是有效的字典键,例如 (255, 0, 128)—this is important because Counter` 是一个 dict 子类,它要求键是可散列的(换句话说,它只能计算可散列的东西)。发送完所有像素后,Counter 实例实际上是图像的直方图。

标签: python image colors histogram


【解决方案1】:

方法一

{k:np.sum(a==k) for k in set(a.ravel().tolist())}

或者更易读

count = lambda A, key : np.sum(A==key)
unique_keys = set(A.ravel().tolist())
return {key : count(A,key) for key in unique_keys}

走过:

{...}

dictionary comprehension 生成映射

set(a.ravel().tolist())

a.ravelflattens the image; to list 允许将其转换为 set,这是唯一元素的容器。

np.sum(a==k)

计算元素在图像中出现的次数。这个is not the most efficient way to do this,但是把直方图变成你要求的格式


综合来看,如果你的图像是 3x3

a = np.array([[1,2,3],[1,3,3],[3,3,3]])

然后

set(a.ravel().tolist()) # yields set([1, 2, 3])

整个表达式产生

{1: 2, 2: 1, 3: 6}

方法二

from PIL.Image import fromarray
b = fromarray(a.astype(np.uint8)) # convert to a PIL image
hist =  {idx:count for idx, count in enumerate(b.histogram()) if count}

这非常相似(使用字典理解),但使用 PIL histogram 功能和 enumerate 来获取索引。它可能有一些域限制。

“分箱”

如果您想拥有颜色的“箱”,如您所指出的,那么剩下的工作就是定义您的箱结构,这可以通过多种方式完成。例如,在前面的例子中,我们可以通过

num_bins = 2
b = fromarray(a.astype(np.uint8)//num_bins) # convert to a PIL image, binned
hist =  {idx*num_bins:count for idx, count in enumerate(b.histogram()) if count}

【讨论】:

  • 抱歉这么晚才回复。感谢您的回答。但是在这里你只生成了一个索引从 0 到 784 的字典,这不是我想要的。因为这只是每个通道强度计数的扁平计数。我想要的是将颜色空间分组为一个较小的子空间,从 256 x 256 x 256 到 100 个颜色类别。并获得属于这 100 个类别的颜色分布(我们可以通过颜色空间中的立方体定义颜色类别,例如宽度、高度、长度 10 x 10 x 10 )。我想从这个意义上说,它不能被称为通常意义上的颜色直方图。
  • @jack 很好,编辑解决了您的问题吗?
  • sorry但恐怕不是.....当你除以num_bins时,我认为你只划分了数组的每个值。我认为这不是垃圾箱......
  • @jack 嗯,我认为确实如此 :) 您是否在示例中尝试过?如果您的输入数组是 [1,2,3,4,5] 并且使用整数除法除以 2,则得到 [0,1,1,2,2];它们现在按大小 2 分箱。算法正确地解释了 bin [0,2) 中有 1 个元素,[2,4) 之间有两个元素,[4,6) 之间有两个元素。正如我所说,有很多可能的方法可以进行分箱,但这是一种非常常见的方法
  • 我明白了。但是恐怕它仍然只独立处理来自不同通道的强度值,不是吗?因此,如果我想根据您提供的直方图生成随机颜色,我只能从每个通道中独立采样并将它们连接在一起?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 2012-08-22
  • 2015-01-24
  • 1970-01-01
  • 2020-09-07
相关资源
最近更新 更多