Difference operation between images

Hi all,

First of all sorry if this has been asked before but I didn´t find any similar subjects.
While trying to write a simple plugin to do the difference between two images (eg. abs(image2-image1)) I couldn´t find an imagelib2 operation to do such process. I also looked into using the op().ops().equation method but had no luck.

My solution was to do a loop trough all the pixels but this takes forever!

Cursor <Float> inputCursor = proj.cursor();
Cursor <Float> outputCursor = img.cursor();

for(int i = 0; i < 3; i++){
    r.setPosition(i, 2);
        float sub3 = opService.math().subtract(outputCursor.get().getRealFloat(), inputCursor.get().getRealFloat());
        double abs =  opService.math().abs((double) sub3);
        outputCursor.get().setReal((float) abs);

I also tried to do a subtraction and then the abs of the image but the subtraction always trimmed my negative pixels to 255 for some reason (using FloatType images).
Any indications appreciated.


Dear @Helio_Roque,

you can take the following Groovy script as inspiration:

#@IOService ioService
#@OUTPUT Img out
#@OpService opService

import net.imglib2.IterableInterval;

// Generate dummy inputs
img1 = ioService.open("8bit-signed&pixelType=int8&lengths=50,50&axes=X,Y.fake");
img2 = ioService.open("8bit-signed&pixelType=int8&lengths=50,50&axes=X,Y.fake");

// Do the subtraction
subtracted = opService.math().subtract(img2, (IterableInterval) img1);

// Get the op to be applied in the map
absOp = opService.op("math.abs", subtracted.firstElement(), subtracted.firstElement());

// Create output image
out = opService.create().img(result);

// Do the mapping
opService.map((IterableInterval) out, (IterableInterval) result, absOp);

Could you provide a minimal example with some sample data (also see http://imagej.net/Bug_reporting_best_practices) that illustrates the issue?


1 Like

That said, at some point in the future you should be able to do the following:

#@ OpService opService

imageToProcess1 = ...;
imageToProcess2 = ...;

vars = [
  "img1": imageToProcess1,
  "img2": imageToProcess2,

output = opService.eval("math.abs(img2 - img2)", vars)

The issue is that we currently don’t have an implementation that computes the absolute value for each pixel, so you have to do that manually as shown in my script in the previous answer…

1 Like

Thanks for the nice example!

How does that work if your images have differing dimensionality, e.g. if you subtract the max projection from the orignal stack?
You’ll have to use the slice op, if I remember correctly, right?

Well, you have to do some work yourself then, that’s right. The following might be a good inspiration on applying an op on each slice individually:

1 Like

Thanks for the really useful and nice script example! Indeed I am looking to do something as imagejan suggested (difference from a projection to a stack).

Got a bit caught up with work at the moment, but once I find a bit of time i will try to upload a minimal example of the problem I get with the trimming of negative pixels to white. It might be that I´m just doing something wrong, though.