Fit 3d ellipsoid to a distribution of 3d points? - python

I have a number of points in 3d space (cartesian x,y,z) and would like to fit a ellipsoid
to that in order to determine the axis ratios. The issue here is that I have a distribution of points (not points on a surface), and the solutions to this problem mainly consider the points on a surface. Also would this fit be iterative (like some optimize or mcmc type method), I work in Python.
The code i am using was given in this answer: Python: fit 3D ellipsoid (oblate/prolate) to 3D points
But this does not work for me ( I think it was meant for points on the surface of an ellipsoid). But I have more density distribution of points rather than surface points.

I assume that you are not after the tightest bounding ellipsoid nor some best fit ellipsoid based on the "outer" points (such as an ellipsoid fit on the convex hull).
I understand that you are after a distribution, i.e. a unit-sum positive function of the coordinates, which you want to have "ellipsoidal" symmetry, so that the loci of equiprobable points are ellipsoids.
If you assume your distribution to be multivariate normal,
P(p) = c.exp(-(p-µ)^T M (p-µ)/2)
then M is the inverse of the covariance matrix and µ the average vector.

Related

How to determine if an object is flat or not from depth image?

I have a 2x2 matrix of distances from a depth sensor.
The matrix is cropped so only the points we are interested in is in the frame(All the points in the cropped image contains the object).
My question is how can we determine if this object is flat or not?
The depth image is acquired from Realsense d435. I read the depth image and then multiply it by depth_scale.
The object is recognized using AI for the rgb image that is aligned with the depth image.
And I have 4 points on the object. So, all the distances in that rectangle contains the distance of the object from the sensor.
My first idea was standard deviation of all the points. But then this falls apart if the image is taken from an angle. (since the standard deviation won't be 0)
From an angle the distance of a flat object is changing uniformly on the y axis. Maybe somehow, we can use this information?
The 2x2 matrix is a numpy array in python. Maybe there are some libraries which do this already.
After reprojecting your four depth measurements to the 3D space, it becomes a problem of deciding if your set of points is coplanar. There are several ways you can go about it.
One way to do it is to reproject the points to 3D and fit a plane to all four of them there. Since you're fitting a plane to four points in three dimensions, you get an over-determined system, and it's very unlikely that all points would lie exactly on the estimated plane. At this stage, you could prescribe some tolerance to determine "goodness of fit". For instance, you could look at the R^2 coefficient.
To fit the plane you can use scipy.linalg.lstsq. Here's a good description of how it can be done: Fit plane to a set of points in 3D.
Another way to approach the problem is by calculating the volume of a tetrahedron spanned by the four points in 3D. If they are coplanar (or close to coplanar), the volume of such a tatrahedron should be equal to (or close to) 0. Assuming your pointa reprojected to 3D can be described by (x_0, y_0, z_0), ..., (x_3, y_3, z_3), the volume of the tetrahedron is equal to:
volume = abs(numpy.linalg.det(tetrahedron)) / 6, where
tetrahedron = np.array([[x_0, y_0, z_0, 1], [x_1, y_1, z_1, 1], [x_2, y_2, z_2, 1], [x_3, y_3, z_3, 1]])
To check if your points are on the same plane, (equivalently - if the tetrahedron has a small enough volume), it is now sufficient to check if
volume < TOL
for some defined small tolerance value, which must be determined experimentally.
You can define a surface by choosing three of the four 3D points.
Evaluate the distance from the remaining point to the surface.
How to choose the three points is... it may be good to choose the pattern that maximizes the area of the triangle.

Finding the center of mass of a convex hull

I'm trying to find the center of mass of a convex hull. This convex hull is constructed by the triangulation of a set of scattered data points, in particular a Delaunay triangulation, and each point has a value, i.e. w = f(x,y,z). The mass of the convex hull is given by the function f, which is treated as the density of the solid. This function is unknown, so it has to be interpolated from the values w at each point.
I'm a beginner with Python, so I was wondering which would be the best way of finding this center of mass. I was trying with 2D surfaces first. scipy.interpolate.griddata interpolates the data, but then I don't know how to integrate the function in order to compute the center of mass (I need to integrate the interpolated function f over the domain of the convexhull). Any help will be much appreciated! Thanks in advance.

How to calculate the average/best Rotation between two coordinate systems?

Through a sensor I get the rotation between points in coordinate system A to points in coordinate system B. The measured rotations between the coordinate systems are not 100% identical due to the noise of the sensor.
How can I determine the average or optimal rotation matrix between the coordinate systems? Similar to this problem: stackoverflow: Averaging Quatenion, but contrary to that I do not want to use Quaternions, but try some least square approach.
Given: Rba(n): Rotation matrix from a to b, measured at n different time points
Wanted: Rba optimal
My approach: Minimization of the squared distance.
First I define n random points in space and apply the rotations to these points.
And now I can calculate the rotation by means of the Krabsch algorithm using singular value decomposition to minimize the square distance between the input points and the transformed points.
However, what I don't understand is that the calculated rotation matrix seems to be dependent on the input points. That is, I get different rotation matrices as a result for different input points, although the applied rotation matrices Rba(n) remain the same.
Why is that? And what is the right way?

How do you tell when the points on a 3D plot lie on a plane or on a curve?

I have a 3D scatter plot of some data generated using matploblib Axes 3D. I need to decide if it lies on a plane or a curve. I am trying to understand the visual differences that would indicate plane or curve. My guess is that if there are points along a wide range of z values then it lies on a curve because if it lied a plane, this would mean that the points are spread only over a flat surface. Even if my guess is correct, I am only right by virtue of eliminating the only other possibility so how would I tell specifically if it the data lies on a curve?
If the plane is tilted you will also find a wide range of z values.
Assuming you have your 3D points in an nx3 array, you can calculate the plane that fits them using this:
centroid = np.mean(points, axis=0)
_, eigenvalues, eigenvectors = np.linalg.svd(points - centroid, full_matrices=False)
normal = eigenvectors[2]
dispersion = eigenvalues[2]
The plane that best approximates the scattered points is defined by a point (centroid) and its normal vector.
Then, according to the dispersion value along the normal axis you can decide whether it is low enough (the points lie on a plane) or it is too high (they don't lie on a plane).

uniform sampling from a ellipsoidal confidence region

I have a 4-dimensional ellipsoid from which I want to draw samples uniformly. I thought of an approach using a hyper cube around the ellipsoid. We can draw a sample from it and check if it is in the ellipsoid. But the volume ratio of hypercube and ellipsoid in 4 dimensions is 0.3. That means I have only 30 percent success rate. As my algorithm has speed issues I don't want to use this approach. I have also been looking at Inverse transform sampling. Can you give me an insight on how to do this with a 4-dimensional ellipsoid ?
You can transform your hyper ellipsoid to a sphere.
So the given algorithm is valid for the sphere but can easily transformed to your ellipsoid.
Draw from a gaussian distribution N(0,1) for all coordinates x1, to x4. x=[x1,x2,x3,x4].
Normalize the vector x. ==> You have obtained uniformly distributed vectors on the surface.
Now, draw a radius u from [0,1] for the inner point from unit sphere
p=u**(1/4)*x is the uniformly distributed vector within the 4 dimensional unit sphere.

Categories