Hi Curtis,OverlayService.getSelectionBounds seems to behave stranger yet. Take the Foo_Bar test plugin source from my previous post, compile it and place it in ImageJ's plugins directory. Start ImageJ, create a new image (say 400x400 8bpp), draw a rectangular selection inside and invoke Foo_Bar: as reported in my last mail it will report a getSelectionBounds of 399x399 instead of the expected dimension of the rectangular selection. Now crop the image to the rectangular selection via Image->Crop, and invoke Foo_Bar again. It will report the same getSelectionBounds (width 399, height 399) although the active image is now strictly smaller. It's as if the ImageDisplay parameter was getting populated by the image before cropping (and of course still without rectangular selection).
How is one supposed to use OverlayService.getSelectionBounds ? What are those WARNINGs printed upon plugin invokation ? [WARNING] ====> Roi class = ij.gui.Roi[WARNING] ====> RECTANGLE: Roi[Rectangle, x=76, y=92, width=209, height=160]
cheers, Adrian On Tue, 01 Sep 2015 20:41:30 +0200 "Adrian Daerr" <adrian.da...@univ-paris-diderot.fr> wrote:
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.0I 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 coreImgLib2 ROI library [2] is still pending. And there is a substantialpending redesign of the ImageJ Common data model planned as well -- thoughit 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 revampthe tutorials for the upcoming ImageJ conference.The easiest way to give a plugin a (rectangular) roi is to ... justdeclare 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 thecurrent weirdness associated with Overlay parameters.If I launch the default UI, then the ROI will not show, but the plugincan launch. If on the other hand I launch the "swing" UI as in the tutorial, I do see the ROIYes, 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 thedefault). 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 aMethodCallException 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 initializerthrows 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.InvocationTargetExceptionat 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 switchfrom ImageJ1 to ImageJ2, also to avoid concurrency issues[*], and now lots of questions come up. Some concern the way ROIs are handled. Whathas 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 toknow 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 isused 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-imageand 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 viaij.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/
-- http://www.msc.univ-paris-diderot.fr/~daerr/ _______________________________________________ ImageJ-devel mailing list ImageJ-devel@imagej.net http://imagej.net/mailman/listinfo/imagej-devel