I\'m trying to create a mozaic image in Matlab. The database consists of mostly RGB images but also some gray scale images.
I need to calculate the histograms - lik
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;
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.
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
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.
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
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.
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
'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?
Good luck!