ImageJ CLAHE plugin

Hi, Dear ImageJ developers,

ImageJ CLAHE works very well manually for processing our 16bit grayscale radiography images, but we now need to run CLAHE in a Windows program. We tried OpenCV 3.1 CLAHE, but it didn’t work for the 16bit grayscale images. So we’re attempting to port ImageJ CLAHE to a C++ program, but so far, we couldn’t get images processed similarly to ImageJ’s CLAHE.

Has anyone done such porting? Any suggestions and guidance in this regard? (We can share the C++ code if necessary.)

Thanks.

Philosophically, a core goal of ImageJ is to avoid duplication of code because of the duplication of effort, increased maintenance burden, etc…

We usually look for interoperability bridges (e.g., JNI, KNIME, scripts).

Can you provide more information about why running in ImageJ is insufficient?

If you find you absolutely must create a C++ version of CLAHE, note that the plugin’s wiki entry has a link to the source code. So personally I would start there and look at tools wrapping Java to C++ libraries, such as Jar2Lib.

2 Likes

The reason why we have to create a C++ port for the ImageJ CLAHE is because the users want to use CLAHE programmatically in a pipeline that is supported by their current Windows program.

We’ve been looking over the source and struggling to try to port the Java code to C++ manually, as it is fairly small. The ported C++ code looked straightforward and matching to the Java code, but the C++ processing results aren’t produced properly – Not match with the ImageJ CLAHE’s processed results for the same images. Just wonder if there are anyone else who tried to port and what issues that they encountered. Getting the C++ code processing the images to produce results similar to ImageJ CLAHE is what we’re struggling…

Again, we’d share the C++ code if there is any interest. Any helps from this forum would be greatly appreciated.

Thanks for the tip to the Jar2Lib. May try it.

(We also tried OpenCV’s CLAHE, and it is documented not working probably with 16bit grayscale radiography images.)

Has there been anyone who did porting of ImageJ CLAHE to C++ or C#?

Any info sharing would be greatly appreciated.

Hi, If it needs to run in a standalone “windows” program: I do something like that regularly, however, I stick with Java. I develop in Netbeans and use that for the user interface design. Then import ImageJ core and plugins as libraries and use as Java classes. This mostly works just fine. Although I have to admit I found this post because I have trouble getting CLAHE to work this way. It does not seem to have a nice class with “setup” and “run” methods to pass an image to the plugin and get the result back. I wonder if Stephan Saalfeld sdtill maintains this and could help pout with it?

bye,
Rob

1 Like

@Celerity Do you think it would be sufficient if ImageJ had a general-purpose interprocess solution in the form of a RESTful server? We are looking at implementing one in coming months. Perhaps this gives you sufficient integration with your C++ application?

Or in the meantime, you could do a system call to the ImageJ launcher running CLAHE headless to compute the answers you need.

I will second @hinerm’s comments that we really try not to maintain duplicate implementations of code, but rather look for ways of bridging these barriers. LOCI’s core ImageJ team cannot help with C++ projects (we are not experts at that language).

The mpicbg.ij.clahe.Plugin class implements ij.plugin.PlugIn and does have the setup(ImagePlus imp) and run(String arg) methods; in addition, it provides a run(ImagePlus imp) method for static processing:

You can find which class is called by the menu command Process > Enhanced Local Contrast (CLAHE) by running the Command Finder (type L) and typing “CLAHE”.

2 Likes

Dear Jan,
Thanks for the reply. I’m still a bit in the dark how to run this in Netbeans (while not running ImageJ). Normally I would do something like this (using the Skeletonize3D plugin as example):

Skeletonize3D_ skeletonize = new Skeletonize3D_();
ImagePlus skelImg = new ImagePlus("skeleton", impObject.getProcessor().duplicate());
ImageProcessor skelProc = skelImg.getProcessor();
int skelRet = skeletonize.setup("", skelImg);
skeletonize.run(skelProc);

However, if I do:

private mpicbg.ij.clahe.PlugIn rhClahe=new mpicbg.ij.clahe.PlugIn();

or

private PlugIn rhClahe=newPlugIn();

I end up with an object that gives errors “package rhClahe does not exist” whenever I try to do something like “,run()”

and

import mpicbg.ij.clahe.PlugIn;

leads to the error "a type with the same simple name is already defined by the single-type-import of PlugIn"
Which I can overcome by removing “import ij.plugin.PlugIn;”

The parameter like bins, blockradius etc are private without getters or setters. So hard to modify. I know none of this is an issue if the plugin is run from within ImageJ, but for me, using plugins as libraries in a standalone application, this makes things tricky. Of course I am an amateur programmer, and really do welcome any tips on how to make this work.

many thanks,

Rob

Note that Skeleton3D implements ij.plugin.filter.PlugInFilter, not ij.plugin.PlugIn.

You should however be able to run the CLAHE plugin on a lower level by calling Flat.getInstance().run() as seen in its run() method cited above:

import mpicbg.ij.clahe.Flat;

// ...

Flat.getInstance().run( imp, blockRadius, bins, slope, mask, composite );

See also the MPI-CBG javadoc.

2 Likes

Thanks very much Jan, that did the job! Wouldn’t have figured it out without your help.

best wishes,
Rob

1 Like