Conversion 12 bit grayscale dicom image to 16 bit grayscale PNG

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
AlexanderLysenko
Posts: 19
Joined: Tue, 2009-07-07, 14:18

Conversion 12 bit grayscale dicom image to 16 bit grayscale PNG

#1 Post by AlexanderLysenko »

Hello!

I have dicom images having following attributes:
(0028,0002) US 1 # 2, 1 SamplesPerPixel
(0028,0004) CS [MONOCHROME1] # 12, 1 PhotometricInterpretation
(0028,0010) US 4096 # 2, 1 Rows
(0028,0011) US 3328 # 2, 1 Columns
(0028,0030) DS [.070\.070] # 10, 2 PixelSpacing
(0028,0034) IS [180\180] # 8, 2 PixelAspectRatio
(0028,0100) US 16 # 2, 1 BitsAllocated
(0028,0101) US 12 # 2, 1 BitsStored
(0028,0102) US 11 # 2, 1 HighBit
(0028,0103) US 0 # 2, 1 PixelRepresentation

Also in file header present following item:

(0028,3010) SQ (Sequence with undefined length #=1) # u/l, 1 VOILUTSequence
(fffe,e000) na (Item with undefined length #=3) # u/l, 1 Item
(0028,3002) US 1091\2652\16 # 6, 3 LUTDescriptor
(0028,3003) LO [MAMMO] # 6, 1 LUTExplanation
(0028,3006) OW 0000\0000\0000\0000\0000\0000\0000\0000\0001\0001\0001\0001\0001... # 2182, 1 LUTData
(fffe,e00d) na (ItemDelimitationItem) # 0, 0 ItemDelimitationItem
(fffe,e0dd) na (SequenceDelimitationItem) # 0, 0 SequenceDelimitationItem


I need to export it to PNG format.
I used utility dcm2pnm with parameters to extract single frame:
dcm2pnm +on image.dcm image.png
Should i use any special parameter to process LUTData?

According to documentation created image will be 8bit PNG grayscale image, i have looked into created png image properties and found that it is 8 bit.

It looks that we have lost of 33% of pixel data information during conversion of 12bit dicom image to 8 bit PNG.

How to avoid this?
I need to convert it to 16 bit grayscale PNG image, to avoid lost color information.

I checked used libpng library, it support 16bit grayscale PNG images.

Can you please help me with modifying dcm2pnm utility to convert dicom image to 16bit PNG?

As far i understand i should implement following changes in function from
dcmimage\libsrc\dipipng.cc:

int DiPNGPlugin::write(
DiImage *image,
FILE *stream,
const unsigned long frame) const

replace
1) /* create bitmap with 8 bits per sample */
const void *data = image->getOutputData(frame, 8 /*bits*/, 0 /*planar*/);
by
const void *data = image->getOutputData(frame, 12 /*bits*/, 0 /*planar*/);

Here 12 - equal to #BitsStored

2)
int bit_depth = 8;
replace by
int bit_depth = 16; // bit depth of output PNG image

3)
if((image->getInternalColorModel() == EPI_Monochrome1) || (image->getInternalColorModel() == EPI_Monochrome2))
{
color_type = PNG_COLOR_TYPE_GRAY;
bpp = 1;
}

replace by:

if((image->getInternalColorModel() == EPI_Monochrome1) || (image->getInternalColorModel() == EPI_Monochrome2))
{
color_type = PNG_COLOR_TYPE_GRAY;
bpp = 2;

After i have started updated application, i got artifacts in result image.
It was 16 bit PNG, but looks like inverted.
Also in the png appeared bright places not visible in original image.

Please fix me if i used incorrect way to extract image to 16 bit grayscale png.

best regards, Alexander

J. Riesmeier
DCMTK Developer
Posts: 2506
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

#2 Post by J. Riesmeier »

First of all, you should probably call getOutputData() with bits=16. Then you should check the byte-ordering requirements for PNG. Maybe, big endian is required, which is also known as the "network byte order".

AlexanderLysenko
Posts: 19
Joined: Tue, 2009-07-07, 14:18

#3 Post by AlexanderLysenko »

Thanks for response!
It is working!

extra operation required here
is png_set_swap(png_ptr) before call to png_write_image

Also getOutputData should be called with 16bit parameter

J. Riesmeier
DCMTK Developer
Posts: 2506
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

#4 Post by J. Riesmeier »

Thank you for the feedback. I've added this feature (16-bit PNG export) to our to-do list ...

AlexanderLysenko
Posts: 19
Joined: Tue, 2009-07-07, 14:18

#5 Post by AlexanderLysenko »

1 more issue remains:
i don't see difference between image from 8 bit png created from 12bit grayscale dicom and image from 16bit png ...

same issue for another 10 bit dicom file ...

also 8/16bit png files have different size (that is ok).

J. Riesmeier
DCMTK Developer
Posts: 2506
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

#6 Post by J. Riesmeier »

This is probably a "feature" (or non-feature) of your viewer. Many viewers will scale-down the 16 bits per sample to 8 bits for display.

J. Riesmeier
DCMTK Developer
Posts: 2506
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

#7 Post by J. Riesmeier »

Btw, the 16 bit PNG export is now part of the current development version of the DCMTK (see commit).

AlexanderLysenko
Posts: 19
Joined: Tue, 2009-07-07, 14:18

#8 Post by AlexanderLysenko »

Thanks for support, you are very quick :)

George
Posts: 52
Joined: Sun, 2023-11-12, 16:50

Re: Conversion 12 bit grayscale dicom image to 16 bit grayscale PNG

#9 Post by George »

Hello,

Given the thread, it would be nice to understand these questions?

- How do save a frame of bmp or png of 8/16/24/32 bits size formats? I see here that he used getOutputData but how did he save it after that.
- How dcm2pnm is a good idea to change bits? Will the conversion cause loosing data that is important for dicom
- Do you have any function that works to convert also between format like bmp to png or any other?

Best Regards
George

Post Reply

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot] and 1 guest