About imgradient function in Matlab - matlab

I am having doubt to the used equation in the function of imgradient.
In the line of 127:
Gdir = atan2(-Gy,Gx)*180/pi; % Radians to degrees
Why the Gy have to be negative?

The y-axis is inverted in images (it increases downward instead of upward). This causes the angles to increase clockwise instead of counter-clockwise as you're used to. By flipping the y component of the gradient, this line computes an angle in the "normal" sense.
Using the graph that #Dan linked in his comment:
In this graph, y increases upward, and angles increase counter-clockwise. In an image, the coordinate system is flipped. This leads to counter-intuitive angles. Hence they invert the y axis to compute the angle.

Related

Matlab - Discrete values of rho every 10 degrees of object margin in polar coordinates

I have shapes of letters represented in polar coordinates. The centroid of the shape equals the center of the polar representation. I need the values of rho every 10 degrees of the object's outer margin.
Examples of shapes in polar coordinates I have:
I have 2 problems I can't solve:
Matlab's [theta,rho]=cart2pol(x,y) theta doesn't return the angles in degrees. When plotting the object with polar(theta,rho) the object is well represented, but I don't understand what's the equivalence between matlab's theta value and each angle in degrees.
As the margin is in discrete, probably I won't have a margin point for every angle I need, so I need a way to get the nearest margin point for a given angle (and the farthest point for the letters with interior and exterior margin).

Rotate nxn matrix around x-axis by an angle theta in Matlab

I have nxn matrix in 2D space; I would like to rotate the matrix around the x-axis using matlab. Where the x-axis pass through the center of the matrix (pass through the point [n/2 n/2].
I found the Matlab function B = rot90(A) which rotate the matrix A by 90 degree. But I’m looking for a method that rotate matrix A by any given angle (e.g. 30, 45, 170 degree) around the x-axis.
You can as well try imrotate(). This function is from the Image Processing Toolbox, but since its main input is a matrix (either real or logical) it'll work also for non picture-related matrices (I've tried with a magic matrix).
The syntax is:
B=imrotate(A,theta);
where A is you matrix, B is the rotated version of A and theta is the rotation in degrees. The rotation is performed in counterclockwise direction around its center point; to rotate the matrix clockwise, specify a negative value for theta.

How do I interpret the orientation of the gradient when using imgradient in MATLAB?

I am finding the gradient of an image. For now I am simply using a 5 x 5 image. I am more interested in finding the direction of the gradient but I am not getting the results manually on paper as I get them using MATLAB function imgradient. Please refer to the following images to know more about the input images and the Sobel filter that is used here to find the gradient of an image. One of the 3 x 3 sobel operator used here is the one that I get using the function
f1 = fspecial('sobel');
and the other one is obtained by just transposing the f1.
Please note that I am trying to find the direction of only one pixel here that is rounded by red color. Here in the first two cases my result matches with that i obtain using imgradient function but in the third case imgradient gives -135 degree whereas I am getting it to be -45. Please help me find the error.
Also please explain how to interpret the following gradient directions as shown in the follwing image.
Your calculations are correct but it is highly recommended that you don't use the atan(y/x) definition because this calculation is not cognizant of the quadrant that the angle of the gradient resides in. Doing atan(y/x) with your components would falsely report the angle to be -45 degrees when that isn't correct. You should use atan2 instead.
Now the internals of imgradient are quite straight forward. I'd like to point out that the angle reported by imgradient is assuming that the y coordinate is increasing from bottom to top. In addition, imgradient should report the angle of orientation that is pointing to the greatest rate of change. In the case of images, this points in the direction where we progress from dark pixels to light pixels.
First a call to imgradientxy is called and a call to fspecial('sobel') is made if you provide the sobel flag to imgradient. In fact, this portion of imgradientxy is what is important to remember (starting at line 75: MATLAB R2015a):
case 'sobel'
h = -fspecial('sobel'); %// Align mask correctly along the x- and y- axes
Gx = imfilter(I,h','replicate'); %'
if nargout > 1
Gy = imfilter(I,h,'replicate');
end
Notice that the negative of the output of fspecial is performed as well as the comment provided at that line. This is to ensure that the mask to detect horizontal edges (i.e. Gy) is y-down (as it is commonly known in computer graphics). Specifically, the origin of the image is at the top-left corner and not the bottom left.
This is a pictorial representation of how the coordinate system is laid out in y-down:
Source: Wikipedia - Rotation Matrix
As such, when finding the orientation there is an additional requirement to ensure that the angle of the orientation of the gradient is with respect to the y-up coordinate system which is what we're used to. Therefore when you are finding the angle of orientation of the gradient, you need to negate the y coordinate before calculating the angle so that the angle is with respect to the standard convention instead.
Pursuing the definition of the gradient that you seek is the conventional system of the y coordinate increasing from bottom to top. The negation is required and in fact if you examine the source code for imgradient, this is precisely what is being done at line 127 of the code (version R2015a):
Gdir = atan2(-Gy,Gx)*180/pi; %// Radians to degrees
You may be asking yourself why there is a need to negate the mask and again negate the y coordinate after to find the orientation. The reason why is because the modified mask is required to properly capture the magnitude of the gradient and so we negate the mask once and find the gradient magnitude and then we negate the y coordinate so that we can find the angle with respect to the conventional coordinate system.
In your case, given that Gx = 765 and Gy = -765, substituting these quantities into the above equation yields:
>> Gy = 765;
>> Gx = -765;
>> Gdir = atan2(-Gy,Gx)*180/pi
Gdir =
-135
This makes sense because the gradient direction corresponds to the direction towards the greatest rate of change. -135 degrees means that we're pointing to the south west which does make sense as we are progressing from dark pixels to light pixels.
Now if you consult your third example image, the angles reported by imgradient are indeed correct. Simply draw a line from the dark area to the light area and see what angle it makes with the x axis where it is aligned with the columns increasing towards the right. The first angle of +90 degrees makes sense as we are moving from bottom to top to follow the dark area and light. This is a similar situation with the situation where the image is reversed. The third situation is what we have seen before and the fourth situation is simply the third situation rotated by 180 degrees and so naturally the angle of orientation from dark to light is now +45 degrees as opposed to -135 degrees previously.

Onscreen angle of 3D vector

My math is too rusty to figure this out. I want to derive the onscreen angle (the angle as seen on the 2d screen) of a 3d vector.
Given the x and y rotation of a vector (z rotation is zero and doesn't mstter), what does the angle on screen look like?
We know when y is zero and x is positive, the angle is 90. When y is zero and x is negative the angle is -90. When y is 90, for any value of x, the angle is 180. When y is -90, for any value of x, the angle is 0.
So what the formula here so I can derive the angle for the other values of x and y rotation?
The problem, as stated, doesn't make sense. If you're holding z to zero rotation, you've converted a 3D problem to 2D already. Also, it seems the angle you're measuring is from the y-axis which is fine but will change the ultimate formula. Normally, the angle is measured from the x-axis and trigometric functions will assume that. Finally, if using Cartesian coordinates, holding y constant will not keep the angle constant (and from the system you described for x, the angle would be in the range from -90 to 90 - but exclusive of the end points).
The arctangent function mentioned above assumes an angle measured from the x-axis.
Angle can be calculated using the inverse tangent of the y/x ratio. On unity3d coordinated system (left-handed) you can get the angle by,
angle = Mathf.Rad2Deg * Mathf.Atan(y/x);
Your question is what will a 3-d vector look like.
(edit after posted added perspective info)
If you are looking at it isometrically from the z-axis, it would not matter what the z value of the vector is.
(Assuming a starting point of 0,0,0)
1,1,2 looks the same as 1,1,3.
all x,y,z1 looks the same as any x,y,z2 for any values of z1 and z2
You could create the illusion that something is coming "out of the page" by drawing higher values of z bigger. It would not change the angle, but it would be a visual hint of the z value.
Lastly, you can use Dinal24's method. You would apply the same technique twice, once for x/y, and then again with the z.
This page may be helpful: http://www.mathopenref.com/trigprobslantangle.html
Rather than code this up yourself, try to find a library that already does it, like https://processing.org/reference/PVector.html

Creating a cylinder with axis centered differently

I know Matlab has a function called cylinder to create the points for a cylinder when number of points along the circumference, and the radius length. What if I don't want a unit cylinder, and also don't want it to center at the default axis (for example along z-axis)? What would be the easiest approach to create such a cylinder? Thanks in advance.
The previous answer is fine, but you can get matlab to do more of the work for you (because the results of cylinder separate x,y,z components you need to work a little to do the matrix multiplication for the rotation). To have the center of base of the cylinder at [x0 y0 z0], scaled by [xf yf xf] (use xf=yf unless you want an elliptic cylinder), use:
[x y z] = cylinder;
h=mesh(x*xf+x0,y*yf+y0,z*zf+z0)
If you also want to rotate it so it isn't aligned along the z-axis, use rotate. For example, to rotate about the x-axis by 90 degrees, so it's aligned along the y-axis, use:
rotate(h,[1 0 0],90)
Multiply the points by your favourite combination of a scaling matrix, a translation matrix, and a rotation matrix.