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 |
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 |
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 |
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 |
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 |
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 |
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(); } |
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 |
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 |
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 |
Free forum by Nabble | Edit this page |