从 Mathematica 调用 ImageJ

发布于 2025-01-01 10:09:01 字数 184 浏览 2 评论 0原文

从 Mathematica,我希望将图像传递到 ImageJ 插件,并将结果从 ImageJ 发送到 Mathematica。

JLink 是一个可以提供帮助的工具,但我既不熟悉它,也不熟悉 ImageJ(这使得很难利用 SO 上现有的相关问题)。你知道该怎么做吗?

(我已经在我的 Mac 上安装了 ImageJ。)

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时间海 2025-01-08 10:09:01

这应该只是作为一个预告片,向您展示这并不像看起来那么难。没有办法,您必须熟悉 Java、ImageJ-API,当然还有 JLink。

开始的方法如下:您需要 ImageJ java 存档 ij.jar,您可以从 ImageJ 网站。该 jar 包含 ImageJ 本身使用的所有类和函数。

您想要做的是创建图像,而不是通过 ImageJ-GUI 打开它,而是使用 Java 方法。为此,您必须熟悉 ImageJ-API 以了解如何从数字数组等创建图像,因为这就是我们希望将 Mathematica 图像传输到 Java 的方式。
浏览此文档后,我找到了 ImageProcessor 类。正如您所看到的,它们提供了两种方法:setPixelsgetPixels,并且都接受简单数组。让我们使用它并编写一个非常基本的过滤器:

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();
    }
}

该函数获取图像数据和图像尺寸,进行卷积并返回过滤后的图像数据。要编译此文件,请记住 ij.process.FloatProcessor 位于 ij.jar 内。您必须将此存档包含在您的类路径中。稍后,您必须确保 JLink 找到 ij.jar 和您的 SimpleTest.class。我通常也将我的课程打包在一个罐子里。为此,我将其命名为 simple.jar

虽然 Java 端现在已经准备就绪,但我们需要几行代码来从 Mathematica 图像中提取图像数据和尺寸。

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

我们现在要做的是将平面整数数组 data 发送到我们的 Java-函数,获取结果并构建输出图像。为了让 Mathematica 找到您的 jar 档案,一种方法是调用 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]]

通过最后一步,我们完成了循环并得到最终结果。

最后注意事项:

  • 您也许应该(这意味着“这样做”)使用 JLink 用于编译代码的相同 java 版本。
  • ij.jar 中已经有插件。这不会包括所有可用的东西。但请记住:ImageJ-GUI 只是调用 ij.jar 中的方法来使用辅助插件,因此您可以对代码执行相同的操作。
  • 某些插件使用本机(JNI)代码,当您在 Mathematica 中使用它时,可能会导致意外错误

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文