A few days ago I reported some strange results with setPixels with the first page of the stack not being updated. It seems that it is a bug in ImageJ. It isn't necessarily the first page, but rather the image which is currently being displayed.
To make a test case I generated a stack using Convert to Mask which gives an image with pixels either 0 or 255. I can supply such data if someone wants it. The data is the result of Convert to Mask which gives either 0 or 255, after which the stack is converted to 16 bits. Then I can choose any image I wish from the stack as the currently displayed page. I run the program and the displayed page will remain with 0 and 255, with all other pages being 0 or 300. The only sense I can make out of this is that setPixels is failing for the currently displayed slice. For simplicity, I take the case where only a single ImagePlus is displayed and the program operates on it. This is only for the case of making a reproducible bug. I pulled out only the essentials of the program so that it all fits in a single page. Here is the code which demonstrates the problem: import ij.ImagePlus; import ij.ImageStack; import ij.WindowManager; import ij.plugin.PlugIn; import javax.swing.JOptionPane; /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ /** * * @author ilan */ public class Nuclear_Bad implements PlugIn { ImagePlus imgMask; @Override public void run(String arg) { doIt(); } void doIt() { int[] myList = WindowManager.getIDList(); imgMask = WindowManager.getImage(myList[0]); doMasking(); } void doMasking() { int i, j, stkSz, sliceSz; short curVal; ImageStack maskStack; Object pix2; short[] maskIn, maskOut; stkSz = imgMask.getImageStackSize(); maskStack = imgMask.getImageStack(); for( i=1; i<=stkSz; i++) { pix2 = maskStack.getPixels(i); if(!(pix2 instanceof short [])) { JOptionPane.showMessageDialog(null,"Must have 16 bit data on both series"); return; } maskIn = (short[]) pix2; sliceSz = maskIn.length; maskOut = new short[sliceSz]; for( j=0; j<sliceSz; j++) { curVal = maskIn[j]; if( curVal != 0) curVal = 300; maskOut[j] = curVal; } maskStack.setPixels(maskOut, i); } imgMask.repaintWindow(); } } To demonstrate the problem one only needs to put the cursor on the image. On the image which was displayed when the program was run will remain 0 or 255. Scrolling to any other image will give 0 or 300. Scrolling back will return to 0 or 255. This is so simple that it is hard to imagine anything else than a bug. Thanks, Ilan |
On Apr 9, 2014, at 6:45 AM, Ilan wrote:
> A few days ago I reported some strange results with setPixels with the first > page of the stack not being updated. It seems that it is a bug in ImageJ. It > isn't necessarily the first page, but rather the image which is currently > being displayed. > To make a test case I generated a stack using Convert to Mask which gives an > image with pixels either 0 or 255. The test plugin should work as expected if you change imgMask.repaintWindow(); to imgMask.setStack(maskStack); In general, you should use ImagePlus#setStack() to redisplay a stack acquired with ImagePlus#getStack() and modified. -wayne > I can supply such data if someone wants > it. The data is the result of Convert to Mask which gives either 0 or 255, > after which the stack is converted to 16 bits. > Then I can choose any image I wish from the stack as the currently displayed > page. I run the program and the displayed page will remain with 0 and 255, > with all other pages being 0 or 300. The only sense I can make out of this > is that setPixels is failing for the currently displayed slice. > > For simplicity, I take the case where only a single ImagePlus is displayed > and the program operates on it. This is only for the case of making a > reproducible bug. I pulled out only the essentials of the program so that it > all fits in a single page. Here is the code which demonstrates the problem: > > > import ij.ImagePlus; > import ij.ImageStack; > import ij.WindowManager; > import ij.plugin.PlugIn; > import javax.swing.JOptionPane; > > /* > * To change this license header, choose License Headers in Project > Properties. > * To change this template file, choose Tools | Templates > * and open the template in the editor. > */ > > /** > * > * @author ilan > */ > public class Nuclear_Bad implements PlugIn { > ImagePlus imgMask; > > @Override > public void run(String arg) { > doIt(); > } > > void doIt() { > int[] myList = WindowManager.getIDList(); > imgMask = WindowManager.getImage(myList[0]); > doMasking(); > } > > void doMasking() { > int i, j, stkSz, sliceSz; > short curVal; > ImageStack maskStack; > Object pix2; > short[] maskIn, maskOut; > stkSz = imgMask.getImageStackSize(); > maskStack = imgMask.getImageStack(); > for( i=1; i<=stkSz; i++) { > pix2 = maskStack.getPixels(i); > if(!(pix2 instanceof short [])) { > JOptionPane.showMessageDialog(null,"Must have 16 bit data on both > series"); > return; > } > maskIn = (short[]) pix2; > sliceSz = maskIn.length; > maskOut = new short[sliceSz]; > for( j=0; j<sliceSz; j++) { > curVal = maskIn[j]; > if( curVal != 0) curVal = 300; > maskOut[j] = curVal; > } > maskStack.setPixels(maskOut, i); > } > imgMask.repaintWindow(); > } > > } > > To demonstrate the problem one only needs to put the cursor on the image. On > the image which was displayed when the program was run will remain 0 or 255. > Scrolling to any other image will give 0 or 300. Scrolling back will return > to 0 or 255. > This is so simple that it is hard to imagine anything else than a bug. > > Thanks, > Ilan > > -- > View this message in context: http://imagej.1557.x6.nabble.com/Bug-in-setPixels-tp5007255.html > Sent from the ImageJ mailing list archive at Nabble.com.\ -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Ilan
Thanks Wayne. You are correct that the setStack solved the problem. Apparently this is some sort of strange combination of the copy constructor together with working on the original object. On slices off the currently viewed one the setPixels works on the original object. On the currently displayed slice it doesn't. So the setStack replaces the original stack object and solves the problem.
In any case, thanks for the advice. It wasn't something which I could have guessed on my own. Ilan |
Free forum by Nabble | Edit this page |