Modified input image

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Modified input image

Arne Seitz
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/
---------------------------------------------------------------
Reply | Threaded
Open this post in threaded view
|

Re: Modified input image

dscho
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
Reply | Threaded
Open this post in threaded view
|

Re: Modified input image

Adrian Daerr-2
> 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
Reply | Threaded
Open this post in threaded view
|

Re: Modified input image

Michael Doube
  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();