Extract center line from CT empty snail shell

Hello, I know there is a post about extracting a centerline from a solid 3D model. However, my case is more complicated: it is an empty shell with an internal cavity. What I actually want to do is extract a centerline from this cavity, save it as an .obj file, and then obtain contours of several equally spaced cross-sections perpendicular to the centerline for mathematical fitting. Could I get some suggestions on how to approach this?

I can show an example figure to illustrate what I mean. Centerline is shown as B, and the cross-section is shown as C.

ExtractCenterline can work with a model also. I’m not familiar with .obj files, but my understanding is that they get presented as models, which are surface models. The problem with your specimen is that each individual coil is connected with the previous and/or the next. That may be bad for ExtractCenterline. If you get a valid centerline, you may next check the CrossSectionAnalysis module. Again the effect of the connectivity between successive coils is yet to be seen.

I’m also wondering how I could automatically extract the cavity itself, so that everything else can proceed more easily, not that sure?

I imported the .obj file into 3D slicer, so it’s actually called model in software

This part should be easy. Just fill the cavity as a separate segment in Segment Editor using WrapSurfaceSolidify. And then use this segment to create center line.

This part you will probably have to code yourself.

Thanks for your solution, I want to convert the model to a segment, however, it takes quite a long time for 3D slicer to convert. Is there any solution for this?

Just some background: I only have model file .obj, so my first step is to generate segment and generate that cavity file

You can choose to make this step as fast or accurate as you need, by choosing the oversampling factor as described here.

However, there is a much simpler and faster way: You can extract the inner surface of the shell using the Dynamic modeler module’s Select by points tool with GeodesicDistance selection algorithm and dropping a point in the inner surface of the shell somewhere deep inside (you can clip the model with a plane to see inside). The result is an open surface of the lumen. I think you can use this as input for the centerline computation as is, without even closing the surface.

Where is this image from? If it is from a micro-CT scanner then there is an even simpler way: You can avoid all the trouble of segmenting the shell then exporting it as an obj file and then importing into Slicer and trying to recover the segmentation. Instead, you can segment the image in Slicer and get the centerline (each takes just 2-3 clicks).

This is implemented in Cross-section analysis module, you just need to write a short Python code snippet that does the batch export in the format you prefer. This is probably 5-10 line of Python code that ChatGPT should be able to write for you.

Hello, I tried using the “select by points” option, but unfortunately the snail shell does not have a clear boundary between the inner and outer surfaces. Below is my model, which was generated from a CT scan.

Additionally, the aperture of the shell is not parallel to the z-axis, so the centerline may curve upward or downward.

Great! Starting from the CT scan should be much easier. You can extract the interior volume of the spiral using Segment Editor module and then get the centerline directly from the segmentation.

If the boundaries are intact then simple thresholding will work well. It takes just a few clicks. If there are small cracks in the surfaces then you can use the margin effect to make sure any connections between adjacent whorls are broken up. Margin effect takes away voxels from the entire surface of an object, so it should not impact the centerline.

If the holes are bigger then you can erase the connections manually or use the Wrap Solidify effect (choosing “Region” → “largest cavity”).

I tried the segment editor

My approach shown as follows

then click the cube bottom

select okay, source geometry is the segment from .obj.

I haven’t found wrapsurfacesolidify, some tutorial video shows that’s a exnteion, but I haven’t found via searcing.

Also any bottom at the left I clicked, it always shows

If I click yes, it will take quite a long time

It seems that you have created a surface mesh in some software and trying to import it into Slicer as a segmentation. This is a lot of extra steps that adds time, complexity, and may result in loss of details. It should be much simpler to load the CT image (DICOM files or a TIFF, PNG, or JPG stack - not some surface mesh file, such as an OBJ, PLY, or STL) and segment that image using Segment Editor module.

So what I actually need is stacks of tiff files and .obj files? But now I am somewhat confused about the whole logic.

The main logic is load stacks of tiff → volume rendering to generate a volume → segment editor? I totally felt lost.

Surface mesh (OBJ/STL/PLY file) should not be needed in the workflow at this stage. You can follow these steps:

  • Install Slicer
  • Install SurfaceWrapSolidify extension in Slicer’s Extensions Manager
  • Load 3D Image (DICOM, TIFF/JPG/PNG stack, etc.) into Slicer
  • Switch to Segment Editor module
  • Use Threshold effect to segment the shell
  • Use Wrap Solidify effect to extract the largest cavity

There are many variants of this workflow (instead of Wrap Solidify you can manually close down the opening of the shell and then use Islands effect to segment the internal volume; you can use Margin effect to break up connections between adjacent whorls; etc.) but without having access to the data or seeing your intermediate results (e.g., Thresholding and Wrap Solidify output) it is hard to tell what works best.

1 Like

Thanks for your answer, it solves quite a lof of my questions. I had serveral shells in one scan, so what should I do to seperate them? During the segmen editor or any other stage?

I currently obtained a model using wrap solidify to extract the inner structure while excluding the shell.

However, whenever I run extract centerline without a point list, I receive the following notification:

Therefore, I have to add two points to define the start and end. What I am unsure about is whether it matters if my aperture point is placed in the middle of the aperture curve surface.

Another issue is that after using wrap solidify, the inner structure does not perfectly match the shell. Do you think this approach could be a solution?

Your centerline curve in the first image is impressive :+1: . I don’t think that CrossSectionAnalysis would be able to give you the outline of the cross-sections as you expected because there’s a common wall all along. It can still show you the maximum inscribed sphere.

You may also try the Curve Planar Reformat module if you have an input volume, to see how far it can straighten such an elaborate geometry.