RGB histogram using bitshift in matlab

后端 未结 1 1064
-上瘾入骨i
-上瘾入骨i 2021-01-16 13:48

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

相关标签:
1条回答
  • 2021-01-16 14:23

    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;
    

    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.

    Onto your histogram question

    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!

    0 讨论(0)
提交回复
热议问题