Click here to Skip to main content
15,444,993 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.96/5 (67 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)

Written By
Software Developer (Senior) Siemens Healthcare
Germany Germany
Currently working as a Requirement Engineer for Siemens Healthcare in Germany.

Comments and Discussions

Question3D result smaller than real Pin
Member 133416694-Aug-20 22:22
MemberMember 133416694-Aug-20 22:22 
QuestionImage is not displayed Pin
jean-Marie Polain26-Apr-17 22:25
Memberjean-Marie Polain26-Apr-17 22:25 
PraiseThank you so much Pin
MJarvan27-Mar-17 21:23
MemberMJarvan27-Mar-17 21:23 
QuestionReading MRI images? Pin
Member 118453681-Nov-16 4:10
MemberMember 118453681-Nov-16 4:10 
QuestionMRI dataset Pin
Mohammed Shihab29-Sep-15 13:58
MemberMohammed Shihab29-Sep-15 13:58 
QuestionDatasets example Pin
Member 1127608022-Mar-15 3:53
MemberMember 1127608022-Mar-15 3:53 
Masha Samarawickrama10-Jun-14 4:50
MemberMasha Samarawickrama10-Jun-14 4:50 
QuestionMy vote of 5 Pin
Aydin Homay12-Dec-13 17:58
MemberAydin Homay12-Dec-13 17:58 
QuestionProblem reading datasets Pin
Pushpan N27-Nov-13 9:34
MemberPushpan N27-Nov-13 9:34 
QuestionJpeq 2000 Compress Pin
Nhan Nguyen22-Oct-13 23:38
MemberNhan Nguyen22-Oct-13 23:38 
Questionviewing MRI images in wpf using dicom viewer Pin
lokesh198912-Aug-13 2:51
Memberlokesh198912-Aug-13 2:51 
AnswerRe: viewing MRI images in wpf using dicom viewer Pin
Member 118453681-Nov-16 11:00
MemberMember 118453681-Nov-16 11:00 
Questionhelp any other reference for mri Pin
lokesh19898-Aug-13 20:54
Memberlokesh19898-Aug-13 20:54 
QuestionSmooth 3d Pin
matimont20-Jul-13 3:36
Membermatimont20-Jul-13 3:36 
QuestionRM Images Pin
matimont20-Jul-13 2:17
Membermatimont20-Jul-13 2:17 
GeneralMy vote of 5 Pin
MohamedKamalPharm9-Jul-13 6:27
MemberMohamedKamalPharm9-Jul-13 6:27 
GeneralMy vote of 5 Pin
valza13-Jun-13 2:17
Membervalza13-Jun-13 2:17 
GeneralMy vote of 5 Pin
roscler17-May-13 6:32
professionalroscler17-May-13 6:32 
GeneralMy vote of 5 Pin
honorioyango30-Apr-13 15:48
Memberhonorioyango30-Apr-13 15:48 
Thanks... this is great
GeneralMy vote of 5 Pin
Manoj Kumar Choubey11-Jan-13 2:49
professionalManoj Kumar Choubey11-Jan-13 2:49 
QuestionNice job! Pin
joelihn19-Dec-12 21:18
Memberjoelihn19-Dec-12 21:18 
GeneralMy vote of 5 Pin
Alois Kraus11-Nov-12 1:39
MemberAlois Kraus11-Nov-12 1:39 
GeneralRe: My vote of 5 Pin
alinux0826-Nov-12 10:09
Memberalinux0826-Nov-12 10:09 
GeneralMy vote of 5 Pin
Kiran Kumar Singani12-Oct-12 11:02
MemberKiran Kumar Singani12-Oct-12 11:02 
QuestionYour code Pin
FatCatProgrammer11-Oct-12 3:51
MemberFatCatProgrammer11-Oct-12 3: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.