Click here to Skip to main content
15,112,232 members
Articles / Desktop Programming / WPF
Posted 27 Sep 2012

Tagged as


119 bookmarked

Medical image visualization using WPF

Rate me:
Please Sign up or sign in to vote.
4.95/5 (66 votes)
27 Sep 2012CPOL6 min read
The article demonstrates the visualization of medical images (DICOM) using WPF.

2D representation of a single CT DICOM file


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. 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).

The Hounsfield Scale

Picture is taken from: Introduction to CT Physics

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):

  • DICOM CT image displayed with WindowCenter = +40 HU and WindowWidth = 350:

    DICOM CT Image, WindowCenter = +40 HU, WindowWidth = 350

  • Same DICOM CT image displayed with WindowCenter = -600 HU and WindowWidth = 1500:

    DICOM CT Image, WindowCenter = -600 HU, WindowWidth = 1500

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.

Animated visualization of an entire CT Image Series

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:

  • 4 Byte per Pixel (RGB + Alpha value) * RowCount of Pixel Data * ColumnCount of Pixel Data

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):

VolumeView: 3D representation of a CT Image Series

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.


September 2012, Initial version.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Bernhard Kügle
Software Developer (Senior) Siemens Healthcare
Germany Germany
Currently working as a Requirement Engineer for Siemens Healthcare in Germany.

Comments and Discussions

GeneralMy vote of 3 Pin
Dirk Sneider6-Oct-12 12:36
MemberDirk Sneider6-Oct-12 12:36 
QuestionExcellent Article Pin
Ratish Philip5-Oct-12 18:54
MemberRatish Philip5-Oct-12 18:54 
GeneralMy vote of 5 Pin
Ian Yates4-Oct-12 18:21
MemberIan Yates4-Oct-12 18:21 
GeneralGreat article Pin
ZoomDoc883-Oct-12 23:35
MemberZoomDoc883-Oct-12 23:35 
GeneralMy vote of 5 Pin
SundaramA2-Oct-12 10:05
MemberSundaramA2-Oct-12 10:05 
GeneralMy vote of 5 Pin
Dr Bob1-Oct-12 14:53
MemberDr Bob1-Oct-12 14:53 
GeneralMy vote of 5 Pin
bartolo1-Oct-12 7:22
Memberbartolo1-Oct-12 7:22 
GeneralMy vote of 5 Pin
David19761-Oct-12 6:34
MemberDavid19761-Oct-12 6:34 
Great work and Very clean and readable code!
GeneralGreat article Pin
CreF1-Oct-12 3:49
professionalCreF1-Oct-12 3:49 
Questiongreat post Pin
Gigy Joseph29-Sep-12 18:29
professionalGigy Joseph29-Sep-12 18:29 
QuestionAny plans to extend to other modalities? Pin
AnandChavali28-Sep-12 2:27
MemberAnandChavali28-Sep-12 2:27 
GeneralMy vote of 5 Pin
Sergio Andrés Gutiérrez Rojas27-Sep-12 17:31
MemberSergio Andrés Gutiérrez Rojas27-Sep-12 17:31 
QuestionMy vote of 5 Pin
Al-Samman Mahmoud27-Sep-12 13:51
MemberAl-Samman Mahmoud27-Sep-12 13:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.