In March 2006 I wrote about how to overlay a specified color onto specified pixels of a grayscale or RGB image. I put a utility function (imoverlay) for performing this operation on the MATLAB Central File Exchange.
Earlier this week, Matt W. posted a review of that submission, suggesting that additional documentation might be helpful for people displaying image data that's not in the range [0, 1]. MATLAB users often call imagesc to "autoscale" image data, and Image Processing Toolbox users can call imshow(I,) to get a similar effect.
Here's an example using imagesc.
L = membrane(1, 100); imagesc(L), axis equal, colormap(hot) axis equal
Note that L has negative values.
ans = -0.3338
ans = 1
imagesc automatically scales the values of L "into" the colormap, so that the minimum value is displaying using the first colormap color and the maximum value is displayed using the last colormap color. (See my post about scaled indexed images.)
Although Matt's specific suggestion was about getting imoverlay to work with this data, there's a more general concept here about how to save images like the one above to image file formats, such as JPEG or PNG. Image file formats have generally much less flexibility than MATLAB about displaying pixel values as colors. In particular, the most common formats don't have the notion of scaling an arbitrary range of data values into a colormap. In addition, the JPEG format doesn't even have the notion of using a colormap at all.
We could try writing the L values directly into a JPEG file, like this:
imwrite(L,'membrane1.jpg') imshow membrane1.jpg
But we lost all the color information, and there's no automatic data scaling. All the values of L less than 0 were simply clipped to black in the JPEG file.
So how can we turn L and the hot colormap into something that can be stored in a JPEG file?
We can do it in three steps:
- Scale L into the dynamic range [0, 1] by using mat2gray.
- Convert the result into a normal (unscaled) indexed image using gray2ind.
- Convert the indexed image into RGB form by using ind2rgb.
gray = mat2gray(L); X = gray2ind(gray, 256); rgb = ind2rgb(X, hot(256)); imwrite(rgb, 'membrane2.jpg') imshow membrane2.jpg
Now that the membrane image is in RGB form, we can use imoverlay. For example, let's overlay all the negative pixels with a light blue color.
mask = L < 0; light_blue = [.6 .6 1]; overlay = imoverlay(rgb, mask, light_blue); imwrite(overlay, 'membrane3.jpg') imshow membrane3.jpg
Of course, every time you launch MATLAB you see this membrane shape in a more familiar form that looks something like this:
membrane(1,50) colormap(hot) camlight shading interp
The L-shaped membrane has played a fascinating role in the history of MATLAB and The MathWorks. If you are interested in the origins and history of MATLAB, you should check out the Origins of MATLAB video by MATLAB creator and company co-founder Cleve Moler.
Get the MATLAB code
Published with MATLAB® 7.4
Comments are closed.
5 CommentsOldest to Newest
hi u might be able to help me out here,,, as we do axis ij to make y axis start from top,,, is there any way we can do same for Z axis for 3D plot ????
I am using Matlab 7.0 and I have a question concerning imagesc. I am loading an image file and I want to adjust the values of the image to improve the contrast and then save the adjusted image as a .png. I am able to adjust the contrast quite well using clims with imagesc but I cannot figure out how to save the adjusted image. Is it possible to do this?
William—You can do the contrast adjustment arithmetic yourself directly on the image data and then use imwrite. Or you could use print -dpng to print a MATLAB figure window to a file. Or if you have Image Processing Toolbox, you can use the constrast adjustment tool in imtool and then save the resulting image.
I have a 64×64 pixel image scanned for set of frequencies. I can use imagesc to plot the image for a single selected frequency. I want to plot the same image in 3D with x&y axis as 64×64 pixel size, and stack the images for all frequencies(z-axis). In Radar, image is plotted for Range(scanning distance)info in the z-axis. Similarly I want to do the same for set of frequenices.
I tried using all 3d plotting method, but can’t plot what I expect.
I would appreciate if you could you throw some ideas……