Several people have asked me recently how to plot some kind of shape on top of an image, so I thought I'd show the basic technique here. Essentially, you display the image, then call hold on, and then use plot or some other graphics command to superimpose the desired shape.
For my first example, I'll superimpose the boundaries found by the bwboundaries function on top of the original binary image.
bw = imread('circles.png');
b = bwboundaries(bw);
imshow(bw)
Now call hold on. This causes subsequent plotting commands to add to what's already in the figure, instead of replacing it.
hold on
Finally, call plot to superimpose the boundary locations.
for k = 1:numel(b) plot(b{k}(:,2), b{k}(:,1), 'r', 'Linewidth', 3) end
It's good to get in the habit of calling hold off when you're done adding plot elements. That way, the next high-level plotting command will start over, which is usually what is expected.
My second example shows how to superimpose a 25-pixel-by-25-pixel grid on an image. (See Natasha's blog comment.) Display the image first, and then call hold on.
clf rgb = imread('peppers.png'); imshow(rgb) hold on
Now superimpose the grid. To make sure the grid is visible over all pixel colors, I'll use the trick of superimposing two line objects with contrasting colors and line styles. The Pixel Region Tool in the Image Processing Toolbox uses this same trick.
M = size(rgb,1); N = size(rgb,2); for k = 1:25:M x = [1 N]; y = [k k]; plot(x,y,'Color','w','LineStyle','-'); plot(x,y,'Color','k','LineStyle',':'); end for k = 1:25:N x = [k k]; y = [1 M]; plot(x,y,'Color','w','LineStyle','-'); plot(x,y,'Color','k','LineStyle',':'); end hold off
Get
the MATLAB code
Published with MATLAB® 7.3

Dear Steve,
I ran into the following peculiar aspect of overlays - if you decide to fill the BW image in your example with single pixel dots using the plot command, you do not obtain a smooth even coverage - it becomes patterned, as if the plot command is interfering with something else. In include a code example below
Your comments are appreciated
mybw = imread(’circles.png’);
b = bwboundaries(bw);
figure(1);
imshow(bw);
[sx sy]=size(mybw)
myhighim=zeros(sx,sy);
Ihigh=find(mybw>0.5);
myhighim(Ihigh)=1;
hold on;
[mycol myrow]=find(myhighim>0);
plot(myrow,mycol, ‘.’,'color’,'red’,'MarkerSize’,1);
Besides the typos, if you use
plot(myrow,mycol, ‘.’,’color’,’red’,’MarkerSize’,10);
instead of
plot(myrow,mycol, ‘.’,’color’,’red’,’MarkerSize’,1);
the circles will be filled in completely when you enlarge the plot. There may be other issues but this worked for me with my video card and screen resolution.
Tom
Steffen - I observed no pattern when I ran your code. If you resized the figure, then I would expect you to see a pattern.
Hello Steve,
I have a question about one function in the image toolbox, that is, canny in ‘edge’. Applying canny edge detector requires two thresholds, low threshold and high threshold. They are derived from PercentOfPixelsNotEdges and ThresholdRatio which is set as 0.7 and 0.4. How do these two values come from? The file is in \MATLAB701\toolbox\images\images\edge.m, and these two values are at 221st and 222nd line. Thank you so much.
Regards,
Tracy
Tracy - I believe those default threshold values were determined heuristically, which is a fancy way of saying that we experimented and picked values that seemed to work well most of the time.
Hi Steve,
When I have to superimpose lines on images I usually use the line function directly. This way the hold command is not required (and remembering to turn it off!!)
So for your first example I would do:
bw = imread(’circles.png’);
b = bwboundaries(bw);
imshow(bw)
for k = 1:numel(b)
line(’Parent’,gca,…
‘XData’,b{k}(:,2),…
‘YData’,b{k}(:,1),…
‘Color’,'r’,…
‘Linewidth’, 3)
end
Keep up the the great , must read, blog
Matt
Good point, Matt - and thanks for the encouragement!
Hi Steve,
one - probably simple - question: how can I plot shapes (e.g., lines) _into_ an image, so it will remain in the img matrix and I can go on working with it? So, to make this clear, I don’t want to superimpose the plot.
Can you help me on this? Thanks alot!
Karl
Karl - You’ll need to superimpose the plot and then use getframe to get a new image containing the superimposed graphics.
Hi Steve!
Thank you for the great article! I’ve been looking all over the internet for a simple way to plot on an image. Keep the great blog entries coming :)
- Jaakko
Jaakko—Happy to help!
Hi Steve,
I have plotted a polygon (say Polygon-A) on an image. Now, I need to plot another polygon (say Polygon-B), on the image such that Polygon-A is not visible. I need to do this without using either imshow or image or imagesc command again. In other words, how can i simply erase Polygon-A and plot Polygon-B without calling either imshow or image or imagesc command again.
Sridharan—Delete the line object created when you plotted Polygon A. For example, you could get the handle returned by plot and then later delete it when you no longer want it visible:
Thanks a lot Steve
Hello,
I have got a problem with the matlab function bwboundaries, correctly with the using of its results.
Perhaps somebody has already a solution.
I have a black-white picture as data and the boundaries are found by the function.
I can correctly display the boundaries included in the original image.
My problem starts, if I want to display only the boundaries. The bwboundaries seems not “take” every information of the picture, so the boundaries are misscaled and rotated but I can’t find a possiblity to get the original size back.
Thank you for the help.
Barbara—I assume you are plotting the x-y locations of boundary vertices using plot. The plot function by default autoscales the plot so that it encompasses just the data being plotted. Set the XLim and YLim properties so that the plotted range is the same as the image, and set the YDir property so that the y-axis increases downward instead of upward. The xlim and ylim functions are convenient for this purpose. If your image has 100 rows and 200 columns, for example, then do this:
Dear Steve,
I would like to seek your help on the following:
I have a JPEG, which I have divided into 30 rows by 60 columns using your method above.
Now, if I would want to highlight a particular rectangle, say (29, 59), how should I do it?
Thanks a lot!
Julius—You could use the techniques in this blog post to plot that rectangle on top of the image. Or you could superimpose a semitransparent patch covering the desired rectangle. See the MATLAB Graphics documentation covering patches and transparency.
Dear Steven,
Thanks a lot for your help!
Dear Steven,
Maybe this is a little bit offtopic, but I have tried to save an image with the grid like you blogged it with saveas.
saveas(fig, savefile, ‘jpg’ );
But if I save the figure, only the image is saved, the grid isn’t saved with. Why? I tried a few other endings but no one was working.
Thanks for your help,
Martin
Martin—I don’t know. I suggest that you contact technical support.
Oh okey,
Thank you for your fast answer,
Have a nice day,
Martin
Martin—I have a two-minute threshold on blog comments. If I can answer in less than two minutes, I do so immediately. Otherwise I move it onto my list to do “later.” :-)
Great work Steve. I just started image processing and matlab and this has been really helpful. Thanks a lot.
Hello Steve,
Could you tell me a little bit more about your grid overlay function? I’m new to matlab so I wouldn’t know how to tweak your commands off hand.
Ideally I’d like display a 1536 box grid (rectangle) overlay of a set of images.
See this link for an image example:
http://bp3.blogger.com/_vyO1vHnACOc/R0qrYUU2uCI/AAAAAAAAADI/g9lzb5HFEV4/s1600-h/halo.jpg
The grid would serve two purposes.
1. To visually correlate a hit (white spot) with the corresponding treatment (which is already mapped out in alphanumeric coordinates A1, B2, etc)
2. To use the quadrant as a way of keeping track or bounding elements that are identified using the “numObjects” and “regionprops” functions.
Thanks for your help,
Andrew
Also see my superimposed grid:
http://bp3.blogger.com/_vyO1vHnACOc/R0quDUU2uEI/AAAAAAAAADY/-uOxQUy_CLc/s1600-h/halo_w_grid.jpg
How can I align the grid such that the dots are in the center of each box? Thanks so much!
Andrew—It looks to me like you face an image analysis problem before you can even know where to draw the grid. You need to detect the dot spacing and possibly the dot grid rotation. You might want to look at the DNA microarray case study on the MATLAB Central File Exchange.
There’s not much going on in the code in this post. There are basically three steps:
hi,,
my project is face recognition using dct.
i have to extract features like eyes, nose, mouth and take dct of those coefficients. using impixel i can get the pixel value for eye centre and i have constucted a matrix which cover eye region.
now my problm is i have to show the traced eye(which is a matrix) region on the face image in the form of rectangle .
how do i do that??
Pallavi—Have you tried the techniques shown in this post for superimposing a line plot on an image?
Can you educate me how to do template matching for two image?
I just want to know which template is the most match to an image. Please help.
Thank you very much.
Tommy—Take a look at the normxcorr2 function.
Yes, i have tried over this function. Actually, I want to get the highest correlation score within the templates to determine the person of the full face image. I use it on face recognition. However, I am not quite sure how to write it in Matlab. In C, I used affine transform to patch the template on the image and calculate the correlation score. Do you mind to write me or show me where to get such references on template matching algorithm in programming?
Thank you very much.
Tommy—I still don’t see how what you’re describing is different from normalized cross correlation. If you want to see how to program that, look inside normxcorr2.m.
Dear Steve
I’m working with an image of a shaft and the purpose is to measure its diameter. I have problem with the image because it is shining on the top . I tried many ways but no one was working.Hope you can help me.
Hi Steve,
grid works fine, thx. Is it possible to make eache square a button, so i can extract the accordant tile image from the complete image? Would be very nice, if you have some ideas about that.
Thx
Localhorst
Localhorst—You can give the image object a ButtonDownFcn and then program the callback to do whatever you want, including extracting tiles.
Hey Steve,
Is it possible to superimpose a 3D contour onto a real time image?
Thanks
Jon
Hi Steve,
I’m doing motion estimation using block matching and need to create a grid of arrows to represent the motion vectors.
Can you tell me how to plot arrows with using only the start and end co-ordinates?
I tried using the line ‘Marker’ property, but it marks both the ends of the line!
Thanks a lot.
Aditya
Aditya—Use an ‘arrow’ annotation.
Jonathan—I don’t understand your question. What do you mean by “3D contour” - an isosurface? And what do you mean by “real time image”?
Is it possible to superimpose a image onto the XY plane in a 3d plot?
I would like to draw “bars” over certain parts of an image, to show values at those given locations. i was planning on drawing the bars manually, ie, plotting points from z = 0 to the height, for a given x and y.
What about if i would like to create an animation? Ie, the bars change height with time.
Dan—Handle Graphics image objects are rendered only in 2-D views. However, you can texture map on image onto a flat surface object to get a 3-D graphic. Take a look at the documentation for surface.
I am ploting trajectories, an in every timestep I would like to plot the background image corresponding to the most recent point in time.
When I use imshow, all lines ploted in the past are cleared, although I have “hold on”. How can I keep them and only update the background image? Thanks!
Steve,
Sorry for the confusion. I want to overlay a Matlab plot onto a real time video feed. So basically I want to acquire video and then onto these real-time images I want to place a MATLAB plot. I hope this helps.
Jon—You can use the Image Acquisition Toolbox to acquire video. Then you can use standard Handle Graphics functionality to display the video images with superimposed plots. I suggest that you update the CData property of the HG image object directly, instead of calling image (or imshow) for each video frame.