As part of my larger deconvolution project I tested some of the ITK deconvolution algorithms. It was fairly easy to integrate Simple ITK into ImageJ2 using Eclipse in an Ubuntu development environment. Though I haven’t attempted the non-trivial task of creating distributable libraries. I was really impressed at how simple it was to create an image processing plugin using ImageJ2 and Simple ITK so I separated it into a self contained example that can be found here.
Here are the steps I followed to create my Image2/Simple ITK plugin. While this example is for deconvolution it should be easy to modify it for different ITK functionality.
1. Create an ImageJ2 style maven project. There are great examples in imagej-tutrials (if you are not familiar with maven google “maven in 5 minutes”) The “intro-to-imagej-api”, “simple-commands” and “create-a-new-op” projects are very useful.
3. Write some utilities to copy between the imagej “Img” and the itk “Image”. Mine are here, let me know if anybody has some better ones.
4. Write an op to wrap the itk function. An op that wraps itk Richardson Lucy is here. It is derived from this base class. The key is the annotation “@Parameter”. This defines the inputs and outputs. Then the op can be called using the op service. In a Python script it would look something like this.
out=ops.run("RichardsonLucyITK", in, kernel, 10)
The code to convert between image formats and call itk (through the simple itk wrapper) looks like this:
// convert input to itk Images Image itkImage = SimpleItkImagejUtilities.simple3DITKImageFromInterval(input); Image itkPsf = SimpleItkImagejUtilities.simple3DITKImageFromInterval(kernel); itkRL=new RichardsonLucyDeconvolutionImageFilter(); // call itk rl using simple itk wrapper Image out=itkRL.execute(itkImage, itkPsf, numIterations, true, BoundaryConditionType.ZERO_PAD, RichardsonLucyDeconvolutionImageFilter. OutputRegionModeType.SAME); T inputType=Util.getTypeFromInterval(input); // convert output to ImageJ Img output = SimpleItkImagejUtilities.simple3DITKImageToImg( out, input.factory(), inputType);
@Parameter protected OpService ops;
is a means to access the service which runs the operations. The code to call the op is as follows:
// get the Imgs from the dataset Img<T> imgIn=(Img<T>)input.getImgPlus().getImg(); Img<T> imgKernel=(Img<T>)kernel.getImgPlus().getImg(); // call the op Img<T> imgOut = (Img<T>)(ops.run("RichardsonLucyITK", imgIn, imgKernel, numIterations)); output=data.create(new ImgPlus(imgOut));
The images (Img) are retrieved from a Dataset. It is beyond the scope of this small blog post to go into detail about Datasets but I should note that in general a dataset may contain n-dimensional data. So a more complete example would also have code to retrieve 3D hyperslices from a possible n-dimensional space.
The nice thing is that when we use a command we get a simple GUI for free. As shown below.