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