Stream HPC

ImageJ and OpenCL

For a customer I’m writing a plugin for ImageJ, a toolkit for image-processing and analysis in Java. Rick Lentz has written an OpenCL-plugin using JOCL. In the tutorial step 1 is installing the great OS Ubuntu, but that would not be the fastest way to get it going, and since JOCL is multi-platform this step should be skippable. Furthermore I rewrote most of the code, so it is a little more convenient to use.

In this blog-post I’ll explain how to get it up and running within 10 minutes with the provided information.

Download

Download ImageJ here. It works better with a complete Java-distribution as a sub-directory for some reason, but with some tweaking (hint: make sure some ‘jre/lib/ext/tools.jar’ exists), it works with your own Java-distribution.

Second you need our StreamHPC.ImageJ-OpenCL-plugin and unzip it in the imageJ-directory. It contains a simple OpenCL Sobel filter, libraries, and an altered shell-script for Linux-32 (as an example). The zip-file contains the libraries for all operating systems. To make sure the libraries get loaded, you have to start ImageJ as follows, Linux (32 and 64):

java -Djava.library.path=./lib/Linux32/:./lib/:${LD_LIBRARY_PATH} -Xmx512m -jar ij.jar

java -Djava.library.path=./lib/Linux64/:./lib/:${LD_LIBRARY_PATH} -Xmx512m -jar ij.jar

Windows (32 and 64):

java -Djava.library.path=./lib/Windows32/;%PATH% -Xmx512m -jar ij.jar

java -Djava.library.path=./lib/Windows64/;%PATH% -Xmx512m -jar ij.jar

OSX:

java -Djava.library.path=./lib/OSX/:${LD_LIBRARY_PATH} -Xmx512m -jar ij.jar

Installing

I assume you have your OpenCL-environment set up correctly. If not, please go to the OpenCL-pages of Intel, NVIDIA or AMD.

So you just added the files to the ImageJ-directory and the ImageJ GUI is in front of you. To test if compiling works, try to first compile any example by going to “Plugins” -> “Compile and run…” and pick a Java-file from the Examples-directory. If there is an error complaining that javac is not available, fix that first by making sure the Java-SDK is installed on your computer and tools.jar can be found.

Now open any image. Go to “Compile and run…” again and select OpenCL_Sobel.java from the OpenCL-directory. If all goes ok, restart ImageJ and you’ll find a new directory “OpenCL” with “Sobel OpenCL” in it.

Bugs and so

As far as I know, there are a few known bugs in my code:

  • No support for endianness. Coming later.
  • ImageJ does not close in some cases. ‘NO_CHANGES’ in the setup()-function avoided this problem.
  • There are sporadic core-dumps. I think I fixed them all, but let me know what I missed.
  • The class does not support multiple images currently. I also haven’t checked my code with different image-types or even optimised for that.
  • The code is not optimised for speed.
  • The resulting image is in grey-scale. Tips anyone?

So in other words: it is a proof of concept and I hope you like it. The plugin will have some updates in the future, announced via Twitter. JOCL can be updated via the “Plugins” ->” Tools”. The latest JOCL-libraries can be dowloaded here.

Your own plugin

Building your own code, based on this one, is easy.

program = opencl.buildFromFile(“sobel.cl“, “”);
queue = opencl.createQueue(program, imageProcessor);
queue.createFloatBuffers();
queue.createStandardFloatKernel(“sobel“);
// queue.addKernelArg(some_argument);
FloatBuffer outputBuffer = queue.doFloatQueue();
opencl.release(queue);
opencl.release(program);

You only to alter the green parts. Make also sure that the Class-name has a underscore, else it will not show up in the ImageJ-plugin-menu.

In case of cl_invalid_mem_object, the kernel does not have a float* as first two arguments. A kernel should look like:

__kernel void kernelname( __global const float* input, __global float* output, int width, int height )

Extra arguments can be added of type float, int, float[] and int[]. By example:

float[] horCoefs = new Float[]  {1,0,-1,   2,0,-2,  1,0,-1} ;
float[] verCoefs = new Float[]  {-1,-2,-1,  0,0,0,  1,2,1} ;
opencl.addKernelArg(“sobel”, horCoefs);
opencl.addKernelArg(“sobel”, verCoefs);

This would make sure the arguments “const float* coef_ver” and “const float* coef_hor” of your kernel get their data.

If you have problems, send me an e-mail or put a comment here below and I’ll look into it.

Alternative: 4Pixels CTK workbench

update: 4pixels is out of business. CEO works at NVidia now.

ImageJ might be a good place to test out your OpenCL-kernels, but there is software called “CTK Workbench” available which does this much more easier. You can check it out at 4Pixels’ website; a 30 days demo is available. The software is written with the Qt library and works perfectly under Wine, so it is multi-platform.

By drag-and-drop you can setup the base for your experiment. Several kernels are included, but you can easily add your own.

More of ImageJ?

If you want your own ImageJ-plugin with OpenCL-support, contact us for details. We can also provide a multi-kernel version of the plugin.