Arrays Matlab:创建分块RGB直方图

Arrays Matlab:创建分块RGB直方图,arrays,matlab,image-processing,histogram,Arrays,Matlab,Image Processing,Histogram,我想实现以下Matlab函数: function hist = binnedRgbHist(im, numChannelBins) 给定一个图像im和一个介于1和256之间的数字numChannelBins,它应该创建一个直方图大小的(numChannelBins)^3 例如,如果numChannelBins为2,则应生成以下8个大小的直方图: R=128的像素数 这就像创建一个立方体,其中每个轴表示(R、G和B)中的一个,其中每个轴分为2个箱子=>最后立方体中有8个箱子 我的问题是: 它有

我想实现以下Matlab函数:

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

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

  • R<128,G<128,B<128的像素数
  • R<128,G<128,B>=128的像素数
  • R<128,G>=128,B<128的像素数
  • R<128,G>=128,B>=128的像素数
  • R>128、G<128、B<128的像素数
  • R>128,G<128,B>=128的像素数
  • R>128,G>=128,B<128的像素数
  • R>128,G>=128,B>=128的像素数
  • 这就像创建一个立方体,其中每个轴表示(R、G和B)中的一个,其中每个轴分为2个箱子=>最后立方体中有8个箱子

    我的问题是:

    • 它有内置的功能吗
    • 如果不是,如何更好地使用GPU以runtinme的方式实现它?我最好迭代像素一次并手动创建直方图,还是最好迭代存储单元并每次计算满足存储单元条件的像素数
      • 非常适合这种情况。让

        • im
          :输入图像
        • N
          :每个颜色组件的存储箱数
        然后

        它的工作原理

      • ceil(im/255*N)
        将每个颜色值量化为
        1
        2
        ,…,
        N
      • 重塑(排列(…,[3 1 2]),3,[])。
        将量化图像转换为三列矩阵,其中每行为像素,每列为(量化)颜色分量
      • accumarray(…,1,[N])
        将该矩阵的每一行视为3D索引,并统计每个索引出现的次数,给出不带
        0
        的填充索引
      • 示例1

        数据:

        结果:

        result(:,:,1) =
             1     1
             3     4
        result(:,:,2) =
             2     4
             3     2
        
        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
        
        例如,可以检查只有1个像素的所有R、G、B小于128

        示例2

        数据:

        结果:

        result(:,:,1) =
             1     1
             3     4
        result(:,:,2) =
             2     4
             3     2
        
        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容器:

        我看到@Luis Mendo在我写这篇文章时给出了一个很好的单行解决方案。如果它提供了更深层次的直觉,我的解决方案将利用和:

        说明:

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

        这个问题/答案可能也很有趣。我将每个RGB元组转换为单个1D线性索引,然后颜色直方图变成1D数组。我也使用了accumarray,但从颜色到索引的转换非常重要:
        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
        
        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])