Dear all,
when I run (Windows7, ImageJ 1.44i, Java 1.6.6_19(32 bit))the below attached Plugin everything is fine and I receive as expected a new (filtered) image. If I run the Plugin a second time on the same image also my input image is modified. This is something which I do not understand, because to my opinion the input image should not be changed. If the input image is an image stack you can even see that the input image is changed after the first run of the plugin if you scroll through the different images of the stack. Can anybody explain me, why the input image is modified and how to avoid this. Thanks a lot in advance. Cheers Arne import ij.ImagePlus; import ij.WindowManager; import ij.plugin.PlugIn; import ij.process.ShortProcessor; public class test_ implements PlugIn{ public void run(String arg) { ImagePlus imp=WindowManager.getCurrentImage(); int [] kernel={3,5,3,5,8,5,3,5,3}; imp.setSlice(0); ShortProcessor ip=new ShortProcessor(imp.getWidth(),imp.getHeight(),(short[]) imp.getProcessor().getPixels(),imp.getProcessor().getColorModel()); ip.convolve3x3(kernel); ImagePlus newimp=new ImagePlus("Test",ip); newimp.show(); } } --------------------------------------------------------------- Dr. Arne Seitz Head of Bioimaging and Optics Platform (PT-BIOP) Ecole Polytechnique Fédérale de Lausanne (EPFL) Faculty of Life Sciences Station 15, AI 0241 CH-1015 Lausanne Phone: +41 21 693 9618 Fax: +41 21 693 9585 http://biop.epfl.ch/ --------------------------------------------------------------- |
Hi Arne,
On Thu, 4 Nov 2010, Seitz Arne wrote: > when I run (Windows7, ImageJ 1.44i, Java 1.6.6_19(32 bit))the below > attached Plugin everything is fine and I receive as expected a new > (filtered) image. If I run the Plugin a second time on the same image > also my input image is modified. This is something which I do not > understand, because to my opinion the input image should not be changed. > If the input image is an image stack you can even see that the input > image is changed after the first run of the plugin if you scroll through > the different images of the stack. I think the problem is that you haven't duplicated the processor, and as such, you are reusing the very same pixels. You do not see that they already changed after the first run right away, because you did not call imp.updateAndDraw(); > ShortProcessor ip=new ShortProcessor(imp.getWidth(),imp.getHeight(),(short[]) imp.getProcessor().getPixels(),imp.getProcessor().getColorModel()); I'd write this as ShortProcessor ip = imp.getProcessor().duplicate(); Ciao, Johannes |
> Arne Seitz wrote:
>> [...] the input image is changed [...] > Johannes Schindelin answered: > > I think the problem is that you haven't duplicated the processor, and as > such, you are reusing the very same pixels. Just a small explanation because I think Johannes' statement is confusing even though it is (unsurprisingly) correct: instantiating a new Processer (with the 'new' keyword) /does/ give you a processor distinct from the original. And it even becomes a duplicate of the original by virtue of the initialisation from the original image's properties. The problem is that by giving it a pointer to the initial image's pixel array, Arne has it point to the same pixel data. So the processor is a duplicate, but not the associated pixel data. To phrase it differently: with 'new ShortProcessor(<initialisation from imp's properties>)' Arne created a /shallow/ duplicate of the other processor, whereas the processor's duplicate() method does a /deep/ copy which also duplicates the pixel data. The source code of the ShortProcessor.duplicate() method is self-explanatory. http://rsb.info.nih.gov/ij/developer/source/index.html Obviously Johannes suggestion to use duplicate() is way to go: > ShortProcessor ip = imp.getProcessor().duplicate(); but one could also have corrected Arne's code by explicitly copying the pixel data. Compare the following [original] ShortProcessor ip = new ShortProcessor(imp.getWidth(), imp.getHeight(), (short[]) imp.getProcessor().getPixels(), imp.getProcessor().getColorModel()); [with arraycopy] short[] pixels = (short[]) imp.getProcessor().getPixels(); ShortProcessor ip = new ShortProcessor(imp.getWidth(), imp.getHeight(), java.util.Arrays.copyOf(pixels, pixels.length), imp.getProcessor().getColorModel()); Hope this blabla will actually be insightful for somebody, happy imagejing, Adrian |
Thanks for the description Adrian,
There is also a Duplicator class in ij.plugin that can do this work on ImagePlus objects, if you need a copy of an imp with calibration and overlays set. Duplicator dup = new Duplicator(); ImagePlus imp2 = dup.duplicateImage(imp1); Michael On 04/11/2010 17:21, Adrian Daerr wrote: >> Arne Seitz wrote: >>> [...] the input image is changed [...] > Johannes Schindelin answered: >> I think the problem is that you haven't duplicated the processor, and as >> such, you are reusing the very same pixels. > Just a small explanation because I think Johannes' statement is > confusing even though it is (unsurprisingly) correct: instantiating a > new Processer (with the 'new' keyword) /does/ give you a processor > distinct from the original. And it even becomes a duplicate of the > original by virtue of the initialisation from the original image's > properties. The problem is that by giving it a pointer to the initial > image's pixel array, Arne has it point to the same pixel data. So the > processor is a duplicate, but not the associated pixel data. > > To phrase it differently: with 'new ShortProcessor(<initialisation from > imp's properties>)' Arne created a /shallow/ duplicate of the other > processor, whereas the processor's duplicate() method does a /deep/ copy > which also duplicates the pixel data. The source code of the > ShortProcessor.duplicate() method is self-explanatory. > http://rsb.info.nih.gov/ij/developer/source/index.html > > Obviously Johannes suggestion to use duplicate() is way to go: > >> ShortProcessor ip = imp.getProcessor().duplicate(); |
Free forum by Nabble | Edit this page |