How do I display distinct planes from 16bit image stacks?

I have an image stack that contains N layers of 16bit word images.

Wave: img_red_st
Type: Unsigned Word 16 bit
Rows: 6016  Start: 0  Delta: 1  Units:
Columns: 4000  Start: 0  Delta: 1  Units:
Layers: 4  Start: 0  Delta: 1  Units:

I want to display each plane separately. I am confused about how exactly to do so. It seems, the explicit mode only works up to 8bit data. So, this does not work:

ModifyImage/W=ImageWindow img_red_st, plane=0

What would be the best way to handle the display of 16bit stack images to be able to step through the planes?

* Convert to 8bit for display purpose?
* Use an appropriate setting of ModifyImage ... eval={...} to reset the explicit levels to recognize 16bit images?
* Something else entirely?


Ran into related issues just yesterday. My workaround was the the imagetransform convert2gray operation to create an 8 bit image.


I've discovered that this is an oddity in how image stacks are displayed.

When a 16bit stack has 3 or 4 layers, image display presumes to show the entire stack as a composite image. When the 16bit stack has 2 or few layers or when it has 5 or more layers, the image display shows the individual layers from the stack properly even as 16 bit.

UPDATE: This also happens for 8bit stacks.

I'll also report this via email to support and see what happens.

I think you might just need the NewImage/G=1 flag. From the documentation for NewImage:

"/G=g    g =1:    Suppresses the autodetection of three plane images as direct (rgb) color. Flag also suppresses detection of explicit mode.
    g = 0:    Default, which is same as no /G flag."

This seems likes reasonable behavior to me, since 3 or 4 layers could be intended to be displayed as RGB or RGBA images, respectively. There's a little more information in AppendImage, which has the same flag.

Yes, the NewImage/G=1 works. I missed it because I was looking for something in the ModifyImage operation. I want to use one window to swap images between a three-color RGB and a single channel. I also want to scroll through stacks of images.

I'll figure out an option in the meantime.


In reply to by jjweimer

jjweimer wrote:

I want to use one window to swap images between a three-color RGB and a single channel. I also want to scroll through stacks of images.

I'll figure out an option in the meantime.

It sounds like using appendImage/G=1 (for the single channel) followed by removeImage, then appendImage/G=0 (for the RGB) and removeImage again, could give you want you want. It does sound cumbersome since any other settings (range, plane #) would have to re-applied after each swap.

One other thought is that you could take advantage of the transparency settings to simultaneously display both the color and monocolor images. You would toggle which one is displayed by setting one to be transparent and the other opaque. This seems to work nicely:

make/o/w/u/n=(300,300,4) color; color[][][0,2]=enoise(65535/2)+65535/2;color[][][3] = 65535*1        //make a color wave, set fully opaque
make/o/w/u/n=(300,300,20) gray; gray=mod(p+r,10)         //make a monocolor image, 20 planes
colortab2wave grays;duplicate/o M_colors,myctab;redimension/n=(-1,4) myctab;myctab[][3] = 65535*0    //make a custom color table for the monocolor image, set fully transparent
newimage/k=1 color;appendimage/t/l gray;ModifyImage gray ctab= {*,*,myctab,0}        //append images to one graph, set the custom color table for the monocolor image
//image starts off showing just the color image
•myctab[][3] = 65535*1;color[][][3] = 65535*0     //show only gray image by setting it fully opaque and setting color image fully transparent
ModifyImage gray plane=2  //change plane of the monocolor image
•myctab[][3] = 65535*0;color[][][3] = 65535*1 //toggle back to showing color
•myctab[][3] = 65535*1;color[][][3] = 65535*0 //toggle back to showing monocolor

It might seen inefficient to have to change the value of so many points each swap. However, this could be alleviated if the color wave is behind the monocolor image on the graph. In that case, the opacity of the color image can be constant and only the opacity of the monocolor image has to change. Plus, the custom color table could be relatively small.


I see.

For background, I am developing this in the Image Tools Package. As I step through image folders, I just use ReplaceWave to swap the image. For planes, I just do a ModifyImage ... plane=.

The appendimage / removeimage method would likely be the most direct for me to implement. But ... 

With other needs more pressing, I may be biting off a bit more than I want to address by trying to be so flexible enough to handle switching among RGB, RGBA, and multi-stacks with N = 3 or 4. The easier path for me at this moment is to just restrict that my routine to create files -> stacks only works with N > 4 files. For cases with N <= 4, I'll just load the image files into separate folders.

All said and done, I might hope to have a ModifyImage/G flag someday (e.g. in Igor Pro 9)  to make the process easier.

Thanks for the help!


In reply to by jjweimer

The situation does sound less than ideal, but it seems like it might be fairly easy to initialize with a color wave (/G=0) and a stack (/G=1) on display (probably using placeholders). Your RGB waves could replaceWave the former and your stacks could replaceWave the latter. (I am guessing that you would have to assure that the color wave always has 3 or 4 layers or it will revert to displaying as a stack.)

You could use ReorderImages to only show the color wave or stack depending on what is currently meant to be shown. This seems more straightforward than the opacity method that came to my mind previously, though it requires that your images be fully opaque (no opacity channel or opacity = 65535).

Edit: it also occurs to me that the lack of a "TraceName" equivalent for images makes it difficult to use ReplaceWave, but perhaps you could store (e.g., in the window's named user data) the most recent color image and stack wave names (and thus image names) to maintain a handle on each image. It might also be useful to store which one is on top.

There *is* a traceName equivalent for images, we call them "image instance names", usually shortened to "imageName".

The ReplaceWave command takes several forms, one of which is:

ReplaceWave image=imageName, waveName


@gsb: At some point, I may investigate the option to use show/hide image traces for other needs. For example, in my next release of Image Tools, I will include a thresholding tab (and perhaps background removal). I could append the resulting threshold overlaid on the source image and use the show/hide method or use an an opacity filter.

In reply to by JimProuty

JimProuty wrote:
There *is* a traceName equivalent for images, we call them "image instance names", usually shortened to "imageName".

I was focused on the "user-defined trace names" that display/appendToGraph offers with the /TN flag. I don't believe that imageName has an equivalent in that regard?

Instead, it seems that imageNames are always completely specified by the "Y" wave name (and number of images displaying the same Y wave, via #1,#2,#3...). In situations where replaceWave is being used, the lack of user-defined imageNames could be cumbersome. 

@jjweimer: sounds useful all around!

I have added ModifyImage genericNotRGB=g to Igor 9.

The =g value is the same as AppendImage/G=g