-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A quite complex vascular tree with strange radii #50
Comments
Mhmm, those vasculatures should skeletonize pretty well. Would you mind sharing the mesh (you might have to zip it for GitHub to accept the upload) so I can take a closer look? |
Can I send the data by email? |
I'd prefer here as my inbox is overflowing as is but email is Ok too. |
Hi, I was trying to upload the compressed zip file, but the size is still too big which has 109MB. Is the simplified file okay for you to process? |
Sorry, you seem to have posted a link to this issue rather than a file. |
Hi, I ve found out why the radii is incorrect(because I reconstructed a multi-nodes tree to re-define the root point, and incorrectly assign the wrong radius value to the corresponding edge), but I still have a question about what's the relationship between skel.radius and skel.edges ? |
The radii in If you need a radius for every edge rather than every node, you could just take the mean over the radii of the two nodes making up the edge: >>> node_radii = skel.radius[0] # see * note below
>>> len(skel.vertices), len(node_radii)
(1103, 1103)
>>> edge_radii = np.mean(node_radii[skel.edges], axis=1)
>>> len(skel.edges), len(edge_radii)
(1102, 1102) *I just realised that the |
I also just added a |
Thanks you for ur solution!! But I still have some questions below:
|
Re 1Do you mean find out where the root of the skeleton is (either by vertex ID or by xyz location), or the base of your vasculature? Re 2+3It's hard to tell without the mesh (looks like you posted it but then removed it again?) or even having seen a screenshot with the radii you got. In any event: I'd try the wave front method. |
1.The base of vasculature |
Thanks for your suggestions and new methods!! I have tried the new method which is sk.skeletonize.by_wavefront_exact(fixed, step_size=25), but as your said, the topology of the tree looks not pretty much good, please let me know if there is any method that could optimize the topology. |
Hi, I noticed u said the resolution does matter, and I have two questions below:
|
Your skeleton looks much worse than what I remember from my first trials. Is it possible that the mesh you're using has lower resolution? Looks pretty coarse in your screenshot. In any event: the
I use octarine: import octarine as oc
# Open a viewer
# (if you're in an iPython terminal you may have to start a gui event loop via e.g. `%gui qt6`)
v = oc.Viewer()
# Add the skeleton points
v.add_points(skel.vertices, size=skel.radius, size_space='world') You can also visualize the skeleton itself but for that you currently have to go through navis and the octarine-navis plugin: >>> import navis
>>> v.add_neurons(navis.TreeNeuron(skel)) I should probably add a standalone |
m = tm.load('/Users/hcj/科研/new_project/Data/Skeleton Data/final model/simple_0.01/final_model(simple_0.01).stl')
fixed = sk.pre.fix_mesh(m, remove_disconnected=10, inplace=False)
skel = sk.skeletonize.by_wavefront_exact(fixed, step_size=25)
skel.show(mesh=True)
File ~/Library/Python/3.9/lib/python/site-packages/octarine/plugins.py:11, in register_plugins()
[9](https://file+.vscode-resource.vscode-cdn.net/Users/hcj/%E7%A7%91%E7%A0%94/new_project/~/Library/Python/3.9/lib/python/site-packages/octarine/plugins.py:9) """Register a plugin."""
[10](https://file+.vscode-resource.vscode-cdn.net/Users/hcj/%E7%A7%91%E7%A0%94/new_project/~/Library/Python/3.9/lib/python/site-packages/octarine/plugins.py:10) # Find all plugins that defined an entry point
---> [11](https://file+.vscode-resource.vscode-cdn.net/Users/hcj/%E7%A7%91%E7%A0%94/new_project/~/Library/Python/3.9/lib/python/site-packages/octarine/plugins.py:11) discovered_plugins = entry_points(group="octarine.plugins")
[13](https://file+.vscode-resource.vscode-cdn.net/Users/hcj/%E7%A7%91%E7%A0%94/new_project/~/Library/Python/3.9/lib/python/site-packages/octarine/plugins.py:13) # Go over each of the plugins
[14](https://file+.vscode-resource.vscode-cdn.net/Users/hcj/%E7%A7%91%E7%A0%94/new_project/~/Library/Python/3.9/lib/python/site-packages/octarine/plugins.py:14) for plugin in discovered_plugins:
[15](https://file+.vscode-resource.vscode-cdn.net/Users/hcj/%E7%A7%91%E7%A0%94/new_project/~/Library/Python/3.9/lib/python/site-packages/octarine/plugins.py:15) # Import the module
TypeError: entry_points() got an unexpected keyword argument 'group' which might be caused by the old version of importlib.metadata |
|
Hi, I have looked into your algorithm and tried to optimize it by comparing the distance of center1 and center2 with the sum of their radius to judge if they can be the relationship of parent of child. But I am confused why the all positions of centers are correct(shown by octarine) but connection is wrong(shown by skeleton.show()) I am grateful if you can give me some tips |
this_step_track_centers = centers[is_this_step]
prev_step_track_centers = centers[is_prev_step]
this_step_track_verts = np.unique(
data[is_this_step, 2]
) # All track-vertices in this step
prev_step_track_verts = np.unique(
data[is_prev_step, 2]
) # All track-vertices in the previous step
# Get distances between current and previous track vertices
# Note to self: this step takes up about 60% of the time at the moment
# There should be a way to speed this up.
# vertices = [10, 11, 20, 21, 30, 31] | this_step_track_verts = [20, 21] | prev_step_track_verts = [10, 11]
# According to the connection relationship of the tree, get the min distance from 'this_step_track_verts' to # 'prev_step_track_verts'
# min_dist(20 -> 10), min_dist(20 -> 11), min_dist(21 -> 10), min_dist(21 -> 11), ...
# -> d = [[3.0, 2.0],[1.5, 2.5]]
d = np.linalg.norm(
this_step_track_centers[:, np.newaxis, :] - prev_step_track_centers[np.newaxis, :, :],
axis=2
)
# Get the closest previous track-vertex for each current track-vertex
# d.argmin(axis=1) returns the index of min value of each element
# d = [[3.0, 2.0],[1.5, 2.5]] | min([3.0, 2.0]) = 2.0 = index(1) | min([1.5, 2.5]) = 1.5 = index(0) | d.argmin(axis=1) = [1, 0]
# prev_step_track_verts = [10, 11] | d.argmin(axis=1) = [1, 0] | cloest_prev_track_verts # = prev_step_track_verts[d.argmin(axis=1) = [11, 10]
closest_prev_track_verts = prev_step_track_verts[d.argmin(axis=1)]
# 将this_step_track_verts 和 cloest_prev_track_verts中的一一对应
# this_step_track_verts = [20, 21] | cloest_prev_track_verts = [11, 10] | i = 2 |
# is_this_step = [False,False,True,True,False,False] 代表的当前[21, 20]对应的是index 2 3
for this, prev in zip(this_step_track_verts, closest_prev_track_verts):
# parents[2] = step_id_map[(1, 11)] = 1 | parents[3] = step_id_map[(1, 10)] = 1
parents[is_this_step & (data[:, 2] == this)] = step_id_map[(i - 1, prev)]
return centers, radii, parents This optimized algorithm could give a better connection between nodes Could you give me some feedback please because the skeletonized mesh has not been perfect yet. |
Hi, I was trying to skeletonize a vascular tree(.stl) and I tried quite a lot skeleton methods but all got either a strange branch shape or incorrect radius for the thickest branch.
The text was updated successfully, but these errors were encountered: