how to add png file to matlab plot - image

how do i add an image to a plot i made in matlab? the image is from wikipedia:
And below is the code i came up with for the plot i made.
x= 7:0.1:27;
y= normpdf(x,17,exp(1));
title('Normal Distribution')
hold on
xlabel('x')
ylabel('y')
plot(x,y)
I think the script i need to use should be something like this but it's not working. Any ideas? thanks
title('addition: $1+1=2$', 'interpreter', 'latex')

Are you trying to get the image itself to show up in your axes? Or are you trying to have the equation in the image show up in your axes as text? Because to do the first one you'd need:
x= 7:0.1:27;
y= normpdf(x,17,exp(1));
title('Normal Distribution')
hold on
xlabel('x')
ylabel('y')
plot(x,y)
img = imread('http://upload.wikimedia.org/math/7/3/a/73ad15f79b11af99bd2477ff3ffc5a35.png');
img = cat(3, img, img, img);
img = max(img(:)) - img;
img(img == max(img(:))) = 255;
hold on
xRange = [21 29];
yRange = [0.13 0.1];
imgHandle = image(linspace(xRange(1), xRange(2), size(img, 1)), ...
linspace(yRange(1), yRange(2), size(img, 2)), img, 'Parent', gca);
hold off
which reads in the image from the URL given, tweaks it so it shows up as black text on white and then adds it to the axis as an object.
If instead you just want the text of the equation, which is what I think you're after as it is much more elegant, you'd do it this way:
x= 7:0.1:27;
y= normpdf(x,17,exp(1));
title('Normal Distribution')
hold on
xlabel('x')
ylabel('y')
plot(x,y)
text(19, .145, '$f(x, \mu, \sigma) = \frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{(x-\mu)^{2}}{2\sigma^{2}}}$', ...
'interpreter', 'latex', 'FontSize', 14)

Related

Changing a part of an image

How can I paste back a part of my picture after I changed it in MATLAB? I cropped the plates off this image of a car and now I want to put it back automatically. The plates are still at the same coordinates as they were initially, but the background is all black.
The car I want to paste on:
And this is what I want to paste:
Here is my code, I want to change the part where I need to draw by hand the plate.
fontSize = 20;
format compact;
baseFileName1 = 'blurr_plate.jpg';
baseFileName2 = 'car2.jpg';
sourceImage = imread(baseFileName1);
subplot(1, 2, 1);
imshow(sourceImage);
axis on;
caption = sprintf('Source image, %s', baseFileName1);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')
targetImage = imread(baseFileName2);
subplot(1, 2, 2);
imshow(targetImage);
axis on;
caption = sprintf('Target image, %s, original', baseFileName2);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
% Ask user to draw freehand mask.
message = sprintf('In the LEFT IMAGE...\nLeft click and hold to begin drawing.\nSimply lift the mouse button to finish');
subplot(1, 2, 1);
uiwait(msgbox(message));
hFH = imfreehand(); % Actual line of code to do the drawing.
% Create a binary image ("mask") from the ROI object.
mask = hFH.createMask();
xy = hFH.getPosition;
% Paste it onto the target image.
targetImage(mask) = sourceImage(mask);
% Display new image.
subplot(1, 2, 2); % Switch active axes to right hand axes.
imshow(targetImage);
imwrite(targetImage, 'car_new.jpg')
axis on;
caption = sprintf('Target image, %s, after paste', baseFileName2);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
Your code will work only in case when both source and target images are grayscale. As your target image is coloured, make following changes:
Delete line number 35,36 and 41.
paste this code after line 33.
redChannel = targetImage(:, :, 1);
greenChannel = targetImage(:, :, 2);
blueChannel = targetImage(:, :, 3);
redChannel(mask) = sourceImage(mask);
greenChannel(mask) = sourceImage(mask);
blueChannel(mask) = sourceImage(mask);
targetImage = cat(3, redChannel, greenChannel, blueChannel);

Colorbar resizes the subplots

I'm trying to plot 3 images side by side in MATLAB using subplot:
maxValue = 9;
minValue = 5;
figure(1)
subplot(1,3,1);
imshow(im1);
axis equal;
subplot(1,3,2);
imagesc(im2);colorbar;
caxis([minValue maxValue])
axis equal;
subplot(1,3,3);
imagesc(im3);colorbar;
caxis([minValue maxValue])
axis equal;
but the result looks like this:
Apparently the colorbar is resizing the image. How can I make all 3 images the same size and the colorbar fit the size of the image?
Your image is resized to maintain its aspect ratio according to the available space.
Use axis normal; for subplot(1,3,1) instead of axis equal.
You might need to maximise the figure window as well.
For im1 = imread('peppers.png');, the result is:
Here is what I ended up doing:
fig = figure(1);
set(fig, 'Position', [52 529 1869 445]); % Resize the image
subplot(1,3,1); % Add a subplot
subaxis(1,3,1, 'Spacing', 0.03, 'Padding', 0, 'Margin', 0); % Remove whitespace from subplot
imshow(im);
axis equal; % Use undistorted images
subplot(1,3,2);
subaxis(1,3,2, 'Spacing', 0.03, 'Padding', 0, 'Margin', 0);
imagesc(depth_gt);colorbar;
caxis([minValue maxValue])
axis equal;
subplot(1,3,3);
subaxis(1,3,3, 'Spacing', 0.03, 'Padding', 0, 'Margin', 0);
imagesc(depth_pred);colorbar;
caxis([minValue maxValue])
axis equal;
You can get this 'position' my manually resizing the image and then printing the output of fig in the Matlab command terminal

Plot over an image background in MATLAB

I'd like to plot a graph over an image. I followed this tutorial to Plot over an image background in MATLAB and it works fine:
% 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;
imagesc([min_x max_x], [min_y max_y], img);
hold on;
plot(x,y,'b-*','linewidth',1.5);
But when I apply the procedure to my study case, it doesn't work. I'd like to do something like:
I = imread('img_png.png'); % here I load the image
DEM = GRIDobj('srtm_bigtujunga30m_utm11.tif');
FD = FLOWobj(DEM,'preprocess','c');
S = STREAMobj(FD,flowacc(FD)>1000);
% with the last 3 lines I calculated the stream network on a geographic area using the TopoToolBox
imagesc(I);
hold on
plot(S)
The aim is to plot the stream network over the satellite image of the same area.
The only difference between the two examples that doesn't let the code working is in the plot line, in the first case "plot(x,y)" works, in the other one "plot(S)" doesn't.
Thanks guys.
This is the satellite image, imagesc(I)
It is possible that the plot method of the STREAMobj performs it's own custom plotting including creating new figures, axes, toggling hold states, etc. Because you can't easily control what their plot routine does, it's likely easier to flip the order of your plotting so that you plot your stuff after the toolbox plots the STREAMobj. This way you have completely control over how your image is added.
% Plot the STREAMobj
hlines = plot(S);
% Make sure we plot on the same axes
hax = ancestor(hlines, 'axes');
% Make sure that we can add more plot objects
hold(hax, 'on')
% Plot your image data on the same axes
imagesc(I, 'Parent', hax)
Maybe I am preaching to the choir or overlooking something here but the example you used actually mapped the image to the data range of the plot, hence the lines:
% 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;
imagesc([min_x max_x], [min_y max_y], img);
where you directly plot your image
imagesc(I);
If now your data coordinates and your image coordinates are vastly different you either see one or the other.
Thanks guys, I solved in this way:
I = imread('orto.png'); % satellite image loading
DEM = GRIDobj('demF1.tif');
FD = FLOWobj(DEM,'preprocess','c');
S = STREAMobj(FD,flowacc(FD)>1000); % Stream network extraction
x = S.x; % [node attribute] x-coordinate vector
y = S.y; % [node attribute] y-coordinate vector
min_x = min(x);
max_x = max(x);
min_y = min(y);
max_y = max(y);
imagesc([min_x max_x], [min_y max_y], I);
hold on
plot(S);
Here's the resulting image: stream network over the satellite image
Actually the stream network doesn't match the satellite image just because I'm temporarily using different images and DEM.

How to convert a point in image imrotated with loose option to a point in image imrotated with crop option in Matlab?

How to find the relation between image imrotated with loose option Image 1 and image imrotated with crop option Image 2 ? the angle of rotation is not necessary -45° ...
I = imread('cameraman.tif');
Im1 = imrotate(I,-45); % bbox option sets to 'loose' by default
Im2 = imrotate(I,-45,'nearest','crop'); % bbox option sets to 'crop'
figure(1);
subplot(2,1,1), imagesc(Im1), axis image;
subplot(2,1,2), imagesc(Im2), axis image;
I mean if I choose a point (x1,y1) from Im1 what is the equation of its relation with (x2,y2) in Im2 ?? I am looking for loose2crop() equation ?
I found a solution , please feel free to check it for fun :)
I = imread('cameraman.tif');
Im1 = imrotate(I,-45); % Image imrotated with loose option
Im2 = imrotate(I,-45,'nearest','crop');% Image imrotated with crop option
% draw image 1 loose
figure(1);
subplot(2,1,1), imagesc(Im1), axis image;
drawnow;
%%Get a point
title('Select a point'); hold on;
[p1] = ginput;
plot (p1(1),p1(2),'k*');
drawnow;
% convert loose p1 to crop image
p2 = loose2crop(Im1,Im2,p1)
% draw Image 2 cropped
subplot(2,1,2), imagesc(Im2), axis image, hold on;
plot (p2(1),p2(2),'r*');
drawnow;
function p2 = loose2crop(Im1, Im2, p1)
[h1,w1] = size(Im1);
[h2,w2] = size(Im2);
shift_h = (h1 - h2)/2 ;
shift_w = (w1 - w2)/2 ;
p2(1) = p1(1) - shift_h ;
p2(2) = p1(2) - shift_w ;

matlab plot graph of data over an image

What I would like to do is plot an image of a graph (from say a pdf file or a scanned image). Next, I would like to overlay an axis on the graph in the image, and then plot data on that axis (over the image).
Using imtool, I know the coordinates of the graph in the image (x range = ~52-355 pixels, and y range = 23(top) - 262(bottom) pixels in this case).
This is what I have tried:
I = imread('C:\MATLAB\R2014a\help\images\ref\ftrans2_fig.png');
I = squeeze(uint8(mean(I,3)));
figure, imshow(I)
[rows, cols] = size(I);
x_data = (-1 : .01 : +1)';
y_data = 1 - x_data.^2;
h1 = axes('Position',([52, 23, 355-52, 262-23] ./ [cols, rows, cols, rows] ));
set(h1, 'Color', 'none')
hold on
plot(x_data, y_data, '-rx')
Question: Knowing the pixel coordinates of the graph in the image, how do I determine the proper position of the axis in the figure, (my code fails to account for the actual size of the figure box, the gray border around the image). I have to do this for several images and sets of data, so I would like an automated method, assuming I find the coordinates of the graphs in the image ahead of time.
Thanks for your reply! (1st time posting, please be kind)
You may be able to solve your problem by forcing the image onto the same axis as the plot. Try this:
I = imread('C:\MATLAB\R2014a\help\images\ref\ftrans2_fig.png');
I = squeeze(uint8(mean(I,3)));
[rows, cols] = size(I);
x_data = (-1 : .01 : +1)';
y_data = 1 - x_data.^2;
h1 = axes('Position',([52, 23, 355-52, 262-23] ./ [cols, rows, cols, rows] ));
set(h1, 'Color', 'none')
hold on
image(I, 'Parent', h1);
plot(h1, x_data, y_data, '-rx')
That should at ensure that the plot axis and the image axis have the same origin, as they will be one and the same. You may need to adjust your sizing code. Let me know if that doesn't do it for you.
Good Luck!
I think I have it figured out.
It would have been easier if I could use:
figure, h1=imshow(I)
get(h1,'Position')
but that results in "The name 'Position' is not an accessible property for an instance of class 'image'."
Instead, this appears to work:
I = imread('C:\MATLAB\R2014a\help\images\ref\ftrans2_fig.png');
I = squeeze(uint8(mean(I,3)));
in_mag = 300;
figure, imshow(I, 'Border', 'tight', 'InitialMagnification', in_mag)
[rows, cols] = size(I);
x_data = (-1 : .01 : +1)';
y_data = 1 - x_data.^2;
% Coord of graph in image pixels
x_0 = 50; x_max = 354; y_0 = 262; y_max = 23;
h1 = axes('Position',([x_0, rows-y_0, x_max-x_0, y_0-y_max] ...
./ [cols, rows, cols, rows] ));
set(h1,'Color','none')
hold on
plot(x_data, y_data, '-rx')
ylim([0,1.4])
set(gca,'YColor', [0 0 1], 'XColor', [0 0 1])
However, if anybody has a better idea, I would be very happy to explore it!
Thanks

Resources