Hi Adrian, > It's as if the ImageDisplay parameter was getting populated by the > image before cropping
It seems that the ROI syncing between IJ1 and IJ2 is not happening as expected. When your command runs, a sync is supposed to happen during preprocessing because you have a Dataset parameter. But maybe the sync is incomplete for some reason. Sorry I don't have time to investigate it right now, though. > What are those WARNINGs printed upon plugin invokation ? Those were debugging statements, which were erroneously set to log.warn. I fixed it [1]. Regards, Curtis [1] https://github.com/imagej/imagej-legacy/commit/2015336482fe284954d2603fede892d616d20960 On Fri, Sep 4, 2015 at 2:29 PM, Adrian Daerr < adrian.da...@univ-paris-diderot.fr> wrote: > 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.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/ >> > > -- > http://www.msc.univ-paris-diderot.fr/~daerr/ >
_______________________________________________ ImageJ-devel mailing list ImageJ-devel@imagej.net http://imagej.net/mailman/listinfo/imagej-devel