jython - 从 ImageJ/Fiji 脚本导入外部库/包

标签 jython imagej java

我正在使用 Fiji 脚本编辑器在 Jython 中编写 imageJ/Fiji 插件。我需要导入外部数值库(例如 ParallelColt)来帮助我处理多维矩阵。

我从 ParallelColt 开始,将其 jar 文件放置在斐济的 java 文件夹中: “Fiji.app/java/macosx-java3d/Home/lib/ext” 然后我尝试通过编写以下内容来导入它: “导入 ParallelColt”或更具体地说“从 ParallelColt 导入 jplasma” 我收到模块未找到的错误。

我尝试将 jar 放在斐济插件文件夹中,但使用 仍然没有成功。我还尝试使用包含所有 java 类的文件夹 ParallelColt 而不是 jar 文件,我仍然无法导入 我的脚本中的类。

我只是想问的问题是如何从 Jython 脚本导入 java 库。任何帮助将不胜感激。

最佳答案

这里有两个问题。

1。依赖项

为了依赖具有多个 JAR 文件的复杂第三方软件项目,您需要确保已放置该项目的所有依赖项(即它需要的所有 JAR 文件)进入ImageJ.app/jars

一种方法是 find the dependencies on Maven Central然后使用 Maven 或 Gradle 等构建工具下载它们。

在您的情况下,您可以通过制作以下 pom.xml 文件来使用 Maven 来完成此操作:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>dummy</groupId>
  <artifactId>dummy</artifactId>
  <version>0.0.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>net.sourceforge.parallelcolt</groupId>
      <artifactId>parallelcolt</artifactId>
      <version>0.10.1</version>
    </dependency>
    <dependency>
      <groupId>net.mikera</groupId>
      <artifactId>vectorz</artifactId>
      <version>0.34.0</version>
    </dependency>
  </dependencies>

</project>

然后执行:

mvn dependency:copy-dependencies

这将在 target/dependencies 文件夹中生成以下文件:

  29087 AMDJ-1.0.1.jar
   8687 BTFJ-1.0.1.jar
  19900 COLAMDJ-1.0.1.jar
  55638 JKLU-1.0.0.jar
1194003 arpack_combined_all-0.1.jar
  31162 core-lapack-0.1.jar
 212836 csparsej-1.1.1.jar
  88639 edn-java-0.4.4.jar
  91793 jplasma-1.2.0.jar
 762778 jtransforms-2.4.0.jar
 237344 junit-4.8.2.jar
   8693 mathz-0.3.0.jar
 131210 netlib-java-0.9.3.jar
  66134 optimization-1.0.jar
4111744 parallelcolt-0.10.1.jar
  14028 randomz-0.3.0.jar
 593015 vectorz-0.34.0.jar

将它们移至您的 ImageJ.app/jars 文件夹中,您就可以开始了——不过要注意同一库的多个版本,因为 ImageJ 目前无法处理该问题。

2。类引用

from ParallelColt import jplasma 无效。也就是说,没有 ParallelColt.jplasma Java 类或包。您可以从命令行自行验证:

$ find-class() { for f in *.jar; do result=$(jar tf "$f" | grep -l "$@"); if [ "$result" != "" ]; then echo $f; fi; done; }
$ cd ImageJ.app/jars
$ find-class jplasma

两个 JAR 文件的类包含该字符串:

core-lapack-0.1.jar
jplasma-1.2.0.jar

查看它们的内部很快就会发现包名称不是以 ParallelColt 开头:

$ jar tf jplasma-1.2.0.jar | grep jplasma
edu/emory/mathcs/jplasma/
edu/emory/mathcs/jplasma/benchmark/
edu/emory/mathcs/jplasma/test/
edu/emory/mathcs/jplasma/tdouble/
edu/emory/mathcs/jplasma/example/
edu/emory/mathcs/jplasma/benchmark/DgelsBenchmark.class
edu/emory/mathcs/jplasma/benchmark/DposvBenchmark.class
edu/emory/mathcs/jplasma/benchmark/DgesvBenchmark.class
edu/emory/mathcs/jplasma/Barrier.class
edu/emory/mathcs/jplasma/test/DposvTest.class
edu/emory/mathcs/jplasma/test/DgelsTest.class
edu/emory/mathcs/jplasma/test/DgesvTest.class
edu/emory/mathcs/jplasma/tdouble/Dgels.class
edu/emory/mathcs/jplasma/tdouble/Dgeqrf.class
edu/emory/mathcs/jplasma/tdouble/Dglobal$Dplasma_cntrl.class
edu/emory/mathcs/jplasma/tdouble/Dplasma.class
...
edu/emory/mathcs/jplasma/tdouble/Dglobal$Dplasma_aux.class
edu/emory/mathcs/jplasma/tdouble/Pdormqr.class
edu/emory/mathcs/jplasma/example/DposvExample.class
edu/emory/mathcs/jplasma/example/DgesvExample.class
edu/emory/mathcs/jplasma/example/DgelsExample.class

相反,如果您想使用例如edu.emory.mathcs.jplasma.tdouble.Dplasma,则需要将其导入为:

from edu.emory.mathcs.jplasma.tdouble import Dplasma

这是 DgelsExample.java 的端口来自JPlasma在 ImageJ 脚本编辑器中工作的发行版:

from edu.emory.mathcs.jplasma.tdouble import Dplasma
from java.lang import Math
import jarray

M = 15;
N = 10;
NRHS = 5;

A = jarray.zeros(M * N, 'd')
B = jarray.zeros(M * NRHS, 'd')

# Initialize A
for i in range(0, M):
    for j in range(0, N):
        A[M * j + i] = 0.5 - Math.random()

# Initialize B
for i in range(0, M):
    for j in range(0, NRHS):
        B[M * j + i] = Math.random()

# Plasma Initialize
Dplasma.plasma_Init(M, N, NRHS)

# Allocate T
T = Dplasma.plasma_Allocate_T(M, N)

# Solve the problem
INFO = Dplasma.plasma_DGELS(Dplasma.PlasmaNoTrans, M, N, NRHS, A, 0, M, T, 0, B, 0, M)

# Plasma Finalize
Dplasma.plasma_Finalize()

if INFO < 0:
    print("-- Error in DgelsExample example !")
else:
    print("-- Run successfull !")

请参阅Jython Scripting有关编写 Jython 脚本的更多信息,请访问 ImageJ Wiki 页面。

最后的评论:ImageJ 脚本编辑器实际上被设计为一种开发单类脚本和插件的工具,这些脚本和插件依赖于安装中已存在的组件。对于像这样具有许多依赖项的项目,我的建议是使用 Eclipse 等 IDE 来代替 Java 代码,因为此类 IDE 提供了更多提高生产力的功能。您可以使用基于 AST 的自动完成功能来探索您正在使用的库的 API,并轻松浏览 javadoc 和源代码,而无需进行 Web 搜索。

关于jython - 从 ImageJ/Fiji 脚本导入外部库/包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24312280/

相关文章:

java - 在 jython 中使用 jcifs 以便使用 NTLM 安全性访问站点

java - 在Spring Boot中使用YAML文件配置SMTP主机

java - 如何在 izpack-maven-plugin install.xml 中使用 Maven 项目属性?

java - 图像从 PNG 转换为 TIF 后无法删除图像文件

java - 在 Eclipse 或 PyCharm 中将 java 包导入到 jython 项目中

java - 使用 Jython 在 Spring Boot 应用程序中包含 Python 脚本失败 - 找不到模块

python - Python vs Jython vs IronPython vs wxPython有什么区别?

merge - 如何在 ImageJ 中将不同的堆栈合并在一起?

java - 从字节矩阵创建一组图像文件

macros - 改变目录的ImageJ宏代码