1

I'm implementing a DICOM-Image Viewer in C#. I don't (because I'm not allowed to) use any frameworks or libraries that do the image processing for me.

With which algorithm can I calculate the windowing? (With Window Center and Window Width)

I have the following things to work with:

  • The pixel data is stored as a byte[]
  • the pixels are stored in Hounsfield Unit (see first code)

I tried the following:

Calculating Rescale: (Edited)

var intArray = new int[PixelData.Length];
for (int i = 0; i < this.PixelData.Length; i++)
{
  intArray[i] = rescaleSlope*this.PixelData[i] + rescaleIntercept;
}

Calculating Windowing

var lowestVisibleValue = (windowCenter - 0.5 - ((windowWidth - 1) / 2));
var highestVisibleValue = (windowCenter - 0.5 + ((windowWidth - 1) / 2));

for (int i = 0; i < this.PixelData.Length; i++)
{
  if (intArray[i] <=  lowestVisibleValue)
  {
    PixelData[i] = 0;
  }
  else if (intArray[i] > highestVisibleValue)
  {
    PixelData[i] = 255;
  }
  else
  {
    PixelData[i] =(byte)((PixelData[i] - (windowCenter - 0.5))/((windowWidth -1) + 0.5)*(highestVisibleValue - lowestVisibleValue) + lowestVisibleValue);
  }
}

The second code return 0 almost all the time, so the image is almost black. Any ideas what I'm doing wrong?

EDIT 21.02.2017

I edited the code following Paolo Brandolis suggestion. I store the HU in an int[].
The Rescale Intercept is e.g. -1024 and Rescale Slope is 1. When Window Center is 40 and Window Width is 350, everything is black.
So something is still wrong. Any suggestions?

Community
  • 1
  • 1

1 Answers1

1

I think that the problem is caused by the fact that the result of the slope/intercept is truncated to a byte and the higher part of the value is lost

Housfield values don't fit in a single byte. Additionally, the Hounsfield values may be signed.

Paolo Brandoli
  • 4,681
  • 26
  • 38
  • would it be a solution to convert the array to an int[] and do the calculations and then convert it back to byte[]? because I need to have a byte[] because I use marshall.copy to copy it to a bitmap – OldTimeRambler Feb 20 '17 at 14:05
  • You could also store the result of the slope/intercept in a temporary signed integer array and put the result of the Window operation back into the byte array (assuming that the input image is composed of bytes and not shorts or integers). – Paolo Brandoli Feb 20 '17 at 14:08
  • ok, thank you for that suggestions, I've implemented that, but still something is wrong. Maybe you could take a look at my edited question – OldTimeRambler Feb 21 '17 at 09:35
  • From the values of the rescale/slope and the window center/width it seems that the original data needs more than one byte per pixel. The content of the tag 0028,0102 contains the high-bit number: if it is greater than 7 then you are losing the most significant part of the image data – Paolo Brandoli Feb 21 '17 at 10:12
  • Yes, that's indeed right, Bits Allocated = 16, Bits Stored = 12, and High Bit is 11. I'll try to fix the problems I still have, maybe I'll need a piece of advice later. Thank you so far – OldTimeRambler Feb 22 '17 at 10:09
  • Ok, I got one more question concerning the order: First I calculate the Hounsfield Unit and save the result in an int[ ]. Then I compare the Hounsfield Unit with the highest and lowest visible Pixel. When it's lower I set the entry of the current int[ ] (where the Hounsfield units are saved) to Zero, when it's higher I set it to 255 (because I'll convert it to a byte[ ] at the end) and when it's between high and low I'll make a linear conversion. Is that right? – OldTimeRambler Feb 23 '17 at 10:14