【问题标题】:Count appearances of every color (pixel values) in an image计算图像中每种颜色(像素值)的出现次数
【发布时间】:2020-08-03 18:38:45
【问题描述】:

我正在尝试为作业的皮肤分割实现贝叶斯分类器,但我在计数时遇到了一些问题。

问题是我正在关注的论文说我需要 RGB 直方图或某种地图 种类的结构:

map(R,G,B) -> 图像中出现的次数

到目前为止,我已尝试找到满足此要求的地图结构或可以更轻松地完成此计数的某些功能或方法(我仍然希望某处有一个功能可以使我免于遍历所有图像)。

理想情况下,我需要它快速,因为我需要对数据集中的一堆图像的计数求和。

欢迎提出任何想法。

【问题讨论】:

  • 我认为没有原生的 3D 直方图功能。最高的是bivariate。您可以将 RGB 值映射到 1D,然后对 1D 参数进行直方图。示例:using the "exponentiation trick" to convert RGB to grayscale.
  • 另外,虽然我觉得你的问题很有趣,但我不认为这是一个编程问题。 (例如,询问如何将 RGB 映射到灰度将是重复的。)因此我认为它不属于 SO。也许是图像处理 SE 网站。
  • 使用循环:i = 1:256 val = sum(img(:) == i/256) end`,你就有了灰度图像特定强度的计数。这同样适用于 RGB 图像,但多一维,因此需要更多时间。也许循环 unique 颜色可能会加快进程
  • @Argyll 我想计算某个 RGB 像素的出现次数,而不是将其映射到灰度

标签: matlab image-processing colors histogram


【解决方案1】:

也许这会有所帮助:

imdata = double(imread('test.jpg'));
tic 
  [m,n,~] = size(imdata);
  pixels = m*n;  
  x = imdata(:,:,1)*1000000+imdata(:,:,2)*1000+imdata(:,:,3);
  keys = unique(x);
  n_keys = length(keys);
  map = containers.Map(keys,zeros(n_keys,1));
  for i = 1:pixels
    map(x(i)) = map(x(i)) +1;
  end
toc
%here comes post-processing
tic
b = rem(keys, 1000);
g = floor((rem(keys, 1000000) - b)/1000);
r = floor(keys/1000000);
v = map.values;
result = [r g b [v{:}]'];
toc

我很确定这既不是最快也不是最优雅的解决方案。 我想做什么:

  1. 每个当前颜色的可逆单值

  2. 在 Map 对象中使用唯一值作为键

  3. 计算每个值的出现次数

  4. 最后一部分 - 可选 - 将映射转换为数组,其中前 3 列用于颜色分量,最后一列用于出现次数。

我在简单的图片上检查了它,比如附加一个

您可以将它用于测试,它是 500x500,只有 4 种颜色。在我的电脑上用了不到 7 秒。我在真实的 1080x1920 像素图像上进行了尝试——花了 57 秒。很慢,我猜。所以,我尝试了另一种方法 - 我用另一种方法替换了循环:

  for i = 1:n_keys
    map(keys(i)) = sum(sum(x==keys(i)));
  end

对于小图像,它的工作时间不到 0.05 秒(哇!)——在这种情况下,我们的键很少,所以我们进行了几次迭代。 但是对于大的——它有 271833 种独特的颜色——需要几分钟,这使得这种方法无法接受。如果我们可以将关闭的颜色分组到一个 bin 中 - 它会更快。

所以,我会坚持第一种方法。

【讨论】:

  • 非常感谢!我已将可能的像素值从 0-255 减少到 0-32,因此我将在一些测试图像上尝试这两种方法,并为它们计时,看看哪一种效果最好。
猜你喜欢
  • 1970-01-01
  • 2020-04-28
  • 2020-11-02
  • 2015-04-19
  • 1970-01-01
  • 2014-05-12
  • 1970-01-01
  • 1970-01-01
  • 2011-07-06
相关资源
最近更新 更多