Basic Usage

Start by importing the module:

>>> import imfusion

This will create an internal OpenGL context and load all available plugins. Call info() to get some basic information about the framework.

If the OpenGL context could not be created, an exception is raised. See the Troubleshooting for possible solutions. If OpenGL is absolutely not available, the IMFUSION_WITHOUT_OPENGL environment variable can be set before importing the module. This will significantly limit the available features of the SDK and will lead to crashes if not used very carefully!

Some of the plugins included in the ImFusion SDK might conflict with a package installed in your Python environment. If this is the case, you can blacklist the offending ImFusion plugin by defining the IMFUSION_PLUGIN_BLACKLIST environment variable. This variable is expected to contain a list of filenames separated by a semi-colon, for instance “foo.dll;bar.so”.

Loading Data

Let’s begin with loading some data:

>>> data_list = imfusion.load(ct_image_png)
>>> data_list
[imfusion.SharedImageSet(size: 1, [imfusion.SharedImage(USHORT width: 512 height: 512 spacing: 0.661813x0.661813x1 mm)])]

This returns a list of datasets that have been loaded. In this case, it loaded an image set which contains only a single 2D image.

The ImFusion framework supports a wide variety of different data, not limited to image data but also polygon meshes, point clouds, and more. The Working with Images chapter will explain what exactly a SharedImageSet is, but for now, it is enough to think of it as a simple image.

Running Algorithms

Algorithms are the main building block of the ImFusion framework. An algorithm retrieves input data, performs some calculations, and optionally returns output data. Additionally, algorithms support certain properties that can influence the computation.

Algorithms are generally referenced by their id. To get a list of all available algorithms:

>>> imfusion.available_algorithms()
[..., 'Base.MorphologicalOperations', ...]

The list might change depending on the available plugins. Let’s execute the ‘Base.MorphologicalOperations’ algorithm on our image:

>>> imfusion.execute_algorithm('Base.MorphologicalOperations', data_list)
[imfusion.SharedImageSet(size: 1, [imfusion.SharedImage(USHORT width: 512 height: 512 spacing: 0.661813x0.661813x1 mm)])]

The first argument is the id of the algorithm we want to execute and the second one is a list of input images. Each algorithm requires a particular set of inputs, e.g., some algorithms will only work on 2D ultrasound images. If an algorithm is incompatible with the given input data, a IncompatibleError is raised. Check the algorithm’s documentation to find out what input a particular algorithm expects.

In the above example, the algorithm returns a list of output data.

By default, the ‘Morphological Operations’ algorithm performs dilation with a size of 3. These parameters can be changed by passing an optional Properties object to execute_algorithm(). To see which parameters are supported, use algorithm_properties():

>>> p = imfusion.algorithm_properties('Base.MorphologicalOperations', data_list)
>>> p.params()
['inPlace', 'opMode', 'opSize', ...]

For more information about the algorithms and their configurations, please consult the user documentation of the ImFusion Suite.

The Properties class is similar to a Python dict. It stores key-value pairs along with a list of attributes for each key.

Let’s change the pixel size of the dilation to 5:

>>> p = imfusion.Properties()
>>> p['opSize'] = 5
>>> imfusion.execute_algorithm('Base.MorphologicalOperations', data_list, p)
[imfusion.SharedImageSet(size: 1, [imfusion.SharedImage(USHORT width: 512 height: 512 spacing: 0.661813x0.661813x1 mm)])]

Alternatively, you can also pass a Python dict, which will be converted to a Properties implicitly:

>>> imfusion.execute_algorithm('Base.MorphologicalOperations', data_list, { 'opSize': 5 })
[imfusion.SharedImageSet(size: 1, [imfusion.SharedImage(USHORT width: 512 height: 512 spacing: 0.661813x0.661813x1 mm)])]

Saving Data

If you want to save files to disk, you can use the save() function. ImFusion files (ending with ‘.imf’) are supported for all types of data. Beyond that, further formats are supported based on the type of data, such as Nifti (‘.nii’) for SharedImageSet or Point Cloud Data (‘.pcd’) for PointCloud, etc. For the ImFusion file format, save() can also save multiple different types of data into the same file:

>>> image_set = imfusion.SharedImageSet(np.ones((1,8,8,1)))
>>> mesh = imfusion.mesh.create(imfusion.mesh.Primitive.SPHERE)
>>> point_cloud = imfusion.PointCloud([(0,0,0), (1,1,1), (-1,-1,-1)])
>>> another_image_set = imfusion.SharedImageSet(np.ones((1,8,8,1)))
>>> imfusion.save([image_set, mesh, point_cloud, another_image_set], tmp_path / "file.imf")