CAVEconnectome / MeshParty

Apache License 2.0
34 stars 16 forks source link

Failed to skeletonize the mesh #79

Closed xleEmesent closed 2 years ago

xleEmesent commented 2 years ago

Hi, MeshParty Team.

I am skeletonize the mesh provided by MeshParty. But many resulted skeleton vertices are on the surface of the mesh instead of inside the mesh. Are there any extra steps such as parameters I have missed here? Many Thanks here.

The test mesh is from "precomputed://gs://neuroglancer-public-data/kasthuri2011/ground_truth",

from meshparty import trimesh_io
from meshparty import trimesh_vtk
from meshparty import skeleton, skeleton_quality, skeletonize
import os
from pyvista import examples
import trimesh
import numpy as np
def testLoad():
    meshFilePath="../data/test.obj"

    meshA = trimesh.load_mesh(meshFilePath)

    if (os.path.exists(meshFilePath)):
        print(f"{meshFilePath} does exist")

    mesh = trimesh_io.Mesh(vertices=meshA.vertices, faces=meshA.faces)
    mesh_actor = trimesh_vtk.mesh_actor(mesh, color=(1,0,0),opacity=0.5)
    trimesh_vtk.render_actors([mesh_actor])
    sk = skeletonize.skeletonize_mesh(mesh)
    vs = np.asarray(sk.vertices)
    np.savetxt("../output/vs.xyz",vs)
    return 

image image

fcollman commented 2 years ago

This is an intentional feature of the approach/algorithm. I've written an extensive discussion on it in the documentation https://meshparty.readthedocs.io/en/latest/guide/skeletons.html

If having a centered skeleton is important for your use case, there is an approach to move the skeletons half the SDF distance perpendicular to the mesh surface and then smooth the result, this works OK, but if your use case really demands precise centering than a different more computationally intensive skeletonization procedure might be a better way to go. Voxel based skeletonization is possible but is expensive when not done in bulk, and mesh shrinking approaches work well but don't guarantee a tree like topology, so again.. depends on what you are trying to do with it.

xleEmesent commented 2 years ago

@fcollman , thanks for your reply.

Yes, I am interesting in both the topology and precise centering. Regarding to the toplogy, I have used the same code but with a more complex mesh. It turns out some branches and part of the main branches missed.

Any thoughts on possible causes here? Thanks.

fcollman commented 2 years ago

This has to do with the parameters of the algorithm, namely the invalidation_d. The defaults were designed for mammalian neurons assuming mesh vertices were in nm units. If you have a different mesh you will likely need to adjust a lot of parameters to make it work right for you, and so you'll have to read the documentation about how the algorithm works to understand how they should be tuned.

In this case, you should turn down the invalidation distance.. which should be set to on order the distance 'around' the main branches you are interested in skeletonizing in the units of the mesh vertices.

xleEmesent commented 2 years ago

@fcollman , Thanks for your advice. I will have a good read on the documentation.

xleEmesent commented 2 years ago

@fcollman , after your tip. I realised that the input mesh has max distance to the surface roughly around 12 meters. By resetting the invalidation_d down to much smaller parameters. Topology can be captured without loss in this case. Many Thanks again.

fcollman commented 2 years ago

excellent, there are some more computationally intensive but potentially more accurate ways to estimate the caliber and curvature of the mesh at each point which can help you create a centered skeleton, I gave a sketch of them conceptually in the documentation but let me know if you need help running those.