Adjusting WindowWidth And Level using ExplicitVOILUT property
.NET version
Demo code to show the usage of the DicomImage property (ExplicitVOILUT) by generating and applying a LookupTable that has been calculated based on the standard DICOM windowing formula for calculating a Lookup table.
This example code assumes min and max as the range of values you need to handle in input data (anything beyond that is mapped to the first/last value) and for screen display it defaults to 8 bit output.
This sample code here uses the official DICOM windowing formula and reproduces the existing window via an explicit LUT.
void createExplicitVOILUT(DicomImage image)
{
if (image.ExplicitVOILUT != null)
{
image.ExplicitVOILUT = null;
image.VoiLUT = 1;
return;
}
// 8 is enough unless going to a 12 bit printer etc
int bits = image[Keyword.BitsStored].ExistsWithValue ? (int)image[Keyword.BitsStored].Value : 8;
int min = -1024;
int max = (int)(Math.Pow(2, bits) - 1);
float w = image.Width;
float l = image.Level;
int maxoutput = (1 << bits) - 1;
ushort[] LUTdata = new ushort[max - min];
for (int i = min; i < max; i++)
{
// copy current windowing
float v = ((i - l) / w + 0.5F); // standard DICOM windowing formula - gives 0 to 1
v \*= maxoutput; // to go full range
LUTdata[i - min] = (ushort)Math.Min(Math.Max(v, 0), maxoutput);
}
image.ExplicitVOILUT = new LookupTable(min, bits, true, LUTdata);
image.VoiLUT = 1;
}