Open richard-viney opened 1 year ago
Hi Richard!
Thanks for your question! The decision to scale everything to the 0-255 range was taken based on the fact that current browser technology supports 8 bits (or 256) shades of gray. Actually, most medical displays and regular computer screens are often limited to the same range. There are high end medical displays that can display 1024 shades of gray (like the ones optimized for mammography) but, as far as I know, they require specialized hardware to achieve this.
That’s why VoiLut
’s minimum and maximum values were hardcoded to 0 and 255, respectively. So, “the damage is done” before deciding to pack a pixel in an integer by masking with & 0xff
!
We could definitely create a “HighBitDepthLutPipeline” by allowing the user to set VoiLut
min/max and skip pixel packing (this will significantly grow the memory usage though) but I honestly can’t see any practical use. Do you?
Certainly correct that most displays only show 8-bit, though some consumer displays can now do 10-bit colour such as the current MacBook Pros. I think browser support for actually using this via native image formats is fairly limited, probably until AVIF or similar become more widespread.
Still, that aside, one reason for it being more immediately useful to render the full dynamic range with this library is it allows the full underlying data to be extracted & decompressed from its native transfer syntax and then stored in another system/format where transforms such as windowing can be applied dynamically to it during display, as they can make full use of the entire range in the image data, even on an 8-bit display. This corresponds to DICOM tags such as WindowWidth
and WindowCenter
. One could potentially adjust those tag values and then re-render using this library (haven't actually tested this), but for real-time needs this likely isn't workable and they'll need the 10-bit data directly. Other image processing analysis transforms are likely use cases too, not just windowing, but that is a simple & common one.
Hi Richard! Regarding the dynamic change of WindowWidth
and WindowCenter
, have you checked that example file? Holding the left mouse button and dragging it over the image, dynamically changes the WindowWidth
and WindowCenter
and re-renders, using the initial, stored in the file or decompressed, pixel values.
In any case, I see your point! Although the library was created with rendering-on-monitors in mind, there could be use cases in which the rendered pixel data should be stored in different formats that do support 16 bit pixel values.
Hi Pantelis,
I'm looking at how the library is handling high bit depths, 10-bit or 12-bit grayscale data in particular. It looks like it's mostly supported but the
DicomImage.render()
method is converting down to 0-255 via a& 0xff
. Would it be reasonable to add support for returning an Int32Array instead to support both higher bit depths as well as signed pixel data? The latter can come in via uncompressed transfer syntaxes as well as formats such as JPEG 2k.Thanks!