Matlab Image thresholding - matlab

The following code shows an image that is combination of blue and red colors. But if I remove the close statement it yields a grayscale image (which is what I want).
Why does it happen, so that I can avoid it in the future?
I am following this tutorial on youtube.
clear;
animal1=imread('animal1.jpg');
%% GrayScale
animal2=rgb2gray(animal1);
%% scale
bright=animal2*1.5;
imshow(bright);
close;
%% threshold
binary= bright>220;
imagesc(binary);

When you call the imshow function, a new figure is created, and default colormap is set to grayscale. If you do not call close, the imagesc uses the same colormap, and uses gray levels to show the binary image.
Otherwise, the current figure is destroyed, a new one is created, and the imagesc function defines a new colormap. The default colormap in this case is parula, which shades from blue to yellow.
Note that you can display the binary image by using the imshow function directly.

As #dlegland has pointed out, it's an issue with colormaps.
In MATLAB a colormap defines the way that data (in your image, plot, whatever) is mapped to a color on the screen. This is done via a linear mapping which can be different for each axes.
When you call imshow, it is a relatively high-level function which alters a number of properties of the axes on which is it displayed. This includes the colormap, color limits, and other things like the tick marks. In your case, since you fed it a grayscale image (you created using rgb2gray), it set the figure/axes to use the gray colormap.
imagesc, however, is a lower-level function that doesn't make any changes to the current axes with the exception that it alters the color limits to span the entire dynamic range of the image. Because of this, when you use imagesc to plot an image on an axes that was previously used by imshow. It simply uses the colormap that imshow was using (gray).
If imshow hadn't been called, then the figure would be using the default colormap (typically parula) and your image would be displayed using this colormap.
Now the nice thing is that you can change the colormap that is being used with the colormap command. For example to use grayscale, you would do
colormap gray
Or if you wanted to specify that colormap for only a specific axes you could do the following
ax = axes();
colormap(ax, gray)
Your only options aren't gray or parula. MATLAB has a number of built-in colormaps or you can even specify your own custom colormap.

Related

Matlab: Filled contour plot with imcontour

I am trying to create a filled contour plot from an image in MATLAB. However, the command imcontour does not seem to have an option for filled contours. If I use contourf, it draws all the contour lines in black. Since the image has a lot of contour levels, it is shown almost completely in black.
Does anybody know how to make a filled imcontour or how to meaningfully apply contourf on an image?
There is no filled version of imcontour because in theory, the image itself is the filled version.
data = load('clown');
img = ind2rgb(data.X, data.map);
imshow(img);
hold on
imcontour(img(:,:,1), 3);
You could use contourf though, and specify the line color. By specifying a value of 'none' no lines will be shown.
c = contourf(data, 2, 'LineColor', 'none')

Drawing black areas in matlab contourf plot

I am generating a series of plots using matlab contourf. I need to do the following with the resulting figure. From this state:
Make this:
Important note: I know the coordinates of pixels which should be blackened.
The easiest way is possible to use ind2rgb, do the "blackening" manually, then use imagesc and deal with the axes propeerties. But using this I will lose the contourf graphics (e.g. the contour lines).
Any better ideas?
You can manipulate the figure colormap by adding black color to the one you use.
M=colormap;
M=[0,0,0 ; M];
colormap(M)
Now assign to the "should be black" pixels a value smaller than the minimum. This will map this value to the minimum color which is now black.
To assign the value efficiently use subs2ind

MATLAB: imagesc() and image() display the same colormap differently

I have some data I would like to display in a picture form. In one case I want to rescale the x and y axis, which leads me to using imagesc. The issue is that the same colormap (jet) looks different in imagesc as compared to image.
Is there a way to make them the same?
I am using MATLAB R2014a.
Demonstration:
Here is how I show them:
figure; image(cancelledmap); colormap(jet); %image
figure; imagesc(y,x,cancelledmap); colormap(jet); %imagesc
And the output:
The colormap settings for both figures are somehow the same, however:
imagesc scales the color axis, whereas image does not. That's why the colors look different. If you click the colorbar button you'll see that they are on different color scales.
You can change the colorscale with caxis.
By the way, if you only want to scale the X- and Y-axes, you can use either function. Just supply your own scaled x and y vectors.

Colorbar is not showing the colors I want

I have a similar question than the one in this post.
I have a grayscale image and I plot points on it. Fro plotting the points I use colormap('jet') but as I want the image to be grayscale, after plotting the points I reset the colormap, colormap('gray').
But I want to show a colorbar! And the colorbar is plotted in grayscale, not 'jet'.
How can I do that?
EDIT:
I want a Colorbar showing the color of the points!
You should convert your image to RGB by putting the same data into R-, G-, and B-channels (this will be grayscale RGB image). Colormap in MatLab is not applied to RGB images, only to indexed ones. Then plot your points over the image with colormap you like.
As discussed here, there's a few ways:
If you have the image processing toolbox, use subimage to create an independent image with a separate colormap. Then plot the image, your points, and join them into one using linkaxes.
Use freezeColors from the file exchange (or multiple colormaps, which I haven't ever tested personally). This is a very easy way to create a larger colormap, and automatically selecting the right portion of the colormap for display of images and colorbars.
As answered by anandr, convert your greyscale image to RGB; Matlab doesn't use colormaps on RGB images, which leaves you freedom to plot your points and show their colorbar independent of the image.
Example code for (3):
I = imread('cameraman.tif');
imshow(cat(3,I,I,I))
hold on
x = #() round(size(I,1) * rand(50,1));
y = #() round(size(I,2) * rand(50,1));
plot(x(), y(), 'r.')
plot(x(), y(), 'g.')
plot(x(), y(), 'b.')
colormap('jet')
colorbar
result:

Smoothing matlab plot figures

I have obtained the following figure using a 120x120 matrix and the surf function.
Is there a simple way to make the lines between different colors look smoother?
First of all, surf may not be the best way to display 2D-image - if you don't actually need the height information, imagesc will work just fine. Even better, it won't show the differently colored lines between hexagons, since it's not going through the colormap at intersections.
However, regardless of your approach, a low-resolution bitmap will not be automatically transformed into a "arbitrary"-resolution vector graphics - and you may not want that, anyway, if you use the figure to allow you to inspect at which combination of (x,y) you obtained at a given value.
There are three approaches to make your image prettier - (1) segment the hexagons, and use patch to create a vector-graphics image. (2) upsample the image with imresample. (3) create a RGB image and smoothen each color separately to get softer transitions:
%# assume img is your image
nColors = length(unique(img));
%# transform the image to rgb
rgb = ind2rgb((img+fliplr(img)),jet(nColors)); %# there are much better colormaps than jet
%# filter each color
for i=1:3,rgbf(:,:,i)=imfilter(rgb(:,:,i),fspecial('gaussian',9,3),'replicate');end