[ImageJ-devel] ImageJ2 scripting
Brian Northan
bnorthan at gmail.com
Tue Apr 28 11:03:25 CDT 2015
Hi Jan
The following might work for the create op -- it takes a java array not a
python list....
from jarray import array
blank=ops.createimg(array([100, 50], 'l'))
Brian
On Tue, Apr 28, 2015 at 11:53 AM, Jan Eglinger <jan.eglinger at gmail.com>
wrote:
> 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
>>>
>>>
>>>
> _______________________________________________
> ImageJ-devel mailing list
> ImageJ-devel at imagej.net
> http://imagej.net/mailman/listinfo/imagej-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://imagej.net/pipermail/imagej-devel/attachments/20150428/a0511668/attachment-0001.html>
More information about the ImageJ-devel
mailing list