问题描述
我正在尝试在Matlab中创建一个mozaic图像。该数据库主要由RGB图像组成,但也包括一些灰度图像。
I'm trying to create a mozaic image in Matlab. The database consists of mostly RGB images but also some gray scale images.
我需要计算直方图 - 就像维基百科关于 - 用于RGB图像,并考虑在Matlab中使用bitshift运算符来组合R,G和B通道。
I need to calculate the histograms - like in the example of the Wikipedia article about color histograms - for the RGB images and thought about using the bitshift operator in Matlab to combine the R,G and B channels.
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 现在是一个与图像大小相同的矩阵使用索引到像素值的相应bin。
index is now a matrix of the same size as image with the index to the corresponding bin for the pixel value.
如何求和此矩阵中所有唯一值的出现以获得该矩阵的直方图RGB图像?
How can I sum the occurences of all unique values in this matrix to get the histogram of the RGB image?
有没有比bitshift更好的方法来计算RGB图像的直方图?
Is there a better approach than bitshift to calculate the histogram of an RGB image?
推荐答案
计算指数
bitshift
运算符似乎可以。我个人所做的是创建一个将RGB值与bin值相关联的查找关系。首先,您必须弄清楚每个维度中有多少个箱子。例如,假设我们希望每个频道有8个频段。这意味着我们将共有512个箱子。假设我们每个通道有8位,你会产生一个创建如下索引的关系:
Calculating Indices
The bitshift
operator seems OK to do. Me what I would personally do is create a lookup relationship that relates RGB value to bin value. You first have to figure out how many bins in each dimension that you want. For example, let's say we wanted 8 bins in each channel. This means that we would have a total of 512 bins all together. Assuming we have 8 bits per channel, you would produce a relationship that creates an index like so:
% // 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;
这假设我们已将频道拆分为红色
,绿色
和蓝色
。我们还将索引偏移1,因为MATLAB索引数组从1开始。这对我来说更有意义,但 bitshift
运算符看起来效率更高。
This assumes we have split our channels into red
, green
and blue
. We also offset our indices by 1 as MATLAB indexes arrays starting at 1. This makes more sense to me, but the bitshift
operator looks more efficient.
现在,假设您的索引存储在索引中
,你可以使用 accumarray
函数来帮助你做到这一点。 accumarray
接收数组中的一组位置,以及每个位置的权重。 accumarray
会找到相应的位置以及权重,并将汇总放在一起。在您的情况下,您可以使用 sum
。 accumarray
不仅限于总和
。您可以使用提供一对一关系的任何操作。例如,假设我们有以下变量:
Now, supposing you have the indices stored in index
, you can use the accumarray
function that will help you do that. accumarray
takes in a set of locations in your array, as well as "weights" for each location. accumarray
will find the corresponding locations as well as the weights and aggregate them together. In your case, you can use sum
. accumarray
isn't just limited to sum
. You can use any operation that provides a 1-to-1 relationship. As an example, suppose we had the following variables:
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
将为每个权重
的值做,看看中的相应值index
,并将此值累积到相应的广告位中。
What accumarray
will do is for each value of weights
, take a look at the corresponding value in index
, and accumulate this value into its corresponding slot.
因此,通过执行此操作,您可以获得(确定 <$> c $ c> index 和权重
是列向量):
As such, by doing this you would get (make sure that index
and weights
are column vectors):
out = accumarray(index, weights);
out =
6
7
9
2
2
如果看一下,所有索引值为1,中的任何值
共享相同索引1得到的总和 out
。我们有三个值:1,2和3.类似地,对于索引2,我们的值为1,3和3,这给我们7。
If you take a look, all indices that have a value of 1, any values in weights
that share the same index of 1 get summed into the first slot of out
. We have three values: 1, 2 and 3. Similarly, with the index 2 we have values of 1, 3 and 3, which give us 7.
现在,到将此应用到您的应用程序,给定您的代码,您的索引看起来像从1开始。要计算图像的直方图,我们所要做的就是将所有权重设置为1并使用 accumarray
累积条目。因此:
Now, to apply this to your application, given your code, your indices look like they start at 1. To calculate the histogram of your image, all we have to do is set all of the weights to 1 and use accumarray
to accumulate the entries. Therefore:
%// 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
默认情况下会调用 sum
。这应该有希望给你你需要的东西。此外,如果有任何缺少值的索引(例如,假设索引矩阵中缺少索引2), accumarray
聚合时,将方便地在此位置放置零。有道理吗?
accumarray
's behaviour by default invokes sum
. This should hopefully give you what you need. Also, should there be any indices that are missing values, (for example, suppose the index of 2 is missing from your index matrix), accumarray
will conveniently place a zero in this location when you aggregate. Makes sense right?
祝你好运!
这篇关于在matlab中使用bitshift的RGB直方图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!