# Centerline smoothing by vmtkCenterlineSmoothing does not work

**URL:** <https://discourse.slicer.org/t/centerline-smoothing-by-vmtkcenterlinesmoothing-does-not-work/35200>\
**Category:** VMTK\
**Tags:** centerlines\
**Created:** [April 1, 2024, 3:10pm UTC](https://discourse.slicer.org/t/centerline-smoothing-by-vmtkcenterlinesmoothing-does-not-work/35200 "2024-04-01T15:10:47Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomo-akiyama](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tomo-akiyama/32/69831_2.png) [@tomo-akiyama](https://discourse.slicer.org/u/tomo-akiyama)\
**Post date:** [April 1, 2024, 3:10pm UTC](https://discourse.slicer.org/t/centerline-smoothing-by-vmtkcenterlinesmoothing-does-not-work/35200/1 "2024-04-01T15:10:47Z")

</div>

Hello, everyone,

I’m interested in smoothing the centerlines of the cerebral arteries.

Following the parameters recommended by “Kjeldsberg et al. BioMedical Engineering OnLine (2021) Automated landmarking of bends in vascular structures: a comparative study with application to the internal carotid artery ([Automated landmarking of bends in vascular structures: a comparative study with application to the internal carotid artery | BioMedical Engineering OnLine | Full Text](https://doi.org/10.1186/s12938-021-00957-6))”, I set the smoothing factor to 1.2 and the iteration number to 100. I’ve written a script using Python 3.8.10 (Anaconda) and VMTK 1.5.0.

Comparing with the original centerlines, there’s hardly any change in their trajectories. Even when I tried a significantly larger number for the smoothing factor, there was no variation, and the individual coordinates remained unchanged as well. Do you have any suggestions for improvement?

For the vascular data, I’m using the freely available AneuriskWeb’s C0002 ([http://ecm2.mathcs.emory.edu/aneuriskweb/repository#](http://ecm2.mathcs.emory.edu/aneuriskweb/repository#)).

Thank you.

```python
from vmtk import vmtkscripts

def vmtk_centerline_smoothing(centerlines, num_iteration=100, smooth_factor=1.2):
    # smooth centerlines with a moving average filter
    # args: centerlines: centerlines (vtkPolydata)
    # num_iteration: number of iterations (str)
    # smooth_factor: smooth factor (float)
    # returns: smoothed centerline (vtkPolyData)
 
    smoother = vmtkscripts.vmtkCenterlineSmoothing()
    smoother.Centerlines = centerlines
    smoother.SetNumberOfSmoothingIterations = num_iteration
    smoother.SetSmoothingFactor = smooth_factor
    smoother.Execute()
    smoothed_centerlines = smoother.Centerlines
    return smoothed_centerlines

CL # original centerlines
smoothed_centerlines1 = vmtk_centerline_smoothing(CL, num_iteration=100, smooth_factor=0.1)
smoothed_centerlines2 = vmtk_centerline_smoothing(CL, num_iteration=100, smooth_factor=1000)

# check the coordinate
print(CL.GetPoints().GetPoint(10))
print(smoothed_centerlines1.GetPoints().GetPoint(10))
print(smoothed_centerlines2.GetPoints().GetPoint(10))

```

 ![output](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/9/0/90c101f93f7612fd5e2bb681fda71c8377f1f9a2.png)

(62.38236999511719, 4.450344562530518, 63.071693420410156)  
(62.37776184082031, 4.44761848449707, 63.0672607421875)  
(62.37776184082031, 4.44761848449707, 63.0672607421875)

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [April 1, 2024, 3:49pm UTC](https://discourse.slicer.org/t/centerline-smoothing-by-vmtkcenterlinesmoothing-does-not-work/35200/2 "2024-04-01T15:49:02Z")

</div>

Everything seems to work very well. Since the centerline is already very much smoothed and the curve points are very close to each other, you wont see much if you just use 100 iterations and not too strong smoothing factor.

You can copy-paste this code snippet into 3D Slicer’s Python console to see the effect of smoothing:

```python
centerlineFilePath = 'path/to/C0002/morphology/centerlines.vtp'

reader = vtk.vtkXMLPolyDataReader()
reader.SetFileName(centerlineFilePath)
reader.Update()

try:
    import vtkvmtkComputationalGeometryPython as vtkvmtkComputationalGeometry
except ImportError:
    raise ImportError("Please install VMTK extension")
smoothing = vtkvmtkComputationalGeometry.vtkvmtkCenterlineSmoothing()
smoothing.SetInputConnection(reader.GetOutputPort())
smoothing.SetSmoothingFactor(0.1)
smoothing.SetNumberOfSmoothingIterations(100)
smoothing.Update()

modelNode = slicer.modules.models.logic().AddModel(smoothing.GetOutputPort())
modelNode.GetDisplayNode().SetLineWidth(2)

```

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/3/c/3cba1ead1080553a56cf8623f14fa654fb6514f5.png)

After this you can adjust the smoothing parameters and see the result immediately:

```auto
smoothing.SetNumberOfSmoothingIterations(1000)

```

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/9/3/93c5f6f82ad6a8b1ad0ae8c604f3135fd90e94ed.png)

```auto
smoothing.SetSmoothingFactor(0.5)

```

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/1/a1eaa0977c7c4b263e4b51d487ec9ee204ac4f67.png)

---

<div class="post-metadata">

**Author:** ![tomo-akiyama](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tomo-akiyama/32/69831_2.png) [@tomo-akiyama](https://discourse.slicer.org/u/tomo-akiyama)\
**Post date:** [April 3, 2024, 4:58am UTC](https://discourse.slicer.org/t/centerline-smoothing-by-vmtkcenterlinesmoothing-does-not-work/35200/4 "2024-04-03T04:58:44Z")

</div>

@lassoan

Thank you for your reply.

I didn’t have a good understanding of this smoothing. Looking at your display, it seems to be smoothed properly, but when I write a script with the same in Python, it’s clearly not working well. I wonder what the cause might be?

> centerlineFilePath = “path/to/C0002/morphology/centerlines.vtp”

> def load\_vtp(file\_path):  
> reader = vtk.vtkXMLPolyDataReader()  
> reader.SetFileName(file\_path)  
> reader.Update()  
> vtkpolydata = reader.GetOutput()  
> return vtkpolydata

> def vmtk\_centerline\_smoothing(centerlines, num\_iteration, smooth\_factor):  
> smoother = vmtkscripts.vmtkCenterlineSmoothing()  
> smoother.Centerlines = centerlines  
> smoother.SetNumberOfSmoothingIterations = num\_iteration  
> smoother.SetSmoothingFactor = smooth\_factor  
> smoother.Execute()  
> smoothed\_centerlines = smoother.Centerlines  
> return smoothed\_centerlines

> CL = load\_vtp(centerlineFilePath)

> smoothed\_centerlines1 = vmtk\_centerline\_smoothing(centerlines=CL, num\_iteration= **100** , smooth\_factor= **0.1** )
> 
> ![スクリーンショット 2024-04-03 13.50.02](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/0/f/0ffa7e0545d621e44cd2a4f3e011aec11f86d3e5.png)

> smoothed\_centerlines2 = vmtk\_centerline\_smoothing(centerlines=CL, num\_iteration= **1000** , smooth\_factor=**0.1)**
> 
> ![スクリーンショット 2024-04-03 13.54.22](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/7/8/78e031f0439a3a911571eba51f0a0553c81300ab.png)

> smoothed\_centerlines3 = vmtk\_centerline\_smoothing(centerlines=CL, num\_iteration= **1000** , smooth\_factor= **0.5** )
> 
> ![スクリーンショット 2024-04-03 13.55.05](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/8/5/853309d0182f944631b86ba040e16f8471060801.png)

Compared to the original centerlines, all of them are smoothed, but all smoothed centerlines seem to be the same even if the parameters are adjusted…

Incidentally, smoothing once does not change the smoothing situation even if the parameters are adjusted, but further smoothing of centerlines that have been smoothed (smoothing 2 times) seems to result in the intended smoothed centerlines.

 ![f6d3ab3b-c7e9-42ec-b80a-36ef34e57c73](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/4/8/486bcaba2faf622500aafc54540f4b11a42e0eda.png)

One more question, is this smoothing with Moving Average? Is it smoothing using a Laplacian filter? I don’t understand the definition of lambda.

I’m not sure from the VMTK document.

Thank you.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [April 4, 2024, 1:27am UTC](https://discourse.slicer.org/t/centerline-smoothing-by-vmtkcenterlinesmoothing-does-not-work/35200/5 "2024-04-04T01:27:02Z")

</div>

> [@tomo-akiyama](#):
>
> I didn’t have a good understanding of this smoothing. Looking at your display, it seems to be smoothed properly, but when I write a script with the same in Python, it’s clearly not working well.

I would recommend to start in the Slicer Python console and confirm that everything works well. You can then change things step by step and see what change breaks it.

> [@tomo-akiyama](#):
>
> One more question, is this smoothing with Moving Average? Is it smoothing using a Laplacian kernel?

The [documentation](https://github.com/vmtk/vmtk/blob/master/vtkVmtk/ComputationalGeometry/vtkvmtkCenterlineSmoothing.h#L21) mentions [Laplacian smoothing](https://graphics.stanford.edu/courses/cs468-12-spring/LectureSlides/06_smoothing.pdf) and [implementation](https://github.com/vmtk/vmtk/blob/6211af00372d099454acaf5d90520ddfcdf6cf96/vtkVmtk/ComputationalGeometry/vtkvmtkCenterlineSmoothing.cxx#L101-L107) seems to be that, too.

---

<div class="post-metadata">

**Author:** ![tomo-akiyama](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tomo-akiyama/32/69831_2.png) [@tomo-akiyama](https://discourse.slicer.org/u/tomo-akiyama)\
**Post date:** [April 4, 2024, 1:44pm UTC](https://discourse.slicer.org/t/centerline-smoothing-by-vmtkcenterlinesmoothing-does-not-work/35200/6 "2024-04-04T13:44:20Z")

</div>

It worked perfectly with the method you described. I have since realized the mistake in my script. When using the VMTK’s vmtkCenterlineSmoothing class in Python, the ‘Set’ prefix is not required, and direct assignment to properties is necessary.

The correct script is:  
def vmtk\_centerline\_smoothing(centerlines, num\_iteration, smooth\_factor)：  
smoother = vmtkscripts.vmtkCenterlineSmoothing()  
smoother.Centerlines = centerlines  
smoother.NumberOfSmoothingIterations = num\_iteration  
smoother.SmoothingFactor = smooth\_factor  
smoother.Execute()  
smoothed\_centerlines = smoother.centerlines  
return smoothed\_centerlines

Thank you @lassoan and everyone !
