MATLAB: Matrix with binary info (1 and 0) and image command show nothing - matlab

After processing an input I finally have a matrix of N x M x L representing a volume. The values on that matrix are only 0 or 1. When I try to display a "slice" from this volume using image like this:
image(volume(:,:,80))
the displayed figure is all blue. Now if I use imagesc, the image is displayed ok (in blue and red tones). I think this is related to colormap but can't really figure out how to display the images with the image command.
My final goal is to display 3 or 4 slices in one 3d plot, somthing similar to what is shown here: http://www.mathworks.com/help/matlab/visualize/techniques-for-visualizing-scalar-volume-data.html#f5-4457

You are right, your problem is related to colormap. Try
image(volume(:,:,80))
colorbar
You will see that your current colormap ranges from 0 to 64. If you use this command instead:
image(volume(:,:,80),'CDataMapping','scaled')
colorbar
you should get the image you want, and your colormap is now scaled to the range of your data (of course, you don't need to show the colorbar to get the right scaling, I just added it to make things more clear).

Related

Reading grayscale image in matlab [duplicate]

This question already has an answer here:
What does the index refer to when selecting a pixel on an image in Matlab?
(1 answer)
Closed 6 years ago.
I have gray scale image "lena.bmp". I want read this image in matlab using imread() function.
When i use code below to read and show image my image is dark (black).
img = imread('lena.bmp');
imshow(img);
But when i use code below, I have no problem to view.
[img map]= imread('lena.bmp');
imshow(img,map);
It seems that my first code doses not reading image in grayscale mode (like what rgb2gray function generate).
My image is as follows:
What can i do to solve this problem?
Your image is an "indexed" image. That means it contains integer values which act as "labels" more than anything, and each of those labels is mapped to a colour (i.e. an rgb triplet). Your map variable represents that mapping; at row 5 you have the rgb triplet that corresponds to 'label' "5", for instance.
To see what I mean, do unique(img) and you'll see that the values of your img array are in fact quite regular. The command rgbplot can demonstrate the actual colourmap graphically. Run rgbplot(map) on your map variable to see the mapping for each of the red green and blue colours.
Now, save and read the image below on your computer as img2 and compare the array values.
This image was generated by converting from the "indexed" image you linked to, to a "grayscale" one using photoediting software (the GIMP). The difference is that
in a grayscale image, the pixel values represent actual intensities, rather than integer 'labels'. Imread reads grayscale images as uint8 images by default, meaning it assigns intensity values to pixels ranging from 0 (black) to 255 (white). Since these values happen to be integers you could still cheat and treat them as 'labels' and force a colour-mapping on them. But if you assign a 'linear map' (i.e. value 1 = intensity 1, value 2 = intensity 2, etc) then your image will look as you would expect.
You'll see that the values from unique(img2) are quite different. If you imshow(img2) you'll see this displays as you'd expect. If you don't specify a colormap for imshow, it will assume that the map is a linear mapping from the lowest to the highest value in the image array, which explains why your indexed image looked weird, since its values were never supposed to correspond to intensities.
Also try imagesc(img2) which will show this but using the "current" colormap. imagesc causes the colormap to be "scaled", so that the lowest colour goes to the lowest value in the image, and similarly for the highest.
The default colormap is jet so you should see a psychedelic looking image but you should be able to make out lena clearly. If you try colormap gray you should see the gray version again. Also try colormap hot. Now to make sense of the colormaps, try the rgbplot command on them (e.g. rgbplot(gray), rgbplot(hot) etc).
So, going back to imshow, imshow basically allows you to display an indexed image, and specify what colormap you want to use to display it. If you don't specify the colormap, it will just use a linear interpolation from the lowest value to the highest as your map. Therefore imshow(img) will show the image pretty much in the same way as imagesc(img) with a gray colormap. And since the values in your first img represent evenly spaced 'labels' rather than actual intensities, you'll get a rubbish picture out.
EDIT: If you want to convert your indexed image to a grayscale image, matlab provides the ind2gray function, e.g.:
[img, map] = imread('lena.bmp');
img_gray = ind2gray(img, map);
This is probably what you need if you mean to process pixel values as intensities.

Create a plot with a 2D colourmap depending on two variables

I want to display an image (e.g.imshow) and use a colormap to represent the values of my data points.
However, colormap only gives the option to be dependent on a single variable, but I want a "2D colormap" which depends on two variables.
For example I have a simple image 2x2 pixels:
img = [
1 1 5 6;
1 2 8 7;
2 1 4 3;
2 2 15 3]
Here the first two values of each row are the coordinates, the other two are the values describing the pixel (call them x and y).
When displaying the image I want to use a 2D colormap. For example something like this, which picks a colour depending on both variables (x and y):
Is there an option in MATLAB do to this, possibly in one of the extra toolboxes?
If not can this be done manually? I was thinking by overlaying a grey scale image given from the first value over a colormap image given by the second value a similar effect could be achieved.
In your 2D colormap you are actually using the HSV color space.
Basically, your x axis is Hue, and Y axis is Saturation. You can convert any value into this space if its properly scaled. If you make sure that you scale your 3rd and 4rd column in the [0-1] interval you can easily do
colorRGB=hsv2rgb([val3,val4,0.5]);
If you perform this operation for each pixel, you'll get the image you want.
I gave a extended explanation of how HSV works here

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).

Relative Markersize in Matlab plots

I am trying to plot a matrix where each element is in one out of two states. (ising model..)
Now, I would like to have one state colored and the other one white. That works using
[i,j] = find(S);
figure(gcf);
plothandle = scatter(i,j);
axis([0 nNodes+1 0 nNodes+1]);
when S holds the Spins and one state is equal to 0. (find returns a matrix of only non-zero elements)
To have a useful plot, the sizes of the markers should be 1x1 in RELATIVE coordinates. So if the whole matrix S would be in a state non-zero, everything would be colored.
However, it seems like Matlab only allows MarkerSizes in points or inches. How could I solve this?
One idea I had was, that I find out the point-size of the axes and then can easily calculate how big my markers should be. Then I would have to create a callback function if I want to zoom in and so on. Also, I have not yet found a way (without the image acq. toolbox) to find out the absolute size of my axes.
To clarify what I want: How could I plot a chessboard using a matrix with 1 for black and 0 for white fields?
For displaying data of this sort I generally prefer IMAGE or IMAGESC to PCOLOR since PCOLOR won't display the last row and column of the matrix when using faceted shading (the default). Also, IMAGE and IMAGESC flip the y axis so the image more intuitively matches what you think of when looking at a matrix (i.e. rows start from 1 at the top). You can visualize your matrix like this:
S = round(rand(20)); %# Sample 20-by-20 matrix of ones and zeroes
imagesc(S); %# Plot the image
colormap([1 1 1; 0 0 0]); %# Set the colormap to show white (zero elements) and
%# black (non-zero elements)
And here's a sample image:
Just as a suggestion, you can try using pcolor instead of `scatter' Example:
pcolor(hadamard(20))
colormap(gray(2))
axis ij
axis square

Turn a MATLAB plot into image

I have generated a plot like
figure; hold;
axis([0 10 0 10]);
fill([ 1 1 5 5], [5 1 1 5],'b')
and now I want to have this plot as an matrix so that I can i.e. filter the blog with a gaussian. Googleing I found this thread Rasterizing Plot to Image at MATLAB Central. I tried it, but I could only get it to work for line or function plots.
Do you have any ideas?
You can use GETFRAME function. It returns movie frame structure, which is actually rasterized figure. Field cdata will contain your matrix.
F=getframe;
figure(2)
imagesc(F.cdata);
What are the desired characteristics of your target matrix ? And what sort of images do you want to rasterise ?
You see, for the only example you have given us it's almost trivial to define a matrix representing your image ...
1. figmat = ones(10,10,3) % create a 10x10 raster where each entry is a triple for RGB, setting them all to 1 colours the whole raster white
2. figmat(2:5,2:5,1:2) = 0 % sets RG components in the coloured area to 0, leaving only blue
Your matrix is a raster to start with. Now, you can use the built-in function image to visualise your matrix. Have a look at the documentation for that function. And note that my suggestion does not meet the spec for use with image() and colormap().