3

I'm using dcmtk to read dicom images and I have following attribute with the new samples :

(0028,0004) Photometric Interpretation: MONOCHROME2
(0028,0010) Rows: 512
(0028,0011) Columns: 512
(0028,0030) Pixel Spacing: 0.4688\0.4688
(0028,0100) Bits Allocated: 16
(0028,0101) Bits Stored: 16
(0028,0102) High Bit: 15
(0028,0103) Pixel Representation: 1
(0028,0106) Smallest Image Pixel Value: 0
(0028,0107) Largest Image Pixel Value: 2732
(0028,1050) Window Center: 1366
(0028,1051) Window Width: 2732

I use the getOutputData(16) to read int16_t data. It's surprised me, because the values are negative near to -1*(2^16) and when I subtracted the values by 2^15 everything seems ok and I can see the images! :-(

Now I have two questions :

  1. Why should I subtract the value 2^15 and it goes ok? There is no padding value available on image!
  2. In document of getOutputData, it's speaking about The rendered pixel data is alway unsigned.. What does it means specially when my image data is signed because the (0028,0103) attribute is saying it to me? If this method is not proper, so can I get real data by dcmtk?
jap1968
  • 7,747
  • 1
  • 30
  • 37
mf mf
  • 133
  • 5
  • 15
  • `getOutputData` returns a `void *`, and (as you mention yourself) according to [documentation](http://support.dcmtk.org/docs/classDicomImage.html#46da8f4e40464d2659938b2b0bd10519) the output data is always unsigned. So should you not cast the output data to `uint16` instead? – Anders Gustafsson May 29 '13 at 07:07
  • Could you, please, include the values (if they are present) for _Rescale Slope_ (0028,1053) and _Rescale Intercept_ (0028,1052), as Paolo suggested? – jap1968 May 29 '13 at 16:02

5 Answers5

6

The key is the Pixel Representation (0028,0106) data element.

PixelRepresentation = 0 -> unsigned
PixelRepresentation = 1 -> signed

In your case, you have a value of '1', so you must read and interpret the values as signed integers.

You can find additional information here.

jap1968
  • 7,747
  • 1
  • 30
  • 37
  • 1
    I know it. But this isn't the answer to my question! I read the additional information there. There is nothing about why I should subtract with 2^15. – mf mf May 29 '13 at 11:01
  • 1
    This is the operation to calculate the [two's complement](http://en.wikipedia.org/wiki/Two%27s_complement) for a 16 bit number. I mean, this is the operation to convert a number interpreted as unsigned integer to the same one interpreted as signed integer. Have a look at the section _Subtraction from 2N_ – jap1968 May 29 '13 at 12:53
3

Never used dcmtk, but it looks like you have to apply the slope/intercept parameters of the modality VOI in order to obtain the correct numbers.

See rescale slope and rescale intercept and Window width and center calculation of DICOM image.

Community
  • 1
  • 1
Paolo Brandoli
  • 4,681
  • 26
  • 38
  • I shared whole header here : https://docs.google.com/document/d/1XyQXv_DVGfwmoRvnhllBu-vto9TEnxW_JQFLgMXQ3FU/edit?usp=sharing – mf mf May 29 '13 at 19:14
  • So, no rescale data elements. Did you try reading the pixel data as signed integers, just as I suggested in my previous answer? – jap1968 May 29 '13 at 19:21
0

According to the documentation getOutputData applies the presentation VOI before rendering so you always get unsigned data. So, if you ask for 16 bit data you will get pixels ranging fron 0 to 65535, regardless of the min and max values specified in the dataset; this because the returned data is meant to be displayed, it is not the original data stored in the image. I think you should just right shift the values by 8 bits, or just ask for 8 bit data (even if the image is 16 bits): I don't think that your graphic card can handle 16 bits if grayscale anyway.

Paolo Brandoli
  • 4,681
  • 26
  • 38
0

the DICOM header says that data is stored in DICOM file as a signed value, but it looks like that the documentation says that getOutputData converts it to an unsigned value. so, try reading the output of getOutputData as an uint16_t instead of int16_t.

michael pan
  • 589
  • 3
  • 10
  • Maybe the reason is the original values being negative ones. – jap1968 Jun 01 '13 at 16:26
  • 1
    uint_16 has a range of 0 to 65,535. int_16 has a range of –32,768 to 32,767. if the values being stored are greater than 32767, the 16th bit will be set. which is why if you int_16, it will appear as negative. – michael pan Jun 01 '13 at 17:42
0

I found the answer. It had explained here by good offic developers. See the page 2. It's completely related to DCMTK toolkit.

mf mf
  • 133
  • 5
  • 15