This is an archive of the old MediaWiki-based ImageJ wiki. The current website can be found at

ImageJ Ops

ImageJ Ops
Project ImageJ
Source on GitHub
License BSD-2
Release 0.38.0
Date Wed May 24 15:08:10 CDT 2017
Development status Active
Support status Active
Founders Curtis Rueden, Christian Dietz, Martin Horn, Johannes Schindelin
Leads Curtis Rueden, Christian Dietz
Developers Curtis Rueden, Christian Dietz, Brian Northan, Gabriel Einsdorf, Tim-Oliver Buchholz, Leon Yang
Debuggers Curtis Rueden, Christian Dietz, Brian Northan
Reviewers Curtis Rueden, Christian Dietz, Brian Northan
Support Curtis Rueden, Christian Dietz, Brian Northan, Tim-Oliver Buchholz
Maintainers Curtis Rueden, Christian Dietz
Contributors Martin Horn, Johannes Schindelin, Richard Domander, Jan Eglinger, Andreas Graumann, Jonathan Hale, Kyle Harrington, Eike Heinz, Stefan Helfrich, Mark Hiner, Aparna Pal, Simon Schmid, Daniel Seebacher, Alison Walter, Michael Zinsmaier

ImageJ Ops is a framework for reusable image processing operations. Ops extends Java's mantra of "write once, run anywhere" to image processing algorithms.

The central goal is to enable programmers to code an image processing algorithm in the Ops framework, which is then usable as-is from any SciJava-compatible software project, such as ImageJ, CellProfiler, KNIME, OMERO and Alida.

Source code
Project management
Coding style
Writing plugins
ImageJ Ops
Contributing to a plugin
Distributing your plugins
Development lifecycle
Building a POM
Developing with Eclipse
Hands-on debugging
Adding new ops
Adding new formats
Using native libraries
Tips for developers
Tips for C++ developers
ImageJ 1.x plugins

Design goals

Ops has three major design goals:

  1. Easy to use and extend. There must be a wealth of easy-to-use image processing operations ("ops"), as well as an easy framework for extending those ops in new directions.
  2. Powerful and general. An op should be able to consist of any number of typed input and output parameters, operating on arbitrary data structures, including images of N dimensions stored in a myriad of different ways: as files on disk, programmatically generated in memory, or in remote databases. Using the powerful ImgLib2 library achieves this ambitious goal.
  3. Very fast. Even though ImgLib2 is vastly more general than ImageJ 1.x's data model, that generality should not come at the expense of performance. Otherwise, users must pay a time tax to do the same things they could already do in ImageJ 1.x. The ImageJ Ops framework needs to provide a means to override any general-but-slow op with a faster-but-more-specific alternative, fully transparently to the user.

Getting started

Start by reading these Jupyter notebooks:

Ops are a special type of ImageJ plugin, so a basic understanding of the SciJava plugin framework is strongly recommended.

In addition to cloning the imagej-ops itself, the following components have useful Ops examples:

Tutorials and workshops


Why not implement algorithms as "plain old Java" methods?

The Ops matching framework provides extensibility. Ops are plugins, so any developer can override the behavior of a particular op as needed—e.g., for improved performance of a special case. See "Design goals" above.

Can a C/C++ or MATLAB function be converted to an op?

Yes, but there is no automagic wrapping of native/external functionality in Ops. The ops-experiments project is an ongoing effort to work out a maven based build system for ops that use native code. The efforts so far have focused on wrapping, cuda, mkl and tensorflow implementations of deconvolution algorithms using javacpp.

Is there a list of Ops somewhere with brief descriptions of their functionalities?

For an interactive tool to see all available Ops, see the Op Finder documentation.

For the core Ops available, you can go to the ImageJ Ops javadocs. Any class under the package net.imagej.ops is related to Ops.

You can also use the Script Editor in ImageJ and actively search using Ops itself. For example in groovy language:

// @OpService ops

in groovy will give a list of every Op signature. The help op can also provide information about ops or namespaces; e.g.,"add") will return info about available add ops.

Are there any Ops for image processing?

Yes, there are. Take a look at the existing ops using the Ops Browser or the net.imagej.ops.* packages in the ImageJ javadocs.

What are the Ops that need to be developed in the future?

Ops is under development at the moment, as indicated by the 0.x.x version number. For ideas and discussions of future developments visit the ImageJ Ops GitHub page and take a look at the issues and pull requests.

Why is matching important?

This is a necessary part of any plugin-based infrastructure (see inversion of control). The core library (ImageJ Ops) has many built-in operations, but:

  1. cannot possibly cover all possible implementations and
  2. would be impractical if a user had to explicitly call the precise signature for their arguments.

Ops matching is an additional layer that allows plugin selection to be tailored to the arguments of the function being called.

A contrived example: Suppose the default ops implementation of add(array, array) iterates over the arrays and combines their values.

Then guava comes up with a way to combine arrays that is 100x faster; we do not want a guava dependency in the base ops library, but we can have an "imagej-ops-guava" component that provides a GuavaAddArrayOp.

Then an independent developer comes up with a new way to add the arrays that's 50,000x faster. They turn it into a closed-source, proprietary Op and sell it.

Regardless of this proliferation of implementations, a user just has to write ops.math().add(array1, array2) and it will work. If they have the guava implementation on their classpath it will be faster, and if they purchase the proprietary implementation it will be faster still. But their code does not have to be adjusted.

See also