在matlab中使用bitshift的RGB直方图

时间:2014-06-07 12:40:13

标签: image matlab image-processing histogram bit-shift

我正在尝试在Matlab中创建一个mozaic图像。该数据库主要由RGB图像组成,但也包括一些灰度图像。

我需要计算直方图 - 就像维基百科关于color histograms的文章的例子一样 - 用于RGB图像,并考虑在Matlab中使用bitshift运算符来组合R,G和B通道。

nbins = 4;
nbits = 8;

index = bitshift(bitshift(image(:,:,1), log2(nbins)-nbits), 2*log2(nbins)) + ...
            + bitshift(bitshift(image(:,:,2), log2(nbins)-nbits), log2(nbins)) + ...
            + bitshift(image(:,:,3), log2(nbins)-nbits) + 1;

index 现在是一个与 image 大小相同的矩阵,其索引为像素值的相应bin。

如何对此矩阵中所有唯一值的出现进行求和以获得RGB图像的直方图?

有没有比bitshift更好的方法来计算RGB图像的直方图?

1 个答案:

答案 0 :(得分:1)

计算指数

bitshift运算符似乎可以。我个人所做的是创建一个将RGB值与bin值相关联的查找关系。首先,您必须弄清楚每个维度中有多少个箱子。例如,假设我们希望每个频道有8个频段。这意味着我们将共有512个箱子。假设每个通道有8位,您将产生一个创建索引的关系:

% // Figure out where to split our bins
accessRed = floor(256 / NUM_RED_BINS);
accessGreen = floor(256 / NUM_GREEN_BINS);
accessBlue = floor(256 / NUM_BLUE_BINS);

%// Figures out where to index the histogram
redChan = floor(red / accessRed);
greenChan = floor(green / accessGreen);
blueChan = floor(blue / accessBlue);

%// Find single index
out = 1 + redChan + (NUM_RED_BINS)*greenChan + (NUM_RED_BINS*NUM_GREEN_BINS)*blueChan;

这假设我们已将频道拆分为redgreenblue。我们还将索引偏移1,因为MATLAB从1开始索引数组。这对我来说更有意义,但bitshift运算符看起来效率更高。

在您的直方图问题

现在,假设您已将索引存储在index中,您可以使用accumarray函数来帮助您完成此操作。 accumarray接收数组中的一组位置,以及每个位置的“权重”。 accumarray会找到相应的位置和权重,并将汇总放在一起。在您的情况下,您可以使用sumaccumarray不仅限于sum。您可以使用提供一对一关系的任何操作。例如,假设我们有以下变量:

index =

 1
 2
 3
 4
 5
 1
 1
 2
 2
 3
 3

weights = 

 1
 1
 1
 2
 2
 2
 3
 3
 3
 4
 4

accumarray将为weights的每个值执行的操作,查看index中的相应值,并将此值累积到相应的插槽中。

因此,通过这样做,你会得到(确定 indexweights向量):

out = accumarray(index, weights);

out =

 6
 7
 9
 2
 2

如果你看一下,所有索引的值为1,weights中共享相同索引1的任何值都会加到out的第一个槽中。我们有三个值:1,2和3.同样,对于索引2,我们有值1,3和3,它们给我们7。

现在,要将此应用到您的应用程序,给定您的代码,您的索引看起来像从1开始。要计算图像的直方图,我们所要做的就是将所有权重设置为1并使用{{ 1}}累积条目。因此:

accumarray
默认情况下,

%// Make sure these are column vectors index = index(:); weights = ones(numel(index), 1); %// Calculate histogram h = accumarray(index, weights); %// You can also do: %// h = accumarray(index, 1); - This is a special case if every value %// in weights is the same number 的行为会调用accumarray。这应该有希望给你你需要的东西。此外,如果有任何缺少值的索引(例如,假设索引矩阵中缺少索引2),sum将方便地在此位置放置零你聚合了。有道理吗?

祝你好运!