GPU-accelerated image processing in ImageJ using CLIJ
Many of CLIJ’s Kernels are also available as ImageJ Ops. There is also an extensive list of examples.
To use the CLIJ ImageJ Ops in your own project, link it as a maven dependency:
<dependency>
<groupId>net.haesleinhuepf</groupId>
<artifactId>clij-ops</artifactId>
<version>1.6.0</version>
</dependency>
To allow maven finding this artifact, add a repository to your pom.xml file:
<repository>
<id>clij</id>
<url>http://dl.bintray.com/haesleinhuepf/clij</url>
</repository>
When calling an Op, a CLIJService
will automatically initialize CLIJ if this did not already happen. In case you want to initialize CLIJ with a custom GPU, this is the way to go:
import net.imagej.ImageJ;
import net.haesleinhuepf.clij.CLIJService;
ImageJ ij = new ImageJ();
ij.get(CLIJService.class).get("Intel(R) HD Graphics Kabylake Desktop GT1.5");
Afterwards, you can convert RandomAccessibleInterval
or Img
objects to ClearCLBuffer
objects which makes them accessible on the OpenCL device:
Object input = ij.io().open("PATH_TO_IMAGE");
Object inputGPU = ij.op().run(CLIJ_push.class, input);
In this example, inputGPU
is of type ClearCLBuffer
, but while staying in the Ops domain Object
works fine and reduces casting. Which you can still do if you want to access it’s methods.
ClearCLBuffer buffer = (ClearCLBuffer) inputGPU;
Furthermore, you can create images, for example with the same size as a given one:
Object targetGPU = ij.op().run(CLIJ_create.class, inputGPU);
Alternatively, create an image with a given size and a given type:
Object targetGPU = ij.op().run(CLIJ_create.class, new long[] { buffer.getWidth(), buffer.getHeight() }, buffer.getNativeType());
Most CLIJ Ops are hybrid, meaning they can act both as a computer and a function (see the SpecialOps JavaDoc for further details). There are no inplace operations in CLIJ.
In this example the output object will be automatically generated and returned by the Op (function):
targetGPU = ij.op().run(CLIJ_maximumZProjection.class, inputGPU);
In the next example both the input and the output are created beforehand and handed to the Op (computer):
ij.op().run(CLIJ_maximumZProjection.class, targetGPU, inputGPU);
CAUTION Be aware that in this case the output is the first and the input is the second parameter, in contrast to other CLIJ APIs where the order is the other way around. The next ImageJ Op generation will revert this order, meaning that the order might change in a future version of CLIJ as well.
To get the image back into imglib2
format, call the CLIJ_pull
op:
Object target = ij.op().run(CLIJ_pull.class, targetGPU);
ij.ui().show(target);
More examples can be found here.