【问题标题】:Matlab: Creating a binned RGB histogram [duplicate]Matlab:创建分箱 RGB 直方图 [重复]
【发布时间】:2016-02-21 18:21:24
【问题描述】:

我想实现以下Matlab函数:

function hist = binnedRgbHist(im, numChannelBins)

给定一个图像 im 和一个介于 1 和 256 之间的数字 numChannelBins,它应该创建一个大小为 (numChannelBins)^3 的直方图。

例如,如果numChannelBins2,则应生成以下 8 大小的直方图:

  1. R < 128, G < 128, B < 128 的像素数
  2. R < 128, G < 128, B >= 128 的像素数
  3. R < 128, G >= 128, B < 128 的像素数
  4. R < 128, G >= 128, B >= 128 的像素数
  5. R > 128, G < 128, B < 128 的像素数
  6. R > 128, G < 128, B >= 128 的像素数
  7. R > 128, G >= 128, B < 128 的像素数
  8. R > 128, G >= 128, B >= 128 的像素数

这就像创建一个立方体,其中每个轴代表(R、G 和 B)中的一个,其中每个轴分为 2 个 bin => 立方体中最终有 8 个 bin。

我的问题:

  • 它有内置函数吗?
  • 如果不是,使用 GPU 以 runtinme 方式实现它会更好吗?我应该更好地迭代像素一次并手动创建直方图,还是应该更好地迭代 bin 并每次计算满足 bin 条件的像素数?

【问题讨论】:

  • 这个问题/答案可能也很有趣。我将每个 RGB 元组转换为单个 1D 线性索引,然后颜色直方图变为 1D 数组。我也使用了accumarray,但是从颜​​色到索引的转换很重要:stackoverflow.com/questions/25830225/…

标签: arrays matlab image-processing histogram


【解决方案1】:

我看到@Luis Mendo 在我写这篇文章时给出了一个很棒的单线解决方案。如果它提供了一些更深层次的直觉,我的解决方案使用histcountsaccumarray

im             = randi([1 255],[10,5,3]);  %// A random 10-by-5 "image" 
numChannelBins = 2;

[~,~,binR]=histcounts(im(:,:,1),[1 ceil((1:numChannelBins)*(255/numChannelBins))]);
[~,~,binG]=histcounts(im(:,:,2),[1 ceil((1:numChannelBins)*(255/numChannelBins))]);
[~,~,binB]=histcounts(im(:,:,3),[1 ceil((1:numChannelBins)*(255/numChannelBins))]);
hist=accumarray([binR(:) binG(:) binB(:)],1,[numChannelBins,numChannelBins,numChannelBins])

说明:

  • histcounts 的三个调用分别对红色、绿色、蓝色像素进行分类 -- histcounts 的第三个输出 [~,~,binX] 给出了每个像素的分类索引
  • accumarray 累积所有唯一索引三元组

【讨论】:

    【解决方案2】:

    accumarray 非常适合这个。让

    • im:输入图片;
    • N:每个颜色分量的 bin 数量。

    然后

    result = accumarray(reshape(permute(ceil(im/255*N), [3 1 2]), 3, []).', 1, [N N N]);
    

    工作原理

    1. ceil(im/255*N) 将每个颜色值量化为 1, 2, ..., N
    2. reshape(permute(..., [3 1 2]), 3, []).' 将量化后的图像转换为三列矩阵,其中每一行是一个像素,每一列是一个(量化的)颜色分量。
    3. accumarray(..., 1, [N N N]) 将该矩阵的每一行视为 3D 索引,并计算每个索引出现的次数,从而给出未使用 0 出现的填充索引。

    示例 1

    数据:

    >> N = 2;
    >> im = randi(256,4,5,3)
    im(:,:,1) =
       113   152   157    65   229
       138    71   215    39    41
        13   108   230   160   153
       142   128   125   220   214
    im(:,:,2) =
       208   215   182    27   230
       205   161     8    95   180
       225    53    73   129    31
       103    97   160    83   255
    im(:,:,3) =
       242    29   185    89    55
       202   225   156   174    96
       160   197    35    87   113
       244   176   146    85   120
    

    结果:

    result(:,:,1) =
         1     1
         3     4
    result(:,:,2) =
         2     4
         3     2
    

    例如可以检查只有1个像素,所有的R、G、B都小于128。

    示例 2

    数据:

    >> im = repmat(150,20,30,3);
    >> N = 4;
    

    结果:

    result(:,:,1) =
         0     0     0     0
         0     0     0     0
         0     0     0     0
         0     0     0     0
    result(:,:,2) =
         0     0     0     0
         0     0     0     0
         0     0     0     0
         0     0     0     0
    result(:,:,3) =
         0     0     0     0
         0     0     0     0
         0     0   600     0
         0     0     0     0
    result(:,:,4) =
         0     0     0     0
         0     0     0     0
         0     0     0     0
         0     0     0     0
    

    在这种情况下,所有像素都属于同一个 3D-bin:

    【讨论】:

      猜你喜欢
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-06
      • 2018-06-16
      • 1970-01-01
      • 2013-02-06
      相关资源
      最近更新 更多