在处理图像和三维数据方面有一个强大且拓展性强的软件ImageJ,ImageJ本身功能不是特别多,但是多年以来积累了丰富的插件,使得其成为专业图像处理和数据科学、医学图像处理等领域的利器。FIJI ImageJ打包了很多插件,可以实现很多功能,但是总有需求超出功能的时候,我们可能希望自己开发插件。
ImageJ支持多种形式的拓展,支持用我们熟悉的Python语言(Jython)进行拓展开发,也支持JS脚本的macro开发,还支持Java开发的插件。实际上ImageJ开发插件是很简单的,有时候我们只需在demo代码基础上改上短短几行就能实现我们自己定制化的功能。这篇博客主要简单介绍script、macro和plugin开发的流程,指引一下资源位置,给简单的流程介绍,不会具体深入代码层面。
插件检索
建议使用FIJI ImageJ。开发插件之前首先确定我们需要的功能是否已经有人开发好,这样我们就可以直接拿来用了。FIJI ImageJ的本体就是ImageJ,FIJI打包了很多插件,我们可以先检查下有没有插件适合我们(或者功能相近,方便我们后面copy代码)。
在插件网站上查找有没有我们可以直接使用的插件或者代码,这里一般在搜索引擎或者官网进行检索:
在help->plugin management 插件更新管理中,可以看到已经安装的插件对应的网址
imagej nih的官网:imagej.nih.gov 其上方的plugins和resources中可以进行相关的查找
知乎也有专栏,介绍一些插件的使用:
https://zhuanlan.zhihu.com/c_1069243926476673024
Python脚本开发
fiji是支持python的(jython),我们可以使用熟悉的python来对imagej进行拓展
官网介绍:https://imagej.net/Jython_Scripting
https://imagej.net/scripting/jython/examples#jython-tutorials-for-imagej
脚本交互界面教程:https://imagej.net/scripting/generic-dialog
fiji脚本教程:https://syn.mrc-lmb.cam.ac.uk/acardona/fiji-tutorial/
fiji脚本教程的中文翻译:https://qixinbo.info/2018/09/15/imagej-python/
我们有两种方式可以打开脚本编辑器:
File-New-Script打开或者,或者在Command finder按下字母“i”,然后输入script,打开编辑器后选择语言为python, 然后键入代码,我们就已经可以开始开发了
脚本和imageJ的交互接口都在 ij 这个包,具体使用可以读上面的文档,或者教程。这里给一个简单的从脚本中获取打开图像的例子感受一下:
from ij import IJ imp = IJ.getImage() print imp print "title:", imp.title print "width:", imp.width print "height:", imp.height print "number of pixels:", imp.width*imp.height print "number of slices:", imp.getNSlices() print "number of channels:", imp.getNChannels() print "number of time frames:", imp.getNFrames() types = {ImagePlus.COLOR_RGB: "RGB", ImagePlus.GRAY8: "8-bit", ImagePlus.GRAY16: "16-bit", ImagePlus.GRAY32: "32-bit", ImagePlus.COLOR_256: "8-bit color"} print "image type:", types[imp.type]
JS脚本macro开发引导
imagej中的宏就是一些可以快速执行的语句,其编写相对简单,不依赖额外环境,并且官网提供了很多demo,我们点开官网的macros->examples, 查找我们想要参考的例子,每个文件都是一个简单例子
我们把一个宏语句粘贴到我们程序中,这里我们可以选择Run运行文件,也可以选择Interactive Interpreter来交互执行
这里博主为了测试和调试选择交互执行,然后把命令文本粘贴进来就可以执行命令了,把命令保存成文件,也就可以变成一个简单插件了。
我们回来看下ArrayFunction部分的例子,其实有例子,代码也很容易看懂,和我们熟悉的其它脚本语言并无区别
// This macro demonstrates how to use the Array.* functions. requires("1.42j"); a1 = newArray(10, 5, 15, 2, 1.23456); a2 = Array.copy(a1); list("copy", a2); a2 = Array.trim(a1, 2); list("trim", a2); Array.sort(a1); list("sort", a1); Array.getStatistics(a1, min, max, mean, std); print("stats"); print(" min: "+min); print(" max: "+max); print(" mean: "+mean); print(" std dev: "+std); Array.fill(a1, -1); list("fill", a1); a1 = newArray("one", "two", "three", "four"); print(""); a2 = Array.copy(a1); list("copy", a2); a2 = Array.trim(a1, 2); list("trim", a2); Array.sort(a1); list("sort", a1); function list(name, a) { print(name); for (i=0; i<a.length; i++) print(" "+a[i]); }
我们在此基础上简单修改,一个插件就编写好了
插件开发引导
由于博主在M1 mac上遇到一些java环境问题,所以博主没有实际操作(对博主来说用python可以满足需求了,博主并不加密源码)。这部分内容参考自:https://qixinbo.info/2018/10/06/imagej-plugins/
插件开发的好处是使用Java,可以将程序编译打包,防止源码泄漏。由于imagej对插件开发的api有两套(imagej和imagej2),最好统一成fiji imagej的版本(imagej2)。
简述一下过程,就是使用IDE对代码进行编译,将编译成的jar包拷贝到Fiji.app/plugins目录下,然后就可以在菜单栏中发现该插件,点击运行就可以了。
希望能有帮助。