This is a short tutorial that documents how to make a MATLAB plot on top of an image background. This can be useful for a variety of things but when I first learned about it, I was a bit confused by how the axes seem to be flipped sometimes when you do this. In this tutorial I will give several examples that should illustrate how to plot on top of an image properly. I have used this technique for a few things, such as visualizing 1D and 2D classifier decision boundaries when I was preparing my thesis. I have also written a tutorial on how to do a 3D version of this in which an image is shown as a plane in a surface plot.
First, make a new .m file and load any image you want. In this example, I used a gray scale version of one of the images in my artwork gallery, specifically Gentoo Kung Fu, because it is easy to see which way is up in the image unless you think it is possible for a penguin to take on three guys in hand-to-hand combat while standing upside down. You should try it with your own image. Put the following into the .m file:
% replace with an image of your choice img = imread('myimage.png'); % set the range of the axes % The image will be stretched to this. min_x = 0; max_x = 8; min_y = 0; max_y = 6; % make data to plot - just a line. x = min_x:max_x; y = (6/8)*x;
The above code defines the axes range that the image is stretched to and creates some (x, y)
data to plot. The code examples that follow use the above data and variables.
The following code creates the plot itself. (0,0) starts at the bottom left as expected for a regular plot.
plot(x,y,'b-*','linewidth',1.5);
Before getting started with some examples, first show the image in a MATLAB plot to take a look at how the image array (matrix) is actually stored in MATLAB:
figure; imagesc(img); xlabel('Raster Column'); ylabel('Raster Row'); colormap(gray);
The above code produces this:
The coordinates given by (Raster Row, Raster Column) are the 0-based image coordinates. The image array is stored with (0, 0) as the top left corner of the image. In MATLAB's internal memory, (0, 0) corresponds to subscript (1, 1).
It is necessary to understand a bit about what MATLAB is doing when you tell it to show an image and add a plot on top of it. Sometimes the result is wrong and here are some examples with an explanation of why.
Example 1
The first example that shows an image as well as a MATLAB plot.
imagesc([min_x max_x], [min_y max_y], img); hold on; plot(x,y,'b-*','linewidth',1.5);
Here, the imagesc
command is issued in imagesc(x,y,C)
form, which will specify the range of axes labels that the image is displayed within (determined here by [min_x max_x]
and [min_y max_y]
). The hold on
command is issued and then the (x, y)
data are plotted. This is the result:
You will notice that the plot and the Y-axis are now upside down but the image is displayed properly. The reason is when imagesc
is used, MATLAB has reversed the Y-axis so that Y gets larger as you move down. This corresponds to making the Y-axis increase in the same direction as image raster coordiantes. When the plot is made, it is using the new, reversed Y-axis, thus explaining why it is flipped.
Example 2
We can tell MATLAB to flip the axis back to normal, as in the following code with set(gca,'ydir','normal')
:
imagesc([min_x max_x], [min_y max_y], img); hold on; plot(x,y,'b-*','linewidth',1.5); % set the y-axis back to normal. set(gca,'ydir','normal');
This is the result:
Now the image is flipped. That's because when the Y-axis is set back to normal, it affects how MATLAB displays the figure. Y is small at the bottom and large at the top, so MATLAB will show the image upside down. It turns out the Y-axis direction specifies how MATLAB displays the image; the image raster row axes is always displayed in the same direction as the Y-axis. In other words, the image is displayed in such a way that the smallest raster row (which is 0) is at the smallest Y value visible on the axes, and the largest raster row is at the largest Y value visible on the axes.
Example 3
The hold on
command should be issued after the image is displayed. Otherwise, the figure will retain the default set of axes when you display the image, without adjusting to the width and height of the image.
For example, try moving hold on
to before the imagesc
command in Example 2:
hold on; % hold on before the image causes incorrect results imagesc([min_x max_x], [min_y max_y], img); plot(x,y,'b-*','linewidth',1.5); % set the y-axis back to normal. set(gca,'ydir','normal');
The result will look like this:
In order to resolve the problem from Example 2, the image can be flipped before displaying with the flipud
command:
% Flip the image upside down before showing it imagesc([min_x max_x], [min_y max_y], flipud(img)); % NOTE: if your image is RGB, you should use flipdim(img, 1) instead of flipud. hold on; plot(x,y,'b-*','linewidth',1.5); % set the y-axis back to normal. set(gca,'ydir','normal');
Here, the image is flipped first before displaying, so that the bottom of the image is now Y = 0. Then, the y-axis is set back to normal (where Y = 0 is at the bottom). This means that the bottom of the image (which is now Y = 0 due to flipud
) is at the bottom of the plot. The result:
This correctly shows the image and the plot. A few readers have pointed out that if your image is RGB, you can use the flipdim
command instead of flipud
:
flipdim(img,1);
One caveat: Although Example 1 and Example 2 from the previous section are called “incorrect”, they may actually give you the right result in some cases. The image in this tutorial depicts a scene that independently has a “right side up”. Image Row 0 must always be displayed at the top. There may be cases where the image you want to show is created within MATLAB and Image Row 0 might simply need to be associated with the smallest Y-coordinate shown on the axes. In that case, Example 1 or Example 2 might give you want you want. An example might be when you need to visualize classifier decision boundaries. In any case, the information in this tutorial should be enough to figure it out if needed.
Discussion
plz guide me
http://www.mathworks.com/matlabcentral/fileexchange/289-ellipse-m
Just great, I was looking for a simple solution like this. You make my day
help imellipse
doc imellipse
Is it possible to do this:
1. show an image a
2. plot over this image a
3. replace image a with an image b while keeping what I plotted in step 2.
I have number of points coordinates measured in millimeters and would like plot them on the image. The coordinates are already stored in text points and they represent points appear in the image.
Eric
:)
just to improve a little bit, though, you need to use flipdim(img,1) instead of flipud if you are using an RGB image.
It was generous of you to put your code and tutorial on the web. I wanted to overlay a simple plot onto a photo image. (Thought it would make an apt and upmarket image for a report I had to do).
I was able to do that and then do so with a bit of a twist; namely, locating the plot to wherever I wanted within the photo and then to have the background of the plot clear so that the photo still came through.
To be frank, I would never have been able to do it without your examples as a template.
thanks
WG
Thanks!
http://www.mathworks.com/matlabcentral/newsreader/view_thread/159944
Thanks!
Is there any way to rotate an axes in MATLAB?
If the pic matrix is 3-D and the order "flipud" must be 2-D matrix,
does it still work?
With this code:
img = imread('raia.png');
min_x = 0;
max_x = 80;
min_y = 0;
max_y = 60;
x = min_x:max_x;
y = (6/8)*x;
plot(x,y,'b-*','linewidth',1.5);
figure;
imagesc(img);
xlabel('Raster Column');
ylabel('Raster Row');
colormap(gray);
% Flip the image upside down before showing it
imagesc([min_x max_x], [min_y max_y], flipud(img));
hold on;
plot(x,y,'b-*','linewidth',1.5);
% set the y-axis back to normal.
set(gca,'ydir','normal');
Matlab says:
??? Error using ==> flipud at 19
X must be a 2-D matrix.
Error in ==> raia at 20
imagesc([min_x max_x], [min_y max_y], flipud(img));
your new friend from Iran,
Hossein.
For example: I have number of images to point or plot on. and I do not want to do the same work again. I use impoint function for points and then plot between them. Now I move to next image in sequence. and the plot is lost. How do I retain the plot?
first thank you for creating such a nice web site . However I woul like to ask you about an exercise that I am asked to give to my teacher as my last project of the year but I find some difficulty .
here is the exercise :
a/ find or take a picture of your self with a plain background such as green screen, using the JPEG image format.
b/Find a JPEG image of the place that you dream of and decide on the rectangle in the scene where your image should appear. save the width and height of the rectangle and row and column of its top left corner .
c/Re-size your image to be the width and height of the rectangle
d/Use the color masking technique to copy your image without the green screen into the selected rectangle of your dresm scene .
It would be great If you comment on code
thank you so much and I hope you can answer my questions because this is my last chance to get my marks !
http://www.peteryu.ca/tutorials/matlab/image_in_3d_surface_plot_with_multiple_colormaps
You'd have to figure out how to show the colorbar in the figure.
I'd throw a picture on a page and rotate it.
I did this with the SURF Function
But when you rotate the image,
Image is missing.
que dieu te protege
الله يخليك
I had rotate my image at a particular degree but the problem is that it had got stretched like circular object become Elliptic,
xscale = 1;
yscale = 1;
rotation = 30;
oldimg = imread('myimage.png');
theta = rotation*pi/180;
As = [xscale 0; 0 yscale];
Ath = [cos(theta) -sin(theta);sin(theta) cos(theta)];
A = Ath*As;
T = eye(3,3);
T(1:2,1:2)=A;
tform=maketform('affine',T);
newimg = imtransform(oldimg,tform);
size(newimg)
figure,imshow(newimg);
How would you save the final image, after hold on?
Thanks,
load coast
imshow(th_world(:,:,1));
hold on
worldmap('World');
plotm(long,lat);
hold off
how can i but an image in a 3D plot ??
I have disparity map of the plant leave, how can I draw plane that include the majority of these point i have no idea how to start, can you help me please
Thanks for your great tutorial, do you have any idea how to set up the image axes to be (log log). I need to plot some points on image that shows log-log graph.
Regards
I'm just would to ask if we can take a data from the image (X-components,Y-components of some points on the image), where my image is curve.
your tutorial is great!!!
Thank you very much for sharing it!
what to do if same line are taken or draw on the sequence of frames of video??
How can I plot data over a map and set the scale of graph and map the same? Also I want to be able to change the origin of graph so that I can place it to right location of map. Suggestions and hints will be gladly appreciate.
thank you
I want to say that I found you tutorial extremelly helpfull and a very good start for my task.
My problem is the following. I have my image streched correctly along the axis but when I try to overlay a 2D surface(with trasnparency) plot with the 3rd dimension as colour the result is that I see the picture behind the graph as I should but the plot seems to be in one colour only.
I'll send you my code.
I hope you can give me an answer or at least sth to look.
Thank you in advance.
Chris
min_x = 1;
max_x = 4;
min_y = 1;
max_y = 4;
C = imread('C:\Users\user\Desktop\greece.jpg');
imagesc([min_x max_x], [min_y max_y], flipdim(C,1));
hold on;
set(gca,'ydir' , 'normal');
%set(gca,'ydir' , 'normal');
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
pcolor(X,Y,Z); shading interp;
alpha(0.4);
imshow(s)
hold on;
for x = 1: numel(stat)
plot(stat(x).Centroid(1),stat(x).Centroid(2),'r*');
end
I would really appreciate if you could help me with that please in terms of suggested Matlab code.
Thanks in advance and kind regards,
Younis
Reversing the order of the coordinates min_y and max_y also flips the image up/down:
image([min_x max_x], [max_y min_y], img);
Clarification:
Plotting at this point will be upside down; if you type:
get(gca)
you can note that that the y axis property YDir is 'reverse'.
Thus the need for:
set(gca,'ydir','normal');
how can you advice me?
thanks again
Thank you.
I wanted to overlay weather station sites on a user-friendly map from the tourist office. Simply set min and max lat and longs) which entailed a bit of inspection on Google Earth) and and Hey presto - geo-located weather towers on the tourist map.