Using ImageJ Ops to add two Datasets inside a Plugin

Hi,

I want to port an algorithm I developed in Matlab to ImageJ2 using a Plugin and, as suggested on the ImageJ Website, I took a look at the imagej-tutorials repository, which really helped understanding the key concepts.
For the moment, I’m just trying to achieve simple tasks, one of which is to mix two Datasets together in the following fashion: res = alpha*im1+(1-alpha)*im2.
While the add-two-datasets example gives different ways to achieve a similar purpose, some of the methods used are labelled as deprecated and I thought it could be more interesting to use ImageJ Ops to perform the addition and multiplication, such as the ones proposed in the Math Namespace.
However I can’t figure out a way to convert a Dataset to any of the suggested parameters (for instance IterableInterval < T>). Which steps should I take in order to convert a Dataset to one of the suggested parameters? Should I just stick with the methods used in the tutorials?

All help is welcome.

Hello Elian,

Since the Dataset class implements the the IterableInterval interface, I don’t think you need to do a conversion. That is, you can just point a reference of the correct type to your Dataset:

Dataset myDataset;
...
IterableInterval myInterval = myDataset;

Also, you can show the IterableInterval by calling ij.ui().show(myInterval).

Best Regards,
Richard Domander

1 Like

Definitely the way to go. Sorry that we haven’t had time to update the add-two-datasets example—it was written before Ops existed. ImageJ Ops is a major effort to fulfill use cases just like yours as elegantly and succinctly as possible, so please let us know if/how the library falls short, and we will discuss the best way to improve the situation.

The goal of the eval op is to make that sort of thing very easy. Note that last Friday’s new release of ImageJ2 (via the Java-8 update site) included a new version of Ops with a majorly improved eval.

In theory, the following Groovy script should do it:

// @OpService ops
// @Dataset im1
// @Dataset im2
// @double alpha
// @OUTPUT Dataset result

vars = [
	"im1": im1,
	"im2": im2,
	"alpha": alpha
]
result = ops.eval("alpha*im1+(1-alpha)*im2", vars)

Unfortunately, it currently fails with:

java.lang.IllegalArgumentException: No matching 'math.multiply' op

Request:
-	math.multiply(
		Double,
		DefaultDataset)

Candidates:
...

Which in a nutshell means that we haven’t implemented the “multiply an image by a constant value” op yet. (We did math.add as a proof of concept, but sub and mul and div are still missing.) This is certainly the direction things are heading, though.

@rimadoma is correct that Dataset implements the appropriate interfaces. However, due to a bug, you sometimes need to unwrap it with dataset.getImgPlus() right now.

The workshop “ImageJ2 scripts: Parameters + ImageJ Ops” by @bnorthan and me might be helpful here (slides, video part 1, video part 2).

Also maybe interesting is @hinerm’s “Find Ops…” command, which is currently available as a preview from the Hinerm update site.

1 Like

Thanks to both of you for your answers, it really makes things clearer to me. I’m going to use the method @rimadoma provided with @ctrueden 's wrapping suggestion. I’ll definitely take a look at the videos you linked, it may very well help me in the (not so distant) future.

It’s a shame the eval op you are mentionning is not entirely functional yet, as it would have been a perfect fit for my needs, indeed. However I totally understand the library is still in development and I’m greatful for the already existing features and those to come, keep up the good work!

1 Like