Steve on Image Processing

March 28th, 2006

Image overlays

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

38 Responses to “Image overlays”

  1. Ashish replied on :

    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

  2. Steve replied on :

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

    uint16 result

  3. Hellen replied on :

    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 ^_^!

  4. Steve replied on :

    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.

  5. Sridharan Kamalakannan replied on :

    Hi Steve,

    Is there any way to adjust the transparency of the overlaid color.

  6. Steve replied on :

    Sridharan—Not as the function currently exists. You could modify the code yourself to do the necessary blending of colors.

  7. Sheetalkumar replied on :

    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.

  8. Daphne replied on :

    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

  9. Steve replied on :

    Daphne—You can display one image over another using transparency. See the MATLAB graphics documentation regarding transparency and HG image objects.

  10. Sumit replied on :

    Hi Steve
    Is there any grayscale thinning algorithm that has been implemented in MATLAB ?
    Thanks

  11. Steve replied on :

    Sumit—I don’t know. You might want to search the File Exchange.

  12. Mari replied on :

    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.

  13. Steve replied on :

    Mari—I recommend that you use print. With the right option switches, you can print to a file using a specified image format.

  14. James replied on :

    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

  15. Steve replied on :

    James—You might want to look at the transparent image overlay technique I used in this post.

  16. Andrew replied on :

    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.

  17. Steve replied on :

    Andrew—Sure. There are a variety of ways in which you might do that. Do you have a specific question about it?

  18. Andrew replied on :

    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.

  19. Steve replied on :

    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:

    red = I;
    green = I;
    blue = I;
    [y,x] = find(overlay);
    red(overlay) = some_function_of_y(y);
    rgb_image = cat(3, red, green, blue);
    
  20. Andrew replied on :

    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.

  21. Steve replied on :

    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.

  22. VIjay replied on :

    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.

  23. Steve replied on :

    Vijay—You might find the function impoly (and its other ROI cousins) to be useful for programming ROI functionality in a GUI.

  24. VIjay replied on :

    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.

  25. Steve replied on :

    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.

  26. gerard replied on :

    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.

  27. Witek Jachimczyk replied on :

    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

  28. Rushil replied on :

    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

  29. Steve replied on :

    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?

  30. Rushil replied on :

    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.

  31. Steve replied on :

    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.

  32. Rushil replied on :

    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

  33. Steve replied on :

    Rushil—In that case, you might want to explore other options for transparent object display in MATLAB.

  34. Chuck replied on :

    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

  35. Steve replied on :

    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.

  36. Robbe replied on :

    Hi Steve,

    Can you please tell me how can I make imoverlay output line thicker?

  37. Steve replied on :

    Robbe—Dilate the mask:

    thicker_mask = imdilate(mask, ones(3, 3));
    
  38. Robbe replied on :

    Thanks Steve !! it worked perfectly

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Steve Eddins manages the Image & Geospatial development team at The MathWorks and coauthored Digital Image Processing Using MATLAB. He writes here about image processing concepts, algorithm implementations, and MATLAB.

  • Sana: hi steve, could you explain to me how i would be able to use the dir function, to do a loop through a directory...
  • Nishtha: Sir, I have preprocessed the image in following steps: [1] adaptive histogram equalization [2] thresholding...
  • Kristof: I also strongly support the idea. I have just recently bumped into the problem that im2single was not...
  • Steve: David—I’ m glad you found it useful!
  • David Lalejini: I found your example very useful for finding connected nodes in a large set of input pairs. I start...
  • tommy: Dear Steve, I have a question,please if you are kind to help me regarding the accumulator array dimensions of...
  • Steve: Abc—I don’t know how to distinguish the faces. You might try posting your question in the MATLAB...
  • Manju: well if we have a few ovals within each other like in a cell how do we measure the distance from the center...
  • Steve: Manju—What do you mean? How is each region defined?
  • Manju: if we have 2-3 regions within each other how do we measure the regions of each one?

These postings are the author's and don't necessarily represent the opinions of The MathWorks.