Contents
Image Overlay
In response my post on "Tracing George", blog reader Riccardo asked me how to overlay the thinned binary image on top of the original image, using a different color. That is, given George:
url = 'http://blogs.mathworks.com/images/steve/36/george.jpg';
I = imread(url);
imshow(I)
and thinned George, using the method given in my previous post:
threshold = graythresh(I);
bw = im2bw(I, threshold);
bw2 = ~bw;
bw3 = bwmorph(bw2, 'thin', inf);
imshow(bw3)
how do you produce a color overlay like this:
Procedure
We want to produce an RGB (truecolor) image. Everywhere the binary image mask is zero, it should look like the original image. Everywhere the binary image mask is nonzero, it should have the specified color.
Start by making three copies of the original image, one for each channel of the desired RGB image.
out_red = I; out_green = I; out_blue = I;
Second, replace the masked pixels in each channel image with the desired color value.
out_red(bw3) = 255; % Class of out_red is uint8, so use 255 instead of 1.
out_green(bw3) = 255;
out_blue(bw3) = 0;Finally, concatenate the channel images along the third dimension to produce the desired overlay image.
out = cat(3, out_red, out_green, out_blue); imshow(out)
File Exchange - imoverlay.m
I've often thought that this image overlay operation would be a good utility for the MATLAB File Exchange. Riccardo's question finally pushed me to write and submit imoverlay.m. I hope some of you find it useful.
help imoverlay IMOVERLAY Create a mask-based image overlay.
OUT = IMOVERLAY(IN, MASK, COLOR) takes an input image, IN, and a binary
image, MASK, and produces an output image whose pixels in the MASK
locations have the specified COLOR.
IN should be a grayscale or an RGB image of class uint8, uint16, int16,
logical, double, or single.
MASK should be a two-dimensional logical matrix.
COLOR should be a 1-by-3 vector of values in the range [0, 1]. [0 0 0]
is black, and [1 1 1] is white.
OUT is a uint8 RGB image.
Example
-------
Overlay edge detection result in green over the original image.
I = imread('cameraman.tif');
bw = edge(I, 'canny');
rgb = imoverlay(I, bw, [0 1 0]);
imshow(rgb)
Get
the MATLAB code
Published with MATLAB® 7.2



How would this apply for uint16 grayscale images. Does it work for uint16 grayscale. Did not get an overlaid image. Just a black image.
Input : Grayscale uint16
using imoverlay
Output: Blackscreen ( even with the “DisplayRange,[] ” option
Thanks
Ashish - It worked OK for me.
>> I = imread('cameraman.tif'); >> I16 = im2uint16(I); >> bw = edge(I); >> rgb16 = imoverlay(I16, bw, [0 1 0]); >> imshow(rgb16) >> imwrite(rgb16, 'imoverlay_uint16.jpg')Is your george.jpg a 2-dimension image?
I tried the code(not the overlay.m) step by step, but the last image “out” is 9 dimension. I just guess it was caused as I didn’t do it by the origianl image but the one you posed here first which is 3-dimension. Am I right?
Thanks ^_^!
Hellen—Yes, george.jpg is a gray scale image, represented as a 2-D matrix. I updated the URL in the post to give the correct current location. Download the image using that URL and give it another try.
Hi Steve,
Is there any way to adjust the transparency of the overlaid color.
Sridharan—Not as the function currently exists. You could modify the code yourself to do the necessary blending of colors.
Hi Steve,
This is Sheetalkumar. I am doing project on “Image Processing” i.e. Implementation of Thinning Algorithm for Gray Scale Images using MATLAB. So plz do needful..
Thanks and Regards
Sheetalkumar.
Is it possible to overlay two grayscale images and have one of the pseudo-colored?
This is for overlaying microscope images. One should remain in gray (background) and the other is a fluorescent image taken with a specific filter = specific color, e.g. green only.
Also, if there are two filters: one image gray, one with green regions, and a third with red regions, would it be possible not only to overlay with pseudo-color, but to have regions where the colors overlap show that (green+red = yellow)?
Thanks,
Daphne
Daphne—You can display one image over another using transparency. See the MATLAB graphics documentation regarding transparency and HG image objects.
Hi Steve
Is there any grayscale thinning algorithm that has been implemented in MATLAB ?
Thanks
Sumit—I don’t know. You might want to search the File Exchange.
Hi Steve.
I have a bmp image and a vector of points. I want to plot the points on the image and save the results. I tried with:
h=figure();
I=imshow(filenameIN);
hold on;
plot(x,y,’r-+’);
hold off;
saveas(h,filenameOUT);
It works fine if I don’t close MATLAB and I do anything else. But if I open, say, a web page while MATLAB is running this commands, I get this webpage saved on the output image.
Is there any way to solve this problem (possibly without using imshow but using imread instead, cause I’m not interested in displaying the image)?
Thanks in advance for your help.
Mari—I recommend that you use print. With the right option switches, you can print to a file using a specified image format.
Hi,
I have 2 images in tiff format. Both files are in grayscale. one of the image is a bright field image and the other is a fluoresce image. I had wanted to add a green pseudocolor to the fluoresce part of the image and overlay it with the brightfield image. is there anyway to work around it? I am new to matlab.
Thanks in advance
James—You might want to look at the transparent image overlay technique I used in this post.
Steve,
Would it be possible to create an overlay which has varying color which corresponds to data values?
As an example, if I wanted George to have an outline color which varied with the distance from the bottom of the image.
Andrew—Sure. There are a variety of ways in which you might do that. Do you have a specific question about it?
I’m having trouble seeing how I can keep the original grayscale image, but then have parts of the image which have color based on data values (which would then be linked to a colorbar for a reference of the values).
I think an explanation of how to go about the example I posed in post 16 may be sufficient to get me started on what I need to do without going into it too much.
Andrew—I suggest that you convert your grayscale image to RGB form by setting the red, green, and blue components to the original image. Then, depending on what colors you want, you can modify the red or green or blue components corresponding to the overlay pixels to be whatever you wish. Here’s a skeleton:
Steve,
I think the best way to display my image with the data would be to have two colormaps. Is there a way I can set the values in my image which are between 0 and 1 to a grayscale colormap, and then set values from 1 to max(I(:)) to a jet colormap?
I have been messing around with creating colormaps (ex. map = [gray(256);jet(256)], although I don’t know how I would go about setting the limits of the pixel values {0 to 1 and 1 to max(I(:)} to the locations in the colormap.
I’ve read this:
http://www.mathworks.com/support/tech-notes/1200/1215.html#Useful_Properties
but am not sure how/if it can be applied to a single image where there is only one axis.
Andrew—A MATLAB figure window can have only one colormap at a time, so I still suggest that you convert your image to RGB form.
Hi Steve,
I have created a GUI to work on a series of 40 frames of MRI images of the heart (short axis if you want to know). I want to draw an ROI around the aorta (which can be identified as your run the images as a movie) and copy the contour across the 40 frames. The problem is I am not sure how to adjust the ROI and save them. for eg. if the 23rd frame has no blood flowing , it would appear black, I have to indicate that the valve is closed i.e ROI will be really small. Are there any MATLAB functions that would help me out with this? Basically, I want to draw ROI’s across the 40 frames and compute velocity of blood flow thru the aorta. Thanks.
Vijay—You might find the function impoly (and its other ROI cousins) to be useful for programming ROI functionality in a GUI.
Thanks Steve. I use roipoly function but I dont find impoly and it’s associate functions on my version of MATLAB. Also, once I draw a border, how do I adjust it according to the shape of the object in the background and save the limits of the boundary.
Thanks.
Vijay—impoly and related functions were added relatively recently, so you’ll have to upgrade to get them. Otherwise, you’ll have to do your own GUI programming. You might try searching the MATLAB Central File Exchange for some useful code.
Steve, is it possible to overlay text and graphics on a live video stream? I an the video stream coming in from USB and can display it, I would like to develop a gui to be able to place spots and area tools and view the results in real time.
Gerard, Video and Image Processing blockset, a Simulink product, specifically has three components designed to annotate your video in real time: Insert Text, Draw Shapes, Draw Markers. You can inject strings with selectable fonts, and draw rectangles, polygons, lines, circles, etc.
Have a look here: http://www.mathworks.com/products/viprocessing/
Witek
Hi Steve,
I am building a mask very similar to what is described here, I wanted to know if this could be extended to make a multivalued mask instead of a binary one. I will need at least 3-4 levels in my mask. How should I go about this?
Thanks
Rushil—Sure, this technique could be extended to multiple levels. Can you be more specific about the task and about what part you need help with?
Thanks for your reply Steve,
Here one can overlay a binary image as a mask. I have a similar task at hand, only difference being my “mask” needs to be multi-valued, not binary. It has certain gray levels too, currently it has about 3 levels between black(0) and white (1). The data I will be using to plot a mask is not discreet with zeros and ones. What i need is when the value is 0.5 i can see the image partially. I was thinking of doing this pixel wise, and rebuilding a new image while checking for values of the mask. What do you think?
Thank you.
Rushil—Your comment about “seeing the image partially” makes me think you might be interested in displaying one image transparently over another. See this post for examples.
Steve,
Yes, that is what I am looking to do but My “Mask” is not an image, it is a contour of densities (from the contourf function)so is there any way I can adapt what you had showed in “Image overlay using transparency” to suit my task?
Thank you for your help.
Rushil
Rushil—In that case, you might want to explore other options for transparent object display in MATLAB.
Hello:
This overlay looks to be just about what I need.
I have a grayscale image that I currently use imagesc to display, using a stock colormap (jet). The values vary from 0 to perhaps 0.010 across the image. However, my object does not fill the entire image. All pixels outside the object are set to 0 using a mask. The data displayed is an error signal at each pixel.
Now, the issue is that as my object improves, the error at some (many, I hope) pixels approaches 0, and so those pixels are indistinguishable form the background or masked-off areas outside the object. I could set the masked areas to -1, and use CLIMS 0 to 0.010, but this still sets the masked areas to the 0 color.
Your overlay should do exactly what I need for the image. However, how do I now display a colorbar to indicate the original scaled colormap?
Thanks
Chuck
Chuck—My overlay code here produces a “truecolor” image, which is an M-by-N-by-3 array. The first plane is the red component, the second plane is the green component, and the third plane is the blue component. The color of each image pixel is determined directly from these values, rather than indirectly via the figure colormap. Unfortunately, this means that colorbar doesn’t work directly with such images.
So you need to do little extra work. One approach is to display the image as you already do, using imagesc and the desired colormap. Call imagesc with an output argument so you can save the handle to the created image object. Then call colorbar. Finally, set the CData of the image object to the overlay image created using the code shown in this post.
Hi Steve,
Can you please tell me how can I make imoverlay output line thicker?
Robbe—Dilate the mask:
Thanks Steve !! it worked perfectly