Introduction

This article demonstrates the visualization of DICOM CT Images using Windows Presentation Foundation (WPF).
For accessing DICOM files, a parser is provided. After parsing, all the files are added to the instance tree.
The grouping is based on 'Name/Type/Study/Series'. On selection of an individual DICOM file in the instance tree, its DICOM meta information is displayed on the right-side panel.
In case the DICOM file represents a CT Image, its pixel data is displayed as bitmap in addition.
The user has the choice to open an animated 2D representation of the entire CT Image Series (similar to Apple's Cover Flow)
or to open a 3D surface representation of the entire CT Image Series (isosurface reconstruction).

DICOM Parsing

In order to access the DICOM meta information of each DICOM file, a DICOM parser is provided (namespace DICOMViewer.Parsing).
The parser converts the DICOM meta information into a System.Xml.Linq.XDocument representation.
Afterwards, the XDocument tree can be queried using LINQ-queries in order to retrieve all meta information of the DICOM file.
DICOM does support many different encoding rules (DICOM Transfer Syntax).
The table below gives an overview of all possible encoding rules.
For more details on DICOM encoding, please refer to the DICOM standard (Part 5: Data Structures and Encoding).

Transfer Syntax UID

Transfer Syntax Name

Meta Data encoding

Pixel Data encoding

1.2.840.10008.1.2

Implicit VR, Little Endian

Implicit VR, Little Endian

Raw

1.2.840.10008.1.2.1

Explicit VR, Little Endian

Explicit VR, Little Endian

Raw

1.2.840.10008.1.2.2

Explicit VR, Big Endian

Explicit VR, Big Endian

Raw

1.2.840.10008.1.2.4.xx

JPEG xxx (e.g. JPEG 2000)

Explicit VR, Little Endian

JPEG

1.2.840.10008.1.2.4.10x

MPEG xxx (e.g. MPEG2)

Explicit VR, Little Endian

MPEG

DICOM does specify a lot of Transfer Syntaxes which use compression. However, in all cases, the compression is only applied to one DICOM attribute: the pixel data
attribute (7FE0,0010). For all the compressed Transfer Syntaxes, the meta data information shall be encoded using Explicit VR, Little Endian.

In order to build up the instance tree, it is sufficient to access only the meta data information of each DICOM file.
Hence, the provided DICOM parser does only implement the three uncompressed transfer syntaxes:

Implicit VR, Little Endian

Explicit VR, Little Endian

Explicit VR, Big Endian

Visualization of a single CT image

On selection of an instance in the instance tree, the meta data information of the selected DICOM file is shown on the right-side panel.
In case the instance is of type CT Image and the pixel data is uncompressed, the pixel data is converted into a bitmap and displayed
to the user on the button of the right-side panel. The conversion is done in two steps:

Step 1: the pixel data values are converted into Hounsfield values

Step 2: the Hounsfield values are converted into grayscale values

Step 1: Conversion of pixel data into Hounsfield values

For CT Images, the relationship between the stored values (SV) and the Hounsfield values is defined by the following formula:

HU = SV * RescaleSlope + RescaleIntercept

The values for RescaleSlope and RescaleIntercept are retrieved from the meta data section of the DICOM file.
The code for accessing the pixel data and the conversion into Hounsfield Units can be found in
DICOMViewer.Helper.CTSliceInfo.GetHounsfieldPixelValue().

Step 2: Conversion of Hounsfield values (HU) into grayscale values

Once the stored values are converted into Hounsfield values (HU), the Hounsfield values have to be converted further into meaningful grayscale values.
The Hounsfield values range from -1000 (e.g., air) to several thousands (e.g., bone).

Mapping each Hounsfield value to a grayscale value would be the easiest way to display the image.
However, the human eye would not be able to distinguish gray values over such a wide range.
In order to overcome this limitation, the concept of Windowing is introduced.
Depending on the tissue being studied, the examiner of the image can set a Window corresponding to the range of Hounsfield values he is interested in.
Hounsfield values left of the window are displayed as black, Hounsfield values right of the window are displayed as white.

Below pictures show the display of the same DICOM image using different Window settings (pictures taken from: Introduction to CT
Physics):

Most of the available DICOM viewers allow the modification of the Window settings at runtime.
However, this implementation takes the default Window setting from the meta data section of the DICOM file
(DICOM attribute WindowCenter (0028,1050) and WindowWidth (0028,1051)) and does not support any further change of the Window values at runtime.

The code for the grayscale conversion can be found in DICOMViewer.Helper.CTSliceInfo.GetPixelBufferAsBitmap().

Animated visualization of an entire CT Image Series

CT images belonging to the same CT Image Series can be seen as a stack of 2D images.
In order to allow the user to scroll through all CT images of the stack, a user control similar to
Apple's Cover Flow is provided.

The major design idea for the ImageFlowView control (and much of the code) has been taken from Ded's
blog:
WPF Cover Flow Tutorial.

The ImageFlowView control has to support paging. This means, only a few CT
image slices (next to the centered CT
image) are made visible at any point in time.
Displaying all CT images of an entire CT series would lead to a very high memory consumption. A CT series (e.g., a whole body scan) can sum up to 1.000
individual CT images.
The memory allocation for one single CT image can be calculated as follows:

For CT images (taken by a modern CT scanner), a typical Row/Column count is 512. This brings us to a memory consumption of 1 MB for one single CT
image.

Scrolling through the stack can be done either via Left/Right-Key, mouse wheel, or by moving the slider directly.
In case the Shift-Key is pressed, scrolling is done without animation.

Surface rendering of an entire CT Image Series

A CT Image Series can be seen as a 3D scalar field of Hounsfield values.
The VolumeView class implements the well-known Marching Cubes algorithm in order to create an isosurface out of the 3D scalar field of Hounsfield values.
The Marching Cubes algorithm is described in the famous article Polygonising a scalar field from Paul Bourke.
For the C# implementation of the Marching Cubes algorithm, the proposal from Paul Bourke's article was used.
The entire surface rendering implementation can be found in the namespace DICOMViewer.Volume.

The DICOMViewer does allow the surface rendering for two different isovalues:

Isovalue of +500, which will visualize the bones

Isovalue of -800, which will visualize the skin

Bone rendering of the PHENIX patient (Isovalue = +500 HU):

Running the application

After starting the application, select via File -> Load the directory from where you want to load the DIOCM files. The files should be of type *.dcm.

If you don't have DICOM files on hand, you can download sample DICOM images from the OsiriX internet page.
The screenshots for this article had been taken after loading the dataset for the PHENIX patient found on the OsiriX internet page.

Comments and Discussions

hi,
I am looking for a CT sample data.
The link you gave in the article is of Jpeg2000 compression, but the code can deal with uncompressed data only.
Can you please refer to data sample which the viewer can work with?

When i used the same coding in visual studio 2012 in my application it gives out of memory exception. What should i do ?? But when i run the given project of urs in visual 2012 it works perfectly.. Can u suggest me a solution.

Hello,
Thanks for the excellent article. I am having a little problem using the code.
I can't read any other datasets than the PHENIX dataset. The isPixelDataProcessable attribute is not returning proper value when called. Any ideas?