ImageProcessor.getPixel(int x,int y) not returning raw pixel values

imagej
plugin

#21

Thanks very much again mountain man. I have also realised something a bit more about part of an earlier post I made:

Part of my workflow often involves analysing multipe DICOM images from multiple systems all in one go and to do this I import the images as a stack (or more commonly a virtual stack). In some images the pixel data may be signed short, in some unsigned short, in some 32-bit etc.

If you take the images that you uploaded in your last post and put them all in the same directory and import them as an image sequence in imagej then you can run the python script you posted previously to see that the Calibration object created for the whole stack is based on the last image in the stack (I experimented a bit renaming the images so that they were imported in different orders). However, the pixels stored in the ImageProcessor for each slice are each read in as we have already discussed above (fortunately not munged based on the last slices but on the correct DICOM information for that slice as discussed earlier in the thread!).

This was giving me some very strange and inconsistent behaviour because the type of the last slice in my image was usually different so I hadn’t been able to figure out what was going on with the getPixelValue function! It sometimes seemed to work and sometimes didn’t… now I know why.

Thanks again for all of your help.
John


#22

In this case it is best to open all the images as 32-bit by enabling “Open as 32-bit float” in Edit>Options>DICOM. You can make this option the default by adding
run("DICOM...","open");
to the Edit>Options>Startup dialog box. You should also upgrade to the latest daily build (1.52i44), which fixes a bug that caused DICOMs to be displayed incorrectly when “Open as 32-bit float” is enabled.


#23

Thanks very much Wayne, that’s really useful to know.

My plugin actually extends the VirtualStack class to allow for multiple images across multiple directories as many medical vendors output a single image per directory but the images often need to be viewed in a single stack. When i wrote this code (a few years ago) i made it read the pixels in and apply the rescale intercept in the calibration for all data types except 32-bit floating point. The problem was that my plugin contains many other functions that the user can then run on a stack. If they were run on my custom VirtualStack object there was no problem but i wanted them to be able to open the stack however they want. From your and mountain man’s very kind help i have now got my plugin running well on all stacks and combinations of datatypes however they are opened. It was actually very easy once I understood how ImageJ handled the signed short data - I only had to add in two short lines of code.

Thanks again for all your help.
John


#24

I feel bad after all mountain man’s help and really useful explanations that I didn’t mark his answer as the solution. Although I think Mountain man answered first, Wayne summarised it very succinctly and definitively and so i thought it would be a better summary answer for anyone else with this question in the future. Thanks mountain man… your help was really appreciated and taught me a lot!


#25

Hello John -

Hey, no worries! You made the right choice here because Wayne
actually knows what he’s talking about, whereas I cheerfully provide
this forum with much misinformation. So, if you really want to know
what’s going on, Wayne’s your guy!

Thanks, mm


#26

Hello John -

There is one more oddity you might want to be on the lookout for.
(I don’t know whether it’s relevant to your workflow or not.)

16-bit (and presumably 12-bit and others that are converted to 16-bit)
DICOM’s that have a non-trivial “Rescale Slope”, i.e., Rescale Slope
not equal to 1, will have their DICOM calibration ignored – no Rescale
Slope, and also no Rescale Intercept.

This can be worked around by following Wayne’s suggestion to use
the DICOM “Open as 32-bit float” setting.

I tried to do a little archaeology.

There is a (not fully correct) git issue about this:

RescaleSlope/Intercept not applied for signed DICOM files by default #51

This git issue refers back to a 2011 discussion:

PET images read incorrectly

If I understand Wayne’s comment from back then:

it sounds like DICOM is supposed to automatically bump over to
“Open as 32-bit float” if you open a 16-bit image with a non-trivial
Rescale Slope, but that is not what I see happening, and the relevant
part of the current code, DICOM.java, seems to match the old code
quoted in the 2011 discussion. (Maybe a change was made and
then reverted somewhere along the way?)

Anyway, it’s one more thing to be aware of if your plugin ever deals
with non-trivial Rescale Slopes.

Thanks, mm


#27

The latest daily build (1.52i46) fixes this bug by converting DICOM’s with Rescale Slope not equal to 1.0 to 32-bit. The same bug was fixed in v1.45f in 2011, but that fix was reverted for some reason.


#28

Hello Wayne -

I upgraded to 1.52i46 (Help > Update ImageJ... / “daily build”).

I can confirm that opening a 16-bit DICOM image for which Rescale
Intercept <> 1 does automatically open it as a 32-bit float image
(without setting the DICOM option), and that the image uses the
DICOM calibration (Rescale) parameters.

Also, I can confirm that 16-bit DICOM images opened as 32-bit float
do now display correctly – ImageJ’s min and max display parameters
are now correctly derived from the DICOM image’s “Window Center”
and “Window Width” parameters. (It looked like version 1.42h would
subtract “Rescale Intercept” from the correct min and max values
when opening a 16-bit DICOM image as a 32-bit float.)

Thanks, mm


#29

Thanks for the heads up. I do occasionally deal with PET-CT data so it’s good to know about this!

John


#30

Thank you again Wayne!

John