以下是截至 2011 年 8 月 2 日的状态更新。昨天,我们released ImageJ 2.0.0-alpha4,自 12 月上次重大状态更新以来,我们在许多领域取得了巨大进展。
数据与显示

ImageJ2 pixel types: ImageJ2 supports many more types of image data.
ImageJ2 uses the ImgLib2 library for its N-dimensional data model. As such, it natively supports many more types of images than ImageJ 1.x, including: signed and unsigned integers of 8, 16 and 32 bits; 1-bit packed binary images (see right); 12-bit packed unsigned integers, which are increasingly common in scientific imaging; 64-bit signed integers; and floating point (i.e., real) images of 32 or 64 bits.

Binary image: A 1-bit image displayed in ImageJ2.
ImageJ2 provides full support for color lookup tables (LUTs), with one LUT per image plane when available in the original data, or else one LUT per channel, similar to ImageJ 1.x’s CompositeImage. For 24-bit packed RGB data, ImageJ2 transforms it into 8-bit unsigned integer data with three channels (which requires no extra memory), then uses appropriate lookup tables to composite the image as RGB—that is, the first channel has a black-to-red LUT, the second black-to-green, and the third black-to-blue. Hence, RGB images display as expected while providing individual access to each channel. ImageJ2 does support ImageJ 1.x’s “RGB Color” images for compatibility purposes—you can flag an image as “RGB Color” and legacy plugins will see 24-bit packed RGB data. But the distinction exists only for the benefit of ImageJ 1.x legacy plugins.
数据和显示架构允许将多个数据集添加到单个显示器,或者允许同一数据集在多个显示器中以不同方式显示。我们仍在最终确定此架构,但从根本上讲它是有效的,尽管这些功能尚未通过用户界面公开。我们使用此功能的目标是实现我们在科学界看到的更多用例,例如通过引用进行基于图块的图像配准 TrakEM2 和 multiview orthographic projections(即无需在内存中维护图像数据的多个副本)。
我们还扩大了对 ROI 和覆盖的支持。 ImageJ2 不是一次只允许一个 ROI,而是内置了对多个不同覆盖的支持,既可以定义要处理的感兴趣区域,也可以注释图像以供发布和共享。代码的 ROI 部分(即,该像素是在 ROI 的“内”还是“外”?)在 ImgLib2 层中定义,而覆盖部分(即,我的浮动文本是什么颜色?)是 ImageJ 显示层的一部分。
ImageJ2 插件

Math plugins: ImageJ2 math plugins.
We have reimplemented many ImageJ 1.x plugins within the ImageJ2 extensibility framework. These plugins illustrate some of the features of ImageJ2, and serve as examples for how to bring legacy plugins up to date.
ImageJ2 支持多种类型的插件,具体取决于您想要执行的操作。最直接的是ImageJPlugin,它的实现与 IJ1 的Plugin 接口一样简单,只有一个方法 run() 可以执行插件命令。不同之处在于,插件的输入和输出是使用带有 @Parameter 注释的实例字段显式声明的。这样就无需像 IJ1 中那样编写以 UI 为中心的 GenericDialog 代码,并为所有此类插件提供自动脚本编写功能。
ImageJ2 2.0.0-alpha4 引入了另一种更灵活的 ImageJPlugin 类型:DynamicPlugin。通过扩展这个抽象类,插件可以在运行时动态添加、修改和删除其输入和输出。这对于必须提示输入有关当前数据集的每个轴的信息的插件很有用。
另一种类型的插件是Display,它是一段更复杂的代码,能够以某种方式可视化数据。核心 ImageJ 图像查看器作为 Display 实现。
最后,还有在 ImageJPlugin 上运行的 PreprocessorPlugin 和 PostprocessorPlugin。可用的PreprocessorPlugin在插件运行之前应用,允许他们准备插件执行。例如,名为“输入收集器”的PreprocessorPlugin会弹出一个对话框,提示用户输入插件输入的值,类似于IJ1中的GenericDialog。类似地,PostprocessorPlugins 在插件运行后立即执行,并且对于处理结果很有用。一个名为“显示后处理器”的PostprocessorPlugin负责显示插件生成的任何输出数据集。

ImageJ2 Command Finder: ImageJ2's version of the Command Finder plugin, one of the most useful plugins in ImageJ 1.x. This tool can quickly locate and run any plugin by name. We have updated it to support both IJ1 and IJ2 plugins, as well as report more information on the plugins if desired.
All of the above types of plugins are automatically discovered at runtime. The menu bar is constructed from available ImageJPlugins, the Displays are automatically invoked as appropriate when a dataset is created, and the preprocessor and postprocessor plugins are applied automatically as well when a plugin is executed. Changing the behavior of ImageJ is as simple as providing the desired functionality on the Java classpath. As such, ImageJ2 is capable of running in a fully headless environment.
每当执行命令时,还会生成一整套事件。当第一次调用命令时,会触发 ModuleStartingEvent;预处理器被逐一调用,每个预处理器在完成后都会触发 ModulePreprocessEvent;然后 ModuleExecutingEvent 被触发,表明命令本身正在运行; a ModuleExecutedEvent 当命令运行完成时触发;后处理器被一一调用,每个处理器在完成后都会触发 ModulePostprocessEvent;最后,ModuleFinishedEvent表示整个过程完成。
就像在 IJ1 中一样,正如您可能从上面的术语中猜到的那样,插件并不是唯一可以执行的命令类型。还有脚本、IJ1 宏和其他实现基本 ImageJ 命令接口的自定义代码:Module 和 ModuleInfo。因此,并非所有命令都是插件(例如,命令可能是脚本或自定义模块),也并非所有插件都是命令(例如,插件可能是 Display、PreprocessorPlugin 或 PostprocessorPlugin)。

Event Debugger: The Event Watcher plugin monitors various ImageJ events.
To help keep track of all these details, we have created several plugins useful for debugging ImageJ2 during development. With these plugins (located in the Plugins › Debug submenu), you can monitor every event published, every object being tracked including Datasets and Displays, inspect the details of an image’s data structure, and more. Of course, you can do many of these things with an IDE such as Eclipse or NetBeans, but providing these tools from the ImageJ application itself provides more a posteriori debugging capabilities to end users when problems occur.
我们的最终目标是将所有现有的核心 IJ1 插件转换为 IJ2 框架。目前,IJ1 中的大部分功能都可以通过遗留层在 IJ2 中访问(见下文),但是通过重新实现“纯 IJ2”中的插件,我们可以慢慢逐步淘汰遗留层。这样做很重要,因为运行 ImageJ 1.x headless 时会出现问题,因此很难将其用作库。相比之下,ImageJ2 的插件框架在设计时就考虑到了无头操作。
ImageJ2 模块化
我们投入了大量精力将 ImageJ2 的各个部分封装为尽可能独立运行的单独“服务”。截至撰写本文时,主要核心服务如下:
EventService- 将事件发布到event bus,并允许感兴趣的各方订阅它们。该服务提供了代码库各个部分之间通信的中心方式。ObjectService- 跟踪各种类型的可用对象,包括Dataset和Display。PlatformService- 提供用于根据部署平台(操作系统、Java 版本等)扩展 ImageJ 行为的钩子ModuleService- 跟踪可用模块,并提供执行它们的基础设施。PluginService- 跟踪可用插件,并提供执行它们的基础设施(使用ModuleService)。DisplayService- 跟踪可用显示以及活动显示,并提供创建新显示以可视化数据的方法。LegacyService- 实现与 ImageJ 1.x 的兼容性,根据需要在 IJ1 之间来回转换 IJ2 数据结构以运行旧版 IJ1 命令。ToolService- 跟踪可用工具(将用户输入与行为绑定的逻辑)以及活动工具(在工具栏上选择)。UIService- 发现并启动用于与 ImageJ 交互的用户界面。OverlayService- 跟踪可用的叠加层。
ImageJ类的实例只不过是这些服务的集合;该实例称为“应用程序上下文”。虽然 ImageJ 1.x 是一个单例,使用静态方法来访问其大部分功能,但我们已经完成了允许在同一 JVM 中同时存在多个 ImageJ 应用程序上下文所需的大部分基础工作。
ImageJ2互操作性
虽然核心Java API可以在多个平台上使用,但API的某些子集在某些情况下可能会出现问题。特别是,在无头运行时使用AWT可能会导致问题(即使设置了java.awt.headless=true)。我们煞费苦心地避免在ImageJ2核心项目中引用所有AWT包。我们甚至发明了自己的类事件层次结构,而不是重用第§§2§§§中的事件(例如,对于鼠标和事件键盘)。
AWT 和 Swing 的所有使用都包含在 core 项目之外的 ui 项目中,这些项目实现了 ImageJ2 用户界面。我们的大部分开发工作都投入到了 Swing 用户界面中,我们也有一个纯 AWT 的原型(类似于 IJ1),以及 Apache Pivot 和 Eclipse SWT,还计划了操作系统驱动的“无头”UI。
我们希望,在未来,这种仔细的关注点分离可以更轻松地与各种开发环境中的ImageJ进行互操作,例如用于Web开发的§§12§§§、用于移动设备的Android或用于.NET应用程序中的IKVM.NET。然而,仍然存在一些挑战,例如,ImageJ2和ImgLib2大量使用类型泛化,这可能会限制代码的可移植性。尽管如此,只要ImageJ2可以在无头上下文中完全使用,我们就可以通过客户端/架构服务器(例如Web服务)它是公开的,以设置能够在非Java代码中使用。
与 ImageJ 1.x 的兼容性
ImageJ2 继承层提供了与 ImageJ 1.x 的兼容,允许 ImageJ2 并填充继承的 IJ1 插件,就像 IJ1 所做的那样,继承插件在菜单结构中为指定小括号负责标记。 ImageJ2 名为使用 §§13§§§ 的字节工程库来拦截发生的重要 IJ1 事件,并调整行为以与 IJ2 发现无缝匹配。继承层继承需要根据在 ImageJ 1.x(例如,ImagePlus 和 ROI)和 ImageJ2(例如,Dataset、Overlay 和 §插件§8§§§)之间来回转换数据结构,并通过引用引用。该技术允许在 IJ2 数据结构上调用 IJ1 命令,反之亦然,而用户担心大量来自何处。
光谱消耗图像分析

Slim Plugin: Analyzing spectral lifetime data in ImageJ.
For the past several months we have been developing an ImageJ plugin for visualization and analysis of combined spectral lifetime data. While this plugin is functional in ImageJ 1.x, we plan to update it to an ImageJ2 plugin in time for the ImageJ2 release. The plugin will benefit from the more flexible design of ImageJ2 in several ways. First, it utilizes dimensions beyond space and time, so can take advantage of IJ2’s N-dimensional data capabilities. Second, it presents several views into the same data, so will benefit from IJ2’s separation of data and display. Lastly, it demonstrates IJ2’s pluggable display architecture by implementing its own custom display.
未来的方向
我们在显示架构上还有更多的工作要做,以充分实现上述所有目标和想法。仍然存在许多我们必须克服的错误和限制,特别是在覆盖方面。
一旦 API 基本稳定,并且应用程序的行为关注于 ImageJ 1.x,我们将发布 beta 版本以供社区反馈。我们将社区视为一个范围,一端由不编程但希望能够通过 UI 完成所有操作的最终用户组成,另一端由希望以编程方式调用 ImageJ 功能将其部分功能嵌入到自己的应用程序中的开发人员组成中。中间有许多人,他们编写了一些脚本或宏来自动化分析,但也充分利用了UI。通过ImageJ2,我们的目标是整个社区。
今年,ImageJ2 将与 ImageJ 的第 Fiji 发行版合并,以提供自动更新程序,包括多个更新站点,每个更新站点都提供自己的插件。通过这种方式,开发人员可以启动自己的 ImageJ 插件集合,最终用户比以往更容易安装和保持更新 — 不再需要从各个手动网站下载 JAR 文件将它们放入文件夹中(如果您,这仍然可以工作)。
我们还计划更新 ImageJ 网站。特别是,我们将部署网站的一个新部分,其中包含该集中的插件列表。列表将满足无缝,来自注册更新站点的所有插件都会自动提供,供用户评论、评分、标记和讨论,从而更容易找到 ImageJ 插件、脚本和其他提供跨多个领域功能的扩展。 有关未来方向的更多信息,请参阅ImageJ roadmap。