[ImageJ-devel] ImageJ2 scripting
Jan Eglinger
jan.eglinger at gmail.com
Tue Apr 28 10:53:21 CDT 2015
Hi all,
some follow-up questions regarding imagej-ops:
I tried to use some basic ops in python. From the 2014 wiki announcement
[1] and the python template [2], I assumed something like this would
work in python:
# @OpService ops
# @DisplayService display
blank = ops.create([100, 50])
display.createDisplay(blank)
But a choice of candidate functions is listed in output:
**********************************************
Request:
- createimg(
Integer,
Integer)
Candidates:
1. (Img output) =
net.imagej.ops.create.DefaultCreateImg(
==> Type outType?,
ImgFactory fac?,
long[] dims)
Inconvertible type: java.lang.Integer => net.imglib2.type.Type<capture
of ?>
2. (ImgPlus output) =
net.imagej.ops.create.CreateEmptyImgCopy(
ImgPlus input)
Too many arguments: 2 > 1
3. (Img output) =
net.imagej.ops.create.CreateImgNativeType(
ImgFactory fac,
NativeType outType,
Dimensions dims)
Not enough arguments: 2 < 3
4. (Img output) =
net.imagej.ops.create.CreateImgDifferentNativeType(
==> Img input,
NativeType type)
Inconvertible type: java.lang.Integer => net.imglib2.img.Img<capture of ?>
5. (ImgPlus output) =
net.imagej.ops.create.CreateEmptyImgPlusCopy(
ImgPlus input)
Too many arguments: 2 > 1
**********************************************
and I am unsure if I have to provide image type and factory here.
Similarly, for the subtract op:
# @OpService ops
# @StatisticsService stats
# @net.imagej.Dataset inData
# @OUTPUT net.imagej.Dataset outData
outData = inData.duplicate()
mean = stats.alphaTrimmedMean(inData, 0)
print mean
ops.subtract(outData, inData, mean)
I am getting the following list of candidates:
**********************************************
Request:
- math.subtract(
DefaultDataset,
DefaultDataset,
Double)
Candidates:
1. (Object result) =
net.imagej.ops.onthefly.ArithmeticOp$SubtractOp(
Object result,
Object a,
Object b)
Inputs do not conform to op rules
result = blobs.gif
a = blobs.gif
b = 103.26857775590551
2. (int result) =
net.imagej.ops.math.PrimitiveMath$IntegerSubtract(
int a,
int b)
Too many arguments: 3 > 2
3. (long result) =
net.imagej.ops.math.PrimitiveMath$LongSubtract(
long a,
long b)
Too many arguments: 3 > 2
4. (float result) =
net.imagej.ops.math.PrimitiveMath$FloatSubtract(
float a,
float b)
Too many arguments: 3 > 2
5. (double result) =
net.imagej.ops.math.PrimitiveMath$DoubleSubtract(
double a,
double b)
Too many arguments: 3 > 2
6. (RealType out) =
net.imagej.ops.arithmetic.real.RealSubtract(
==> RealType out,
RealType in,
double constant)
Inconvertible type: net.imagej.DefaultDataset => capture of ?
**********************************************
is there a way with the type-unsafe scripting languages to get ops to
use the correct function? Or am I misunderstanding the concept of
imagej-ops here?
Thanks again for any hints.
Jan
[1] http://fiji.sc/2014-04-04_-_Announcing_ImageJ_OPS
[2]
https://github.com/imagej/imagej-legacy/blob/master/src/main/resources/script_templates/Python/OpsThresholdIJ1Analyze.py
On 28.04.2015 09:03, Jan Eglinger wrote:
> Dear Mark and Curtis,
>
> thank you very much for the quick replies and helpful pointers!
>
> Jan
>
>
> On 27.04.2015 20:42, Curtis Rueden wrote:
>> Hi Jan,
>>
>> Here is another version of the script, which avoids wrapping each
>> Dataset in another ImgPlus (which the framework would then wrap into yet
>> another Dataset....):
>>
>> # @DisplayService display
>> # @OpService ops
>> # @net.imagej.Dataset inputData1
>> # @net.imagej.Dataset inputData2
>>
>> inputData1.setName("my1")
>> inputData2.setName("my2")
>> display.createDisplay(inputData1)
>> display.createDisplay(inputData2)
>>
>> But note that you also don't need to explicitly call createDisplay. Any
>> output parameters of your script will automatically have displays
>> created for them. E.g.:
>>
>> # @OUTPUT net.imagej.Dataset outputData
>>
>> Will be shown at the conclusion of the script.
>>
>> Apologies for the appalling lack of documentation -- it would be great
>> to flesh out the wiki docs about all this.
>>
>> HTH,
>> Curtis
>>
>> On Mon, Apr 27, 2015 at 1:23 PM, Mark Hiner <hiner at wisc.edu
>> <mailto:hiner at wisc.edu>> wrote:
>>
>> Hi Jan,
>>
>> >an error message is displayed: "A Dataset is required but none
>> exist."
>>
>> This was due to limitations with the input preprocessor presenting
>> the list of datasets. Since ImagePluses aren't explicitly tracked by
>> the IJ2 framework, having an ImagePlus recognized as a Dataset
>> requires some extra layers. We had covered the single input case
>> (which is why your first script worked) but not the general
>> multi-input case. There is an issue tracking the multi-input
>> <https://github.com/imagej/imagej-legacy/issues/106> case, which I
>> resolved today. So this should work as intended in our next release
>> - and thank you for the motivation to wrap this up!
>>
>> You can also manually enable ImagePlus <> Dataset synchronization to
>> ensure ImagePluses always have a corresponding Dataset:
>> http://imagej.net/Compatibility#Translation_of_data_structures
>>
>> >(where can this title be set, by the way?)
>>
>> For the multiple choice input selection, the labels are based on the
>> name of the input type. Since the input type is Dataset, the Dataset
>> name is used (which delegates to the wrapped ImgPlus). In your code
>> you are applying labels to the Display, but not the underlying
>> dataset - if you name the ImgPlus, or explicitly create a Dataset
>> and set its name, that name will propagate up to the input chooser
>> (and the Display). As a side note, you should use the
>> net.imagej.ImgPlus instead of the net.imglib2.meta.
>>
>> An updated script would be:
>>
>>
>> # @DisplayService display
>> # @OpService ops
>> # @net.imagej.Dataset inputData1
>> # @net.imagej.Dataset inputData2
>>
>> from net.imagej import ImgPlus
>>
>> display.createDisplay(ImgPlus(inputData1, "my1"))
>> display.createDisplay(ImgPlus(inputData2, "my2"))
>>
>> Hope that helps. Let me know if you have any other questions.
>>
>> Best,
>> Mark
>>
>> On Mon, Apr 27, 2015 at 8:58 AM, Jan Eglinger
>> <jan.eglinger at gmail.com <mailto:jan.eglinger at gmail.com>> wrote:
>>
>> Dear all,
>>
>> *** TL;DR:
>> How do I proceed to get multiple input Datasets as ImageJ2
>> parameters from open images in Fiji?
>> ***
>>
>> I was recently exploring ImageJ2 scripting in Fiji and found the
>> OpsThresholdIJ1Analyze template [1] in the script editor very
>> helpful.
>>
>> When trying to get more than one @net.imagej.Dataset input
>> parameter however, I noticed some inconsistencies.
>> Let me try to illustrate with the two following scripts:
>>
>> # @DisplayService display
>> # @OpService ops
>> # @net.imagej.Dataset inputData1
>>
>> from net.imglib2.meta import ImgPlus
>>
>> display.createDisplay("my1", ImgPlus(inputData1))
>>
>>
>> The above script re-displays the current image as expected (I
>> tried with the Blobs sample image open, which will be
>> re-displayed with a non-inverted LUT.)
>>
>> When I ask for two input datasets (right after a fresh start of
>> Fiji with only the Blobs sample image open):
>>
>> # @DisplayService display
>> # @OpService ops
>> # @net.imagej.Dataset inputData1
>> # @net.imagej.Dataset inputData2
>>
>> from net.imglib2.meta import ImgPlus
>>
>> display.createDisplay("my1", ImgPlus(inputData1))
>> display.createDisplay("my2", ImgPlus(inputData2))
>>
>> an error message is displayed: "A Dataset is required but none
>> exist."
>> The same error message is displayed when I open a second image
>> in Fiji before running the script.
>>
>> Now, when I run script #2 after script #1 was run at least once,
>> I get a dialog with two choices "InputData1" and "InputData2",
>> both choice fields containing "blobs.gif" and a number of
>> "Untitled" entries (where can this title be set, by the way?).
>>
>> I guess that a choice is only displayed if there are ImageJ2
>> datasets (i.e. wrapped ImagePlus) already available. The single
>> input case seems to be special-cased as it auto-wraps the
>> currently open image.
>>
>> So how do I proceed to get more than one input in ImageJ2
>> scripting from open (ImageJ1-)images?
>>
>> Thanks for your advice,
>> Regards,
>> Jan
>>
>>
>> [1]:
>>
>> https://github.com/imagej/imagej-legacy/blob/master/src/main/resources/script_templates/Python/OpsThresholdIJ1Analyze.py
>>
>>
More information about the ImageJ-devel
mailing list