How to get the hue/saturation of a grayscale image?

Will I still able to get the hue/saturation of an image if the picture is already a grayscale? Can I use the HSV for getting the hue?

 Accepted Answer

Here is how to get the hue and saturation image for a grayscale image:
hueImage = zeros(size(grayscaleImage));
saturationImage = zeros(size(grayscaleImage));
Of course, they are both all zero for a monochrome, grayscale image. Why would they not be? Were you expecting something different?

11 Comments

http://en.wikipedia.org/wiki/HSL_and_HSV#Basic_principle indicates that pure black and pure white are considered fully saturated, which would be saturation value 1 rather than 0. There is special code in rgb2hsv() that does some tricky uncommented hue and saturation adjustments for the border cases; it is not at all clear to me why some of the adjustments are done.
So yes, it would seem to be reasonable to think that the saturation might not be 0. And the hue at black (saturation 0) does not appear to be well defined other than by convention.
MATLAB, the website Easyrgb.com http://easyrgb.com/index.php?X=MATH&H=20#text20, and ImageJ's Color inspector plugin all seem to have it different than wikipedia. If you run this MATLAB code:
rgb = cat(3, [1 0], [1 0], [1 0]) % 1 white pixel and 1 black pixel
hsv = rgb2hsv(rgb)
You'll see that MATLAB considers hue and saturation to both be zero for black or white "colors". If you step into the rgb2hsv code, you'll see that it does set h and s both to zero in the case of R=G=B. I admit that the uncommented equations are a bit arcane and hard to follow.
Can you explain how to get the gray pixels then, after rgb2hsv, since both the h and s are set to zero?
Raka: I have no idea what you mean when you say "both the h and s are set to zero". Who or what is setting them to zero?
Also explain what you mean when you say "get".
  1. Does that mean produce a masked image where only the gray pixels are in the image, and it's black everywhere else?
  2. Does that mean a list (vector) of all the RGB values of those pixels that are considered to be gray?
  3. Does that mean you want to make, or turn, color pixels in the RGB image to pure gray?
Or something else? I have no idea.
If it's #1, you can get a binary image of where the image is sufficiently close to gray by thresholding the saturation channel:
hsvImage = rgb2hsv(rgbImage);
% Get map (binary/logical image) of what pixels are close to gray.
grayMap = hsvImage(:, :, 2) < 0.2; % Or whatever value you want.
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Blacken outside the map. Make all non-gray pixels black
redChannel(~grayMap) = 0;
greenChannel(~grayMap) = 0;
blueChannel(~grayMap) = 0;
rgbImage = cat(3, redChannel, greenChannel, blueChannel);
If you then want to do #2, you can separate the RGB channels and use that mask to get the RGB values of the "gray" pixels
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
grayRValues = redChannel(grayMap);
grayGValues = greenChannel(grayMap);
grayBValues = blueChannel(grayMap);
If you want #3, you can set the S values to 0 and inverse transform:
sImage = hsvImage(:, :, 2);
sImage(grayMap) = 0; % Desaturate - remove any color.
hsvImage = cat(3, hsvImage(:, :, 1), sImage, hsvImage(:, :, 3));
rgbImageNew = hsv2rgb(hsvImage);
If "get" meant something different to you, then please define "get" much more precisely.
Thank you so much for the effort. I have a binary image, which needs to be coloured so I performed the gray2rgb function. The image is then converted to a MX3 array which is V. Now in this RGB image I need to find out the gray pixels only. So shall I proceed with method 2?
V=imread("D:\Project\image1.jpeg");
if size(V,3)==3
V=gray2rgb(V);
end
[m ,n, p]=size(V);
rgb=zeros(m,n,3);
rgb(:,:,1)=V;
rgb(:,:,2)=V;
rgb(:,:,3)=V;
V=rgb/255;
hsv=rgb2hsv(V);
hImage = hsv(:, :, 1);%hue (what color)
sImage = hsv(:, :, 2); %saturation (how much color)
vImage = hsv(:, :, 3);%value (brightness) of your reference
grayMap = sImage < 0.1
Here hImage and sImage are only having 0 values. This is what I was talking about, apologies for not being clear enough.
Thank you.
I can tell you right now that if you take a binary image and convert it to RGB then ALL the pixels will be gray (either pure white or pure black, which are both considered gray scale) and the saturation image will be completely zero. Why are you expecting otherwise???
I want the colour gray to be detected in the image. How is that possible if I have R G and B channels?
You are starting with a binary image. Every pixel is gray already. The binary 0 are gray with no brightness and the binary 1 are gray with full brightness. There are no intermediate values, because intermediate values would be a third value which would contradict the premise that the original is binary.
"How is that possible if I have R G and B channels" <== Well, why did you create the RGB image in the first place from the binary image? Just don't make it. Use the original binary image, or the grayscale image from where that binary image came from.
When you copy the same values to the r, g, and b color planes, then the result is a grayscale image. Every pixel will be gray, unless you want to define pure black or pure white as not being "gray" for your purposes.
Thank you so much. I have got it now. :)

Sign in to comment.

More Answers (1)

Thank you for the answers I understand it now :)

Categories

Find more on Modify Image Colors in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!