# Create cylinder shell shaped segment

**URL:** <https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449>\
**Category:** Development\
**Tags:** segmentation\
**Created:** [September 16, 2019, 6:17pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449 "2019-09-16T18:17:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [September 16, 2019, 6:17pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/1 "2019-09-16T18:17:49Z")

</div>

Hello, I am using the following code to create a cylinder shell, for segmentation. Running it causes the 3DSlicer to close. Any ideas on why is this happening?

```
    segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
    segmentationNode.CreateDefaultDisplayNodes() # only needed for display
    segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(inputVolume)

    segmentationCylinder1 = vtk.vtkCylinderSource()
    segmentationCylinder1.SetRadius(1.02 * diameter / 2)
    segmentationCylinder1.SetHeight(len(slicer.util.arrayFromVolume(inputVolume)) * inputVolume.GetSpacing()[2] * 1.2)
    segmentationCylinder1.SetResolution(100)

    segmentationCylinder2 = vtk.vtkCylinderSource()
    segmentationCylinder2.SetRadius(0.98 * diameter / 2)
    segmentationCylinder2.SetHeight(len(slicer.util.arrayFromVolume(inputVolume)) * inputVolume.GetSpacing()[2] * 1.5)
    segmentationCylinder2.SetResolution(100)

    filter = vtk.vtkBooleanOperationPolyDataFilter()
    filter.SetOperationToDifference()
    filter.SetInputData(0, segmentationCylinder1.GetOutput());
    filter.SetInputData(1, segmentationCylinder2.GetOutput());

    filter.Update()
    segmentationNode.AddSegmentFromClosedSurfaceRepresentation(filter.GetOutput(), "Segmentation", [0.0, 1.0, 0.0])

```

I am suspecting it’s a problem with VTK itself, not Slicer.

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [September 16, 2019, 7:43pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/2 "2019-09-16T19:43:46Z")

</div>

Oh well, I ended up constructing the cylinder shell using vtkRotationalExtrusionFilter, but the segmentation result was not I was expecting. I’ll post a screenshot of what I got:

 ![Screenshot](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/9/0/90927b906b9a460b740edc7b97dca462e9c4289e.png)

I wanted to segment just inside the thin shell volume, but I got the whole cylinder instead. Any suggestions?

---

<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:** [September 17, 2019, 4:28am UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/3 "2019-09-17T04:28:17Z")

</div>

> [@giovform](#):
>
> Hello, I am using the following code to create a cylinder shell, for segmentation. Running it causes the 3DSlicer to close. Any ideas on why is this happening?

Unfortunately, Boolean operations in VTK do not work robustly. There have been a few alternatives developed but they are not yet in VTK master.

> [@giovform](#):
>
> I ended up constructing the cylinder shell using vtkRotationalExtrusionFilter

Probably you would need to use vktLinearExtrusionFilter instead (with appending two circles, one with clockwise and the other with counter-clockwise ordered points). But if you don’t need sharp edges then you can create a shell from a cylinder using vtkImplicitModeller:

```python
cyl = vtk.vtkCylinderSource()
cyl.SetRadius(20.0)
cyl.SetHeight(60.0)
cyl.SetResolution(60)
cyl.CappingOff()

modeller = vtk.vtkImplicitModeller()
modeller.SetInputConnection(cyl.GetOutputPort())
modeller.SetAdjustDistance(0.20) # make sure the thickened model fits in output bounds

thickness = 5.0
contourFilter = vtk.vtkContourFilter()
contourFilter.SetInputConnection(modeller.GetOutputPort())
contourFilter.SetValue(0, thickness/2.0)
contourFilter.Update()

segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes() 
segmentationNode.AddSegmentFromClosedSurfaceRepresentation(contourFilter.GetOutput(), "Cylinder", [0.0, 1.0, 0.0])

```

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [September 17, 2019, 1:01pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/4 "2019-09-17T13:01:56Z")

</div>

It worked. The following line was causing trouble though (the cylinder was rendered in separated strips), and I just deleted:

```
modeller.SetAdjustDistance(0.20)

```

Thanks again Andras,

Giovanni

---

<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:** [September 17, 2019, 1:39pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/5 "2019-09-17T13:39:56Z")

</div>

> [@giovform](#):
>
> It worked. The following line was causing trouble though (the cylinder was rendered in separated strips), and I just deleted:
> 
> ```auto
> modeller.SetAdjustDistance(0.20)
> 
> ```

This parameter was necessary to avoid clipping of sides when cylinder radius was 20, height 60, and thickness 5. If you have thinner wall or different aspect ratio then size adjustment may not be needed and/or you need to change other parameters from their default (e.g., resolution).

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [October 7, 2019, 8:42pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/6 "2019-10-07T20:42:48Z")

</div>

Hello Andras, I noticed that even if I increase the cylinder resolution a lot (using .SetResolution(…)), it still seems to reach a max resolution (I get rough edges, more than two pixels in some places). I would like a finer segmentation… is that possible?

---

<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:** [October 7, 2019, 9:17pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/7 "2019-10-07T21:17:08Z")

</div>

The cylinder resolution should not matter much. You need to make fine enough the resolution of the segmentation’s labelmap representation. You can click on the segmentation geometry button (next to the master volume selector) to adjust this resolution.

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [October 8, 2019, 4:14pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/8 "2019-10-08T16:14:34Z")

</div>

I’ll place some pictures of what I am getting. I tried to set the resolution as you told, but no success. I could only downgrade the resolution, not get a finer one for the segmentation cylinder.

Here is the original volume rendered, it is smooth:

 ![Anota%C3%A7%C3%A3o%202019-10-08%20130835](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/2/a2cf8a2fb3685b84cda5dec7d2cea5cbf02ed994.png)

Here is the segmentation cylinder created:

![Anota%C3%A7%C3%A3o%202019-10-08%20131144](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/2/c2cbd5f7e9c6363d878becd2ccc7d885a74acde3.png)

And here is the resulting volume extracted using a Mask:

 ![Anota%C3%A7%C3%A3o%202019-10-08%20131302](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/e/f/efea4416cc61d26c8d88d907626bf0bf15440bdd.png)

As you can see, it is very different from the segmentation surface and the original volume. It has lost its “resolution”.

I tried smoothing the segmentation, using the segment editor, but also no success. Any ideas?

Thanks!

---

<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:** [October 8, 2019, 4:31pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/9 "2019-10-08T16:31:24Z")

</div>

You need to set the finer resolution in the segmentation before you add the cylinder segment.

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [October 8, 2019, 5:39pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/10 "2019-10-08T17:39:41Z")

</div>

Hmm, interesting, I’ve seem to hit a bug. The steps are:

- load a volume (DICOM);

- create a segmentation and change the oversampling factor, of my volume as source geometry, to a value larger than 1.00 (I tried 1.25 and 1.5);

- use the Scissors tool with a circle, to fill inside. The segmentation indeed becomes smoother than without setting the oversampling;

- use this segmentation as a Mask, with some fill outside value. The resulting new volume doesn’t appear at all.

I repeated those steps without changing the oversampling factor, and got a resulting volume. These tests were done with Slicer 4.10.2 and Slicer 4.11.0-2019-09-01.

---

<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:** [October 8, 2019, 6:18pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/11 "2019-10-08T18:18:14Z")

</div>

Do you have any error in the application log?

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [October 8, 2019, 6:22pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/12 "2019-10-08T18:22:09Z")

</div>

No. No errors. The masked volume just doesn’t appear.

---

<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:** [October 8, 2019, 6:48pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/13 "2019-10-08T18:48:21Z")

</div>

I’ve found the issue and fixed it in rev28538 (available tomorrow in Preview Release).

Until then, a workaround is to create segments _after_ you’ve updated the segmentation geometry.

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [October 9, 2019, 2:02pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/14 "2019-10-09T14:02:13Z")

</div>

Thank you again Andras. One more question. How could I set the oversampling factor programmatically? I’ve tried this, but got no modifications to my segmentation:

```
    segmentationGeometryLogic = slicer.vtkSlicerSegmentationGeometryLogic()
    segmentationGeometryLogic.SetInputSegmentationNode(segmentationNode)
    segmentationGeometryLogic.SetOversamplingFactor(0.1)
    segmentationGeometryLogic.SetSourceGeometryNode(inputVolume)
    segmentationGeometryLogic.CalculateOutputGeometry()

```

Edit: I have placed this code just after creating my segmentation node, and before creating any segments.

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [October 10, 2019, 9:35pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/15 "2019-10-10T21:35:36Z")

</div>

Well, tried other path, I was sure it would work, but now I am kind of out of options. My code is as shown (note that despite telling to show the Segmentation Geometry Widget, it doesn’t appear):

```
    segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")

    # create segment editor to get access to effects
    segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
    segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
    segmentEditorWidget.show() # just to check if everything is setup correctly
    slicer.savedWidget = segmentEditorWidget
    segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
    slicer.mrmlScene.AddNode(segmentEditorNode)
    segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)

    segmentationGeometryWidget = slicer.qMRMLSegmentationGeometryWidget()
    segmentationGeometryWidget.setMRMLScene(slicer.mrmlScene)
    segmentationGeometryWidget.setParent(segmentEditorWidget)
    segmentEditorWidget.show() # just to check if everything is setup correctly
    segmentationGeometryWidget.setOversamplingFactor(0.05)
    segmentationGeometryWidget.setSegmentationNode(segmentationNode)
    segmentationGeometryWidget.setSourceNode(inputVolume)
    segmentationGeometryWidget.setParent(segmentEditorWidget)
    segmentationGeometryWidget.setReferenceImageGeometryForSegmentationNode()
    segmentationGeometryWidget.updateGeometry()
    segmentationGeometryWidget.update()

```

I have called a lot of methods, in the hope they would apply the new Oversampling I wanted to test.

---

<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:** [October 10, 2019, 11:25pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/16 "2019-10-10T23:25:39Z")

</div>

You never call `show()` for segmentationGeometryWidget, so it is not displayed. Anyway, you only need qMRMLSegmentationGeometryWidget if you want users to interactively change parameters on a GUI. If you just want to change the geometry from a script (without user interaction) then you can use [vtkSlicerSegmentationGeometryLogic](https://apidocs.slicer.org/master/classvtkSlicerSegmentationGeometryLogic.html) class instead.

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [October 11, 2019, 2:28am UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/17 "2019-10-11T02:28:14Z")

</div>

My bad, indeed it was supposed to be a call to show the Geometry Widget… copy, paste and some tiredness I guess. I thought I was supposed to use the Geometry Widget because I am using the Segment Editor Widget to apply some effects, so I went the same route.

Despite that, my first solution, just above my last answer was what you told. The code snippet is:

```
    # changing the segmentation resolution
    segmentationGeometryLogic = slicer.vtkSlicerSegmentationGeometryLogic()
    segmentationGeometryLogic.SetInputSegmentationNode(segmentationNode)
    segmentationGeometryLogic.SetOversamplingFactor(0.1)
    segmentationGeometryLogic.SetSourceGeometryNode(inputVolume)
    segmentationGeometryLogic.CalculateOutputGeometry()

```

This code is inserted before any segments are created, but it doesn’t take effect on my segments added later in the code. I don’t know what else I could set to make it work. I tried to find some example script and searched the forum, but nothing, so I am kinda lost on this matter.

---

<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:** [October 11, 2019, 4:41am UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/18 "2019-10-11T04:41:38Z")

</div>

You calculated the output geometry but did not set it in the segmentation. You can do it like this:

```python
segmentationGeometryLogic = slicer.vtkSlicerSegmentationGeometryLogic()
segmentationGeometryLogic.SetInputSegmentationNode(segmentationNode)
segmentationGeometryLogic.SetSourceGeometryNode(segmentationNode)
segmentationGeometryLogic.SetUserSpacing([0.5,0.5,0.5])
segmentationGeometryLogic.CalculateOutputGeometry()
geometryImageData = segmentationGeometryLogic.GetOutputGeometryImageData()
geometryString = slicer.vtkSegmentationConverter.SerializeImageGeometry(geometryImageData)
segmentationNode.GetSegmentation().SetConversionParameter(
    slicer.vtkSegmentationConverter.GetReferenceImageGeometryParameterName(), geometryString)

```

If you just want to prescribe some fixed spacing then you can do it even simpler, just setting the reference image geometry directly. A complete example:

```python
# Create segmentation node

segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes() 

# Set segmentation resolution (for closed surface to binary labelmap conversion)
geometryImageData = slicer.vtkOrientedImageData()
geometryImageData.SetSpacing(0.15, 0.15, 0.15)
geometryString = slicer.vtkSegmentationConverter.SerializeImageGeometry(geometryImageData)
segmentationNode.GetSegmentation().SetConversionParameter(
    slicer.vtkSegmentationConverter.GetReferenceImageGeometryParameterName(), geometryString)

# Add segment from polydata

cyl = vtk.vtkCylinderSource()
cyl.SetRadius(20.0)
cyl.SetHeight(60.0)
cyl.SetResolution(60)
cyl.CappingOff()

modeller = vtk.vtkImplicitModeller()
modeller.SetInputConnection(cyl.GetOutputPort())
modeller.SetAdjustDistance(0.20) # make sure the thickened model fits in output bounds

thickness = 5.0
contourFilter = vtk.vtkContourFilter()
contourFilter.SetInputConnection(modeller.GetOutputPort())
contourFilter.SetValue(0, thickness/2.0)
contourFilter.Update()

segmentationNode.AddSegmentFromClosedSurfaceRepresentation(contourFilter.GetOutput(), "Cylinder", [0.0, 1.0, 0.0])

```

---

<div class="post-metadata">

**Author:** ![giovform](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/giovform/32/4687_2.png) [@giovform](https://discourse.slicer.org/u/giovform)\
**Post date:** [October 14, 2019, 4:48pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/19 "2019-10-14T16:48:48Z")

</div>

It worked Andras. It would be difficult to find this out on my own at my current stage of understanding about the Slicer and VTK. 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:** [October 14, 2019, 7:00pm UTC](https://discourse.slicer.org/t/create-cylinder-shell-shaped-segment/8449/20 "2019-10-14T19:00:46Z")

</div>

Segmentation internal labelmap representation geometry is unfortunately quite complicated. We are still improving the API to make common tasks easier to do. For example setting the segment resolution should be achievable by a single line of code (instead of the current 4 lines).
