You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
what is the ideal solution to find a color in an image?
2 views (last 30 days)
Show older comments
Hi, what is the ideal solution to find a color in an image? knowing that I have used these lines with matlab but I didn't come to make clear the correct RGB values of colors. Every time I find a value for example light brown I found that: R = 173, G = 129, B = 80 and on other sites I found that: R = 181, G = 101, B = 29
idx = I(:,:,1) == ?? & I(:,:,2) == ?? & I(:,:,3) == ??;
C = any( idx(:) );
thanks
Answers (2)
Image Analyst
on 15 Oct 2012
Guess what? They're both light brown. Did you think that light brown was only 1 of the 16 million possible colors, and not, say tens of thousands of possible values? Actually colors are a continuum and where in color space you say one color stops and the other takes over is a matter of opinion - a judgment call. What you call a color can span a range of RGB values - it's not just one single value.
You might want to look over my color segmentation tutorials: http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862
37 Comments
Pamela Paolo
on 15 Oct 2012
Thaks Image Analyst
Can you be a little specific. How color segmentation can help me to find a specific color in an image for example light brown
Image Analyst
on 15 Oct 2012
Edited: Image Analyst
on 15 Oct 2012
Try the delta E method: http://www.mathworks.com/matlabcentral/fileexchange/31118-color-segmentation-by-delta-e-color-difference You can pick a color as an example and then it will find all the other pixels with similar color to that in your image. Are Pamela and Carole working on the same project of finding light brown things?
Pamela Paolo
on 15 Oct 2012
I need to find some colors in an image but i just used an example of color: the light brown given by Carole. I will try your method thanks
Carole
on 15 Oct 2012
Hi
This code doesn't satisfy my need. It allows the user to pick a color as an example and then it will find all the other pixels with similar color to that in the image while this isn't the case in my project. The code should allow to search for a specific color from the beginning (light brown) without user intervention and post 1 if the color exists and 0 if it doesn't exist.
Image Analyst
on 15 Oct 2012
Obviously you have to adapt it to your situation. You can use it to find the mean LAB or HSV color of light brown. Then you can take those known values and hard code them into your program instead of having the user lasso an area to determine them. The rest of the code to get binary maps of what pixels have that color within the specified delta E will be roughly the same, except that again, you may want to hard code in a specific delta E (color difference) instead of asking your user.
Carole
on 15 Oct 2012
Edited: Carole
on 16 Oct 2012
I didn't understand how I can find the mean LAB or HSV color of light brown?? I tried to do this but it's used to find LAB or HSV color of the orginal image. I hope you'll be patient because this is the first time I've worked on this kind of application. I try to implement the code step by step using your advice
rgbImage=imread('img21.png'); %the original image that i will detect the color from it
figure(1);imshow(rgbImage);
fontSize=14;
% Convert image from RGB colorspace to lab color space.
cform = makecform('srgb2lab');
lab_Image = applycform(im2double(rgbImage),cform);
% Extract out the color bands from the original image
% into 3 separate 2D arrays, one for each color component.
LChannel = lab_Image(:, :, 1);
aChannel = lab_Image(:, :, 2);
bChannel = lab_Image(:, :, 3);
% Display the lab images.
figure(2);imshow(LChannel, []);
title('L Channel', 'FontSize', fontSize);
figure(3);imshow(aChannel, []);
title('a Channel', 'FontSize', fontSize);
figure(4);imshow(bChannel, []);
title('b Channel', 'FontSize', fontSize);
% Get the average lab color value.
[LMean, aMean, bMean] = GetMeanLABValues(LChannel, aChannel, bChannel)
Image Analyst
on 16 Oct 2012
I won't have time to look at it today. Call impixelinfo to show the LAB values as you mouse around over it. Then threshold your images to get that range, just like I do in my RGB and HSV color demos.
Image Analyst
on 17 Oct 2012
That is a judgment call since there is a continuum of colors. We use linear discriminant analysis in situations like that to adjust where the color classes begin and end. I get models from my statistician that I implement. You could just try various thresholds in HSV color space to specify the color classes.
Pamela Paolo
on 17 Oct 2012
Edited: Pamela Paolo
on 17 Oct 2012
oops it's complicated. I couldn't understand you very well. Can you give some codes. I really need your help :(
Pamela Paolo
on 17 Oct 2012
Edited: Pamela Paolo
on 17 Oct 2012
In your demo, you used these lines to let user outline region over rgb image. But i couldn't adapt these line to my situation and find the mean LAB color of a specific color
mask = DrawFreehandRegion(h1, rgbImage); % Draw a freehand, irregularly-shaped region.
% Mask the image.
maskedRgbImage = bsxfun(@times, rgbImage, cast(mask, class(rgbImage)));
% Get the average lab color value.
mask should be used to get mean LAB values
[LMean, aMean, bMean] = GetMeanLABValues(LChannel, aChannel, bChannel, mask);
In a previous message you said that we should find the mean LAB or HSV color of light brown for example. How?? what's the input image??
Carole
on 20 Oct 2012
Moved: DGM
on 30 Dec 2023
I used this image to extract mean values: LMean, aMean, bMean of light brown.
Is this correct??
[mask storedColorMap] =imread('cork1.png');
figure(1);imshow(mask);
fontSize=14;
[rows columns numberOfColorBands] = size(mask);
if strcmpi(class(mask), 'uint8')
eightBit = true;
else
eightBit = false;
end
if numberOfColorBands == 1
if isempty(storedColorMap)
mask = cat(3, mask, mask, mask);
else
mask = ind2rgb(mask, storedColorMap);
if eightBit
mask = uint8(255 * mask);
end
end
end
h1 = subplot(3, 4, 1);
imshow(mask);
cform = makecform('srgb2lab');
lab_Image = applycform(im2double(mask),cform);
LChannel = lab_Image(:, :, 1);
aChannel = lab_Image(:, :, 2);
bChannel = lab_Image(:, :, 3);
figure(2);imshow(LChannel, []);
figure(3);imshow(aChannel, []);
figure(4);imshow(bChannel, []);
[LMean, aMean, bMean] = GetMeanLABValues(LChannel, aChannel, bChannel, mask)
[rgbImage storedColor] =imread('7.png');
figure(5);imshow(rgbImage);
fontSize=14;
[R C numberOfColorBand] = size(rgbImage);
cform = makecform('srgb2lab');
lab = applycform(im2double(rgbImage),cform);
L = lab(:, :, 1);
a = lab(:, :, 2);
b = lab(:, :, 3);
figure(6);imshow(L, []);
figure(7);imshow(a, []);
figure(8);imshow(b, []);
LStandard = LMean * ones(R, C);
aStandard = aMean * ones(R, C);
bStandard = bMean * ones(R, C);
deltaL = L - LStandard;
deltaa = a - aStandard;
deltab = b - bStandard;
deltaE = sqrt(deltaL .^ 2 + deltaa .^ 2 + deltab .^ 2);
maskedDeltaE = deltaE .* mask;
meanMaskedDeltaE = mean(deltaE(mask));
stDevMaskedDeltaE = std(deltaE(mask));
message = sprintf('The mean LAB = (%.2f, %.2f, %.2f).\nThe mean Delta E in the masked region is %.2f +/- %.2f',...
LMean, aMean, bMean, meanMaskedDeltaE, stDevMaskedDeltaE);
imshow(maskedDeltaE, []);
caption = sprintf('Delta E between image within masked region\nand mean color within masked region.\n(With amplified intensity)');
title(caption, 'FontSize', fontSize);
But i had this error
??? Error using ==> mtimes
Inputs must be 2-D, or at least one input must be scalar.
To compute elementwise TIMES, use TIMES (.*) instead.
Error in ==> findcolor at 49
LStandard = LMean * ones(R, C);
Image Analyst
on 20 Oct 2012
Pamela, I think it's best that you start your own thread rather than continue to get your questions, comments, and code intertwined with Carole's. I'll answer after that. Be sure to post your image again there.
Image Analyst
on 20 Oct 2012
Moved: DGM
on 30 Dec 2023
The whole image is uniform, so to get the LAB, just do
theL = lab(1,1,1);
theA = lab(1,1,2);
theB = lab(1,1,3);
Since it's a uniform patch, the LAB from the first pixel will the the same as it is at every pixel. And of course since it's uniform the delta E between any point and any other point is zero since everything is the same color and there is no color difference anywhere.
Carole
on 20 Oct 2012
Moved: DGM
on 30 Dec 2023
I used the image cork1.png uploaded just as a mask to extract from it LMean, aMean, bMean values of light brown. Then I used these values to find light brown in the image 7.png. So as you said since the image cork1.png is uniform should i do this
LChannel = lab_Image(1,1,1);
aChannel = lab_Image(1,1,2);
bChannel = lab_Image(1,1,3);
no this??
theL = lab(1,1,1);
theA = lab(1,1,2);
theB = lab(1,1,3);
Is this correct?? because i had this warning dialog (The error message is: Index exceeds matrix dimensions)
Image Analyst
on 20 Oct 2012
Moved: DGM
on 30 Dec 2023
It should be the name of the lab image, which, from your earlier code, is lab_Image. And your cork image is totally uniform - it's all one color. Look at it again. So that's why the lab values can be read off of any pixel at all in the entire image, such as the 1,1 pixel in the upper left corner.
Carole
on 20 Oct 2012
Moved: DGM
on 30 Dec 2023
Hi, Did you mean that since the image cork is uniform, I don't need the function GetMeanLABValues? I tried to do this code. Is it correct because i had this error?? How I can correct it?
??? Error using ==> times
Matrix dimensions must agree.
Error in ==> findcolor at 45
maskedDeltaE = deltaE .* mask;
The code
lab_Image = applycform(im2double(mask),cform);
LMean = lab_Image(1,1,1);
aMean = lab_Image(1,1,2);
bMean = lab_Image(1,1,3);
[rgbImage storedColor] =imread('7.png');
figure(2);imshow(rgbImage);
[R C numberOfColorBand] = size(rgbImage);
cform = makecform('srgb2lab');
lab = applycform(im2double(rgbImage),cform);
L = lab(:, :, 1);
a = lab(:, :, 2);
b = lab(:, :, 3);
figure(3);imshow(L, []);
figure(4);imshow(a, []);
figure(5);imshow(b, []);
LStandard = LMean * ones(R, C);
aStandard = aMean * ones(R, C);
bStandard = bMean * ones(R, C);
deltaL = L - LStandard;
deltaa = a - aStandard;
deltab = b - bStandard;
deltaE = sqrt(deltaL .^ 2 + deltaa .^ 2 + deltab .^ 2);
mask=double(mask);
maskedDeltaE = deltaE .* mask;
meanMaskedDeltaE = mean(deltaE(mask));
stDevMaskedDeltaE = std(deltaE(mask));
figure(6);imshow(maskedDeltaE, []);
figure(7);imshow(deltaE, []);
numberOfLines = 1;
strTolerance = sprintf('%.1f', meanMaskedDeltaE + 3 * stDevMaskedDeltaE);
defaultAnswer = {strTolerance};
response = inputdlg(prompt, dialogTitle, numberOfLines, defaultAnswer);
tolerance = str2double(cell2mat(response));
Image Analyst
on 21 Oct 2012
Moved: DGM
on 30 Dec 2023
Will you please look again at this picture: http://img15.hostingpics.net/pics/506203cork1.png Tell me what you see. Perhaps you're seeing something different than the uniform image I and everyone else is seeing.
Image Analyst
on 21 Oct 2012
Moved: DGM
on 30 Dec 2023
OK. We can use the uniform image for debugging if you want, though I'm sure you'll eventually have to replace it with the actual image of the cork. When you say this to get the LAB values,
lab_Image = applycform(im2double(mask),cform);
what is mask? That doesn't sound like it would be the name of the original rgb image. Did you get it by doing
mask = imread('506203cork1.png');
because usually mask is what you'd call a binary (logical) image that defines what pixels you do or do not want to process.
Carole
on 21 Oct 2012
Moved: DGM
on 30 Dec 2023
mask is the image cork1. This is the code:
[mask storedColorMap] =imread('cork1.png');
figure(1);imshow(mask);
fontSize=14;
[rows columns numberOfColorBands] = size(mask);
if strcmpi(class(mask), 'uint8')
eightBit = true;
else
eightBit = false;
end
if numberOfColorBands == 1
if isempty(storedColorMap)
mask = cat(3, mask, mask, mask);
else
mask = ind2rgb(mask, storedColorMap);
if eightBit
mask = uint8(255 * mask);
end
end
end
cform = makecform('srgb2lab');
lab_Image = applycform(im2double(mask),cform);
LMean = lab_Image(1,1,1);
aMean = lab_Image(1,1,2);
bMean = lab_Image(1,1,3);
[rgbImage storedColor] =imread('7.png');
figure(2);imshow(rgbImage);
[R C numberOfColorBand] = size(rgbImage);
cform = makecform('srgb2lab');
lab = applycform(im2double(rgbImage),cform);
L = lab(:, :, 1);
a = lab(:, :, 2);
b = lab(:, :, 3);
figure(3);imshow(L, []);
figure(4);imshow(a, []);
figure(5);imshow(b, []);
LStandard = LMean * ones(R, C);
aStandard = aMean * ones(R, C);
bStandard = bMean * ones(R, C);
deltaL = L - LStandard;
deltaa = a - aStandard;
deltab = b - bStandard;
deltaE = sqrt(deltaL .^ 2 + deltaa .^ 2 + deltab .^ 2);
mask=double(mask);
maskedDeltaE = deltaE .* mask;
meanMaskedDeltaE = mean(deltaE(mask));
stDevMaskedDeltaE = std(deltaE(mask));
figure(6);imshow(maskedDeltaE, []);
figure(7);imshow(deltaE, []);
numberOfLines = 1;
strTolerance = sprintf('%.1f', meanMaskedDeltaE + 3 * stDevMaskedDeltaE);
defaultAnswer = {strTolerance};
response = inputdlg(prompt, dialogTitle, numberOfLines, defaultAnswer);
tolerance = str2double(cell2mat(response));
But i had this error
??? Error using ==> mtimes
Inputs must be 2-D, or at least one input must be scalar.
To compute elementwise TIMES, use TIMES (.*) instead.
Error in ==> findcolor at 49
LStandard = LMean * ones(R, C);
Image Analyst
on 21 Oct 2012
Moved: DGM
on 30 Dec 2023
OK, now what is 7.png? Where can I download that?
Image Analyst
on 21 Oct 2012
Moved: DGM
on 30 Dec 2023
Most likely, the cork1.png image is not the same size as the 7.png image.
Image Analyst
on 22 Oct 2012
Moved: DGM
on 30 Dec 2023
I don't think you really understand what's going on. You don't understand what a mask is, what a reference color is, and probably a lot of other stuff. Look over this demo and try to understand what I did. It is well commented. Make sure you change the folder and filenames to what they are on your computer.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
format longg;
format compact;
fontSize = 12;
folder = 'C:\Users\Carole\Documents\Temporary';
uniformFileName = fullfile(folder, '506203cork1.png');
rgbUniformImage =imread(uniformFileName);
[rows columns numberOfColorBands] = size(rgbUniformImage);
subplot(3, 4, 1);
imshow(rgbUniformImage);
title('Reference Color Uniform Image', 'FontSize', fontSize);
corkFileName = fullfile(folder, '658945img21.png');
rgbCorkImage =imread(corkFileName);
[rows2 columns2 numberOfColorBands2] = size(rgbCorkImage);
subplot(3, 4, 2);
imshow(rgbCorkImage);
title('Cork Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
cform = makecform('srgb2lab');
% Get lab versions.
lab_ImageUniform = applycform(im2double(rgbUniformImage),cform);
lab_ImageCork = applycform(im2double(rgbCorkImage),cform);
% Get the lab value of the reference uniform image.
L_reference = lab_ImageUniform(1,1, 1);
A_reference = lab_ImageUniform(1,1, 2);
B_reference = lab_ImageUniform(1,1, 3);
message = sprintf('The mean LAB of the reference = (%.2f, %.2f, %.2f).\n',...
L_reference, A_reference, B_reference);
uiwait(msgbox(message));
% Get the delta E between the ref color and the sample image.
deltaL = lab_ImageCork(:, :, 1) - L_reference;
deltaA = lab_ImageCork(:, :, 2) - A_reference;
deltaB = lab_ImageCork(:, :, 3) - B_reference;
% Show them all
subplot(3, 4, 3);
imshow(deltaL, []);
title('Delta L Image', 'FontSize', fontSize);
subplot(3, 4, 4);
imshow(deltaA, []);
title('Delta A Image', 'FontSize', fontSize);
subplot(3, 4, 5);
imshow(deltaB, []);
title('Delta B Image', 'FontSize', fontSize);
% Get the delta E between the ref color and the sample image.
deltaE = sqrt(deltaL.^2 + deltaA.^2 + deltaB.^2);
subplot(3, 4, 6);
imshow(deltaE, []);
title('Delta E Image', 'FontSize', fontSize);
% Get a histogram of the deltaE image
[counts values] = hist(deltaE(:), 64);
subplot(3, 4, 9:12);
bar(values, counts, 1);
title('Histogram of the Delta E Image', 'FontSize', fontSize);
grid on;
% Threshold the deltaE image to get low delta Es.
deltaEthreshold = 44;
binaryImage = deltaE < deltaEthreshold;
subplot(3, 4, 7);
imshow(binaryImage, []);
caption = sprintf('Delta Es < %d', deltaEthreshold);
title(caption, 'FontSize', fontSize);
% Get a masked image
% Mask the image.
maskedRgbImage = bsxfun(@times, rgbCorkImage, cast(binaryImage,class(rgbCorkImage)));
subplot(3, 4, 8);
imshow(maskedRgbImage, []);
title('Masked Delta E Image', 'FontSize', fontSize);
Image Analyst
on 22 Oct 2012
Moved: DGM
on 30 Dec 2023
That was just what I thought from looking at the histogram of the delta E's. You can use whatever value you want.
Pamela Paolo
on 3 Nov 2012
Moved: DGM
on 30 Dec 2023
Hello,
To summarize a single color has different values of R, G and B. To find a color in an image, we are therefore obliged to convert the RGB image to HSV or to lab and use a uniform image to find the mean LAB or HSV values? The only solution is to use a uniform image? There is no known HSV values or lab for each color? Is there an easier solution than using a uniform image??
Image Analyst
on 3 Nov 2012
Moved: DGM
on 30 Dec 2023
No. Nearly everything you said is false. You're best off starting your own thread. If you're looking at the code I posted above, I just used uniform because that's what she supplied as an input image. You don't need to use a uniform image. Why she is using one, I have no idea.
Pamela Paolo
on 3 Nov 2012
Moved: DGM
on 30 Dec 2023
To find a specific color (blue-grey) in an image we can't use:
idx = I(:,:,1) == ?? & I(:,:,2) == ?? & I(:,:,3) == ??;
C = any( idx(:) );
Because every color has many R, G and B values. So how i can find this color without using a uniform image?
Image Analyst
on 4 Nov 2012
Moved: DGM
on 30 Dec 2023
Right. And I know you've seen my color classification tutorials in my File Exchange, so......why can't you use one of them? What colors you get around blue-gray depends on what method you use. The delta E mathod carves out a sphere out of the gamut in LAB space, while the HSV method carves out a sector in HSV space. So, while similar, they may get different colors out near the extremes of the range you're extracting.
Pamela Paolo
on 5 Nov 2012
The delta E method allows the user to pick a color as an example from the image and then it will find all the other pixels with similar color to that in the image while this isn't the case in my project. The code should allow to find a specific color from the beginning (blue-grey) without user intervention. As you said, to adapt this code to our situation, we can use it to find the mean LAB or HSV color of blue-grey. How? What is the image used to find this mean Lab or HSV color of blue-grey?
This code <https://www.mathworks.com/matlabcentral/fileexchange/28512-simple-color-detection-by-hue/content/SimpleColorDetectionByHue.m> detect yellow regions using a given low and high thresholds. In my case i don't have the low and high thresholds of blue-grey. How can I do this?
6 Comments
Image Analyst
on 5 Nov 2012
Moved: DGM
on 30 Dec 2023
Pamela, both of those applications can be adapted to your situation. The program doesn't know by magic what blue gray is - you have to tell it. This can be either by having the user indicate it on the image, or by you inspecting the color space image in the program and then hard coding those values into your program. If you want a sector in hsv space, then just look at the h, s, and v values at some particular pixel location that has a blue-gray pixel to discover what the h, s, and v values actually are. Then hard code those into the program instead of the values for yellow that I used. Same if you want to use the delta E method. Draw some area then find out what values for LAB correspond to blue gray and then hard code those into your program.
Pamela Paolo
on 5 Nov 2012
Moved: DGM
on 30 Dec 2023
I understand those applications but the question is how i can find the values hsv of blue grey used to find this color in the image without the intervention of the user
Image Analyst
on 5 Nov 2012
Moved: DGM
on 30 Dec 2023
You, as the programmer, do it in advance. YOU figure it out. Then you don't have to ask your users.
Pamela Paolo
on 6 Nov 2012
Moved: DGM
on 30 Dec 2023
I know this. I think you can't understand my question. I will try to explain more. The question is how i can find the hsv values of blue grey to be used as input to find this color in an image. For example in your code 'SimpleColorDetectionByHue, to find yellow color, you used a low and high thresholds. How i can also find this thresholds of blue grey?
Image Analyst
on 6 Nov 2012
Moved: DGM
on 30 Dec 2023
I do understand your question. I know you don't know the values - yet - that's why I said " just look at the h, s, and v values at some particular pixel location that has a blue-gray pixel to discover what the h, s, and v values actually are". Then you know what the values are, then you hard code it into your program. Why will that not work?
Image Analyst
on 15 Nov 2012
Moved: DGM
on 30 Dec 2023
Pick your color values from one of these web sites:
http://ivrg.epfl.ch/files/content/sites/ivrg/files/research/alindner/CIC2012/www/ColorThesaurus.html Type blue-grey (using the UK spelling of gray) into the search field. You can type any color in any language in and get the color. Or, pick a color from a color picker and find out the names in 9 or 10 different languages for that color.
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)