Skip to content
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

How to get edge information? #16

Closed
FranzEricSchneider opened this issue Jan 29, 2023 · 6 comments
Closed

How to get edge information? #16

FranzEricSchneider opened this issue Jan 29, 2023 · 6 comments

Comments

@FranzEricSchneider
Copy link

This is just a question, not exactly an issue. The linux executable is great, and ran immediately. When I look at the saved skeleton output though, it appears to be a pointcloud only (image below). One of the important parts of a skeleton is the connectivity information between various points. Is it possible to view/access that connectivity information somehow?

Here's the tree I'm starting with:

Screenshot from 2023-01-29 17-46-11

And the resulting ply file from "Export skeleton" visualized in CloudCompare:

Screenshot from 2023-01-29 17-49-32

@LiangliangNan
Copy link
Member

Hi, CloudCompare (and also many other tools like MeshLab) is mainly for processing point clouds and meshes, and thus they don't support certain types of primitives like 'edge' or 'segment'.
If you open the saved PLY file, the file header looks like

ply
format ascii 1.0
element vertex 15964      
property float x
property float y
property float z
element edge 15133    <------ This line says there are 15133 edges stored in this file.
property list uchar int vertex_indices    <------ This line says that each edge has a property 'vertex_indices'
end_header

Then if you scroll down the file, you will see:

...
134.116 34.8058 0.674722
134.137 34.817 0.625265
134.154 34.8264 0.570861
134.17 34.8359 0.516457
134.191 34.847 0.467
2 0 1   <----- The edge property starts here.  See the explanation below. 
2 1 2
2 2 3
2 3 4
2 4 5
2 5 6
...

In each line, the first number '2' (type uchar) tells us this edge property has a list of two 'int' values. These two integer values are the indices of the two endpoints of this edge.

In the above, I show an ASCII file, while AdTree uses binary PLY format by default. You can simply change its behavior by modifying this line of code.

If you just want to visualize the skeletons (instead of writing your viewer), you can use my other program Mapple (or one of the example viewers in Easy3D).

Hope this helps.

@FranzEricSchneider
Copy link
Author

Thank you for your help, that's great to know! I had been previously visualizing skeletons in cloudcompare using very thin cylindrical meshes (hacky but functional...), I hadn't realized there were these edge attributes.

It looks like there's a python library that can read the edge attributes (https://github.com/dranjan/python-plyfile), I wasn't able to read them into the standard formats in open3d which is mostly what I've been using.

As a follow-up question, is the radius information available somewhere? I think that's the last piece of the puzzle.

@LiangliangNan
Copy link
Member

A skeleton (represented as a graph) file doesn't necessarily store the thickness of each line segment, because of a couple of reasons:

  • conceptually, a skeleton encodes only the connectivity/topology information of the tree branches.
  • the radii are unknown at the skeleton extraction stage.
  • after the radii are known, the tree geometry is reconstructed, and it can be better represented as a surface mesh. A surface mesh representation is widely accepted by almost all mesh processing software.

But of course, after reconstruction one can assign the radius to every vertex/edge in the skeleton.
For your convenience, I've modified the AdTree code, and now it allows storing the radius value of each vertex in the PLY file. Please note now the radius is a per-vertex attribute because the branches are generalized cylinders (meaning the two endpoints of an edge can have different radii). You can build AdTree from its current source code.

Below is a visualization of the skeleton using Mapple. Note: all edges have a uniform radius, but the radii are visualized as a scalar field.
Screen Shot 2023-01-31 at 09 58 49

@FranzEricSchneider
Copy link
Author

Wow, thank you! Very much appreciated. I will take a look at building AdTree from source and see if I can get that working!

@FranzEricSchneider
Copy link
Author

FranzEricSchneider commented Jan 31, 2023

Thank you so much for the support! I'm seriously impressed with the AdTree setup and maintenance, it just built cleanly immediately and radius shows right up in the saved ply files. Going above and beyond!

In [1]: from plyfile import PlyData

In [2]: no_radius = PlyData.read("/home/eric/Downloads/test_skeleton.ply")

In [3]: radius = PlyData.read("/home/eric/Downloads/test_skeleton_w_radius.ply")

In [4]: print(no_radius.elements[0])
element vertex 4591
property float x
property float y
property float z

In [5]: print(no_radius.elements[0][0])
(-0.0363, 0.2346, -0.0903)

In [6]: print(radius.elements[0])
element vertex 10746
property float x
property float y
property float z
property float radius

In [7]: print(radius.elements[0][0])
(0.8200171, 0.99451315, -0.9600609, 0.05012625)

In [8]: print(radius.elements[0][10])
(0.843149, 0.994522, -0.48895532, 0.04830073)

In [9]: print(radius.elements[0][100])
(2.5758896, 1.4676628, 0.02899671, 0.00332903)

@LiangliangNan
Copy link
Member

LiangliangNan commented Feb 7, 2023

I received the following question from GitHub notification (but it doesn't appear here).

Thanks for the work of adding the radius. Would it be possible that instead of each skeleton having a uniform radius, we could instead be able to access the fitted radius - the one the mesh uses?

The fitted radius values (as a per-vertex attribute) are already in the exported PLY file.
In this format, each branch is represented by a sequence of generalized cylinders, and each vertex is associated with a `radius' property. The radius values are the same as those used for meshing the skeletons into triangle meshes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants