MeVisLab Scripting Reference
Python Image Processing

Introduction

MeVisLab supports implementing ML image processing modules using Python. Although the performance of a scripted image processing module is slow compared to C++, this allows implementing image processing modules without the hassle of needing a C++ compiler and with immediate module reloading without restart.

The following classes are available when scripting your own Python image processing modules:

This allows to do the following:

  • Write page based ML modules in Python
  • Support for N input images and M output images [N=0-8, M=0-4]
  • Support for handling invalid/disconnected inputs
  • Standard ML datatypes and complex datatypes (vector datatypes are not yet implemented)
  • Running processAllPages from Python

Apart from this, it is also possible to access the ML images via the MLABField::image() API, which allows to call MLPagedImageWrapper::getTile() from Python. This can be used to create modules that do slice-by-slice calculation on their input images.

Examples

MeVisLab contains several example Python image processing modules at MeVisLab/Standard/Modules/Examples/PythonImageProcessing. Have a look at the following example modules in MeVisLab:

  • PythonPagedImagingExample - an example the implements blending of two input images in Python
  • PythonGetTileExample - shows how to use getTile to do slice-by-slice or whole volume processing
  • PythonProcessAllPagesExample - an example that shows how to implement processing of all pages
  • PythonArithmetic - a generic image calculator implemented using the Python ML API

A simple example that just generates test pattern stripes is shown below. For more details, please have a look at the more elaborated example modules listed above. NOTE: ML pages are typically 6 dimensional and NumPy handles the dimensions in a different ordering than the ML convention. The NumPy ndarray.shape returns a tuple of (u,t,c,z,y,x) dimensions, while the ML methods expect/return (x,y,z,c,t,u) tuples. So if you use indexing in NumPy, keep in mind that you have to either do ndarray.squeeze() to get rid of the dimensions that are 1 or you need to write N leading zeros to fill up all 6 dimensions. The example below uses squeeze and [y,x] indexing.

PythonModuleExample.def:

MLModule PythonModuleExample {
DLL = "MLPythonImageProcessing"
class = PythonModule_In0_Out1
Commands {
#include $(MLAB_MeVisLab_Standard)/Modules/ML/MLPythonImageProcessing/PythonModuleCommands.script
source = $(LOCAL)/PythonModuleExample.py
}
Description {
#include $(MLAB_MeVisLab_Standard)/Modules/ML/MLPythonImageProcessing/PythonModuleDescription.script
}
}

PythonModuleExample.py:

import numpy
def calculateOutputImageProperties(index, outImage):
outImage.setDataTypeFromName("float")
outImage.setImageExtent(256,128,64,1,1,1)
outImage.setPageExtent(256,128,1,1,1,1)
outImage.setMinVoxelValue(0)
outImage.setMaxVoxelValue(1000)
def calculateOutputSubImage(outImage, outIndex):
# squeeze from 6 dimensions to 2 dimensions to allow [y,x]
# access below:
outImage = numpy.squeeze(outImage)
count = 0
for y in xrange(0, outImage.shape[0]):
for x in xrange(0, outImage.shape[1]):
outImage[y,x] = count%1000
count+=1