MATLAB Answers

How many colors with their name present in the image.

9 views (last 30 days)
Atique Khan
Atique Khan on 11 Sep 2020
Commented: Adam Danz on 16 Sep 2020
I am looking for a way to find the number and name of certain colors present in the image so that I can use them to count for each pixel. I am doing it but actually some other colors or can say mixed colors are also present in the image which when I count are left in the counting and it counts less and as I increase the size of image pixels the uncounted number increase. I am giving the color ranges for the visible 13 colors in the image but their are some other colors present too which I am missing. How can I find them? Thanks in advane for the help, I am stuck with the problem since long time. My image is

  1 Comment

Adam Danz
Adam Danz on 12 Sep 2020
Perhaps better than my just-for-fun approach, check out imhist().

Sign in to comment.

Accepted Answer

Adam Danz
Adam Danz on 12 Sep 2020
Edited: Adam Danz on 12 Sep 2020
Here's how I explored your image data just-for-fun because I found it intersting and my solution to finding the number of colors represented in your image. I'm not an expert in image analysis. I suggest going through the entire answer and pay attention to the comments.
I'll address the color names at the end.
% Read-in the image
% Attached is a copy of the png image provided in your question.
[I,cmap] = imread('image.png');
h = imshow(I);
% Convert color values to mx3 RGB where m is the number of pixels
% in the image.
RGB = double(I)./255;
% To convince youself that the conversion is accurate, the
% colors don't change when you apply the new RGB values:
% h.CData = RGB
RGBmat = reshape(RGB,[],3);
% List all unique RGB values.
[RGBunq, ~, RGBgroup] = unique(RGBmat,'rows');
% Number of unique colors
nRGB = size(RGBunq,1);
From here we see that there are 13791 unique colors! Let's look at all of the colors that are represented.
% Show pallet
[x,y] = meshgrid(1:ceil(sqrt(nRGB)), 1:ceil(sqrt(nRGB)));
figure()
ax = axes();
scatter(x(1:nRGB),y(1:nRGB),10,RGBunq,'filled')
axis tight
title('All colors in image file')
set(ax, 'XTick', [], 'YTick', [])
Why so many colors and why are does there appear to be near-duplicates? If you zoom into the orginal image, you'll see many smal pixels contain colors that aren't represented by the larger sections of the image. You also have RGB values that are very similar but not exactly alike.
There are several ways to deal with this. You could using image processing tools to remove the smaller "noisy" pixels. You could also choose the unique colors based on how often they appear in the image. Since your image largely consists of solid colors, I chose the latter approach. But it's not as robust as other methods. See the list of limitations to this method toward the end.
% Let's look at the frequency of each unique color
RGBcounts = histcounts(RGBgroup,[1:nRGB,inf]);
figure()
ax2 = axes();
loglog(sort(RGBcounts,'descend'),'LineWidth',2)
xlabel('Ranked color index')
ylabel('Number of pixels')
title('RGB counts in the image')
axis tight
As you can see, many colors are only represented by less than 100 pixels (out of 1,000,000 pixels!). If you want to ignore those colors, you can set a rule that for a color to be counted, it must consume a minimum number of pixels. This could easily be changed to a percentage of pixels. I chose 550 pixes as a minimum because that's where the frequency distribution starts to fall out. I added a horizontal line at y=550 using yline(550,'k:').
% Define minimum pixel count.
minPixCount = 550; % Chosen based on the plot above!
% Identify colors with too few pixels
tooFewIdx = RGBcounts < minPixCount;
% To see the percentage of colors that will be eliminated:
% mean(tooFewIdx)*100
% Eliminate those colors from the list
RGBunqTrim = RGBunq(~tooFewIdx,:);
% How many unique colors are left?
nRGBtrim = size(RGBunqTrim,1);
Now there are 18 colors left (nRGBtrim = 18). Next we'll represent each remaining color and it's relative frequency in the image using a bar plot with 18 bars in order of frequency.
% Represent all remaining colors by their relative number of pixels
RGBcountsTrim = RGBcounts(~tooFewIdx);
[RGBcountTrim, sortIdx] = sort(RGBcountsTrim,'descend');
figure()
ax4 = axes();
bh = bar(RGBcountTrim,1);
bh.FaceColor = 'flat';
bh.CData = RGBunqTrim(sortIdx,:);
bh.EdgeColor = 'k';
ax4.YScale = 'log';
xlabel('RGB ranking')
ylabel('Number of pixels')
title(sprintf('All colors with at least %d pixels\n(Bars show RGB color)',minPixCount))
White is the most frequent color followed by yellow, cyan, and orange.
The RGB values for each remaining color is presented in a table along with their ranking and number of pixels (out of 1,000,000).
% List all RGB values in command window in order of ranking
T = array2table([(1:nRGBtrim)',RGBunqTrim(sortIdx,:),RGBcountsTrim(sortIdx)'], ...
'VariableNames', {'Rank','R','G','B','nPixels'});
Rank R G B nPixels
____ _______ _______ _______ _________
1 1 1 1 5.397e+05
2 1 1 0 49429
3 0 1 1 48123
4 1 0.5451 0 47655
5 0.29412 0 0.50588 47310
6 1 0.74902 0.79216 44757
7 0.64314 0.16471 0.16471 44104
8 1 0 0 41483
9 0 0.50196 0 38874
10 0 1 0 8379
11 1 0 1 8052
12 0 0 1 7982
13 0 0.50196 0.50196 5953
14 1 0.54118 0 1261
15 0.2902 0 0.50196 1076
16 1 0.7451 0.78824 970
17 0 0.49804 0 600
18 0.63922 0.16078 0.16078 551
Limitations to this method
  1. This method counts any pixel that matches the RGB value, even the smaller "noisy" pixels that happen to have the same color as the final selection.
  2. This method is not robust to precision issues. For example, [1, 1, 0.99991] is treated as a different color than [1, 1, 0.99992].
  3. Because of limitation #2, there could be a color with very small variation that is broken up into separate color groups which will underestimate the frequency of that closely-related color range.
Color names
There isn't a color name for every possible color but there are several functions on the file exchange that receive RGB values and return their closest matching colorname. Color names aren't typically useful during analysis and the RGB triplets are must more useful and informative. There are also eyedrop tools online that can sample a color and return a color name.

  7 Comments

Show 4 older comments
Adam Danz
Adam Danz on 16 Sep 2020
I'm not sure what you mean. What are you concatenating?
Are you looking for imtile?
Atique Khan
Atique Khan on 16 Sep 2020
one thing more sir that can we count how many colors each are there in the following figure:
Adam Danz
Adam Danz on 16 Sep 2020
That's already included in my answer.
See the comment "Number of unique colors".

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 12 Sep 2020
Like Adam showed you, there are many, many colors, not just 13. Here is a scatterplot of them:
If you want just 13 you should do cluster analysis. I'm attaching some demos that you may find instructive.

  4 Comments

Show 1 older comment
Atique Khan
Atique Khan on 15 Sep 2020
Thanks a lot for the great help. One thing I need to do is to reduce my image to the thirteen dominant colors which includes white too. By using this
[indexedImage, map] = rgb2ind(rgbImage, 13); % Reduce to just 13 colors.
the image is indexed to thirteen colors but can I know which thirteen colors are there? also can I specify the colors to which the image should reduce?
Image Analyst
Image Analyst on 15 Sep 2020
If you look up rgb2ind() in the help, you can see that the second argument can either be the number of colors you want or the actual colors you want.
If you pass in 13, it will give you an indexed image, and the 13 colors will be listed in map.
[indexedImage, map] = rgb2ind(rgbImage, 13); % Reduce to just 13 colors.
map is a 13 by 3 list of what colors it thinks best represent your image.
If you pass in some map you've created, then it will assign the pixel to the color in the map that is closest to its original color
myCustomMap = jet(13); % Whatever you specify. It's a N by 3 matrix.
indexedImage = rgb2ind(rgbImage, myCustomMap);
Now you're specifying the map so it doesn't have to figure it out on its own. You will get an image where the value of the image is the index (row) into the colormap you told it. So if the indexedImage(4, 9) is 5, then color of the original RGB image pixel at row 4, column 9, is best described by the color you put into row 5 of your custom color map matrix.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!