labeling image with different colors - image

I am using the connected component labeling algorithm in Matlab. Is it possible to use different color for different labels when showing the output? (Even though the labels have the same intensity).
Clarification:
I used connected component labeling algorithm to label the connected components of a binary images. Now I got different labels. All the labels contains pixel of equal intensity. (All the labels have pixel intensity value of 1) and all the labels appear in the same color. I want to display the different labels using different colors so that I can eliminate the unwanted one easier.

That is easy - use the imagesc function:
p = imread('peppers.png'); %Read image
b = (p(:,:,2)>100); % Thresholding by some constant threshold
If you already have a binary image, just use this section of the code: (b is the image)
L = bwlabel(b); %Find components
figure(); %Create figure
imagesc(L); %Draw the components, each in its own color.
You can also change the colors by using the colormap command:
colormap(bone)
In order to customize the colors, define an nx3 matrix, and give it as input to colormap
cm = [1 0 0;
0 1 0;
0 0 1
0 1 1
1 1 0
];
colormap(cm)

Related

Combining masks

I'm trying to obtain an image which has everything but several colorful objects grayed out, as shown here:
My original image is this (the caps have slightly different colors than the example above):
I tried to apply a threshold process then binarize the image, which gave me the following result (mask is on the left, result of multiplication is on the right):
And now I'm trying to combine all of these masks. Should I use if loop to combine it into a single image or is there a better way? I tried using (&,&,&) but it turned into a black images.
Your original image has 7 distinct regions: 5 colorful tips, the hand, and the background. The question then becomes, how do we disregard the wall and the hand, which happen to be the two largest regions, and only keep the color of the tips.
If your MATLAB license permits, I would recommend using the Color Thresholder App (colorThresholder), which allows you to find a suitable representation of the colors in your image. Experimenting with it for a minute I can say that the L*a*b* color space allows good separation between the regions/colors:
We can then export this function, yielding the following:
function [BW,maskedRGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 25-Dec-2018
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2lab(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.040;
channel1Max = 88.466;
% Define thresholds for channel 2 based on histogram settings
channel2Min = -4.428;
channel2Max = 26.417;
% Define thresholds for channel 3 based on histogram settings
channel3Min = -12.019;
channel3Max = 38.908;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Invert mask
BW = ~BW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end
Now that you have the mask we can easily convert the original image to grayscale, replicate it along the 3rd dimension, then take the colorful pixels from the original image using logical indexing:
function q53922067
img = imread("https://i.stack.imgur.com/39WNm.jpg");
% Image segmentation:
BW = repmat( createMask(img), 1, 1, 3 ); % Note that this is the function shown above
% Keeping the ROI colorful and the rest gray:
gImg = repmat( rgb2gray(img), 1, 1, 3 ); % This is done for easier assignment later
gImg(BW) = img(BW);
% Final result:
figure(); imshow(gImg);
end
Which yields:
To combine masks, use | (element-wise logical OR), not & (logical AND).
mask = mask1 | mask2 | mask3;

Coloring an 8-bit grayscale image in MATLAB

I have an 8-bit grayscale image with different values (0,1,2,3,4,..., 255). What I want to do is color the grayscale image with colors like blue, red, etc. Until now, I have been doing this coloring but only in a greyscale. How can I do it with actual colors?
Here is the code I have written so far. This is where I am searching for all values that are white in an image and replacing them with a darkish gray:
for k = 1:length(tifFiles)
baseFileName = tifFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
imageArray = imread(fullFileName);
%// Logic to replace white grayscale values with darkish gray here
ind_plain = find(imageArray == 255);
imageArray(ind_plain) = 50;
imwrite(imageArray, fullFileName);
end
What you are asking is to perform a pseudo colouring of an image. Doing this in MATLAB is actually quite easy. You can use the grayscale intensities as an index into a colour map, and each intensity would generate a unique colour. First, what you need to do is create a colour map that is 256 elements long, then use ind2rgb to create your colour image given the grayscale intensities / indices of your image.
There are many different colour maps that are available to you in MATLAB. Here are the current available colour maps in MATLAB without the recently added Parula colour map that was introduced in R2014:
How the colour maps work is that lower indices / grayscale values have colours that move toward the left side of the spectrum and higher indices / grayscale values have colours that move toward the right side of the spectrum.
If you want to create a colour map with 256 elements, you simply use any one of those colour maps as a function and specify 256 as the input parameter to generate a 256 element colour map for you. For example, if you wanted to use the HSV colour map, you would do this in MATLAB:
cmap = hsv(256);
Now, given your grayscale image in your MATLAB workspace is stored in imageArray, simply use ind2rgb this way:
colourArray = ind2rgb(double(imageArray)+1, cmap);
The first argument is the grayscale image you want to pseudocolour, and the second input is the colour map produced by any one of MATLAB's colour mapping functions. colourArray will contain your pseudo coloured image. Take note that we offset the grayscale image by 1 and also cast to double. The reason for this is because MATLAB is a 1-indexed programming language, so we have to start indexing into arrays / matrices starting at 1. Because your intensities range from [0,255], and we want to use this to index into the colour map, we must make this go from [1,256] to allow the indexing. In addition, you are most likely using uint8 images, and so adding 1 to a uint8 will simply saturate any values that are already at 255 to 255. We won't be able to go to 256. Therefore, you need to cast the image temporarily to double so that we can increase the precision of the image and then add 1 to allow the image to go to 256 if merited.
Here's an example using the cameraman.tif image that's part of the image processing toolbox. This is what it looks like:
So we can load in that image in MATLAB like so:
imageArray = imread('cameraman.tif');
Next, we can use the above image, generate a HSV colour map then pseudocolour the image:
cmap = hsv(256);
colourArray = ind2rgb(imageArray+1, cmap);
We get:
Take note that you don't have to use any of the colour maps that MATLAB provides. In fact, you can create your own colour map. All you have to do is create a 256 x 3 matrix where each column denotes the proportion of red (first column), green (second column) and blue (third column) values per intensity. Therefore, the first row gives you the colour that is mapped to intensity 0, the second row gives you the colour that is mapped to intensity 1 and so on. Also, you need to make sure that the intensities are floating-point and range from [0,1]. For example, these are the first 10 rows of the HSV colour map generated above:
>> cmap(1:10,:)
ans =
1.0000 0 0
1.0000 0.0234 0
1.0000 0.0469 0
1.0000 0.0703 0
1.0000 0.0938 0
1.0000 0.1172 0
1.0000 0.1406 0
1.0000 0.1641 0
1.0000 0.1875 0
1.0000 0.2109 0
You can then use this custom colour map into ind2rgb to pseudocolour your image.
Good luck and have fun!

Showing three different edge images in single figure for comparison (No Subplot)

Hello friends,
I have applied Canny edge detection to three different images and I got three images of edges of circles of three different sizes. I want to show these three edges of circles of different radius in same figure but with different colors to compare them. How it can be done?
I have tried to use imfused command but did not get desired result. Please help me
Here is a quick solution but it might not be the best method:
% edge detection
I = imread('circuit.tif');
bw1 = edge(I,'canny');
bw2 = edge(I,'sobel');
% black result image (it could be anything else)
imrgb = repmat(zeros(size(bw1)), [1 1 3]);
% color matrices, red and green
rm = repmat(cat(3,1,0,0),size(bw1,1),size(bw1,2));
gm = repmat(cat(3,0,1,0),size(bw1,1),size(bw1,2));
% logical matrices with same dimension as the result image
lm1 = repmat(bw1,[1 1 3]);
lm2 = repmat(bw2,[1 1 3]);
% overwrite pixel positions from the color matrices according to the logical matrices
% logical matrices were derived from the edge detected ones
imrgb(lm1) = rm(lm1);
imrgb(lm2) = gm(lm2);
imshow(imrgb)

K means clustering in MATLAB - output image

To perform K means clustering with k = 3 (segments). So I:
1) Converted the RGB img into grayscale
2) Casted the original image into a n X 1, column matrix
3) idx = kmeans(column_matrix)
4) output = idx, casted back into the same dimensions as the original image.
My questions are :
A
When I do imshow(output), I get a plain white image. However when I do imshow(output[0 5]), it shows the output image. I understand that 0 and 5 specify the display range. But why do I have to do this?
B)
Now the output image is meant to be split into 3 segments right. How do I threshold it such that I assign a
0 for the clusters of region 1
1 for clusters of region 2
2 for clusters of region 3
As the whole point of me doing this clustering is so that I can segment the image into 3 regions.
Many thanks.
Kind Regards.
A: Given that your matrix output contains scalar values ranging from 1 to 3, imshow(output) is treating this as a grayscale matrix and assuming that the full range of values is 0 to 255. This is why constraining the color limits is necessary as otherwise your image is all white or almost all white.
B: output = output - 1
As pointed out by Ryan, your problem is probably just how you display the image. Here's a working example:
snow = rand(256, 256);
figure;
imagesc(snow);
nClusters = 3;
clusterIndices = kmeans(snow(:), nClusters);
figure;
imagesc(reshape(clusterIndices, [256, 256]));

Color map to show differences between grey level images

I have two grey level images and I am looking for a "proper" way to show the difference image.
The difference image should be a color image and it should show negative, zero and positive values.
Currently I am using a color map that shows negative values as blue, positive value as yellow and zero value as grey (see for example "A color map to show differences between images" http://www.cb.uu.se/~cris/blog/index.php/archives/56).
The minimum value found in the difference image is mapped to RGB=(0, 0, 1) and the maximum value found in the difference image is mapped to RGB=(0.9, 0.9, 0), the mapping is linear.
Is there any reference in the literature (academic papers, books...) to such a map?
For a reference, see the (archived) page that helped push these colormaps; references are at the bottom of the page.
If you want to build such a colormap, i.e. one that is linear in saturation (as opposed to e.g. hue), you need HSL2RGB from the File Exchange, and then you can construct a colormap like this:
cLength = 64; %# length of colormap
hue = [ones(floor(cLength/2),1)*0.66; ones(ceil(cLength/2),1)*0.16];
sat = [linspace(1,0,floor(cLength/2))';linspace(0,1,ceil(cLength/2))'];
lum = ones(cLength,1)*0.50;
cmap = hsl2rgb([hue,sat,lum]);
%# apply colormap
colormap(cmap)
For your visualization, if the most negative and the most positive difference are not the same, use CAXIS to ensure that the color grey maps exactly to zero.
maxAbsDiff = max(abs(differenceImage(:)));
caxis([-maxAbsDiff,maxAbsDiff])
Look at the help for the colormap function.
You should a function to create the required color map (see hot.m as an example). For example:
function c = blueyellow(m)
if nargin < 1, m = size(get(gcf,'colormap'),1); end
x = (0:m-1)'/max(m-1,1);
c = bsxfun(#plus, [0 0 1], x * [0.9 0.9 -1]);
then run
colormap('blueyellow')

Resources