Comments (11)
The DICOM image that Mukul Lanke provided results in the pixelData
variable being set to a GrayscalePixelDataU16
object.
Investigation has revealed that even so, the OutputLUT
is only applied to 8-bit values, 0-255. The return LUT value for pixel data values of 256 and above will effectively be set to LUT 255.
The correct application of the LUT table should be that it accounts for the actual range in the provided pixel data.
from fo-dicom.
OK, by identifying the minimum and maximum values of the pixel data (0 and 606 in this particular image), rescaling the pixel data values to be within the range 0-255 and then apply the LUT, I manage to obtain this image:
The question is now, is this the (only) right way to go? For example, if you apply the min-max range LUT approach to two images with different pixel data value spans, the comparison could be misleading. At least when comparing images, it would be more relevant to use a common LUT conversion range for both images.
I would like to have your opinions here, please discuss!
from fo-dicom.
One more finding: in the DICOM image concerned here, window center and width are 294 and 511, respectively. When those parameters are available, it is of course natural that the LUT is applied within the ranges that the center and width dictates. If so, the same rule should be applied to 8-bit images as well for consistency, or? Please discuss!
from fo-dicom.
I have now investigated the issue in even more detail. The problem starts when trying to apply the "raw" color table LUT onto the image, without accounting for rescale intercept and slope, window center and width, LUT shape and inversion properties.
All this information can be obtained from the image data by calling the GrayscaleRenderOptions.FromDataset
static method. By default, this information is transferred into a GenericGrayscalePipeline
object which composes a CompositeLUT
object that is used when rendering the image via DicomImage.RenderImage
.
However, this approach is limited to Monochrome 1 and Monochrome 2 color tables; if you want to apply a different color table, say the "green-fire-blue" table you will need to compose the composite LUT manually.
Here is a method that lets you do exactly this. It contains all the steps taken to generate a look-up table in GenericGrayscalePipeline
, except that it applies a specified color table instead of the standard monochrome color tables when initializing the OutputLUT
component:
public static ILUT CreateFromDataset(DicomDataset dataset, Color32[] colorTable)
{
var options = GrayscaleRenderOptions.FromDataset(dataset);
var composite = new CompositeLUT();
OutputLUT output;
if (options.RescaleIntercept != 0.0 || options.RescaleSlope != 1.0)
{
composite.Add(new ModalityLUT(options));
}
composite.Add(VOILUT.Create(options));
composite.Add(
output =
new OutputLUT(colorTable ?? (options.Monochrome1 ? ColorTable.Monochrome1 : ColorTable.Monochrome2)));
if (options.Invert)
{
composite.Add(new InvertLUT(output.MinimumOutputValue, output.MaximumOutputValue));
}
return new PrecalculatedLUT(composite, options.BitDepth.MinimumValue, options.BitDepth.MaximumValue);
}
Now in the example above, instead of initializing the LUT via the OutputLUT
constructor:
OutputLUT oLUT = new OutputLUT(colorTable);
call the CreateFromDataset
method:
var oLUT = CreateFromDataset(di.Dataset, colorTable);
and Tadaa!
I admit that fo-dicom is non-intuitive in this respect, and there is a definite need to make the LUT application more easily dealt with.
This issue will be kept open, and we will consider whether to incorporate the presented helper method or something similar to facilitate a more flexible LUT application.
Everyone interested, please share your thoughts and ideas regarding this issue! Leave your comments below.
from fo-dicom.
Great Anders !! Fantastic, Just Fantastic !! π
Well, I hadn't gone up-to this depth of analysis of Fellow-Oak Dicom Library and the effects of parameters - WC, WW, RescaleSlope, RescaleIntercept while applying LUT. So, right now, I think that the solution that you have provided is the best.
I will incorporate the method that you have given above in the latest source-code of Fellow-Oak that I have (ver 1.1.0). And I will just cross-verify that whether the images produced using the above method for other LUT files (like Fire, MagentaHot, etc) match with those produced from the other Viewer. I will reply again after I verify at my end.
from fo-dicom.
Hooray !! I found that all the LUT files for which I was previously getting different colors than expected - are now getting applied correctly! In fact, if we compare the images minutely, then they are showing even better detailing (or sharpness) than the expected ones!
I have inserted the images produced from other viewer and from Fellow-Oak.
Thanks a lot Anders !! π
from fo-dicom.
That's great, Mukul, glad this solution could be of help to you!
Regards,
Anders
from fo-dicom.
Great job @anders9ustafsson. Including some form of this in the library would be neat. In the meantime I guess this is a great candidate for the wiki
from fo-dicom.
Thanks, @IanYates . I already have some ideas on how to incorporate this in the library, but in the meantime an addition to the wiki sounds reasonable.
from fo-dicom.
Wiki page added!
from fo-dicom.
Hooray !! I found that all the LUT files for which I was previously getting different colors than expected - are now getting applied correctly! In fact, if we compare the images minutely, then they are showing even better detailing (or sharpness) than the expected ones!
I have inserted the images produced from other viewer and from Fellow-Oak.
Thanks a lot Anders !! π
Hi Mukul,
can you provide me a source to get all those different LUT files that you used here?
I'm new to this domain and still learning basics. It would be helpful if you provide it.
from fo-dicom.
Related Issues (20)
- TLS: tlsInitiator set pfx fileοΌthen client.SendAsync(), a sspi error has occurred. HOT 4
- How come a DICOM file has zero size? HOT 2
- How to read a dicom file from network stream HOT 3
- Equipment generates more than one print in the job queue
- Read DICOM file using UnseekableStream HOT 2
- Could not decode string '????' with given encoding, using replacement characters. HOT 6
- DICOM dataset is missing pixel data element HOT 2
- Cannot Set the AE Title for Server HOT 8
- DICOMDIR Sorting Problem HOT 1
- Trying to understand GetPrivateTag function of DicomDataset HOT 1
- Dataset::AddOrUpdate method does not serialize the DICOM tag value of VR type DT according to the standard HOT 3
- Example of Secondary Capture Image & Encapsulated Document HOT 1
- PN Cannot Exceed 64 characters in total length HOT 2
- fo-dicom is missing NuGet package README file
- JsonDicomConverter is throwing an ArgumentException for Infinity values FL and FD VRs HOT 1
- HTj2k compression support HOT 1
- Error while trying to render image when OverlayData is present HOT 11
- Optimize Rendering by reducing memory usage
- Implement the new forumula of VOI LUT Function Linear_Exact
- Rendering of YBR_RCT and YBR_ICT fail
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fo-dicom.