Convert label map volume into a scalarvolumenode

Good morning,

To convert my label map volume into a scalarvolumenode after correction on Segment editor and “export” the label map, I have some difficulties…
I am able to convert this updated label map into a numpy array (called ‘a’) but then, I don’t succeed in converting it into a vtkMRMLScalarVolumeNode : do you know how can I do this ?
Maybe I have committed some errors before by exporting my label map with my segmentation…

This is my code :

seg = slicer.util.getNode(‘CorrectionSegmentationFoie’)
labelmapVolumeNode = slicer.mrmlScene.AddNewNodeByClass(‘vtkMRMLLabelMapVolumeNode’,‘LabelFoiefinal’)

foiesegfin = slicer.modules.segmentations.logic().ExportAllSegmentsToLabelmapNode(seg, labelmapVolumeNode)
a = slicer.util.array(‘LabelFoiefinal’)
volumeNode = slicer.mrmlScene.AddNewNodeByClass(‘vtkMRMLScalarVolumeNode’,“VolumeFoieSegmente”)
foieseg = slicer.util.updateVolumeFromArray(volumeNode, a)

Thanks a lot in advance !
Laura

P.S : Do you know how to force in my python script to check the “sphere brush” in my 'Segment editor" module and force also my “MasterVolume” to be the label map that I have created from my previous uncorrected volume ?

Hi Laura,

You can try CreateScalarVolumeFromVolume .

Hey !

Thanks for this idea, I have tried so much but not this one !
Unfortunately, when I write this on my python script :

seg = slicer.util.getNode('CorrectionSegmentationFoie')
labelmapVolumeNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode','LabelFoiefinal')
slicer.modules.segmentations.logic().ExportAllSegmentsToLabelmapNode(seg, labelmapVolumeNode)
outputvolumenode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", 'FoieSegmenteApresCorrection')
sef = slicer.modules.volumes.logic().CreateScalarVolumeFromVolume(slicer.mrmlScene,labelmapVolumeNode, outputvolumenode)

My 3D Slicer crashes without saying nothing… Just crashes and asks me if I want to reload Slicer without any explanation…
Do I made a mistake ?
Thanks a lot in advance and enjoy your weekend !
Laura

1 Like

I don’t see any problems with your code after a quick look. A few things to check:

  1. What does the log say? You can find it in About menu / Report a problem window
  2. If you show labelmapVolumeNode in the slice view or in 3D volume rendering do you see anything?
  3. If you enter the lines one by one which one causes the crash?

I just tried her code and Slicer crashed after running the last command. The last line of my log is not suspicious:

[DEBUG][Qt] 22.07.2018 17:42:34 [] (unknown:0) - Python console user input: outputvolumenode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", 'FoieSegmenteApresCorrection')

Also, the label map looks fine.

Try swapping the arguments:

sef = slicer.modules.volumes.logic().CreateScalarVolumeFromVolume(slicer.mrmlScene, outputvolumenode, labelmapVolumeNode)

According to the docs, the second argument is your output and the third is the input.

But of course Slicer shouldn’t just crash :slight_smile:

Thanks, Fernando!
Does this function crash with any data? If so, then it should be an easy fix. Otherwise I can fix it if you give me the labelmap that you get after exporting.

1 Like

Anything should work. I just thresholded MRHead in the Segment Editor, renamed the segmentation node and pasted the code.

1 Like

I fixed the crash, I’ll integrate it in a minute so it shouldn’t crash in tomorrow’s version.

There is also something to fix in VTK too, though, because DeepCopy shouldn’t crash if you give it null pointer, which is what happens here (so my fix in Slicer is only a superficial fix). This is where it starts (and I made sure it doesn’t get this far):


Then vtkImageData and vtkDataSet handles the null properly, but then in vtkDataObject this call causes the crash ultimately:

Optimally this should be fixed in VTK.

To answer the original question, I think Fernando’s suggestion is the solution, which is to swap the arguments.

1 Like

Unfortunately, DeepCopy has no return value and VTK does not use exceptions, so there is not really a clean way to handle invalid DeepCopy input. Maybe VTK could log an error and return when the input is NULL instead of crashing? There is a chance that the error would be missed, but probably it is still better than crashing.

In the DeepCopy functions of vtkImageData and vtkDataSet the null argument was simply handled with an if statement. Indeed, no error was logged. I think adding it would be a nice solution, but then to make it consistent we’d need to change potentially a hundred VTK classes.
Maybe the easiest would be to just fix this one in vtkDataObject.

By the way, @Laura, swapping the arguments was the solution to your problem, I could confirm. So the last line should be

sef = slicer.modules.volumes.logic().CreateScalarVolumeFromVolume(slicer.mrmlScene, outputvolumenode, labelmapVolumeNode)

Good morning,

Thank you so so much to everybody, this works perfectly !!!
Have a good day
Laura

1 Like

Another little question @cpinter and @Fernando : do you know how to force in my python script to check the “sphere brush” in my 'Segment editor" module and force also my “MasterVolume” to be the label map that I have created from my previous uncorrected volume ?

Thanks again for everything !

Laura

Hi Laura,

You can find information about driving Segment Editor from python here:
https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#How_to_run_segment_editor_effects_from_a_script

I think if you set the reference volume using the function called SetReferenceImageGeometryParameterFromVolumeNode in the segmentation node, then it should be selected when you enter Segment Editor. Please note that you need to set this as soon as you have both nodes in the scene, and definitely before you enter Segment Editor.

You can also explicitly call segmentEditorWidget.setMasterVolumeNode(...) as it is done in almost all segmentation scripting examples.

It is a parameter effect, which you can modify by calling effect.SetParameter(…) as shown in examples, or modifying the segment editor node directly: getNode('SegmentEditor').SetAttribute('BrushSphere','1')

That’s right, you’re already using the Segment Editor widget from script anyway, so this will make it simpler.

Thanks a lot for your super help !
I succeed for the brush but I am still looking for the ‘setMasterVolumeNode’ because, when I write :

editorWidget = slicer.modules.segmenteditor.createNewWidgetRepresentation()
editorWidget.setMRMLScene(slicer.app.mrmlScene())
slicer.util.getNode(‘SegmentEditor’).SetAttribute(‘BrushSphere’,‘1’)
editorWidget.setMasterVolumeNode(inputVolCor)
editorWidget.show()

I have this error caused by my last line :

AttributeError: qSlicerScriptedLoadableModuleWidget has no attribute named ‘setMasterVolumeNode’

But I am looking for a solution !
Thanks again !
Laura

This line does not seem to be correct. You should not instantiate a new module widget.
You either create a new segment editor widget (as is shown in most examples; I would recommend this):

editorWidget = slicer.qMRMLSegmentEditorWidget()

or access the existing module widget of the SegmentEditor module:

slicer.util.selectModule("SegmentEditor")
editorWidget=slicer.modules.segmenteditor.widgetRepresentation().self().editor

Good morning,

I agree with you but this is the only way I found to create a popup of Segment Editor :

  • for your first solution :

editorWidget = slicer.qMRMLSegmentEditorWidget()

No segment editor popup appears even when I use the script in most examples with the line ‘.show()’ and I would like to paint and erase as I need so this is not convenient for what I do

  • for your second solution :

slicer.util.selectModule(“SegmentEditor”)
editorWidget=slicer.modules.segmenteditor.widgetRepresentation().self().editor

The Segment Editor Widget appears of course but not in a popup so I haven’t my extension wizard background so this is not convenient neither :slight_smile:

That’s why I have found this one :

editorWidget = slicer.modules.segmenteditor.createNewWidgetRepresentation()