dominant color for an RGB image
Show older comments
Hello,
I want to extract the dominant color of an RGB image.
How can I proceed to do that?
23 Comments
Walter Roberson
on 26 Feb 2013
It would help if you defined "dominant color" for your purposes.
mariem farhat
on 26 Feb 2013
mariem farhat
on 26 Feb 2013
Edited: Walter Roberson
on 26 Feb 2013
Walter Roberson
on 26 Feb 2013
So if I have 10 pixels that are the same shade of bright blue, and the rest of the image is quite red-toned but no one red-tone has more than 9 pixels exactly the same, then the dominant color would be that bright blue ?
mariem farhat
on 27 Feb 2013
Walter Roberson
on 27 Feb 2013
You defined dominant in terms of "the color most used". You need to tell us how you want to measure how much a color is "used".
deeksha rastogi
on 17 Nov 2016
how do we findout the dominant color of a pixel?
Image Analyst
on 17 Nov 2016
A pixel has only one color, so its only color is its dominant color. You can use impixel() if you want.
deeksha rastogi
on 29 Nov 2016
but how can i extract the dominant part from an rgb image? and i have to find that within what range the color is dominant(red) or the color is not dominant? please write some code
Image Analyst
on 29 Nov 2016
Maybe just convert to hsv space with rgb2hsv() and then take the histogram of the hue channel and find the mode. For a more general algorithm, see the Color Frequency Image: http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A58030
sam CP
on 24 Jun 2018
if true
IM = imread('demo.jpg');
IM=imresize(IM,[256,256]);
figure, imshow(IM),title('Input Image');
hsv = rgb2hsv(IM);
How can i take histogram of the hue channel and find the mode for detecting the dominant color in the attached image ?
Image Analyst
on 24 Jun 2018
I don't see that you attached 'demo.jpg'. You should not use jpg format for image analysis if possible. Anyway, just call
hsvImage = rgb2hsv(rgbImage);
hImage = hsvImage(:, :, 1);
counts = histcounts(hImage);
[binHeight, index] = max(counts);
index is the bin where the mode is - the most common hue.
sam CP's own questions on this topic:
@sam CP: please don't hijeck old threads. It actually does not help when you ask the same question in four different locations, because then we have a hard time keeping track of what you have told us and what you have been told.
Shiv srikakolum
on 23 Nov 2021
To be honest i HAd the same question how do I find the dominant colour or most colour used in an Image? Is that i can plot a scatter plot of RGB and how many scatter does these 3 have so i can define that this is the most colour used?
Image Analyst
on 23 Nov 2021
Edited: Image Analyst
on 23 Nov 2021
@Shiv srikakolum you can take a histogram if you want with a nested for loop.
[rows, columns, numberOfColorChannels] = size(rgbImage);
rgbHist = zeros(256,256,256); % Indexes are r, g, b
for row = 1 : rows
for col = 1 : columns
r = rgbImage(row, col, 1);
g = rgbImage(row, col, 2);
b = rgbImage(row, col, 3);
rgbHist(r, g, b) = rgbHist(r, g, b) + 1;
end
end
You can then look for the mode, but the mode (most common color) may not be the dominant color.
Did you ever read my answer below? It explains it in more detail.
Also, there is now a function called colorcloud() that can plot the 3-D histogram (gamut). If you have more questions start a new question and attach your image and explain what your definition of "dominant" is. Is it the average color? The mode color? The color/hue range with the most pixels in it? You need to define it. Or better yet, let us define it for you but you have to tell us what the next step for you is. Assuming you have whatever it is you want, then what will you do with that information NEXT?
Shiv srikakolum
on 23 Nov 2021
@Image Analyst Oh thank you for this, I will what you said and show it to our professor and will ask him if this is the output he wanted.
Shiv srikakolum
on 23 Nov 2021

Shiv srikakolum
on 23 Nov 2021
in Above Image which colour is most used? how do i prove it by code? or results thorugh matlab?
To get the most common color, try this:
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
%workspace; % Make sure the workspace panel is showing.
format short g;
format compact;
rgbImage = imread('peppers.png');
[rows, columns, numberOfColorChannels] = size(rgbImage);
rgbHist = zeros(256,256,256); % Indexes are r, g, b
for row = 1 : rows
for col = 1 : columns
r = rgbImage(row, col, 1) + 1;
g = rgbImage(row, col, 2) + 1;
b = rgbImage(row, col, 3) + 1;
rgbHist(r, g, b) = rgbHist(r, g, b) + 1;
end
end
% Find the max count
maxCount = max(rgbHist(:));
fprintf('The most common color appears %d times.\n', maxCount);
% Get the linear index
indexes = find(rgbHist == maxCount);
% Get the indexes
[rMax, gMax, bMax] = ind2sub(size(rgbImage), indexes);
% Get the most common color(s)
for k = 1 : length(rMax)
rMostCommon = rMax(k) - 1; % Convert from 1-256 indexes to 0-255 gray levels.
gMostCommon = gMax(k) - 1; % Convert from 1-256 indexes to 0-255 gray levels.
bMostCommon = bMax(k) - 1; % Convert from 1-256 indexes to 0-255 gray levels.
fprintf('The most common color is (r,g,b) = (%d, %d, %d).\n', rMostCommon, gMostCommon, bMostCommon)
end
I don't think it's what you need for your homework assignment though. For that you'll have to do clsutering by hue of blocks that are not part of the background. You'd have to use something like linear discriminant analysis (demo attached).
Shiv srikakolum
on 24 Nov 2021
Thank you so much @Image Analyst
DGM
on 10 May 2022
This line
[rMax, gMax, bMax] = ind2sub(size(rgbImage), indexes);
should be
[rMax, gMax, bMax] = ind2sub(size(rgbHist), indexes);
Answers (4)
Sean de Wolski
on 27 Feb 2013
colors = 'RGB';
I = imread('peppers.png');
[~,idx] = max(sum(sum(I,1),2),[],3);
dominant = colors(idx)
Image Analyst
on 26 Feb 2013
How about this:
dominantRedValue = mean2(rgbImage(:, :, 1));
dominantGreenValue = mean2(rgbImage(:, :, 2));
dominantBlueValue = mean2(rgbImage(:, :, 3));
Will that work for you?
11 Comments
Walter Roberson
on 26 Feb 2013
That could give you a color that no pixel has, violating the condition that "dominant color is the color that has more pixel count"....
Image Analyst
on 26 Feb 2013
Edited: Image Analyst
on 26 Feb 2013
Yes that can be true. Though it might also work - it depends on the content of her images (which she hasn't posted yet for some reason). I guess the proper way to do it would be to generate the color frequency image, which, fortunately, someone has done and uploaded to the File Exchange: http://www.mathworks.com/matlabcentral/fileexchange/28164-color-frequency-image
Muthu Annamalai
on 27 Feb 2013
Dominant in the question's context seems like index to peak of the color RGB-histogram.
Walter Roberson
on 27 Feb 2013
Histogram with which width? And what if there are multiple identical peaks?
I also have the sneaking suspicion that hsv might be involved in this.
Image Analyst
on 27 Feb 2013
Edited: Image Analyst
on 27 Feb 2013
You might be interested in this site: http://labs.tineye.com/multicolr/#colors=6e2e76;weights=100; and this one: http://www.npr.org/blogs/thetwo-way/2010/12/10/131960390/color-picker-sorts-flickr-photos-for-fun
Walter Roberson
on 27 Feb 2013
Cool!
mariem farhat
on 27 Feb 2013
Image Analyst
on 27 Feb 2013
I gave a proposed definition, but you didn't. Please give your mathematical definition so I can see why my definition does not match yours. Later today I might try to get the 3D gamut of your image and upload it so you can see what it really looks like.
Image Analyst
on 27 Feb 2013
Edited: Image Analyst
on 22 Dec 2016
Look at this 3D, frequency-weighted, color gamut and tell me now what you think the dominant color is.

Walter Roberson
on 27 Feb 2013
Darned if I can tell. Unless, that is, we start referring to Hue rather than "color"
Image Analyst
on 27 Feb 2013
Edited: Image Analyst
on 23 Nov 2021
Even looking at hue, it's not so easy, as you can see from this screenshot:

That's looking down the value axis from the top. Here's another view from a different perspective:

As you can see whether there is more "green" or "white" pixels depend on where you put the "dividing line" between green and white. It's sort of a continuum so you have to make some kind of criteria. Basically you have to do color classification but to do that you have to decide how many colors you want. Here's one where I chose 48 color classes:

but there are still classes in the "in between" greenish/whitish region and you'll have to decide what to call those. But after that you can find out how many pixels are in each class, then maybe boil it down to two classes and see which has more pixels in it.
mariem farhat
on 27 Feb 2013
0 votes
5 Comments
Walter Roberson
on 27 Feb 2013
What result are you expecting for that image?
mariem farhat
on 27 Feb 2013
Image Analyst
on 27 Feb 2013
Why not white?
Walter Roberson
on 27 Feb 2013
There are so many shades of green there, that I think it plausible that there might be more white than any particular shade of green.
Jan
on 25 Apr 2017
The imageshack link is dead now. Please post the image directly instead of hosting it on any external server.
DGM
on 10 May 2022
While imstats can obviously calculate things like mean, median, or mode, the pagewise mode is usually not what's intended.
rgbpict = imread('peppers.png');
cc = imstats(rgbpict,'mode')
cc =
255 36 0
While there's a lot of red in the image, that tuple does not exist anywhere in the image. Does that matter in your application? It's certainly not close to the most common color either.
From the synopsis:
% 'mode' returns the mode (most common values) per channel
% 'modecolor' calculates the most common color. This differs from 'mode' as
% the most frequent values in individual channels are not necessarily colocated.
% Consider an image which is 40% [1 0 0], 30% [1 1 1] and 30% [0 1 1].
% For this example, 'mode' returns [1 1 1], whereas 'modecolor' returns [1 0 0].
% The latter would be the intuitive answer.
% 'moderange' calculates a selected range of the most common colors in the image.
% Contrast this with 'modecolor' which calculates the singular most common color.
% The range of colors and number of output tuples is specified by parameter 'nmost'.
% This mode supports only I/RGB images.
% 'modefuzzy' calculates the frequency-weighted mean of a selected range of the
% most common colors in the image. The range of colors is specified by parameter
% 'nmost'. This mode supports only I/RGB images.
% The 'modecolor', 'modefuzzy', and 'moderange' options all do color quantization,
% and can therefore alter the color population to some degree. Be wary of using
% the output of these modes for anything of technical importance.
Pay attention to the caveats. The need for quantization is a compromise for speed and memory conservation. Consider how a simple 3D histogramming method might work when the input is a floating-point or uint16 image. The goal of these special 'mode' options is more about visual appearances than exactly matching any one pixel in the image.
Consider the following example. This helps illustrate the different results returned by the various options.
rgbpict = imread('peppers.png');
% get some different image stats
cc = imstats(rgbpict,'mean','median','mode','modecolor','modefuzzy','moderange','nmost',10);
% use those stats to construct a swatch chart for single-output stats
labels = {'mean','median','mode','modecolor','modefuzzy'};
sz = imsize(rgbpict,2);
ntiles = (numel(labels));
tilesz = [round(sz(1)/ntiles) 100];
block1 = zeros([tilesz 3 ntiles],'uint8');
for k = 1:ntiles
thistile = colorpict([tilesz 3],cc(k,:),'uint8'); % colored swatch
thislabel = im2uint8(textim(labels{k},'ibm-iso-16x9')); % text label image
thistile = im2uint8(imstacker({thislabel thistile},'padding',0)); % match geometry
block1(:,:,:,k) = mergedown(thistile,1,'lineardodge'); % blend label and swatch
end
block1 = imtile(block1,[ntiles 1]); % vertically arrange tiles
block1 = imresize(block1,[sz(1) tilesz(2)]); % make sure it's the right size
% create another chart for moderange's multiple outputs
ntiles = (size(cc,1)-ntiles);
tilesz = [round(sz(1)/ntiles) 100];
block2 = zeros([tilesz 3 ntiles],'uint8');
for k = 1:ntiles
thistile = colorpict([tilesz 3],cc(k+4,:),'uint8'); % colored swatch
thislabel = im2uint8(textim(num2str(k),'ibm-iso-16x9')); % text label image
thistile = im2uint8(imstacker({thislabel thistile},'padding',0)); % match geometry
block2(:,:,:,k) = mergedown(thistile,1,'lineardodge'); % blend label and swatch
end
block2 = imtile(block2,[ntiles 1]); % vertically arrange tiles
block2 = imresize(block2,[sz(1) tilesz(2)]); % make sure it's the right size
% show the combined images
imshow([rgbpict block1 block2])

As mentioned before, the results from 'mode' are obviously not the visually-dominant color. In this particular example, 'modecolor' and 'modefuzzy' return similar results. The results from 'moderange' are all very similar. This similarity is not generally the case, so in those cases, you may see 'modefuzzy' results become skewed.
Consider the same code run on other images:




Note how the most frequent colors in the lighthouse image are represented by two different objects/regions. The results from 'modefuzzy' really only make sense if those colors come from one visually distinct region/object, otherwise it won't make sense to take the weighted mean of them. Similar happens with the rubber band picture.
I'm sure that there are some sort of clustering techniques that would work for this task, but I'll leave that to someone who's familiar with it. I just figured I'd throw this out there. For simple things like color-matching components of an image composition, these imstats() options offer a convenience in simple syntax and relatively low resource cost, even if the quantization reduces their usefulness in more technical contexts. While 'modefuzzy' and 'moderange' only work on I/RGB images, most options (including 'modecolor') work on any I/IA/RGB/RGBA/RGBAAA image.
Categories
Find more on Spline Postprocessing in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!