Dear ImageJ experts,
I'm trying to discover a method of using ImageJ to create a modal zprojection image from a stack -- that is, with the resulting image value at each xy being the mode / modal value of z rather than the median or mean. So for example if for pixel 1,1 the values along z in the stack were 0,0,0,96,96,128,128,256,256, I want the resulting zprojection image at 1,1 to have a value of 0 (modal value) rather than 96 (median) or 106.66 (mean). I've spent a few days searching forums and documentation, and I'd be grateful for any advice on how to proceed. Background: I'm working with stacks that are actually time series of software screen recordings, so the mode may be much more useful to me than in spectroscopy applications. Bins aren't an issue (most common values recur precisely) and the possibility of multiple modes isn't a concern (if there is more than one mode, returning the first one is fine). I've been investigating writing something as a macro / plugin, which I assume would be nested loops marching through x,y with the inner loop taking the mode a selection line running through the stack along z and then writing the result to a file - but I've been unable to figure out how that inner loop call should look like - should I try to use the existing "modal gray value" functionality that returns a number based on a selection, for example? Is there plugin or macro code that already exists? Finally, while I'd very much prefer a way of implementing this in ImageJ, suggestions of other methods to create a modal value zprojection would be appreciated as well. Thanks for your time. |
On Wednesday 31 December 2008, jeremydouglass wrote:
> I'm trying to discover a method of using ImageJ to create a modal > zprojection image from a stack -- that is, with the resulting image value > at each xy being the mode / modal value of z rather than the median or > mean. So for example if for pixel 1,1 the values along z in the stack were > 0,0,0,96,96,128,128,256,256, I want the resulting zprojection image at 1,1 > to have a value of 0 (modal value) rather than 96 (median) or 106.66 > (mean). The mode cannot be guaranteed. What is the mode of pixel values {1, 3, 7, 80} G. |
As I specified above, the first mode of 1,3,7,80 is 1. The first mode of 47,47,50,50 is 47.
|
On Wednesday 31 December 2008, jeremydouglass wrote:
> As I specified above, the first mode of 1,3,7,80 is 1. The first mode of > 47,47,50,50 is 47. The lowest valued mode, I see. You could reslice your stack. Now all the pixels in the z direction exist in the same (new) slices, so they can be processed quicker than having to get each pixel from a different slice. You put the result of the mode (calculated along the y axis) in the top row of pixels (depending how you resliced, of course) and finally you un-reslice the result back. The top slice should have the result. Cheers, G. |
Thank you so much G. This was extremely helpful.
After working for a while in this direction, I've written a macro to compute the modal zprojection that does exactly as you suggest -- first performing a reslice, then computing the mode(s) of each pixel column in each slice, and the reslices back to assemble the modal z projection image. It appears to be working correctly although it is quite inefficient. For anyone interested, I'm including my source below, with the caveat that this was my first ImageJ plugin and it might have problems. Note that here the modal value used for each pixel is always the *last* value returned to the results list if more than one mode is returned.
if (nSlices<2) exit("This macro requires a stack."); makeModalZProject(); function makeModalZProject() { setBatchMode(true); run("Set Measurements...", " modal redirect=None decimal=3");
run("Reslice [/]...", "input=1.000 output=1.000 start=Top"); depth = nSlices; width=getWidth(); for (z=0; z<depth; z++) { // loop through slices
setSlice(z+1); for (x=0; x<width; x++) { // loop through rows in a slice makeRectangle(x, 0, 1, depth); // select each column run("Measure");
zmodal = getResult("Mode",nResults-1); // be careful if multiple modes are returned this will take the last one.
setPixel(x, 0, zmodal); } } run("Select None"); run("Reslice [/]...", "input=1.000 output=1.000 start=Top"); setBatchMode(false); // display
} |
On Thursday 01 January 2009, jeremydouglass wrote:
> It appears to be working correctly although it is quite inefficient. The modification below runs about 3 times faster on the mri-stack.tif file. If implemented as a plugin it might run even faster. Cheers Gabriel //------------------8<------------------------- // Smallest valued mode of a stack if (nSlices<2) exit("This macro requires a stack."); makeModalZProject(); function makeModalZProject() { //t=getTime(); setBatchMode(true); run("Reslice [/]...", "input=1.000 output=1.000 start=Top"); depth = nSlices; width=getWidth(); height=getHeight(); for (z=0; z<depth; z++) { // loop through slices setSlice(z+1); for (x=0; x<width; x++) { // get the z pixels h=newArray(256); modef=0; zmode=-1; for (y=0;y<height;y++){ p= getPixel(x,y); h[p]++; if (h[p]>modef) modef=h[p]; } // the following will get the smallest valued mode i=0; // change to 255 to get the largest valued mode while(h[i]<modef) i++; // change to i--; to get the largest valued mode zmode=i; setPixel(x, 0, zmode); } } run("Reslice [/]...", "input=1.000 output=1.000 start=Top"); run("Duplicate...", "title=stack_mode"); setBatchMode(false); // display //print (getTime()-t); } //------------------8<------------------------- |
Free forum by Nabble | Edit this page |