Hi Curtis, hi all,
If all you care about is the bounding box of the active selection,
you can just do it the same way as the ImageJ2 CropImageJ command:
by calling OverlayService.getSelectionBounds. Then you would
avoid some of the current weirdness associated with Overlay
parameters.
This was working fine with a programmatically added rectangular
overlay/selection, but when I call getSelectionBounds on an image with
an interactively created rectangular selection it returns the whole
image dimension. It does not seem to be aware of the ROI. Below is a
MVCE to reproduce. After compiling and placing it in the plugins
folder, I start imagej, create a new image, draw a rectangular
selection using ImageJ's leftmost tool and then invoque the plugin. It
logs the following to the console:
[WARNING] ====> Roi class = ij.gui.Roi
[WARNING] ====> RECTANGLE: Roi[Rectangle, x=100, y=163, width=196,
height=112]
[INFO] image: plugin:class net.imagej.display.DefaultImageDisplay:
type=interface net.imagej.display.DataView, name=Untitled,
objects={net.imagej.display.DefaultDatasetView@757dbeaf,
net.imagej.display.DefaultOverlayView@2198a037}
[INFO] region: +0.0 +0.0, 559.0 x 559.0
I expected the region in the last line (that obtained through
OverlayService.getSelectionBounds) to coincide with the Roi mentionned
in the WARNING.
The CropImage command you mentionned does not do anything either
before calling getSelectionBounds, and cropping works fine. Do you
understand what is going on ?
Cheers,
Adrian
import net.imagej.display.ImageDisplay;
import net.imagej.display.OverlayService;
import org.scijava.command.Command;
import org.scijava.log.LogService;
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;
import org.scijava.util.RealRect;
@Plugin(type = Command.class, menuPath = "Plugins>Foo_Bar")
public class Foo_Bar implements Command {
@Parameter
private ImageDisplay display;
@Parameter
private OverlayService overlayService;
@Parameter
private LogService log;
@Override
public void run() {
RealRect r = overlayService.getSelectionBounds(display);
log.info("image: "+display);
log.info("region: +" + r.x + " +" + r.y
+ ", " + r.width + " x " + r.height);
}
}
On Mon, 24 Aug 2015 16:22:15 -0500
Curtis Rueden <ctrue...@wisc.edu> wrote:
Hi Adrian,
Glad to hear you found a working solution!
The short answer about ROIs is that they have not been a focus of
ImageJ2
or ImgLib2 development in recent years. Support for labelings
(highly
related to ROIs) was rewritten this January [1], but a rewrite of
the core
ImgLib2 ROI library [2] is still pending. And there is a substantial
pending redesign of the ImageJ Common data model planned as well --
though
it is unlikely anyone will work on it this year.
At this juncture, the most effective balance for most plugin
developers is
probably to use parameterized commands and/or scripts, but with the
ImageJ1
data structures (ij.ImagePlus, etc.) -- unless you need access to a
new
capability that ImageJ2 + ImgLib2 make possible (>5D images, very
large
image planes, very large numbers of image planes, dynamically
generated
images, images stored in places besides disk, cell-based image
caching,
image types beyond uint8/uint16/float32, etc.).
That said, your feedback is very much appreciated.
And some issues will be ironed out in the next couple of weeks as we
revamp
the tutorials for the upcoming ImageJ conference.
The easiest way to give a plugin a (rectangular) roi is to ... just
declare a net.imagej.overlay.RectangularOverlay as an input
parameter.
It is properly populated by the origin and extent of a rectangular
selection drawn on the active image.
If all you care about is the bounding box of the active selection,
you can
just do it the same way as the ImageJ2 CropImageJ command: by
calling
OverlayService.getSelectionBounds [3]. Then you would avoid some of
the
current weirdness associated with Overlay parameters.
If I launch the default UI, then the ROI will not show, but the
plugin
can launch. If on the other hand I launch the "swing" UI as in the
tutorial, I do see the ROI
Yes, that tutorial was written when the ImageJ2 Swing UI was still
the
default. It is not tested/working with the Legacy UI (which is now
the
default). I will try to remedy that very soon.
(not until I call Image>Adjust>Brightness/Contrast..., but that's a
minor detail),
Yes, that annoying bug has been around for quite a while. Many
things that
refresh the display will do, such as pressing + then - to zoom
in/out.
but now the invocation of the plugin at the end of main() will throw
a
MethodCallException with the stackTrace pasted below. How can the
choice of a UI make the plugin execution fail ?
...
Caused by: java.lang.NullPointerException
at Goutte_pendante.initTitle(Goutte_pendante.java:94)
In 2014, we made a conscious decision to support the ImageJ 1.x
classes
_only_ from the legacy UI. You cannot use them from the Swing UI. In
your
case: the ActiveImagePlusPreprocessor cannot set the active
ImagePlus
because WindowManager.getCurrentImage() returns null [4], because no
ImageJ
1.x user interface exists. So it stays null and then your
initializer
throws the NPE.
Regards,
Curtis
[1]
https://github.com/imglib/imglib2-roi/tree/imglib2-roi-0.3.2/src/main/java/net/imglib2/labeling
[2] https://github.com/imglib/imglib2-roi
[3]
https://github.com/imagej/imagej-plugins-commands/blob/imagej-plugins-commands-0.5.1/src/main/java/net/imagej/plugins/commands/imglib/CropImage.java#L104
[4]
https://github.com/imagej/imagej-legacy/blob/imagej-legacy-0.17.1/src/main/java/net/imagej/legacy/plugin/ActiveImagePlusPreprocessor.java#L49-L52
On Sun, Aug 23, 2015 at 6:30 AM, Adrian Daerr <
adrian.da...@univ-paris-diderot.fr> wrote:
Hello,
While I am still interested in answers concerning the
status/API/roadmap
for ROIs and overlays beyond what's on http://imagej.net/ROIs, I
have
solved the problem at hand which was keeping me from making
progress, so I
post the (rather obvious, once I found the net.imagej.overlay
package)
solution here for the record and to close this thread.
The easiest way to give a plugin a (rectangular) roi is to ...
just declare a net.imagej.overlay.RectangularOverlay as an input
parameter. It is properly populated by the origin and extent of a
rectangular selection drawn on the active image.
cheers,
Adrian
On Wed, 19 Aug 2015 17:10:06 +0200
"Adrian Daerr" <adrian.da...@univ-paris-diderot.fr> wrote:
Dear ImageJ developers,
I have included code from the AddROIs tutorial into the main()
method of my plugin (for the moment essentially one of Curtis'
commands-with-preview example), to select a Rectangle before
calling the plugin. The source is available here:
https://gitlab.com/pendant-drop/pendant-drop
(in Goutte_pendante.java)
If I launch the default UI, then the ROI will not show, but the
plugin can launch. If on the other hand I launch the "swing" UI
as in the tutorial, I do see the ROI (not until I call
Image>Adjust>Brightness/Contrast..., but that's a minor detail),
but now the invocation of the plugin at the end of main() will
throw a MethodCallException with the stackTrace pasted below. How
can the choice of a UI make the plugin execution fail ?
Is there any other way that main can set a ROI on a loaded image
that the plugin, which still uses an ImagePlus as input
parameter, will see when calling imp.getProcessor().getRoi() ?
TIA
Adrian
$> mvn package
$> fiji --class-path target/pendant_drop-2.0.0-SNAPSHOT.jar
Goutte_pendante.class
[INFO] Overriding About Pendant Drop; identifier:
command:About_Pendant_Drop; jar:
file:/home/adrian/Programmes/plugins_ImageJ_src/Traitement_Gouttes/target/pendant_drop-2.0.0-SNAPSHOT.jar
[INFO] Overriding Pendant Drop; identifier: command:Goutte_pendante;
jar:
file:/home/adrian/Programmes/plugins_ImageJ_src/Traitement_Gouttes/target/pendant_drop-2.0.0-SNAPSHOT.jar
[INFO] Populating metadata
[INFO] Populating metadata
[INFO] Found 10 JHotDraw adapters.
org.scijava.module.MethodCallException: Error executing method:
Goutte_pendante#initTitle
at org.scijava.module.MethodRef.execute(MethodRef.java:73)
at
org.scijava.module.AbstractModuleItem.initialize(AbstractModuleItem.java:199)
at
org.scijava.module.AbstractModule.initialize(AbstractModule.java:86)
at
org.scijava.command.CommandModule.initialize(CommandModule.java:147)
at
org.scijava.module.process.InitPreprocessor.process(InitPreprocessor.java:60)
at
org.scijava.module.ModuleRunner.preProcess(ModuleRunner.java:104)
at
org.scijava.module.ModuleRunner.run(ModuleRunner.java:156)
at
org.scijava.module.ModuleRunner.call(ModuleRunner.java:126)
at
org.scijava.module.ModuleRunner.call(ModuleRunner.java:65)
at
org.scijava.thread.DefaultThreadService$2.call(DefaultThreadService.java:191)
at
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.scijava.module.MethodRef.execute(MethodRef.java:69)
... 14 more
Caused by: java.lang.NullPointerException
at Goutte_pendante.initTitle(Goutte_pendante.java:94)
... 19 more
[ERROR] Module threw exception
java.lang.NullPointerException
at Goutte_pendante.cancel(Goutte_pendante.java:87)
at
org.scijava.command.CommandModule.cancel(CommandModule.java:140)
at
org.scijava.module.ModuleRunner.cleanupAndBroadcastCancelation(ModuleRunner.java:189)
at
org.scijava.module.ModuleRunner.run(ModuleRunner.java:161)
at
org.scijava.module.ModuleRunner.call(ModuleRunner.java:126)
at
org.scijava.module.ModuleRunner.call(ModuleRunner.java:65)
at
org.scijava.thread.DefaultThreadService$2.call(DefaultThreadService.java:191)
at
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
On Sat, 15 Aug 2015 13:14:13 +0200
Adrian Daerr <adrian.da...@univ-paris-diderot.fr> wrote:
Hello,
I am seizing a major rewrite of a plugin as an opportunity to switch
from ImageJ1 to ImageJ2, also to avoid concurrency issues[*], and
now
lots of questions come up. Some concern the way ROIs are handled.
What
has happened in this regard since
http://imagej.net/ROIs
was last updated ?
[*] cf discussion on the ImageJ list archived at
http://imagej.1557.x6.nabble.com/ExtendedPlugInFilter-GenericDialog-and-synchronization-td5013333.html
Here are two concrete questions:
1) My plugin relies on a rectangular ROI being drawn on the image to
know which area to include in the computation. How do I draw this
ROI
once I have loaded the image as a dataset in the main() method that
is
used for testing purposes ?
public static void main(final String... args) throws Exception {
final String testImagePath = "testImage.jpg";
// Launch ImageJ as usual.
final ImageJ ij = net.imagej.Main.launch(args);
// Open test image.
final Dataset dataset = ij.dataset().open(testImagePath);
// display the dataset
ij.ui().show(dataset);
// create rectangular ROI
//imp.setRoi(120,60,340,420);// How to do this on a dataset ?
// Launch the "Foo_Bar" command.
ij.command().run(Foo_Bar.class, true);
}
(alternatively, how would I generate a new dataset, or I guess
something
like a "View" in ImageJ2 terminology, of the ROI sub-image of the
original
dataset ? I could then substitute the original dataset with this
sub-image
and have the plugin operate on the whole image by default)
2) The plugin preview generates overlays using java.awt.geom.Path2D,
java.awt.geom.Area and java.awt.Shape, which are then converted via
ij.gui.ShapeRoi() and ij.gui.Overlay(), assembled with
overlay.add(),
and drawn using imp.setOverlay(). Is there a new IJ2-way to do this
(especially since the cited web page (rightly) insists on separation
of selection and visualisation shapes) ?
TIA,
Adrian
_______________________________________________
ImageJ-devel mailing list
ImageJ-devel@imagej.net
http://imagej.net/mailman/listinfo/imagej-devel
--
http://www.msc.univ-paris-diderot.fr/~daerr/
_______________________________________________
ImageJ-devel mailing list
ImageJ-devel@imagej.net
http://imagej.net/mailman/listinfo/imagej-devel
--
http://www.msc.univ-paris-diderot.fr/~daerr/
_______________________________________________
ImageJ-devel mailing list
ImageJ-devel@imagej.net
http://imagej.net/mailman/listinfo/imagej-devel
--
http://www.msc.univ-paris-diderot.fr/~daerr/
_______________________________________________
ImageJ-devel mailing list
ImageJ-devel@imagej.net
http://imagej.net/mailman/listinfo/imagej-devel