# Apply filters on vtkMRMLVolumeNode and then display the filtered volume in Slicer

**URL:** <https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569>\
**Category:** Development\
**Created:** [November 30, 2017, 8:38pm UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569 "2017-11-30T20:38:55Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![urbancsaba](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/urbancsaba/32/932_2.png) [@urbancsaba](https://discourse.slicer.org/u/urbancsaba)\
**Post date:** [November 30, 2017, 8:38pm UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/1 "2017-11-30T20:38:55Z")

</div>

Hi All,

I have a custom loadable modul. In this modul, I want to apply IKT or VTK filters on the previously loaded DICOM volume. I have something like this:

```
vtkMRMLVolumeNode* volumeNode = d->MRMLVolumeNode; // this contains the loaded DICOM volume
vtkImageData* imageData = volumeNode->GetImageData(); //now I have the image data of that volume

```

//apply filter, for example:

```
vtkSmartPointer<vtkImageGaussianSmooth> gaussianSmoothFilter = vtkSmartPointer<vtkImageGaussianSmooth>::New();
gaussianSmoothFilter->SetInputData( const_cast<vtkImageData*>( imageData ) );

```

I think I missed something from here because assertation happens during debug in the Update() function  
`gaussianSmoothFilter->Update();`

Maybe I missed the `gaussianSmoothFilter->SetInputConnection(...)` function call before the Update(), but how can I get the proper input for this function? I have only the `volumeNode` object…

But now let’s assume that the `filtered` pointer holds the Gaussian filtered image:  
`vtkImageData* filtered = gaussianSmoothFilter->GetOutput();`

My question is, how can I display this volume in the slice viewes?  
(Example codes are highly appreciated.)

Thank’s,  
Csaba

---

<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:** [November 30, 2017, 8:44pm UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/2 "2017-11-30T20:44:03Z")

</div>

Something like this should work:

```
vtkMRMLVolumeNode* volumeNode = d->MRMLVolumeNode;
vtkNew<vtkImageGaussianSmooth> gaussianSmoothFilter;
gaussianSmoothFilter->SetInputData(volumeNode->GetImageData());
gaussianSmoothFilter->Update();
volumeNode->SetImageData(gaussianSmoothFilter->GetOutput());
```

---

<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:** [November 30, 2017, 8:54pm UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/3 "2017-11-30T20:54:38Z")

</div>

For applying ITK and VTK filters, you don’t need to develop C++ loadable modules. The simplest is to use Python scripted modules or CLI modules. There are lots of examples for various module types [in the Slicer core](https://github.com/Slicer/Slicer/tree/master/Modules).

---

<div class="post-metadata">

**Author:** ![urbancsaba](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/urbancsaba/32/932_2.png) [@urbancsaba](https://discourse.slicer.org/u/urbancsaba)\
**Post date:** [November 30, 2017, 10:33pm UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/4 "2017-11-30T22:33:32Z")

</div>

Thank you Andras!

A little correction:

This one causes exception in Update():  
`gaussianSmoothFilter->SetInputData(volumeNode->GetImageData());`  
but this is okay and works well:  
`gaussianSmoothFilter->SetInputConnection( volumeNode->GetImageDataConnection() );`

---

<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:** [December 1, 2017, 2:27am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/5 "2017-12-01T02:27:09Z")

</div>

What exception did you get?

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [September 4, 2018, 8:58am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/6 "2018-09-04T08:58:32Z")

</div>

> [@lassoan](#):
>
> SetInputData(volumeNode-\>GetImageData()); gaussianSmoothFilter-\>Update();

Hi Andras,  
Would you please tell me what I am doing wrong in the code below:

I need to apply normalize image filter of simple filters to volume.

```
normal = vtk.vtkImageNormalize()
normal.SetInputData(volumeNode.GetImageData())
normal.Update()
volumeNode.SetImageData(normal.GetOutput())

```

Error:  
Traceback (most recent call last): File “\<string\>”, line 8, in \<module\> AttributeError: ‘MRMLCorePython.vtkMRMLScalarVolumeNode’ object has no attribute ‘SetImageData’

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [September 4, 2018, 9:03am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/7 "2018-09-04T09:03:13Z")

</div>

I got the results with below but its not showing correct results when compared to results obtained using slicer APP. is this the correct filter for normalize image filter?

> normal = vtk.vtkImageNormalize()  
> normal.SetInputConnection(volumeNode.GetImageDataConnection())  
> normal.Update()  
> volumeNode.SetImageDataConnection(normal.GetOutputPort())

---

<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 5, 2018, 3:45am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/8 "2018-09-05T03:45:36Z")

</div>

What do you expect this filter would do? What happens instead?  
How did you obtain the good results that you mentioned?  
Why would you like to normalize an image?

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [September 5, 2018, 4:30am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/9 "2018-09-05T04:30:22Z")

</div>

> [@lassoan](#):
>
> ld you like to normalize an image

I was expecting normalized image intensities. The result are:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/5/b/5bdd45c37229ecf4d6b9d95cd8300190cfa5dd25.png)  
was expecting  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/f/7/f721f973cc1c00bf44cad25def187bb5ace66764.jpeg)

I want to normalize an image to obtain standardize intensities before doing automatic segmentation.

---

<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 6, 2018, 5:18am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/10 "2018-09-06T05:18:03Z")

</div>

> [@Saima](#):
>
> I want to normalize an image to obtain standardize intensities before doing automatic segmentation.

Applying linear intensity scaling will most likely not affect automatic segmentation results. Even the most basic methods are insensitive to global image brightness/contrast adjustments.

Check out [segmentation tutorials](https://www.slicer.org/wiki/Documentation/Nightly/Training#Slicer4_Image_Segmentation) and read these posts to have an idea how you can segment semi-automatically or automatically in Slicer:

> [@Automated Spinal Cord Segmentation](https://discourse.slicer.org/t/automated-spinal-cord-segmentation/3161/3):
>
> Some initialization (albeit very limited) is required by the user (which may impede its effectiveness) You can usually automate seed placement and thus have a completely automatic method. For example you can register a generic “atlas” image and transferring seeds to the patient image. Or you may use simple global thresholding to get candidate regions and keep the most likely candidate (that meets minimum size and shape requirements). You may also use the segmentation that sct provides as seed…

> [@Segmentation method for cerebrspinal fluid space](https://discourse.slicer.org/t/segmentation-method-for-cerebrspinal-fluid-space/1980):
>
> Hi, I am a new 3D slicer user. I am looking to build a 3D model of the cerebrospinal fluid space from CT images of the human brain. I was wondering if someone could elaborate on how I should go about it. I tried using thresholding in the editor module as they have a predefined scale for CSF space, but that didn’t quite work out. Any help would be great!

> [@Bone segmentation to create 3D-printable STL](https://discourse.slicer.org/t/bone-segmentation-to-create-3d-printable-stl/960/5):
>
> Prof. Doc. Andras, Dear Everyone, I was writing back to you . I have fixed the stl export issue. I used segmentaions module\>export,models\>export. and finally could save it as a stl file. Thank you again Professor for the support. All the best, Hanaa[image] [image]

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [September 11, 2018, 9:32am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/11 "2018-09-11T09:32:54Z")

</div>

Dear Andras,  
Is there a way to do automated segmentation for brain, tumor and ventricles together in any MRI without user input?

Regards,  
Saima Safdar

---

<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 11, 2018, 5:56pm UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/12 "2018-09-11T17:56:09Z")

</div>

Fully automatic segmentation is probably not the best approach, but you can get very close to it (probably 1-2 minutes of user’s time) if you implement a custom script:

- brain: you can use SwissSkullStripper extension to get the brain completely automatically
- ventricles: probably you can get ventricles by thresholding in brain segment region, potentially with some pre/post processing for optimal results
- tumor: there is a large variety of their size, location, and appearance, so fully automatic detection may be very difficult; however, you should be able to segment a tumor within one minute, with minimal user input, using “Grow from seeds” effect

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [September 12, 2018, 8:14am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/13 "2018-09-12T08:14:58Z")

</div>

Does the swiss skull stripper always use the atlas image and atlas mask. Is it reliable to use the same mask and image for any mri for extracting brain.

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [September 12, 2018, 11:05am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/14 "2018-09-12T11:05:13Z")

</div>

in accessing the swissskullmodule one step is to convert the atlasmask which is in volume into labelvolume.

I am doing this through script but have some problem. Dont get the correct output result for swiss.

I know the problem is in the mask setting it to labelvolume as the downloaded atlas is a scalarvolumenode. I did it using the GUI and it does it job.

```
vol = slicer.modules.volumes
log = vol.logic()
outputlabelnode = slicer.vtkMRMLLabelMapVolumeNode()
labelVolNode = log.CreateLabelVolumeFromVolume(slicer.mrmlScene, outputlabelnode, nodeMaskAtlas)

```

Is this the way to convert a volumenode to labelvolume.

Problem with one parameter atlasmaskvolume as it takes the labelvolume.

full code: I do not know what I am doing wrong. tried alot but dont get the extracted skull in outputvolume.

```
import SampleData
sampleDataLogic = SampleData.SampleDataLogic()
masterVolumeNode = sampleDataLogic.downloadMRBrainTumor1()
[success, atlasImage] = slicer.util.loadVolume('D:/atlasImage.mha', returnNode = True)
[success2, atlasMask] = slicer.util.loadVolume('D:/atlasMask.mha', returnNode = True)

nodeImageAtlas = slicer.util.getNode(atlasImage.GetName())
nodeMaskAtlas = slicer.util.getNode(atlasMask.GetName())

vol = slicer.modules.volumes
log = vol.logic()
vol =log.SetActiveVolumeNode(nodeMaskAtlas)
#scal = slicer.vtkMRMLScalarVolumeNode()
#slicer.mrmlScene.AddNode(scal)
labelVolume = log.CreateAndAddLabelVolume(slicer.mrmlScene, nodeMaskAtlas, nodeMaskAtlas.GetName())

outVolume = slicer.vtkMRMLScalarVolumeNode()
slicer.mrmlScene.AddNode(outVolume)
maskLabel = slicer.vtkMRMLLabelMapVolumeNode()
slicer.mrmlScene.AddNode(maskLabel)

parameters = {}
parameters['atlasMRIVolume'] = nodeImageAtlas.GetID()
parameters['atlasMaskVolume'] = labelVolume.GetID()
parameters['patientVolume'] = masterVolumeNode.GetID()

parameters['patientOutputVolume'] = outVolume.GetID()
parameters['patientMaskLabel'] = maskLabel.GetID()

swissSkullStripper = slicer.modules.swissskullstripper
slicer.cli.runSync(swissSkullStripper,None, parameters)
```

---

<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 13, 2018, 5:39am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/15 "2018-09-13T05:39:20Z")

</div>

> [@Saima](#):
>
> Is this the way to convert a volumenode to labelvolume

Yes, `CreateLabelVolumeFromVolume` method converts a scalar volume to a label volume. However, in your full script you used `CreateAndAddLabelVolume` method, which creates an empty label volume based on geometry specified by another volume.

The simplest is to load the label volume with the correct loading function: `slicer.util.loadLabelVolume()` - then you don’t need any conversion.

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [September 21, 2018, 7:45am UTC](https://discourse.slicer.org/t/apply-filters-on-vtkmrmlvolumenode-and-then-display-the-filtered-volume-in-slicer/1569/16 "2018-09-21T07:45:36Z")

</div>

> [@lassoan](#):
>
> - tumor: there is a large variety of their size, l

Hi Andras,  
Could you please share the ventricle segmentation tutorial so I can get the idea of workflow and write the script for ventricle extraction. It can be done automatically through script calling modules. right?  
I was using threshold and island effect but island effect require user input which I do not want.
