Matlab: RGB to HSV Values of specific pixels not working - matlab

I have been trying to get HSV values of few RGB pixels using the following code
im = imread('peppers.png'); %// example image
c = [12 146 410]; %// column coordinates of desired pixels
r = [104 156 129]; %// row coordinates of desired pixels
pixels = impixel(im,c,r); %// rgb values of pixels
hsv = rgb2hsv(pixels); %// convert to hsv
hue = hsv(:,1); %// hue is first column of hsv
But I get an error, Valid colormaps cannot have values outside the range [0,1].
Can someone please tell me what is wrong with my code?

The range of the RGB colormap must be [0,1] (double) for rgb2hsv to work; your problem is the pixels matrix color range goes from 0 to 255 (int). You have to find a way to fix this. im2double might help.
See the rgb2hsv documentation for details.
Also, I would recommend the use of imfinfo to know the kind of image you are dealing with to then act accordingly in your code.

Related

How to programatically process the image to black and white and separate out the polygon

I have an image that represents a polygon.
I want to process it in matlab and generate the image below.
Basically i am asking to separate the polygon from the rest of the image out. This question got inspired here.
We only interested in the red pixels we can use the first channel(Red) to extract coordinates centroid of each scaled pixel. Since there may be slight differences between the same coordinates we can use third output of the uniquetol function to convert absolute coordinates to relative coordinates then use accumarray to convert coordinates to a binary image.
[a,m]=imread('KfXkR.png'); %read the indexed image
rgb = ind2rgb(a,m); %convert it to rgb
region = rgb(:,:,1)>.5; %extract red cannel convert to binary to contrast red pixels
cen = regionprops(region,'Centroid'); %find absolute coordinates of centeroid of each pixel
colrow = reshape([cen.Centroid],2,[]); %reformat/reshape
[~,~,col] = uniquetol(colrow(1,:),0.1,'DataScale',1); %convert absolute coordinated to relative coordinates correcting possible slight variations
[~,~,row] = uniquetol(colrow(2,:),0.1,'DataScale',1);
result = accumarray([row col],1); %make the binary image from coordinates of pixels
imwrite(result,'result.png')
Scaled result:
Unscaled:
I think function contourc will get the ploygon:
C = contourc(img, [1 1]); % img is 2-D double in range [0 1]
The format of output C is a little tricky. But for one level contour, it should be easy. You can read the documentation for contourc to construct the polygon.

The RGB vectors for white and red color are same for this image (Matlab)

I was working with this picture in Matlab to detect the color of the circles. This is a 512 by 512 jpeg image.
I am finding the centers of circles using imfindcircles, then I am taking the R, G, B components of some points near the center of each circle to detect color.
But, I am confused because, for both the red and white circles, I find that the R, G, B components are same [239 227 175].
I am new to image processing, so can anyone explain what's actually happening here.
The centers output of imfindcircles gives the coordinates of the centers in x/y coordinates and you need to index into your image using row/column coordinates so you need to be sure to reverse the two columns when indexing into the image
centers = imfindcircles(IM);
center1 = IM(centers(1,2), centers(1,1),:);
center2 = IM(centers(2,2), centers(2,1),:);
Presumably you are not doing this because you are instead sampling pixels from the background which obviously result in the same RGB values for the centroids.
Update
It appears that actual issue is that you are casting the location of the centroids to a uint8 to make it an integer value so you can then use it as an index. The maximum integer representable by uint8 is 255 and the number of rows and columns in your image is large than 255 (and so are the centroids) so they will get truncated to 255 resulting in the wrong pixel being sampled.
Rather than using uint8, just use round to round the centroids to their nearest integers
cX = round(centers(n_c,1));
cY = round(centers(n_c,2));

Reduce number of colors in matlab using rgb2ind

I am doing some image processing and I needed to reduce the number of colors of an image. I found that rgb2ind could do that and wrote the following snippet:
clc
clear all
[X,map] = rgb2ind(RGB,6,'nodither');
X = rgb2ind(RGB, map);
rgb=ind2rgb(X,map);
rgb_uint8=uint8(rgb*255+0.5);
imshow(rgb_uint8);
But the output looks like this and I doubt there are only 6 colors in it.
It may perceptually look like there is more than 6 colours, but there is truly 6 colours. If you take a look at your map variable, it will be a 6 x 3 matrix. Each row contains a colour that you want to quantize your image to.
To double check, convert this image into a grayscale image, then do a histogram of this image. If rgb2ind worked, you should only see 6 spikes in the histogram.
BTW, to be able to reconstruct your problem, you used the peppers.png image that is built-in to MATLAB's system path. As such, this is what I did to describe what I'm talking about:
RGB = imread('peppers.png');
%// Your code
[X,map] = rgb2ind(RGB,6,'nodither');
X = rgb2ind(RGB, map);
rgb=ind2rgb(X,map);
rgb_uint8=uint8(rgb*255+0.5);
imshow(rgb_uint8);
%// My code - Double check colour distribution
figure;
imhist(rgb2gray(rgb_uint8));
axis tight;
This is the figure I get:
As you can see, there are 6 spikes in our histogram. If there are truly 6 unique colours when you ran your code, then there should be an equivalent of 6 equivalent grayscale intensities when you convert the image into grayscale, and the histogram above verifies our findings.
As such, you are quantizing your image to 6 colours, but it doesn't look like it due to quantization noise of your image.
Don't doubt of your result, the image contains exactly 6 colours.
As explained in the Matlab documentation, the rgb2ind function returns an indexed matrix (X in your code) and a colormap (map in your code). So if you want to check the number of colours in X, you can simply check the size of the colormap: size(map)
In your case the size will be 6x3: 6 colours described on 3 channels (red, greed and blue).

Matlab: imgradient returns quantized images

In Matlab, I want to display the gradient magnitude and direction of a grayscale image. Here is the code I am trying:
image = imread('gray_image.bmp');
[gmag, gdir] = imgradient(image);
figure, imshow(image);
figure, imshow(gmag);
figure, imshow(gdir);
However, gmag and gdir seem to be quantized to just two values: black and white. Every pixel in gmag and gdir is either black, or white. My image itself has a range of gradient magnitudes and directions. Why are these not showing up in the gmag and gdir images? Yes, I would expect gmag to have pure black for pixels with zero gradient, and pure white for pixels with maximum gradient, but I would also expect a range of gray values for gradients between those. Similarly, I would expect a range of gray values in gdir representing the range of angles.
For example, here is the grayscale image:
Here is gmag:
And here is gdir:
Why are gmag and gdir only displaying black or white, with no intermediate gray values?
Two issues
'gmag' and 'gdir' calculated with IMGRADIENT have double datatype.
Thus, if you want to display them as such, MATLAB would treat them as
intensity images and would expect them to be in the range [0 1].
Thus, we need to normalize ‘gmag’ and ‘gdir’, which is shown in the
code later on.
If you wish to save these images, MATLAB expects UINT8 datatype and
the values must lie in the range [0 255].Thus, before saving you need
to multiply it by 255 and then convert to UINT8.
Code
image = imread('gray_image.bmp');
[gmag, gdir] = imgradient(image);
%%// Normalize gmag and gdir
gmag = (gmag-min(gmag(:)))./(max(gmag(:))-min(gmag(:)));
gdir = (gdir-min(gdir(:)))./(max(gdir(:))-min(gdir(:)));
%%// Display images
figure, imshow(image);
figure, imshow(gmag);
figure, imshow(gdir);
%%// Save gradient images
imwrite(uint8(255.*gmag),'Lena_gmag.bmp');
imwrite(uint8(255.*gdir),'Lena_gdir.bmp');
Ouput images
GMAG -
GDIR -
As a test, one can notice the bar-like structure right behind Lena in the GDIR image now, which wasn't visible before.

How to change colormap of indexed image to HSV colormap in MATLAB

I am using an indexed image.How do I programatically obtain the pixel intensity values obtained by changing the colormap to hsv in the imtool? Is there a way to change the colormap of the indexed image to hsv(256)?
I am new to MATLAB, kindly help!
I have attached the image below:
Which channel does the imtool display and what does the value '91' in the imtool stand for? How do I obtain this value?
The Pixel info at the bottom displays the following information:
Pixel info: (X, Y): Pixel Value
Here, we have pixel value of 91 at (309, 510). 91 is the pixel intensity in a range of values (mostly 0 to 255). Only 1 channel is being read because it is a grayscale image.
You can create a hsv image out of an RGB image but it doesnt make sense to talk of a hsv conversion for a gray scale image. What you have is a grayscale image.