I need to measure the distance between two n-diensional vectors. It seems that Mahalanobis Distance is a good choise here so i want to give it a try.
My Code looks like this:
import numpy as np
import scipy.spatial.distance.mahalanobis
x = [19, 8, 0, 0, 2, 1, 0, 0, 18, 0, 1673, 9, 218]
y = [17, 6, 0, 0, 1, 2, 0, 0, 8, 0, 984, 9, 30]
scipy.spatial.distance.mahalanobis(x,y,np.linalg.inv(np.cov(x,y)))
But I get this error message:
/usr/lib/python2.7/dist-packages/scipy/spatial/distance.pyc in mahalanobis(u, v, VI)
498 v = np.asarray(v, order='c')
499 VI = np.asarray(VI, order='c')
--> 500 return np.sqrt(np.dot(np.dot((u-v),VI),(u-v).T).sum())
501
502 def chebyshev(u, v):
ValueError: matrices are not aligned
The Scipy Doc says, that VI is the inverse of the covariance matrix, and i think np.cov is the covariance matrix and np.linalg.inv is the inverse of a matrix...
But I see what is the problem here (matrices are not aligned): The Matrix VI has the wrong dimension (2x2 and not 13x13).
So possible solution is to do this:
VI = np.linalg.inv(np.cov(np.vstack((x,y)).T))
but unfortuanly the det of np.cov(np.vstack((x,y)).T) is 0, which means that a inverse matrix does not exsists.
so how can i use mahalanobis distance measure when i even cant compute the covariance matrix?
Are you sure that Mahalanobis Distance is right for you application? According to Wikipedia you need a set of points to generate the covariance matrix, not just two vectors. Then you can compute distances of vectors from the set's center.
You don't have a sample set with which to calculate a covariance. You probably just want the Euclidean distance here (np.linalg.norm(x-y)). What is the bigger picture in what you are trying to achieve?
Related
I have a plane defined by the origin(point) and normal. I need to apply 4 by 4 transformation matrix to it. How to do this correctly?
This is a helpful wikipedia link.
In case where your you are dealing with a three dimensional space, a 4 by 4 transformation matrix is probably a presentation of an affine transformation.
Check this wikipedia link.
to apply this transformation, you would first represent the plane using a 4x1 homogeneous representation (x, y, z, 1), where x, y, and z are the coordinates of a point on the plane, and the last component is 1 to indicate that the vector is a homogeneous vector.
Next, you would multiply this vector by the transformation matrix to obtain a new 4x1 vector, which represents the new position of the plane after the transformation.
the normal vector should not be affected by the translation part of the transformation matrix. This is because a normal vector represents the orientation of a surface and not its position, so it should not be affected by translation. thus the representation of the vector should be (x,y,z,0).
again, you would multiply this vector by the transformation matrix to obtain a new 4x1 vector, which represents the new orientation of the plane after the transformation.
only the top 3 elements of both the resulted vectors describe the new origin and the new normal (in-short the new plane).
This is an example in Python:
import numpy as np
# Original plane
o = np.array([0, 0, 0, 1])
n = np.array([0, 0, 1])
# Transformation matrix
T = np.array([[1, 0, 0, 2],
[0, 1, 0, 3],
[0, 0, 1, 4],
[0, 0, 0, 1]])
# Apply transformation to the origin
o_new = T # o
# Apply transformation to the normal
n_new = T[:3, :3] # n
print("New origin:", o_new[:3])
print("New normal:", n_new)
output :
New origin: [2 3 4]
New normal: [0 0 1]
Note: n_new = T[:3, :3] # n is the same as if n had its fourth element as 0 and then n_new = (T # n)[:3]
I am trying to get a plot of a set of eigenvalues of a matrix against a detuning factor epsilon. I want the plot to look like this
Matlab Plot using eig()
However when I use np.linalg.eigvals I get the following
Python eigvals plot
I also tried using np.linalg.eigvalsh which gave Python eigvalsh plot.
The problem seems to be how the eigenvalues are ordered upon the return for the function. I was wondering if there's any way to get it so I produce plot lines like in the first image from matlab. I've also tried the equivalent scipy functions which just gave the same as the numpy.
Here is a copy of my code
import numpy as np
import matplotlib.pyplot as plt
mu = 57.88e-3
eps = np.linspace(-0.26,0.26,100)
def Model_g1g2(g1, g2, B, t):
E = np.empty([len(eps), 5]) # Initialise array for eigenvalues
for i in range(len(eps)):
# Matrix A
A = np.array([[(-eps[i]+(g1+g2)*mu*B)/2, 0, 0, 0, 0],
[0, -eps[i]/2, 0, (g1-g2)*mu*B, 0],
[0, 0, (-eps[i]-(g1+g2)*mu*B)/2, 0, 0],
[0, (g1-g2)*mu*B/2, 0, -eps[i]/2, t],
[0, 0, 0, t, eps[i]/2]
])
E[i,:] = np.linalg.eigvals(A) # Store eigenvalues
return E
E = Model_g1g2(1, 4, 0.5, 0.06)
# Produce Plot
for i in range(5):
plt.plot(eps, np.real(E[:,I]))
plt.show()
In Matlab, the eigenvalues are sorted.
Change E[i,:] = np.linalg.eigvals(A) to E[i,:] = sorted(np.linalg.eigvals(A)), then you'll get what you want.
I want to compute the gradient (direction and magnitude) of an overdefined plane (> 3 points), such as e.g. four x, y, z coordinates:
[0, 0, 1], [1, 0, 0], [0, 1, 1], [1, 1, 0]
My code for computing the gradient looks like this (using singular value decomposition from this post, modified):
import numpy as np
def regr(X):
y = np.average(X, axis=0)
Xm = X - y
cov = (1./X.shape[0])*np.matmul(Xm.T,Xm) # Covariance
u, s, v = np.linalg.svd(cov) # Singular Value Decomposition
return u[:,1]
However as a result I get:
[0, 1, 0]
which does not represent the gradient nor the normal vector. The result should look like this:
[sqrt(2)/2, 0, -sqrt(2)/2]
Any ideas why I am getting a wrong vector?
You can use the function numpy.gradient for that. Here is some math background how it works.
In short:
The directional derivative will be the dot product of the gradient with the (unit normalized) vector of the direction.
An easier solution is to use numdifftools, especially the convenience function directionaldiff.
An example can be found here. And if you look at the source code you can see the relation to the math mentioned above.
I am trying to reconstruct a 3d shape from multiple 2d images.
I have calculated a fundamental matrix, but now I don't know what to do with it.
I am finding multiple conflicting answers on stack overflow and academic papers.
For example, Here says you need to compute the rotation and translation matrices from the fundamental matrix.
Here says you need to find the camera matrices.
Here says you need to find the homographies.
Here says you need to find the epipolar lines.
Which is it?? (And how do I do it? I have read the H&Z book but I do not understand it. It says I can 'easily' use the 'direct formula' in result 9.14, but result 9.14 is neither easy nor direct to understand.)
Stack overflow wants code so here's what I have so far:
# let's create some sample data
Wpts = np.array([[1, 1, 1, 1], # A Cube in world points
[1, 2, 1, 1],
[2, 1, 1, 1],
[2, 2, 1, 1],
[1, 1, 2, 1],
[1, 2, 2, 1],
[2, 1, 2, 1],
[2, 2, 2, 1]])
Cpts = np.array([[0, 4, 0, 1], #slightly up
[4, 0, 0, 1],
[-4, 0, 0, 1],
[0, -4, 0, 1]])
Cangles = np.array([[0, -1, 0], #slightly looking down
[-1, 0, 0],
[1, 0, 0],
[0,1,0]])
views = []
transforms = []
clen = len(Cpts)
for i in range(clen):
cangle = Cangles[i]
cpt = Cpts[i]
transform = cameraTransformMatrix(cangle, cpt)
transforms.append(transform)
newpts = np.dot(Wpts, transform.T)
view = cameraView(newpts)
views.append(view)
H = cv2.findFundamentalMat(views[0], views[1])[0]
## now what??? How do I recover the cube shape?
Edit: I do not know the camera parameters
Fundamental Matrix
At first, listen to the fundamental matrix song ;).
The Fundamental Matrix only shows the mathematical relationship between your point correspondences in 2 images (x' - image 2, x - image 1). "That means, for all pairs of corresponding points holds " (Wikipedia). This also means, that if you are having outlier or incorrect point correspondences, it directly affects the quality of your fundamental matrix.
Additionally, a similar structure exists for the relationship of point correspondences between 3 images which is called Trifocal Tensor.
A 3d reconstruction using exclusively the properties of the Fundamental Matrix is not possible because "The epipolar geometry is the intrinsic projective geometry between two views. It is
independent of scene structure, and only depends on the cameras’ internal parameters
and relative pose." (HZ, p.239).
Camera matrix
Refering to your question how to reconstruct the shape from multiple images you need to know the camera matrices of your images (K', K). The camera matrix is a 3x3 matrix composed of the camera focal lengths or principal distance (fx, fy) as well as the optical center or principal point (cx, cy).
You can derive your camera matrix using camera calibration.
Essential matrix
When you know your camera matrices you can extend your Fundamental Matrix to a Essential Matrix E.
You could say quite sloppy that your Fundamental Matrix is now "calibrated".
The Essential Matrix can be used to get the rotation (rotation matrix R) and translation (vector t) of your second image in comparison to your first image only up to a projective reconstruction. t will be a unit vector. For this purpose you can use the OpenCV functions decomposeEssentialMat or recoverPose (that uses the cheirality check) or read further detailed explanations in HZ.
Projection matrix
Knowing your translation and rotation you can build you projection matrices for your images. The projection matrix is defined as . Finally, you can use triangulation (triangulatePoints) to derive the 3d coordinates of your image points. I recommend using a subsequent bundle adjustment to receive a proper configuration. There is also a sfm module in openCV.
Since homography or epipolar line knowledge is not essentially necessary for the 3d reconstruction I did not explain these concepts.
With your fundamental matrix, you can determine the camera matrices P and P' in a canonical form as stated (HZ,pp254-256). From these camera matrices you can theoretically triangulate a projective reconstruction that differs to the real scene in terms of an unknown projective transformation.
It has to be noted that the linear triangulation methods aren't suitable for projective reconstruction as stated in
(HZ,Discussion,p313) ["...neither of these two linear methods is quite suitable for projective reconstruction, since they are not projective-invariant."]
and therefore, the mentioned recommended triangulation technique should be used to obtain valueable results (that is actually more work to implement).
From this projective reconstruction you could use self-calibration approaches that can work in some scenarios but will not yield the accuracy and robustness that you can obtain with a calibrated camera and the utilization of the essential matrix to compute the motion parameters.
I'm trying to build a toy recommendation engine to wrap my mind around Singular Value Decomposition (SVD). I've read enough content to understand the motivations and intuition behind the actual decomposition of the matrix A (a user x movie matrix).
I need to know more about what goes on after that.
from numpy.linalg import svd
import numpy as np
A = np.matrix([
[0, 0, 0, 4, 5],
[0, 4, 3, 0, 0],
...
])
U, S, V = svd(A)
k = 5 #dimension reduction
A_k = U[:, :k] * np.diag(S[:k]) * V[:k, :]
Three Questions:
Do the values of matrix A_k represent the the predicted/approximate ratings?
What role/ what steps does cosine similarity play in the recommendation?
And finally I'm using Mean Absolute Error (MAE) to calculate my error. But what I'm values am I comparing? Something like MAE(A, A_k) or something else?