Flood filling with masking?

Hi Folks,
I was thinking about perfecting a segment between tissues. Flood filling does a really nice job throughout a volume, but it isn’t perfect due to slight variations in the intensity - too much and it goes into the tissue I don’t want it in, too little and it doesn’t go far enough.
I was thinking I could use flood filling with masking to limit the extent of the fill so it doesn’t go beyond where I want it. Alternatively, I was thinking of doing the flood filling, then grow the segment, but use a mask to limit the growth to a value I preselect. The filling and growing work on their own, but when I select the mask, then nothing happens.

Question 1. Am I doing something obvious wrong?
Question 2. Is there a work around? I’ve tried multiple clicking with the flood filling tool, but more often than not, it included more than I would like.

Thanks for any advice,

Jarrett

We made available “Flood filling” effect so that it can be evaluated and compared to other effects. Results indicate that this effect performs worse than “Grow from seeds effect”, because flood filling cannot cope well with spatially varying image intensity, segmenting multiple objects at once is cumbersome, hard to make incremental adjustments, etc., so there is not much incentive in trying to improve flood filling effect.

In Slicer-4.10.2 and recent preview releases, “Grow from seeds” effect takes masking into account, therefore probably you can achieve what you need. Let us know how it works for you or if you have any questions.

1 Like

Flood filling is perfect for segmenting arteries on contrast enhanced CT angioscan. It saves a lot of time, really, a lot of time, compared to ‘Grow from seeds’ and any other technique. Please keep in extra effects.

We should see how you use Flood filling and Grow from seeds effects and why the latter takes more time. Let’s do this at the project week!

@Sunderlandkyl

As an alternative to flood filling with masking, I’d suggest thresholding followed by island effects and paint or scissors to cut of links between the vessels and other structures. I typically find that to be a much more direct approach.

By the way, if people have example data sets and preferred segmentation techniques please post data and screenshots so we can all try various approaches.

This forum is amazing.
Thanks for your lightening-quick replies.

I’m been noodling around with the grow with seeds, and I think this will work very well. I still like flood filling, and I think it has a lot of good to do in the world. For the application I had in mind, the Grow from seeds is more powerful and customizable. I’ll check out the island effects add on too.

Thanks again for all of the input.

If this note is open, here is a link showing the result of arterial segmentation using Flood Filling only on contrast enhanced CT scan. For normal arteries, and for pathological aorto-iliac segments, it’s just a few clicks away, using Intensity Tolerance between 100 - 250 and Neighbourhood Size of 2. For pathological arteries below the groin, it takes more clicks and adjustments.

In any case, for such convoluted structures, Grow From Seeds will require much painting of outside structures, not feasible in practice.

This, following the contrast media with mouse clicks. This approach is not suitable for structures without contrast, like veins. Surrounding tissues are much of the same or near intensities. Grow From Seeds might better fit the bill here.

Well I’ve got a few hundreds of pathological arterial CT angioscans. If you wish a specific type of dataset, I may probably find one of interest to you.

Yes, thank you for sharing those examples @chir.set :+1: They are very good examples of challenging segmentation tasks. In addition to the artifact from the hip replacements, some parts are so stenotic that there’s barely any contrast in some of the vessels. I’m curious what your goal is for segmenting these. Are you trying to quantify something about the vasculature?

image

@lassoan you should have a look at those examples if you haven’t already.

Also I should mention that with 4.10.1 when I load the aorto_iliac mrml scene and then switch to the Segment Editor I get a crash with the stack trace below. It doesn’t happen if I have Segment Editor open when I load the scene.

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libvtkCommon-8.2.1.dylib      	0x00000001221d2564 vtkImageData::GetNumberOfScalarComponents() + 4
1   libqSlicerSegmentationsModuleWidgets.dylib	0x000000012dc4009b qMRMLSegmentEditorWidgetPrivate::updateAlignedMasterVolume() + 651
2   libqSlicerSegmentationsModuleWidgets.dylib	0x000000012dc4bf0d qMRMLSegmentEditorWidget::updateVolume(void*, bool&) + 189
3   org.qt-project.QtCore         	0x000000011e78d139 QMetaObject::activate(QObject*, int, int, void**) + 3113
4   libqSlicerSegmentationsEditorEffects.dylib	0x000000012dde9f64 qSlicerSegmentEditorAbstractEffectPrivate::updateVolumeSignal(void*, bool&) + 68
5   libqSlicerSegmentationsEditorEffects.dylib	0x000000012ddcd0ce qSlicerSegmentEditorAbstractEffect::masterVolumeImageData() + 30
6   libqSlicerSegmentationsEditorEffects.dylib	0x000000012dde81a2 qSlicerSegmentEditorAbstractEffect::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 1682
7   libqSlicerSegmentationsEditorEffects.dylib	0x000000012dde955c qSlicerSegmentEditorAbstractEffect::qt_metacall(QMetaObject::Call, int, void**) + 140
8   libqSlicerSegmentationsEditorEffects.dylib	0x000000012ddeac48 qSlicerSegmentEditorScriptedEffect::qt_metacall(QMetaObject::Call, int, void**) + 24
9   libPythonQt.dylib             	0x00000001167eb79b PythonQtCallSlot(PythonQtClassInfo*, QObject*, _object*, bool, PythonQtSlotInfo*, void*, _object**, void**, PythonQtPassThisOwnershipType*) + 1051
10  libPythonQt.dylib             	0x00000001167edbd3 PythonQtSlotFunction_CallImpl(PythonQtClassInfo*, QObject*, PythonQtSlotInfo*, _object*, _object*, void*, void**, PythonQtPassThisOwnershipType*) + 1091
11  libPythonQt.dylib             	0x00000001167ec599 PythonQtMemberFunction_Call(PythonQtSlotInfo*, _object*, _object*, _object*) + 185
12  libpython2.7.dylib            	0x000000011cf6d784 PyObject_Call + 100
13  libpython2.7.dylib            	0x000000011cffa71d PyEval_EvalFrameEx + 29149
14  libpython2.7.dylib            	0x000000011cff31ad PyEval_EvalCodeEx + 1997
15  libpython2.7.dylib            	0x000000011cf9641b function_call + 363
16  libpython2.7.dylib            	0x000000011cf6d784 PyObject_Call + 100
17  libpython2.7.dylib            	0x000000011cf799d5 instancemethod_call + 325
18  libpython2.7.dylib            	0x000000011cf6d784 PyObject_Call + 100
19  libpython2.7.dylib            	0x000000011cfff435 PyEval_CallObjectWithKeywords + 165
20  libqSlicerBaseQTCore.dylib    	0x000000010f014244 qSlicerPythonCppAPI::callMethod(int, _object*) + 196
21  libqSlicerSegmentationsModuleWidgets.dylib	0x000000012dc3f06f qMRMLSegmentEditorWidgetPrivate::notifyEffectsOfMasterVolumeNodeChange() + 175
22  org.qt-project.QtCore         	0x000000011e78d139 QMetaObject::activate(QObject*, int, int, void**) + 3113
23  libqMRMLWidgets.dylib         	0x000000010e9e8d8d qMRMLNodeComboBox::currentNodeChanged(vtkMRMLNode*) + 61
24  libqMRMLWidgets.dylib         	0x000000010e9605b0 qMRMLNodeComboBox::emitCurrentNodeChanged() + 64
25  org.qt-project.QtCore         	0x000000011e78d139 QMetaObject::activate(QObject*, int, int, void**) + 3113
26  org.qt-project.QtWidgets      	0x000000011db9d05b 0x11da79000 + 1196123

Masking in Grow from seeds is a game changer. Using that, marking “other” region is much simpler (and may not be even necessary).

Anyway, if use cases come up that make Flood filling work better than Grow from seeds then we can invest some more time in it. The underlying VTK filter can take a mask, so we could make Flood filling support masking, too. We just have to prioritize developments, because there are a number of other low-hanging fruits in various other effects, too.

I’ve fixed the crash in r28289. It happened because the master volume could not be loaded from the scene (they were DICOM files that were not included in the zip file).

Here it’s only for demonstrative purposes, showing that Flood Filling is an efficient tool of interest.

I do not perform such extensive segmentation on a daily basis. I need it to isolate the blood flow that is not readily analyzable behind heavily calcified walls in Volume Rendering for instance. It’s helpful also for non-vertical arteries, like the iliac, aortic branches or carotid bifurcation.

You are right to show a Volume Rendering image that is a good summary of the flow status, and indeed, that’s my daily tool for surgical planning.

hi, you could use your mask to create a segment then use logical operation>intersect with your flood filled segment to crop everything out of the mask, is that what you’re trying to achieve?