Steve on Image Processing

Counting occurrences of image colors 9

Posted by Steve Eddins,

Blog reader André recently asked me how to count the number of times each color appears in an image. One short solution involves optional output arguments from the function unique, as well as the relatively new function accumarray.

Let's look first at the function unique. Probably most people use it with a single output argument, like this:

v = [1 1 3 5 5 2 3 2 2]
v =

     1     1     3     5     5     2     3     2     2

u = unique(v)
u =

     1     2     3     5

unique can also return two additional outputs:

[u, m, n] = unique(v);
m
m =

     2     9     7     5

n
n =

     1     1     3     4     4     2     3     2     2

So what do m and n mean? Well, m tells you where you can find the unique values in the original vector. Specifically, m(1) is the index of the last occurrence of the value u(1) in the original vector v. Similarly, m(3) is the index of the last occurrent of the value u(3) in v.

fprintf('m(3) = %d; u(3) = %d, v(m(3)) = %d\n', m(3), u(3), ...
    v(m(3)))
m(3) = 7; u(3) = 3, v(m(3)) = 3

The output argument n gives you indices you can use to reconstruct the original vector from the vector of unique values. In orders, v equals u(n).

u(n)
ans =

     1     1     3     5     5     2     3     2     2

If you count how many times the value 2 appears in the vector n, that will tell you how many times the value u(2) appears in the vector v. That brings us to the second function I mentioned, accumarray. Here's the pertinent sentence from the function description in the doc:

A = accumarray(subs, val) creates an array A by accumulating elements of the vector val using the subscript in subs.

Passing n as subs and 1 as val to accumarray gives us a way to count how many times each value of n appears.

counts = accumarray(n(:), 1)
counts =

     2
     3
     2
     2

counts(1) is the number of times that the value u(1) appears in v. counts(2) is the number of times that the value u(2) appears in v, and so on.

for k = 1:numel(counts)
    fprintf('The value %d appears %d times in v.\n', ...
        u(k), counts(k));
end
The value 1 appears 2 times in v.
The value 2 appears 3 times in v.
The value 3 appears 2 times in v.
The value 5 appears 2 times in v.

So unique and accumarray help to count the number of occurrences of scalars. How do we adapt this technique to count colors? Specifically, how do we count how many times each unique color occurs in a M-by-N-by-3 truecolor image?

First, we reshape the image so that the columns correspond to three color channels.

rgb = imread('peppers.png');
imshow(rgb)
size(rgb)
ans =

   384   512     3

rgb_columns = reshape(rgb, [], 3);
size(rgb_columns)
ans =

      196608           3

Then we use our procedure above with unique and accumarray, except that the we add the 'rows' option to unique.

[unique_colors, m, n] = unique(rgb_columns, 'rows');
color_counts = accumarray(n, 1);

fprintf('There are %d unique colors in the image.\n', ...
    size(unique_colors, 1))
There are 99059 unique colors in the image.

Finally, let's find out what color occurs most frequently.

[max_count, idx] = max(color_counts);

fprintf('The color [%d %d %d] occurs %d times.\n', ...
    unique_colors(idx, 1), unique_colors(idx, 2), ...
    unique_colors(idx, 3), max_count)
The color [254 254 254] occurs 344 times.

And where does this common color occur?

bw = n == idx;
bw = reshape(bw, size(rgb, 1), size(rgb, 2));
imshow(bw)


Get the MATLAB code

Published with MATLAB® 7.5

9 CommentsOldest to Newest

two minor comments

- let’s not forget the typical approach

v=10*[1 1 3 5 5 2 3 2 2];
[nc,newix]=histc(v,unique(v));

% which comes with the added bonus of re-indexing the
% values in v in ascending order from 1:#uniques

nc
[v;newix]

- using the option FIRST, unique returns the index to the first rather than the last occurrence (default behavior) of unique values in the second output argument

us

Taking this a step further how could you get matlab to count and display not just the maximum occurring color but the top three color occurrences and their locations? Thank you very much for your time.

Austin—Sort the color_counts vector. Use the second output from sort, the permutation index, to re-order the the colors in the unique_colors matrix. Pick off the first three rows.

I’am a student and this is very intersting to a project that iám working but i have a question this works in MATLAB without the Image Processing Toolbox?

Hi,code gives error.

 Undefined function or variable "column_data".

Error in ==> count_occ_stev at 84
size(column_data)

Thanks

Hi

This the same question as Austin, how find the second largest color, as u said i sorted the color_counts. And after that i did not understand . The permutation index, to re-order the the colors in the unique_colors matrix.

How to do it can u please tell..

Thank You ..

These postings are the author's and don't necessarily represent the opinions of MathWorks.