DICOM Multi-Planar Reconstruction
The ImageGear.Windows.Controls namespace provides functionality (in the ImageGear.Windows.Controls.Dicom assembly) to support the end user’s interaction and UI for multi-planar reconstruction (MPR). The term “MPR” defines the ability to reconstruct volumes from a set of 2D image data and display multiple 2D planes of data from within the reconstructed data set.
ImageGear allows the following 2D plane views:
- Axial View - This is a horizontal cut away slice of the body as seen from the top. Most commonly DICOM images are taken in this view.
- Coronal View - This view is a vertical cut away slice of the body as seen from the front.
- Sagittal View - This is a vertical cut away slice of the body as seen from its left side.
- Oblique View - This Oblique view has not a specific definition. It is just a cut away slice of the body taken at some angle to the X axis of one of the above described views.
Multi-frame DICOM images contain a collection of slices of the body. For example, considering each axial slice represents an (X-Y) plane of the body, then a collection of slices will represents Z axis.
In the simplest case, multi-planar reconstruction (MPR) involves generating perspectives at right angles to a stack of axial slices so that coronal and sagittal images can be generated. The described views can be graphically represented as the following:
So if we have a multi-frame DICOM image that contains F frames of images with (W x H) dimension, then W would be the X axis, H would be the Y axis and F would be the Z axis.
The coronal view could be considered as the oblique view with 0 degree rotation angle about Z axis, while the sagittal view could be considered as the oblique view with 90 degree rotation angle about Z axis.
It is possible to perform MPR not only from multi-frame DICOM images, but also from a collection of single-frame DICOM images with the same width and height.
As each frame of a DICOM image is represented as a page in IG, so multi-frame DICOM is represented as a collection of pages, so each page represents a horizontal slice of the axial view or vertical slice of the coronal/sagittal view of the body.
There are 3 classes within the ImageGear.Windows.Controls namespace that provide handling of the described views:
After providing the initial stack of images for multi-planar reconstruction, each view could be bound to other views to display MPR results. For example, ImGearMprAxialController has the following 3 properties: CoronalDisplay, SagittalDisplay and ObliqueDisplay. The horizontal “MPR line” is shown over the ImGearAxialController’s view to allow the user to perform coronal reconstruction by moving that line over the view and the result of the coronal reconstruction is available through the ImGearMprAxialController.CoronalDisplay property. The Display property of a PageView control can be bound to the CoronalDisplay property to display the coronal view. Similarly, the vertical “MPR line” is shown over the ImGearAxialController’s view to allow the user to perform sagittal reconstruction by moving that line over the view and the result of the sagittal reconstruction is available through the ImGearMprAxialController.SagittalDisplay property, which a PageView control can bind to. For ObliqueDisplay, the 45 degree diagonal “MPR line” is shown over the ImGearAxialController’s view to allow the user to perform oblique reconstruction by moving and resizing that line over the view.
The MPR is always performed in left to right direction of the “MPR line”. The start point of the line is considered the one that has a smaller X coordinate.
You can bind as many views to each property as you need.
To support full MPR, involving reconstruction of all described views, ImageGear.Windows.Controls has a user control called ImGearMprVisualizer. This control contains 4 views for each of the MPR views and provides the user the possibility to reconstruct each of them by moving “MPR lines” over the original MPR view. The original MPR view is defined by providing a stack of images in the corresponding view and initializing the ImGearMprVisualizer object with them.
The look of the MPR visualizer and MPR controllers can be customized using a template. The default template XAML is provided below. To support the axial view, an ImGearMprAxialController must be specified with the name “AxialController”. Similarly, to support the coronal view, an ImGearMprCoronalController named “CoronalController” must be specified, and to support the sagittal view, an ImGearMprSagittalController named “SagittalController” must be specified.
XAML Example |
Copy Code |
<Window x:Class="WPF_Example.MprVisualizerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:igwc="clr-namespace:ImageGear.Windows.Controls;assembly=ImageGear.Windows.Controls"
xmlns:igdicom="clr-namespace:ImageGear.Windows.Controls;assembly=ImageGear.Windows.Controls.Dicom"
Title="MPR Visualizer" Height="500" Width="600">
<Grid>
<igdicom:ImGearMprVisualizer x:Name="mprVisualizer">
<igdicom:ImGearMprVisualizer.Template>
<ControlTemplate>
<Grid Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border BorderThickness="1" BorderBrush="White">
<igdicom:ImGearMprAxialController x:Name="AxialController">
<igdicom:ImGearMprAxialController.Template>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Axial" Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type igdicom:ImGearMprVisualizer}}, Path=Settings.AxialLineBrush, Mode=OneWay}"/>
<igwc:PageView MouseTool="SelectMark" UpdateMode="Automatic" Grid.Row="1" ContextMenu="{x:Null}" Display="{Binding RelativeSource={RelativeSource AncestorType={x:Type igdicom:ImGearMprAxialController}}, Path=PageDisplay, Mode=OneWay}"/>
</Grid>
</ControlTemplate>
</igdicom:ImGearMprAxialController.Template>
</igdicom:ImGearMprAxialController>
</Border>
<Border BorderThickness="1" BorderBrush="White" Grid.Row="0" Grid.Column="1">
<igdicom:ImGearMprCoronalController x:Name="CoronalController">
<igdicom:ImGearMprCoronalController.Template>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Coronal" Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type igdicom:ImGearMprVisualizer}}, Path=Settings.CoronalLineBrush, Mode=OneWay}"/>
<igwc:PageView MouseTool="SelectMark" UpdateMode="Automatic" Grid.Row="1" ContextMenu="{x:Null}" Display="{Binding RelativeSource={RelativeSource AncestorType={x:Type igdicom:ImGearMprCoronalController}}, Path=PageDisplay, Mode=OneWay}"/>
</Grid>
</ControlTemplate>
</igdicom:ImGearMprCoronalController.Template>
</igdicom:ImGearMprCoronalController>
</Border>
<Border BorderThickness="1" BorderBrush="White" Grid.Row="1" Grid.Column="0">
<igdicom:ImGearMprSagittalController x:Name="SagittalController">
<igdicom:ImGearMprSagittalController.Template>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Sagittal" Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type igdicom:ImGearMprVisualizer}}, Path=Settings.SagittalLineBrush, Mode=OneWay}"/>
<igwc:PageView MouseTool="SelectMark" UpdateMode="Automatic" Grid.Row="1" ContextMenu="{x:Null}" Display="{Binding RelativeSource={RelativeSource AncestorType={x:Type igdicom:ImGearMprSagittalController}}, Path=PageDisplay, Mode=OneWay}"/>
</Grid>
</ControlTemplate>
</igdicom:ImGearMprSagittalController.Template>
</igdicom:ImGearMprSagittalController>
</Border>
<Border BorderThickness="1" BorderBrush="White" Grid.Row="1" Grid.Column="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Oblique" Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type igdicom:ImGearMprVisualizer}}, Path=Settings.ObliqueLineBrush, Mode=OneWay}"/>
<igwc:PageView Name="mprViewOblique" MouseTool="SelectMark" UpdateMode="Automatic" Grid.Row="1" Display="{Binding RelativeSource={RelativeSource AncestorType={x:Type igdicom:ImGearMprVisualizer}}, Path=ObliqueDisplay, Mode=OneWay}" ContextMenu="{x:Null}"/>
</Grid>
</Border>
<Border BorderThickness="1" BorderBrush="White" Grid.Row="2" Grid.ColumnSpan="2">
<Slider HorizontalAlignment="Stretch" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ImGearMprVisualizer}}, Path=ActiveController.PageNumber, Mode=TwoWay}" Maximum="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ImGearMprVisualizer}}, Path=ActiveController.MaximumPageNumber, Mode=OneWay}" Minimum="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ImGearMprVisualizer}}, Path=ActiveController.MinimumPageNumber, Mode=OneWay}">
<Slider.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type igdicom:ImGearMprVisualizer}}, Path=ActiveController, Mode=TwoWay}" Value="{x:Null}">
<Setter Property="Slider.Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Slider.Style>
<ToolTipService.ToolTip>
<ToolTip Content="Move the bar to navigate through image pages"/>
</ToolTipService.ToolTip>
</Slider>
</Border>
</Grid>
</ControlTemplate>
</igdicom:ImGearMprVisualizer.Template>
</igdicom:ImGearMprVisualizer>
</Grid>
</Window> |