Imagesc set the yscale - matlab

I have a function say Echo of size 100*100. I use:
x=linspace(-5000, 5000, 100); y=linspace(-200, 200, 100);imagesc(x, y, Echo);
I see the image is not properly oriented, so if I use:
Echo=rot90(Echo); imagesc(x, y, Echo);
I get the desired image but the yscale is starting from 200 (lower right) to -200 (upper right). I want -200 (lower right) and 200 (upper right). How do I do that?

You can try:
flipud on the matrix
or modify the figure/axes properties: axis ij (compare with axis xy)

In general if you want to reverse the direction of one of the axes relative to the normal orientation used in figures (example here: Y axis), use
set(gca,'YDir','reverse')
Edit
Since imagesc shows y axis in reverse orientation by default, try the following:
set(gca,'YDir','normal')
Note that in fact this is equivalent to #Bonlenfum's alternative suggestion of axis xy

Related

How to set origin of matlab plot at center?

I tried to plot a piecewise function in matlab.
syms x
y = piecewise(-1<x<0, x^2+2*x, 0<=x<1, 0);
fplot(y)
as the plot came is correct but visually its no good.
I want to set its origin at the center of the plot. How to do it?
Set same minimum and maximum space on both sides of the origin.
ax = gca;
MaxX = max(abs(ax.XLim)); MaxY = max(abs(ax.YLim));
axis([-MaxX MaxX -MaxY MaxY]);
If you also want (psuedo)-axis lines at origin, you may further use:
xline(0,'--'); yline(0,'--'); %requires R2018b
But if you actually want to move the axis location to origin then you may use the properties
XAxisLocation and YaxisLocation instead of pseudo axis lines.
ax.XAxisLocation='origin'; ax.YAxisLocation='origin';

Consistently generate line at at a specified angle as measured by user in MATLAB

Consider the simple code below that generates a straight downward sloping line in MATLAB.
clear, clc, close all
t = 0:0.1:1;
y = -t+1;
plot(t,y)
ax = gca
This is a line with slope -1, so the (acute) angle between the horizontal axis and the line is 45 degrees. Except it isn't when you measure with a protractor on your monitor.
Without changing the range of values displayed on the x and y axes or the height of the figure window, how could I ensure I would measure 45 degrees from the horizontal axis to the line if I held a protractor up to the screen?
My current approach is to change the width of the figure window. In the limit as the figure window is infinitely thin, the line x is a vertical line. Conversely, if the figure window is stretched to the edges of a monitor, it flattens out. Somewhere in the middle, the line has the angle I want. I just can't find a good way to mathematically find this point and instantiate it in code.
Edit: A slightly more generic solution for any acute angle. (I didn't test obtuse angles.)
clear, clc, close all
ang_deg = 70;
slope = tand(ang_deg);
t = 0:0.1:1;
y = -slope*t+1;
f = figure;
f.Position(3) = f.Position(3)*1.5;
plot(t,y)
% For a given height, change the width
ax = gca;
ax.Units = 'pixels';
ax.Position(3) = ax.Position(4)/slope;
You can achieve that with
axis equal
which, according to the documentation,
uses the same length for the data units along each axis.
You may want to also use
axis tight
which
fits the axes box tightly around the data by setting the axis limits equal to the range of the data
Follow up your commands with a declaration that you'll be working in pixels, and then set the width to the height:
ax.Units = 'pixels';
ax.Position(3) = ax.Position(4);

How to have vertical x labels?

Soft Question: How to edit the x label in a bar graph to be vertical in Matlab?
Here is an example of the x-axis I would like to have
You have to get the handle of the axis first. Then you can edit the X axis Tick rotation property which is zero by default. By setting this parameter to 90, it will rotate your x-axis like your picture.
h = gca; % handle for current axis
h.XTickLabelRotation = 90; % rotate the tick label

Rotate image around world x axis

Having this coordinate system:
And this dominant vertical vanishing point:
I would like to rotate the image around x axis so the vanishing point is at infinity. That means that all vertical lines are parallel.
I am using matlab. I find the line segmentes using LSD and the vanishing point using homogeneous coordinates. I would like to use angle-axis representation, then convert it to a rotation matrix and pass this to imwarp and get the rotated image. Also would be good to know how to rotate the segments. The segments are as (x1,y1,x2,y2).
Image above example:
Vanishin point in homogenous coordinates:
(x,y,z) = 1.0e+05 * [0.4992 -2.2012 0.0026]
Vanishin point in cartesian coordinates (what you see in the image):
(x,y) = [190.1335 -838.3577]
Question: With this vanishing point how do I compute the rotation matrix in the world x axis as explained above?
If all you're doing is rotating the image so that the vector from the origin to the vanishing point, is instead pointing directly vertical, here's an example.
I = imread('cameraman.tif');
figure;imagesc(I);set(gcf,'colormap',gray);
vp=-[190.1335 -838.3577,0]; %3d version,just for cross-product use,-ve ?
y=[0,1,0]; %The vertical axis on the plot
u = cross(vp,y); %you know it's going to be the z-axis
theta = -acos(dot(vp/norm(vp),y)); %-ve ?
rotMat = vrrotvec2mat([u, theta]);
J=imwarp(I,affine2d (rotMat));
figure;imagesc(J);set(gcf,'colormap',gray); %tilted image
You can play with the negatives, and plotting, since I'm not sure about those parts applying to your situation. The negatives may come from plotting upside down, or from rotation of the world vs. camera coordinate system, but I don't have time to think about it right now.
EDIT
If you want to rotation about the X-axis, this might work (adapted from https://www.mathworks.com/matlabcentral/answers/113074-how-to-rotate-an-image-along-y-axis), or check out: Rotate image over X, Y and Z axis in Matlab
[rows, columns, numberOfColorChannels] = size(I);
newRows = rows * cos(theta);
rotatedImage = imresize(I, [newRows, columns]);

Wrong 3D plot in Matlab

I'm trying to create 3D plots in Matlab, and I have practically no experience. I'd really like to draw the figure described by these equations:
x = cos(u) sinh(t) / (cosh(t) - cos(u));
y = cos(u) sin(u) / (cosh(t) - cos(u));
z = sin(u);
where both u and t vary from -pi to pi. This is what Paul Bourke calls Ghost Plane.
clc
clear
a = -pi:.01:pi;
b = -pi:.01:pi;
[U,T] = meshgrid(a,b);
X = (cos(U).*sinh(T))./(cosh(T)-cos(U));
Y = (cos(U).*sin(U))./(cosh(T)-cos(U));
Z = sin(U);
figure
surf(X,Y,Z)
With the code, I get something... indescribable. How do I plot the figure?
Your code is correct. You just need to zoom in.
Some tips to make this more viewable:
Use less fine grids, by changing a = ... and b = ... to: linspace(-pi,pi,40);
Add this ,'FaceColor','none','EdgeColor','interp'); to the surf command to only plot the lines and those in color.
Add this axis equal vis3d; after the surf command, so the axis will have correct scaling and behave well while rotating.
Add whitebg('black'); and grid off; to make the background black.
Change to surf(X,Y,Z,-U,...); and add colormap('HSV'); if you want the same colors as in the original.
set(gca,'xtick',[]); set(gca,'xticklabel',[]); set(gca,'yticklabel',[]); set(gca,'ytick',[]); to remove the axis ticks
You might want to use the cameratoolbar to: Change the projection to perspective projection, zoom all the way out, move the camera in very close, to get nice perspective distortions.
VoilĂ :