Regionprops.inertia_tensor_eigvals

what does regionprops.inertia_tensor_eigvals return? I test on 2d image, it give the major and minor axis, But when I use it on 3d image, it return 3-element tuple, but not as expected. (for I just put two zeros array upon and behind the 2d one, the result should be the 2d result, with a 0 added)

so, what does the inertia_tensor_eigvals mean? How can I get the expected result.
I want np.eig(np.cov(np.where(label==xxx)))

I use the code below got the cov matrix, and do eig.

idx = [[2,1,0,1,0,0,1,0,0],
       [0,1,1,1,2,1,0,1,0],
       [0,0,1,0,0,1,1,1,2]]
cov = r.moments_central[idx].reshape((3,3))
cov /= (r.moments_central[0,0,0]-1)
e,v = np.linalg.eig(cov)

but is it the best way? and what does the inertia_tensor_eigvals mean?

Hi @yxdragon!

You are not alone in thinking that the inertia tensor is the same as the normalised central moments, but this impression was corrected for me in this issue. =) The inertia tensor doesn’t correspond to the covariance, but to “how difficult” it is to rotate the object around that axis. So the smallest eigenvalue corresponds to the “major” axis of the object.

The reason it works in 2D is that we used to swap the x and y axes, so we had to worry about backwards compatibility, but we never had that issue in 3D. Use coordinates='rc' when calling regionprops to get consistent behaviour in 2D and 3D.

1 Like

Thanks, Infact I master rigid body physics, but did not look up “inertia” in english dictionary befor. “how difficult” it is to rotate. this descreption remind me.

But now I want to get the 3d object’s eig values, which I can get from the code below,

idx = [[2,1,0,1,0,0,1,0,0],
       [0,1,1,1,2,1,0,1,0],
       [0,0,1,0,0,1,1,1,2]]
cov = r.moments_central[idx].reshape((3,3))
cov /= (r.moments_central[0,0,0]-1)
e,v = np.linalg.eig(cov)

Is there any simple method?

1 Like

It seems there is some way, for it means sum(m*r^2), r is distance from point to the axis, so the 3 value means:
inertia_tensor_eigvals means [sum(m*(xx+yy)), sum(m*(xx+zz)), sum(m*(yy+zz))]
then: inertia_tensor_eigvals.sum() means sum(m*(xx+yy+zz))

sum(inertia_tensor_eigvals)/2 - inertia_tensor_eigvals is the var in each axis.
so the code is:

ite = inertia_tensor_eigvals
std = np.sqrt(sum(ite)/2-ite)