Getting longest dimension of surface mesh with SVD

Hello,

I am working with vtk and np.linalg.svd to get the main axes of a surface mesh.
I want to use the SVD singular values to find the longest dimensions of the model (as far as I understand, the singular values represent this).

The axes calculated from the SVD function look good (thanks @mau_igna_06 for the initial code to use the SVD for the axes)

but the singular values are way off. I am getting singular values = [191.01749 137.47546 26.27877] but based on a quick measurement I would expect the first singular value (longest dimension) to be something like 30:

My mean points look fine scale wise when I print them out.

modelPoints = vtk_to_numpy(model.GetPolyData().GetPoints().GetData())


# Calculate the mean of the points, i.e. the 'center' of the cloud
modelPointsMean = modelPoints.mean(axis=0)

print("printing model points mean")
print(modelPointsMean)
# print("Model Points:", modelPoints)  # Print the first 5 points
# Do an SVD on the mean-centered data.
uu, singular_values, rightSingularVectors = np.linalg.svd(modelPoints - modelPointsMean)
print("printing singular values")

Hi

Try creating an ellipsoid with vtk and using its points for the SVD. That way you’ll know if there is something wrong and exactly where

HIH

You can get the principal-axes-oriented bounding box from Segment Statistics module. That provides you the position and orientation of the principal axis and the diameter along that axis.

The direction of the first principal axis (direction of maximal variance) is not exactly the same as direction along you can find the two farthest data points, but usually they are very similar. Probably you actually want to use the principal axis, as it is a very robust, reproducible metric (not sensitive to noise in the data) and it is also very simple and fast to compute.

1 Like