Matlab: imgradient returns quantized images - matlab

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.

Related

MATLAB: Combine Two Grayscale Images With Different Alpha

I started writing a program in MATLAB to overlay two grayscale images of same size with different alpha dynamically. Therefore both images are plotted in one figure and beneath them is a slider with which the alpha of the second image can be increased from zero to one. So when moving the slider one can actually sees the two images blending. Suppose the slider is at 0.3 then the 'AlphaData' of the second image is set to 0.3, while the 'AlphaData' of the first image is always 1. On the screen I now see an image, which is a combination of these two images.
Now I want to get exactly this image from the figure (with the same size, as the images before) and work with it. But I have no idea how to do it.
Grayscale image is just array of numbers. Depending on how you get the data it could be 0~1 or 1~255. Overlaying two images is merely adding the numbers. Blending two images is merely computing their weighted sum.
clear;clc;close all
I1_rgb = imread('peppers.png');
I1_gray = rgb2gray(I1_rgb);
figure(1)
imshow(I1_gray)
I2_gray = imread('coins.png');
I2_gray = padarray(I2_gray, size(I1_gray)-size(I2_gray), ...
'circular', 'post');
figure(2)
imshow(I2_gray)
alpha = .3; % this can be dynamically adjusted by a slider
O1 = I1_gray + I2_gray*alpha; % overlay
figure(3)
imshow(O1)
O2 = I1_gray*(1-alpha) + I2_gray*alpha; % blend
figure(4)
imshow(O2)
For mixing colored images, see my answer at MATLAB: Applying transparent mask over an RGB image and blending with another

imshow() displays a white image for a grey image

I have computed an image with values between 0 and 255. When I use imageview(), the image is correctly displayed, in grey levels, but when I want to save this image or display it with imshow, I have a white image, or sometimes some black pixels here and there:
Whereas with imageview():
Can some one help me?
I think that you should use imshow(uint8(image)); on the image before displaying it.
Matlab expects images of type double to be in the 0..1 range and images that are uint8 in the 0..255 range. You can convert the range yourself (but change values in the process), do an explicit cast (and potentially loose precision) or instruct Matlab to use the minimum and maximum value found in the image matrix as the white and black value to scale to when visualising.
See the following example with an uint8 image present in Matlab:
im = imread('moon.tif');
figure; imshow(im);
figure; imshow(double(im));
figure; imshow(double(im), []);
figure; imshow(im2double(im));

MATLAB: Show colorbar of a grayscale image in a figure containing a RGB image

Suppose we have two images:
1) RGB Image:
% initialize RGB image:
rgbIm = zeros(100, 100, 3);
rgbIm(20:80, 20:80, 1) = 1;
2) Grayscale Image:
% initialize grayscale image:
grayIm = zeros(100);
grayIm(20:80, 20:80) = 1;
Lets show both of them:
figure, imshow(rgbIm), colormap('jet'), colorbar;
figure, imshow(grayIm), colormap('jet'), colorbar;
As we can see, the colorbar in the 2nd figure (i.e. grayscale image) makes total sense. On the other hand I can't really understand the information given by the colormap in the 1st figure.
What I would like to achieve is to display the colorbar of the grayscale image in the figure corresponding to the RGB image.
It might seem that this does not make sense but this is just a very minimal example that I just made up to show what I would like to do in a larger project.
Any thoughts?
Thanks a lot :)
EDIT1: Allow me to explain why I would need this
Suppose I compute some physiological parameters one MRI slice in certain regions of interest, yielding something like this:
Now I want to superimpose these parameters on top of the original slice, and I create one RGB image to achieve this:
The colormap does not make sense, and this is why I would like to display the colormap corresponding to the parametric image in the RGB image (i.e. the superimposition image).
Any ideas?
Thank you for your attention.
I still think what you are asking does not make sense.
Let me explain:
What is colorbar? Colorbar is a representation of a function (mapping) from gray-level (scalar) to color. Using jet, in your example, you map the 0 to dark blue and 1 to red.
By asking for a colorbar for an RGB image, you are actually asking for a mapping from RGB triplet to RGB color -- this mapping is the identity mapping! you do not need a colorbar to see this mapping, each pixel represent it!
EDIT
After seeing the edited question, I revise my answer a bit:
Since both MRI signal and whatever physiological parameters you computed makes no sense in RGB space, you have two 1D mappings:
1. MRI signal at each voxel to gray level ("gray" colormap)
2. Physiological measure at each voxel to "jet" color
What I usually do in this cases is convert the 2D MRI slice into RGB gray image by simply replicate it along the third dimension
rgbSlice = twoDSlice(:,:,[1 1 1]);
Now show the images on top of each other
figure;
imshow( rgbSlice );
hold on;
h = imshow( physiologicalParams );
colormap jet;
set(h, 'AlphaData', .5 );
colorbar
You might need to play with the color mapping of the axes using caxis or clim to get it right.
(Answering my own question so I can hopefully help someone in the future)
I just accomplished what I intended, with the help of the above answer and a post from Steve Eddins' blog.
Here's how:
baseImage = baseImage/(max(baseImage(:))); % normalize base (anatomical) image
rgbSlice = baseImage(:,:,[1 1 1]); % converting to RGB (ignore colormaps)
imshow(parameterROIImage, []); % show parametric image
colormap('jet'); % apply colormap
hold on;
h = imshow(rgbSlice); % superimpose anatomical image
set(h, 'AlphaData', ~bwROIlocations); % make pixels in the ROI transparent
colorbar;
where parameterROIImage is:
bwROIlocations is the logical matrix containing the ROI pixels:
Final result:
Thanks for the help Shai.

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:

An explanation for this MATLAB code snippet

Consider:
%# load a grayscale image
img = imread('coins.png');
%# display the image
figure
imshow(img,[]);
%# false-color
colormap('hot')
The above code is from here:
Infrared image processing in Matlab
But I don't understand how figure (what's the difference with/without it?) and colormap (how does it affect the already shown image?) work?
figure is not required, imshow just displays img on it. If a figure hadn't been opened, imshow would've created a new one.
The colormap colors the intensities of the image. The hot map colors values in increasing intensity with black, red, yellow, and white-hot. Another popular colormap is jet which has a number of interesting colors.
False colors
So the matrix you want to see has intensities which can have any range of values. For better visualization, the intensities are displayed in a range of colors or a set of false colors. Normally, a grayscale image will display an image is shades of grey, where white is maximum and black is minimum. False color is an extension of that concept with several colors in between (like jet) and an effect of metal being heated in hot.
Colormap at the pixel level
Suppose you have a matrix with pixel values ranging from [cmin xmax]. Now, normalize the values so that the range is [0,1]. Also, suppose you have a color map, such that a range of colors are mapped to some values from 0 to 1 (e.g. 0.5 is mapped to RGB(100,200,100))- then you get the false color mapping by finding the closest intensity in the map and display the corresponding color.
More on colormap in the MATLAB documentation. I've included some picture from that link here:
Jet
(source: mathworks.com)
Bone
alt text http://www.mathworks.com/access/helpdesk/help/techdoc/ref/bone_spine.gif