Instantiating ITK filter from filter name

I am having some difficulties with writing some code to take in a string and use that data to select and execute a SimpleITK filter. There doesn’t appear to be any way to access a filter object from sitk other than doing sitk. which won’t work with a string.

instead I am creating a dictionary with all the filters in the SimpleFilters widget and saving their id with their name. then I set the id as the current filter for the widget and apply the filter, but if i have more than one filter to apply, the app will crash since both are trying to run at the same time.

is this an error with slicer, which will normally wait until the execution of a filter is complete before continuing to the next line, or is there an error with my code that requires some kind of flag to know that the filter has completed?

also, is there a better way I should be doing this?

any help is appreciated, thanks.

Regarding:

You can do:

In [6]: filter = 'AbsImageFilter'

In [7]: sitk.__getattribute__(filter)
Out[7]: SimpleITK.SimpleITK.AbsImageFilter

Not sure I follow the rest of the question (a short code snippet demonstrating the app crash might help).

ok, that was what just what I was looking for, thanks. I would like to add that what you sent returns the class for the filter, rather than the filter itself though. so if you wanted to get the same reference as you would with sitk.AbsImageFilter(), you need to add the parenthesis to the end of the call like this:
sitk.__getattribute__(filter)()

as for the second part it isn’t really necessary anymore, but the method i was using was this:

filtersDict = {}
slicer.util.selectModule('SimpleFilters')
filtersWidget = slicer.modules.SimpleFiltersWidget
filtersJSON = filtersWidget.jsonFilters
for filterIdx in range(filtersWidget.filterSelector.count):
        filtersDict[filtersJSON[filterIdx]['name']] = filterIdx

customFilters = ['RecursiveGaussianImageFilter', 'LaplacianSharpeningImageFilter']
for filterName in customFilters:
        filtersWidget.filterSelector.setCurrentIndex(filtersDict[filterName])
        filtersWidget.onApplyButton()

this doesn’t really have a return for when the filter is complete, so the script would just keep running when a filter was going and crash the app.

1 Like

When you use a module from another module, you should never use a module’s GUI (…Widget class) but its logic (…Logic class). So, don’t call onApplyButton but instead logic.run.

SimpleFilters module creates a background thread to not block the GUI (so that you can abort filter execution). You can have a look at the Simple Filter module’s source code to see which events you need to observe to get completion notification. However, if you don’t need this background execution feature then everything becomes really simple: you just instantiate a filter directly and run it on the main thread. The filter will not return until execution is completed.

2 Likes