Calling ImageJ from Mathematica
Asked Answered
K

1

9

From Mathematica, I wish to pass an image to an ImageJ plugin and get the result sent from ImageJ to Mathematica.

JLink is the tool that will help, but I am familiar neither with it nor with ImageJ (making it hard to leverage existing related questions on SO). Would you know how to do that?

(I have installed ImageJ on my mac already.)

Kiushu answered 2/2, 2012 at 6:9 Comment(5)
Presumably you'll have to read the ImageJ API for starters. Could you give an example of a problem that you need to use ImageJ for? There are several Mathematica participants here who are experts in image processing and may be able to suggest native Mathematica methods. You may also want to consider posting here: mathematica.stackexchange.com/questionsParaselene
Can you give some (simple!) example Java code that demonstrates how to use ImageJ? This is the first step. Then we can translate that code to JLink.Bulwark
@MikeHoneychurch Good idea, I shall cross-post if nothing comes up here. I'm interested in ImageJ plugins which are not in Mathematica.Kiushu
@Bulwark That's part of the question... it seems there can be different types of ImageJ plugins. I still need to figure out how to call them programmatically.Kiushu
If you worked on this, perhaps you can contribute an answer here: mathematica.stackexchange.com/q/180513/12Bulwark
G
5

This should only serve as teaser to show you, that this is not as hard as it seems. There is no way around, that you have to be familiar with Java, the ImageJ-API, and yes, JLink.

So here is how you get started: You need the ImageJ java archive ij.jar which you can download from the ImageJ Website. This jar contains all classes and functions ImageJ is using by itself.

What you want to do is to create an image not by opening it through the ImageJ-GUI but by using Java-methods. For this you have to get familiar with the ImageJ-API to know how you can create an image from e.g. an array of numbers, because that's how we want to transfer the Mathematica-images to Java. Skimming through this documentation brought me to the ImageProcessor classes. As you can see they provide two methods: setPixels and getPixels and both accept simple arrays. Let's use this and write a very basic filter:

import ij.process.FloatProcessor;

public class SimpleTest {

    public static float[] func(float []bm, int nx, int ny) {
        FloatProcessor p = new FloatProcessor(nx,ny);
        p.setPixels(bm);
        float[] kernel = new float[{0.111f,0.111f,0.111f,0.111f,
                                    0.111f,0.111f,0.111f,0.111f,0.111f};
        p.convolve(kernel, 3, 3);
        return (float[]) p.getPixels();
    }
}

This function gets the image-data and the image-dimensions, does a convolution and returns the filtered image-data. To compile this, remember that ij.process.FloatProcessor is inside the ij.jar. You have to include this archive in your classpath. Later, you have to ensure that JLink finds both, the ij.jar and your SimpleTest.class. I usually pack my classes inside a jar too. For this I called it simple.jar.

While the java-side is now ready to rock, we need a few lines to extract image-data and dimensions from a Mathematica-image

img = ColorConvert[ExampleData[{"TestImage", "Lena"}], "Grayscale"];
{nx, ny} = ImageDimensions[img];
data = ImageData[img] // Flatten;

What we do now is sending the flat integer array data to our Java-function, taking the result and building the output-image. To make Mathematica find your jar-archives, one way is to call AppendToClassPath:

Needs["JLink`"]
AddToClassPath["/pathTo/ij.jar","pathTo/simple.jar"];

simpleTest = LoadJavaClass["SimpleTest", StaticsVisible -> True];
output = SimpleTest`func[data, nx, ny];
Image[Partition[output, nx]]

With this last step we complete the cycle and get our final result.

Final notes:

  • You should maybe (and this means "do it") use the same java-version JLink is using for the compilation of your code.
  • There are already plugins in the ij.jar. This will not include all available stuff. But remember: The ImageJ-GUI just calls methods from ij.jar to use auxiliary plugins, so you can do the same with your code.
  • Some plugins use native (JNI) code which may lead to unexpected errors, when you use this from within Mathematica
Griskin answered 3/2, 2012 at 6:59 Comment(2)
Thanks for the proof of concept. Indeed I would need to sit down and read more doc, and then perhaps ask more specific questions.Kiushu
I never did something with ImageJ either and to look the stuff up took only a few minutes. Therefore, chances are good that your learning curve will be very steep. Take a good Java-IDE! That's half the way. You could of course take instead C++ and use ITK. Then you could ask your colleques how to set things up quickly ;-)Griskin

© 2022 - 2024 — McMap. All rights reserved.