I write Java plugins - mostly interactive data gathering applications. My Java skills are good, but my knowledge of ImageJ utilities is weak. I now have an application which looks like it is a direct application of ImageJ utilities about which I know nothing - in particular, the RoiManager.
Given an (extension of a) StackWindow displaying an ImageStack (plus overlays which I prefer to not disturb), I would like to allow the observer to: a) draw Polygon ROIs (0, 1, or (if easy) many) in each slice b) freely browse through the stack, using the normal stack controls (plus other controls implemented in my extension) - with ONLY the Roi(s) associated with a particular slice displayed at each step So...can some kind soul please point me at the appropriate documentation, or sample Java code, that does something similar? The only user interaction with the top level program will be to say "done", or possibly to say "add this Roi". I was about to implement all of this "from scratch", but it occurs to me that (in the abstract) this is a common process. It *may* be desirable to compute (and display in another window) some information on the current slice (for example, the area of the Rois in that slice) - but this is optional. At the end, the plugin will analyze the collection of Rois and write a report file - which is why I need the "done" indication. If the "add/edit Rois while browsing the stack" can be isolated in a separate thread - a WaitForUserDialog() may be all I need at the top level. All clues gratefully rented. -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Kenneth,
sounds to me like this could be best done with adding the rois to the overlay. You can have a special name for the rois added, to later remove them all from the overlay and leave the rest of the overlay untouched: overlay.add(Roi roi, String name) https://github.com/imagej/imagej1/blob/master/ij/gui/Overlay.java#L42 overlay.remove(String name) https://github.com/imagej/imagej1/blob/master/ij/gui/Overlay.java#L73 Before adding the roi, set the stack position: roi.setPosition(int n) https://github.com/imagej/imagej1/blob/master/ij/gui/Roi.java#L2092 or if it is a multi-dimentional stack roi.setPosition(int channel, int slice, int frame) https://github.com/imagej/imagej1/blob/master/ij/gui/Roi.java#L2112 For the gui part, the easiest would probably be a WaitForUserDialog telling the user what to do and pressing 'ok' when done. For adding single Rois, I'd add a KeyListener for the image canvas, and ask the user to press some otherwise unused key for adding the ROIs. https://github.com/imagej/imagej1/blob/master/ij/gui/WaitForUserDialog.java Michael ________________________________________________________________ On 24.07.20 20:36, Kenneth Sloan wrote: > I write Java plugins - mostly interactive data gathering applications. My Java skills are good, but my knowledge of ImageJ utilities is weak. I now have an application which looks like it is a direct application of ImageJ utilities about which I know nothing - in particular, the RoiManager. > > Given an (extension of a) StackWindow displaying an ImageStack (plus overlays which I prefer to not disturb), I would like to allow the observer to: > > a) draw Polygon ROIs (0, 1, or (if easy) many) in each slice > b) freely browse through the stack, using the normal stack controls (plus other > controls implemented in my extension) - with ONLY the Roi(s) associated with a > particular slice displayed at each step > > So...can some kind soul please point me at the appropriate documentation, or sample Java code, that does something similar? > > The only user interaction with the top level program will be to say "done", or possibly to say "add this Roi". > > I was about to implement all of this "from scratch", but it occurs to me that (in the abstract) this is a common process. > > It *may* be desirable to compute (and display in another window) some information on the current slice (for example, the area of the Rois in that slice) - but this is optional. > > At the end, the plugin will analyze the collection of Rois and write a report file - which is why I need the "done" indication. If the "add/edit Rois while browsing the stack" can be isolated in a separate thread - a WaitForUserDialog() may be all I need at the top level. > > All clues gratefully rented. > > -- > Kenneth Sloan > [hidden email] > Vision is the art of seeing what is invisible to others. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Thanks for the reply.
Ordinarily, I would use the Overlay (and have done that it in similar plugins - but it this case I am trapped by my own ineptitude. The StackWindow involved is part of a code base that supports many plugins (briefly, two StackWindows which are different extensions of StackWindow and which talk to each other and separately manage their own Overlays). It uses the Overlay for different purposes, and when I originally wrote it I had some confusion about how to handle Overlays. As a result, I am loathe to go back to that code to modify it. If memory serves, I first tried to implement the Overlay processing to allow for sharing of the Overlay (using names) - but during debugging I gave up and made that code "greedy" so that it has total control over the Overlay - which it re-establishes on every interaction with the StackWindow. That's on my list of things to fix the next time I do a major re-structuring (which I need to do soon...just not this week!) I may, indeed, use a KeyListener to add a new Roi - I'm still at the "on paper design stage". The simplest scheme is to have the user click on "OK" (in a wfud box) and then fetch the current Roi. But, I will experiment with using roi.setPosition(). I assume that if I do this for every Roi, then *only* the Roi attached to a particular slice will be displayed? That's what I want, but I was prepared to use an ImageListener to notice when the slice changes, and change the current Roi on the fly. I already need to keep a separate stack of Roi's (one per slice) for later processing - so this is not all that much extra work. But, if roi.setPositition() works as advertised, perhaps I can eliminate this stack and simply process the Rois at the end by fetching them from the StackWindow. Using KeyListener would allow multiple Roi editing functions (add, delete, clear all, ...) and I just finished debugging a KeyListener for another plugin. There, I had trouble maintaining "focus". Perhaps this new plugin is a chance to see if I have internalized the lessons learned there. If it matters, the immediate application is to compute the volume of an object from cross-sections traced by the user, using the Calalieri principle with care taken to handle the "lost cap" issues on either end. Now...for extra credit...using roi.setPosition(), can I have multiple Roi's in each slice? I don't really need this (now...) and can't quite see how to control which Roi is the "current" Roi while allowing multiple Roi's to be displayed (I just haven't tried this before). But - if this is possible, it makes it more likely that I would use a KeyListener to control this feature. -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Kenneth,
concerning: > Ordinarily, I would use the Overlay ... It uses the Overlay for different purposes I think you can still use the overlay and use names to separate the different rois in the overlay. Unless you have hundreds of thousands of overlays, where performance becomes an issue, you can use a single call to delete all overlays with a given name. > I already need to keep a separate stack of Roi's (one per slice) for later processing Unless you have a huge number of rois (see above), you could also use the roi names in the overlay to determine which rois serve which purpose. Then you can iterate over the rois in the overlay and only use these with the desired name. So you don't need to keep a separate list (unless that list has some structure that you won't have with roi names, e.g. a linked list, tree, etc.) > I may, indeed, use a KeyListener to add a new Roi Of course, you can also use a nonblocking dialog, e.g. a NonBlockingGenericDialog where you can add a panel with buttons, or a PlugInFrame. From the user's point of view, it is usually nicer to use the keyboard if one has to add lots of rois; but I'd prefer a dialog with buttons if it is only few clicks (The buttons avoid the need for a help text telling the user to use a keystroke). > Using KeyListener would allow multiple Roi editing functions (add, delete, clear all, ...) Yes, but you could do the same using a dialog with several buttons. >...using roi.setPosition(), can I have multiple Roi's in each slice? Yes. I have done it with hundreds of rois per slice. Michael ________________________________________________________________ On 27.07.20 20:25, Kenneth Sloan wrote: > Thanks for the reply. > > Ordinarily, I would use the Overlay (and have done that it in similar plugins - but it this case I am trapped by my own ineptitude. The StackWindow involved is part of a code base that supports many plugins (briefly, two StackWindows which are different extensions of StackWindow and which talk to each other and separately manage their own Overlays). It uses the Overlay for different purposes, and when I originally wrote it I had some confusion about how to handle Overlays. As a result, I am loathe to go back to that code to modify it. If memory serves, I first tried to implement the Overlay processing to allow for sharing of the Overlay (using names) - but during debugging I gave up and made that code "greedy" so that it has total control over the Overlay - which it re-establishes on every interaction with the StackWindow. That's on my list of things to fix the next time I do a major re-structuring (which I need to do soon...just not this week!) > > I may, indeed, use a KeyListener to add a new Roi - I'm still at the "on paper design stage". The simplest scheme is to have the user click on "OK" (in a wfud box) and then fetch the current Roi. But, I will experiment with using roi.setPosition(). I assume that if I do this for every Roi, then *only* the Roi attached to a particular slice will be displayed? That's what I want, but I was prepared to use an ImageListener to notice when the slice changes, and change the current Roi on the fly. > > I already need to keep a separate stack of Roi's (one per slice) for later processing - so this is not all that much extra work. But, if roi.setPositition() works as advertised, perhaps I can eliminate this stack and simply process the Rois at the end by fetching them from the StackWindow. > > Using KeyListener would allow multiple Roi editing functions (add, delete, clear all, ...) and I just finished debugging a KeyListener for another plugin. There, I had trouble maintaining "focus". Perhaps this new plugin is a chance to see if I have internalized the lessons learned there. > > If it matters, the immediate application is to compute the volume of an object from cross-sections traced by the user, using the Calalieri principle with care taken to handle the "lost cap" issues on either end. > > Now...for extra credit...using roi.setPosition(), can I have multiple Roi's in each slice? I don't really need this (now...) and can't quite see how to control which Roi is the "current" Roi while allowing multiple Roi's to be displayed (I just haven't tried this before). But - if this is possible, it makes it more likely that I would use a KeyListener to control this feature. > > -- > Kenneth Sloan > [hidden email] > Vision is the art of seeing what is invisible to others. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Following advice here, I'm trying to associate a user-drawn Roi with a specific slice in a StackWindow.
I do (in a Java plugin): int slice = ip.getCurrentSlice(); Roi roi = ip.getRoi(); roi.setPosition(slice); ip.setRoi(roi); But, the Roi is displayed on every slice. If I edit (or re-draw) the Roi while positioned at a different slice - it changes (and is displayed) everywhere. What am I doing wrong, please? I suppose I can work around this by storing the Rois in my own stack, and using an ImageListener to notice when the slice changes (on a slice change - re-instate the correct Roi from my saved stack). But, I was optimistic that this would not be necessary, and that ImageJ would handle this all for me. Is there some method I'm missing in the documentation? Should I be using the StackWindow instead of the ImagePlus used to create the StackWindow? (I don't see any relevant methods in the StackWindow api). -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Ah...I think I see the issue. The Roi is NOT part of the Overlay set for the StackWindow.
As previously noted, it's not (easily) possible for me to use this Overlay (it's being used - incompetently - in another piece of code managing this StackWindow). So...off to implement the ImageListener solution. I'm getting closer and closer to biting the bullet and fixing the offending Overlay code... -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |