can't fill first slice of hyperstack

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

can't fill first slice of hyperstack

Ben Glick
Hi,

I'm writing a plugin that executes a custom filter on an open hyperstack, yielding a new hyperstack of filtered images. The code is working except for one thing: the first slice of the new hyperstack remains blank.

Here is a simplified code snippet that creates a new hyperstack and then copies each slice of the original hyperstack to the new hyperstack, where "copy" is an ImagePlus and "copyStack" is an ImageStack:

        copy = IJ.createImage(windowTitle + " Filtered", "8-bit black", width, height, images);
        copy.setDimensions(channels, slices, frames);
        copy.setOpenAsHyperStack(true);
       
        copyStack = copy.getStack();
       
        for (int i = 1; i <= images; i++) {
          pixels = (byte[]) stack.getPixels(i);
          copyStack.setPixels(pixels, i);
        }
       
        copy.show();

For some reason this code works for every slice except i=1. Any help will be much appreciated.

Thanks,
Ben
Reply | Threaded
Open this post in threaded view
|

Re: can't fill first slice of hyperstack

Robert Baer
My guess is that it has to do with java using 0-based rather than
1-based arrays. What happens if you use:

for (int i = 0; i <= images; i++) {
           pixels = (byte[]) stack.getPixels(i);
           copyStack.setPixels(pixels, i);
         }

Do your hyperstacks poopulate now?

Rob

On 1/28/2013 12:46 PM, Ben Glick wrote:

> Hi,
>
> I'm writing a plugin that executes a custom filter on an open hyperstack,
> yielding a new hyperstack of filtered images. The code is working except for
> one thing: the first slice of the new hyperstack remains blank.
>
> Here is a simplified code snippet that creates a new hyperstack and then
> copies each slice of the original hyperstack to the new hyperstack, where
> "copy" is an ImagePlus and "copyStack" is an ImageStack:
>
> copy = IJ.createImage(windowTitle + " Filtered", "8-bit black", width,
> height, images);
>          copy.setDimensions(channels, slices, frames);
>          copy.setOpenAsHyperStack(true);
>          
>          copyStack = copy.getStack();
>          
>          for (int i = 1; i <= images; i++) {
>            pixels = (byte[]) stack.getPixels(i);
>            copyStack.setPixels(pixels, i);
>          }
>          
>          copy.show();
>
> For some reason this code works for every slice except i=1. Any help will be
> much appreciated.
>
> Thanks,
> Ben
>
>
>
> --
> View this message in context: http://imagej.1557.n6.nabble.com/can-t-fill-first-slice-of-hyperstack-tp5001578.html
> Sent from the ImageJ mailing list archive at Nabble.com.
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html


--

Robert W. Baer, Ph.D.
Professor of Physiology
Kirksille College of Osteopathic Medicine
A. T. Still University of Health Sciences
Kirksville, MO 63501 USA


--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: can't fill first slice of hyperstack

Robert Baer
In reply to this post by Ben Glick
Sorry, have to fix upper end of for loop too:

for (int i = 0; i < images; i++) {
           pixels = (byte[]) stack.getPixels(i);
           copyStack.setPixels(pixels, i);
         }




On 1/28/2013 12:46 PM, Ben Glick wrote:

> Hi,
>
> I'm writing a plugin that executes a custom filter on an open hyperstack,
> yielding a new hyperstack of filtered images. The code is working except for
> one thing: the first slice of the new hyperstack remains blank.
>
> Here is a simplified code snippet that creates a new hyperstack and then
> copies each slice of the original hyperstack to the new hyperstack, where
> "copy" is an ImagePlus and "copyStack" is an ImageStack:
>
> copy = IJ.createImage(windowTitle + " Filtered", "8-bit black", width,
> height, images);
>          copy.setDimensions(channels, slices, frames);
>          copy.setOpenAsHyperStack(true);
>          
>          copyStack = copy.getStack();
>          
>          for (int i = 1; i <= images; i++) {
>            pixels = (byte[]) stack.getPixels(i);
>            copyStack.setPixels(pixels, i);
>          }
>          
>          copy.show();
>
> For some reason this code works for every slice except i=1. Any help will be
> much appreciated.
>
> Thanks,
> Ben
>
>
>
> --
> View this message in context: http://imagej.1557.n6.nabble.com/can-t-fill-first-slice-of-hyperstack-tp5001578.html
> Sent from the ImageJ mailing list archive at Nabble.com.
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html


--

Robert W. Baer, Ph.D.
Professor of Physiology
Kirksille College of Osteopathic Medicine
A. T. Still University of Health Sciences
Kirksville, MO 63501 USA

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: can't fill first slice of hyperstack

Ben Glick
In reply to this post by Robert Baer
That change gives an "Argument out of range" error. From what I can tell, ImageJ doesn't follow the Java convention of numbering stack slices from 0, but instead numbers them from 1.

Note that all of the other slices in the new hyperstack are in the right place. Nothing is out of register.

Ben
Reply | Threaded
Open this post in threaded view
|

Re: can't fill first slice of hyperstack

dscho
In reply to this post by Ben Glick
Hi Ben,

On Mon, 28 Jan 2013, Ben Glick wrote:

> I'm writing a plugin that executes a custom filter on an open
> hyperstack, yielding a new hyperstack of filtered images. The code is
> working except for one thing: the first slice of the new hyperstack
> remains blank.
>
> Here is a simplified code snippet that creates a new hyperstack and then
> copies each slice of the original hyperstack to the new hyperstack,
> where "copy" is an ImagePlus and "copyStack" is an ImageStack:
>
> copy = IJ.createImage(windowTitle + " Filtered", "8-bit black", width,
> height, images);
>         copy.setDimensions(channels, slices, frames);
>         copy.setOpenAsHyperStack(true);
>        
>         copyStack = copy.getStack();
>        
>         for (int i = 1; i <= images; i++) {
>           pixels = (byte[]) stack.getPixels(i);
>           copyStack.setPixels(pixels, i);
>         }
>        
>         copy.show();
>
> For some reason this code works for every slice except i=1. Any help will be
> much appreciated.

I enhanced your snippet quite a bit so that it actually runs as a
Beanshells script in Fiji's Script Editor here:

-- snip --
IJ.run("Mitosis (26MB, 5D stack)");
IJ.run("8-bit");
stack = IJ.getImage().getStack();

width = 171;
height = 196;
channels = 2;
slices = 5;
frames = 51;
images = channels * slices * frames;
copy = IJ.createImage(windowTitle + " Filtered", "8-bit black",
        width, height, images);
copy.setDimensions(channels, slices, frames);
copy.setOpenAsHyperStack(true);

copyStack = copy.getStack();

for (int i = 1; i <= images; i++) {
        print(i);
        pixels = (byte[]) stack.getPixels(i);
        copyStack.setPixels(pixels, i);
}

copy.show();
-- snap --

But it works, even for i == 1. Maybe your ImageJ version is out-of-date?

Ciao,
Johannes

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: can't fill first slice of hyperstack

Barry DeZonia
In reply to this post by Ben Glick
Hi Ben,

I took your code and adapted it in a fake plugin. I am able to get an image
with each slice correctly filled with the plane numbers from 1-24. I
suspect your source stack does not contain the correct data.

 public void run() {

  int width = 50;

  int height = 50;

  String windowTitle = "Fred";

  int channels = 3;

  int slices = 2;

  int frames = 4;

  int numPlanes = channels * slices * frames;

  ImageStack stack = new ImageStack(width, height, numPlanes);

  for (int i = 1; i <= numPlanes; i++) {

    byte[] plane = new byte[width * height];

    for (int k = 0; k < plane.length; k++)

      plane[k] = (byte) i;

    stack.setPixels(plane, i);

  }

  ImagePlus copy = IJ.createImage(windowTitle + " Filtered", "8-bit black",
width, height, numPlanes);

  copy.setDimensions(channels, slices, frames);

  copy.setOpenAsHyperStack(true);


  ImageStack copyStack = copy.getStack();


  for (int i = 1; i <= stack.getSize(); i++) {

    byte[] pixels = (byte[]) stack.getPixels(i);

    copyStack.setPixels(pixels, i);

  }



  copy.show();

}


On Mon, Jan 28, 2013 at 1:56 PM, Ben Glick <[hidden email]> wrote:

> That change gives an "Argument out of range" error. From what I can tell,
> ImageJ doesn't follow the Java convention of numbering stack slices from 0,
> but instead numbers them from 1.
>
> Note that all of the other slices in the new hyperstack are in the right
> place. Nothing is out of register.
>
> Ben
>
>
>
> --
> View this message in context:
> http://imagej.1557.n6.nabble.com/can-t-fill-first-slice-of-hyperstack-tp5001578p5001583.html
> Sent from the ImageJ mailing list archive at Nabble.com.
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: can't fill first slice of hyperstack

Ben Glick
Thanks for the helpful feedback. It's good to know that I'm not doing something blatantly foolish, but the mystery remains unsolved.

I'm using ImageJ 1.46, the latest version available for standard download.

If I create a new single-slice image, I can use setPixels() to populate that image with the pixels from the first slice in my source stack. So my source stack is okay.

The problem seems to be that the first slice of the new hyperstack is unable to receive the data. Perhaps I'm doing something wrong with the setup of the plugin. If there is a patient person with a keen eye, here is all of the relevant code:


public class Filter_Stack implements PlugInFilter {
 
        private ImagePlus imp, copy;;
        private ImageStack stack, copyStack;
        private byte[] pixels;
        private boolean[] filterChannels; // Indicates which channels will be filtered.
        private int width, height, channels, slices, frames, images;  
        private String windowTitle;
       
        public int setup(String arg, ImagePlus imp) {
          this.imp = imp;
          stack=imp.getStack();
          return DOES_8G + STACK_REQUIRED;
        }
       
        public void run(ImageProcessor orig) {
               
                width = stack.getWidth();
                height = stack.getHeight();
                channels = imp.getNChannels();
                slices = imp.getNSlices();
                frames = imp.getNFrames();
                images = channels * slices * frames;
                windowTitle = imp.getTitle();
               
                filterChannels = getColors(channels);
               
                copy = IJ.createImage(windowTitle + " Filtered", "8-bit black", width, height, images);
                copy.setDimensions(channels, slices, frames);
                copy.setOpenAsHyperStack(true);
               
                copyStack = copy.getStack();
               
                for (int i = 1; i <= images; i++) {
                  pixels = (byte[]) stack.getPixels(i);

                  // Now fill the slice with either filtered or unfiltered data.
                  if (filterChannels[(i - 1) % channels])
                    copyStack.setPixels(filterSlice(), i);
                  else
                    copyStack.setPixels(pixels, i);
                }
               
                copy.show();
        }
Reply | Threaded
Open this post in threaded view
|

Re: can't fill first slice of hyperstack

dscho
Hi Ben,

On Mon, 28 Jan 2013, Ben Glick wrote:

> Thanks for the helpful feedback. It's good to know that I'm not doing
> something blatantly foolish, but the mystery remains unsolved.
>
> I'm using ImageJ 1.46, the latest version available for standard download.

It would be good if you tried with ImageJ 1.47i to see whether that solves
your problem.

Ciao,
Johannes

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: can't fill first slice of hyperstack

Ben Glick
Updating ImageJ didn't help, but I got it to work by using the ImageProcessor. To set the pixel array for a slice, instead of

   copyStack.setPixels(pixels, i)

I now use

   copy.setSlice(i);
   copyProcessor.setPixels(pixels);

It gives the same result, except that the first slice is correctly populated.

Ben
Reply | Threaded
Open this post in threaded view
|

Re: can't fill first slice of hyperstack

Barry DeZonia
I think this is because the ImagePlus' internal ImageProcessor does not get
updated when you poke the ImageStack. Your original code  would have worked
if before the copy.show() you did a copy.setStack(copyStack); or a
copy.setProcessor(copyStack.getProcessor(x)); where x is the slice number
you want to be pointing at.


On Tue, Jan 29, 2013 at 9:38 AM, Ben Glick <[hidden email]> wrote:

> Updating ImageJ didn't help, but I got it to work by using the
> ImageProcessor. To set the pixel array for a slice, instead of
>
>    copyStack.setPixels(pixels, i)
>
> I now use
>
>    copy.setSlice(i);
>    copyProcessor.setPixels(pixels);
>
> It gives the same result, except that the first slice is correctly
> populated.
>
> Ben
>
>
>
>
> --
> View this message in context:
> http://imagej.1557.n6.nabble.com/can-t-fill-first-slice-of-hyperstack-tp5001578p5001592.html
> Sent from the ImageJ mailing list archive at Nabble.com.
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html