I've fully implemented the algorithm and I'm a bit confused by how the rotation matrix works. So you end with a "structure" matrix which is 3xP, and the contents (if I'm correct) are P 3D points (so rows are x,y,z).
The rotation matrix however is 2fx3. F being the number of frames since initially we stack 3 frames of tracked feature points into a matrix. And it's 2f because the top half are the x coordinates and the bottom half the y coordinates.
Anyway, the resulting matrix is this 2fx3 and it seems like you have 2 rotation matrices so I'm a bit confused how it corresponds to a normal rotation matrix
Here's a short overview of the algorithm
http://www.cs.huji.ac.il/~csip/sfm.pdf
I actually figured out the answer. So like I said the R matrix is of the size 2fx3 and I was confused how that corresponded to a normal 3x3 rotation matrix. So it turns out that since R is stacked such that you have
r1x
r2x
r3x
r1y
r2y
r3y
Where each row is a 1x3 vector that corresponds to a row in a normal rotation matrix to get the rotation from the initial points to the new ones you take the corresponding r rows for x,y and cross them for z. So to get the rotation matrix for the 1st frame it would be
(each of these is a 1x3 vector)
r1x
r1y
cross(r1x, r1y)
Related
I'm currently implementing an algorithm for 3D pointcloud filtering following a scientific paper.
I run in some problems when computing the rotation matrix for specific values. The goal is to rotate points into the coordinatesystem which is defined by the direction of the normal vector ( Z Axis). Since the following query is rotationally symmetric in X,Y axis, the orientation of these axis does not matter.
R is defined as follows: Rotationmatrix
[1 1 -(nx+ny)/nz]
R = [ (row1 x row3)' ]
[nx ny nz ]
n is normalized. The problem occures when n_z becomes really small or zero. Therefore i considered to normalize row 1 before computing the crossproduct for row 2.
Nevertheless the determinant becomes -1. Will the rotationmatrix sill lead to correct results? R is orthogonal but det|R| not +1
thanks for any suggestions
You always get that
det(a, a×b, b) = - det( a, b, a×b)
= - dot(a×b, a×b)
is always negative. Thus you need to change the second row by negating it or by re-arranging the overall order of the rows.
Are you interested in rotating points around arbitrary axis? If yes, maybe quaternions is good solution.
You can check this if you want to transform a quaternion to matrix before you actually use it.
I would like to know the angular difference between the orientation of two 3D matrices (4x4). Two matrices that are both oriented in the same direction would be zero, and two matrices that are oriented in opposite directions would be 180º. By 'orientation' I am referring to the direction that an object transformed by the matrix would be facing. So I'm only concerned with rotation, not translation or scale.
Specifically, I am using instances of WebKitCSSMatrix which refer to the 16 3D matrix values as .m11 through .m44.
in that case compare only one axis from the matrices
extract direction vector from your matrix
which one it is depends on your mesh models
it is the one the object is going forward
in mine models it is usually Z-axis
but I also see that other people often use X-axis
look here: matrix vectors extraction
I am not familiar with your matrix library
but there is a chance that your matrices are transposed !!!
so if it not works like it should extract the transposed vectors ... (rows instead columns)
compute the difference
just compute this: angle = acos ( (V1.V2)/(|V1|.|V2|) )
where V1,V2 are the direction vectors
As far as I know, Direct3D works with an LH coordinate system right?
So how would I get position and x/y/z axis (local orientation axis) out of a LH 4x4 (world) matrix?
Thanks.
In case you don't know: LH stands for left-handed
If the 4x4 matrix is what I think it is (a homogeneous rigid body transformation matrix, same as an element of SE(3)) then it should be fairly easy to get what you want. Any rigid body transformation can be represented by a 4x4 matrix of the form
g_ab = [ R, p;
0, 1]
in block matrix notation. The ab subscript denotes that the transformation will take the coordinates of a point represented in frame b and will tell you what the coordinates are as represented in frame a. R here is a 3x3 rotation matrix and p is a vector that, when the rotation matrix is unity (no rotation) tells you the coordinates of the origin of b in frame a. Usually, however, a rotation is present, so you have to do as below.
The position of the coordinate system described by the matrix will be given by applying the transformation to the point (0,0,0). This will well you what world coordinates the point is located at. The trick is that, when dealing with SE(3), you have to add a 1 at the end of points and a 0 at the end of vectors, which makes them vectors of length 4 instead of length 3, and hence operable on by the matrix! So, to transform point (0,0,0) in your local coordinate frame to the world frame, you'd right multiply your matrix (let's call it g_SA) by the vector (0,0,0,1). To get the world coordinates of a vector (x,y,z) you multiply the matrix by (x,y,z,0). You can think of that as being because vectors are differences of points, so the 1 in the last element goes the away. So, for example, to find the representation of your local x-axis in the world coordinates, you multiply g_SA*(1,0,0,0). To find the y-axis you do g_SA*(0,1,0,0), and so on.
The best place I've seen this discussed (and where I learned it from) is A Mathematical Introduction to Robotic Manipulation by Murray, Li and Sastry and the chapter you are interested in is 2.3.1.
I would like to know how to find the rotation matrix for a set of features in a frame.
I will be more specific. I have 2 frames with 20 features, let's say frame 1 and frame 2. I could estimate the location of the features in both frames. For example let say a certain frame 1 feature at location (x, y) and I know exactly where it is so let's say (x',y').
My question is that the features are moved and probably rotated so I wanna know how to compute the rotation matrix, I know the rotation matrix for 2D:
But I don't know how to compute the angle, and how to do that? I tried a function in OpenCV which is cv2DRotationMatrix(); but the problem which as I mentioned above I don't know how to compute the angle for the rotation matrix and another problem which it gives 2*3 matrix, so it won't work out cause if I will take this 20*2 matrix, (20 is the number of features and 2 are the location in (x,y)) and multiply it by the matrix by 2*3 which is the results from the function then I will get 20*3 matrix which it doesn't seem to be realistic cause I'm working with 2D.
So what should I do? To be more specific again, show me how to compute the angle to use it in the matrix?
I'm not sure I've understood your question, but if you want to find out the angle of rotation resulting from an arbitrary transform...
A simple hack is to transform the points [0 0] and [1 0] and getting the angle of the ray from the first transformed point to the second.
o = M • [0 0]
x = M • [1 0]
d = x - o
θ = atan2(d.y, d.x)
This doesn't consider skew and other non-orthogonal transforms, for which the notion of "angle" is vague.
Have a look at this function:
cvGetAffineTransform
You give it three points in the first frame and three in the second. And it computes the affine transformation matrix (translation + rotation)
If you want, you could also try
cvGetPerspectiveTransform
With that, you can get translation+rotation+skew+lot of others.
I just came to strange problem with my project in 3D. Everyone knows algorythm of calculating LookAt vector, but it is not so easly to calculate "up" vector from transformation matrix (or at least maybe I simple missed something).
The problem is following:
"Up" vector is (0, 1, 0) for identity rotation matrix and rotate with matrix, but do not scale nor translate. If you have simple rotation matrix procedure is easy (multiply vector and matrix). BUT if matrix contains also translation and rotation (e.g. it was produced by multiplying several other matrices), this won't work, as vector would be translated and scaled.
My question is how to get this "up" vector from single transformation matrix, presuming vector (0, 1, 0) correspond to identity rotation matrix.
Translation actually does affect it. Let's say in the example the transformation matrix didn't do any scaling or rotation, but did translate it 2 units in the Z direction. Then when you transform (0,1,0) you get (0,1,2), and then normalizing it gives (0,1/sqrt(5), 2/sqrt(5)).
What you want to do is take the difference between the transformation of (0,1,0) and the transformation of (0,0,0), and then normalize the resulting vector. In the above example you would take (0,1,2) minus (0,0,2) (0,0,2 being the transformation of the zero vector) to get (0,1,0) as desired.
Apply your matrix to both endpoints of the up vector -- (0, 0, 0) and (0, 1, 0). Calculate the vector between those two points, and then scale it to get a unit vector. That should take care of the translation concern.
Simply multiply the up vector (0,1,0) with the transformation, and normalize. You'll get the new calculated up vector that way.
I'm no expert at matrix calculations, but it strikes me as a simple matter of calculating the up vector for the multiplied matrix and normalizing the resulting vector to a unit vector. Translation shouldn't affect it at all, and scaling is easily defeated by normalizing.
I am aware this is an OLD thread, but felt it was necessary to point this out to anyone else stumbling upon this question.
In linear Algebra, we are taught to look at a Matrix as a collection of Basis Vectors, Each representing a direction in space available to describe a relative position from the origin.
The basis vectors of any matrix (the vectors that describe the cardinal directions) can be directly read from the associated matrix column.
Simply put your first column is your "x++" vector, your second is the "y++" vector, the third is the "z++" vector. If you are working with 4x4 Matrices in 3d, the last elements of these columns and the last column are relating to translation of the origin. In this case, the last element of each of these vectors and the last column of any such matrix can be ignored for the sake of simplicity.
Example: Let us consider a matrix representing a 90 degree rotation about the y axis.
[0, 0, -1]
[0, 1, 0]
[1, 0, 0]
The up vector can be plainly extracted from the third column as (-1, 0, 0), because the matrix is applying a 90 degree rotation about the y axis the up vector now points down the x axis (as the vector says), You can acquire the basis vectors to acquire the positive cardinal directions, and negating them will give you their opposite counterparts.
Once you have a matrix from which to extract the directions, no non-trivial calculations are necessary.