Line structuring element with ImgLib2

fiji
imagej-ops

#1

Hello,

sorry for the newbie question, but I cannot figure how to carry out an opening with a line in ImgLib2. I couldn’t find a line object in StructuringElements, so I tried to create one with StructuringElements.periodicLine.
Here’s my code:

// @Img img
// @OpService ops
import net.imglib2.algorithm.morphology.StructuringElements
import ij.IJ;

assert(img.numDimensions() == 2)
span = 3
int[] periodicity = [1, 0]
se = StructuringElements.periodicLine(span, periodicity)
img = ops.run("morphology.open", img, se)

I get this error:

java.lang.IllegalArgumentException: No matching 'net.imagej.ops.Ops$Morphology$Erode/net.imagej.ops.special.computer.UnaryComputerOp' op

Request:
-	net.imagej.ops.Ops$Morphology$Erode/net.imagej.ops.special.computer.UnaryComputerOp(
		IterableInterval,
		DefaultDataset,
		null,
		Boolean)

Candidates:
1. 	(IterableInterval out?) =
	net.imagej.ops.morphology.erode.DefaultErode(
		IterableInterval out?,
		RandomAccessibleInterval in1,
==>		Shape in2,
		boolean isFull?,
		OutOfBoundsFactory f?)
	Missing required argument
2. 	(IterableInterval out?) =
	net.imagej.ops.morphology.erode.ListErode(
		IterableInterval out?,
		RandomAccessibleInterval in1,
==>		List in2,
		boolean isFull?)
	Missing required argument

Any help or example appreciated!
Thanks,

Nicolas


#2

If you put your structuring element se in a list [se], it works fine:

#@ Img img
#@ OpService ops
import net.imglib2.algorithm.morphology.StructuringElements

assert(img.numDimensions() == 2)
span = 3
int[] periodicity = [1, 0]
se = StructuringElements.periodicLine(span, periodicity)

result = ops.run("morphology.open", img, [se])

Several things aren’t obvious to me, however:

  • The morphology.open op has a single signature with a List argument:

    • IterableInterval out?  <=  Open(IterableInterval out?, RandomAccessibleInterval in1, List in2)
      
  • The morpholgy.erode op has two signatures, one with Shape and one with List:

    • IterableInterval out?  <=  Erode(IterableInterval out?, RandomAccessibleInterval in1, List in2, boolean isFull?)
      
    • IterableInterval out?  <=  Erode(IterableInterval out?, RandomAccessibleInterval in1, Shape in2, boolean isFull?, OutOfBoundsFactory f?)
      

So, why did your call to morphology.open try to match the net.imagej.ops.Ops$Morphology$Erode at all? Is this the result of successfully matching an Open signature first, and then the internal match to Erode failing later?

Maybe @ctrueden or @gselzer have more insights here?

Also, the open op should maybe also have a signature accepting List<Shape>?


#3

Thank you @imagejan!

I’m glad this question isn’t addressed to me!

Nicolas


#4

Hi @Nicolas and @imagejan

I did some debugging, and @imagejan is correct in that it is an internal failure to match (specifically here). I am still really confused as to why it is that in2 is null, and do not know enough about the matcher to explain it without doing more digging. However it sounds like @imagejan found a solution that works (correct me if I am wrong).

@imagejan you will be excited to see our new OpCollections within Ops 2.0. We are essentially wrapping all of the imglib2-algorithm open signatures into Op one-liners, so this last point you address will be fixed in time. If you are interested you can see what they will look like here


#5

Yes, it works, thank you.