Motivation

Optical Coherence Tomography (OCT) is a widely used modality in ophthalmic imaging and diagnosis. Spectral domain OCT volumes depict retinal structures in great detail down to a scale of a couple of micrometers and are a valuable resource for clinicians to diagnose and study diseases such as age related macular degeneration or diabetic retinopathy.

Noise is a major disadvantage of OCT scans. Viehland et al. proposed a rendering pipeline to deal with noisy OCT images. They perform volumetric filtering (median and gaussian), edge enhancement, feature enhancement, depth shading, and phong shading to obtain a clearer result. We implemented this pipeline in two versions (shaders: ENHANCED and ENHANCED_FULL) for comparison.

Clinicians are interested in viewing 2D slices as well as 3D volumes in their work, which is why it is important to provide them with both. We allow them to view arbitrary 2D slices through the volume and also display the slice plane in the 3D view to convey the spatial context. The slice plane can be scaled and translated and its normal vector can be pointed in any direction. In addition, we allow users to cut the 3D volume at this arbitrary slice plane and a second cutting plane to better inspect the inside of the dataset.

Certain features of the retina are of great interest to clinicians, for instance pockets filled with fluid or different retinal layers. We draw a fluid and a photoreceptor segmentation (ENHANCED_FULL shader only) to expose these features.



Implementation and Processing

The implementation is based on the open-source Aardvark platform for visual computing, real-time graphics, and visualization. It is written in F#, a functional-first language in the .Net environment. All shaders are written in FShade which extends F# with domain specific language for shaders and is well integrated in Aardvark. The user interface is written in HTML and JavaScript. It communicates with the main application through a Suave webserver and is updated in regular intervals to reflect changes made in the main application.

Preprocessing of raw OCT data is done in Matlab. We extract the b-scans as individual bitmap images and perform 3D median filtering on the volume to remove excessive noise. After that, we export volumes where each slice has been filtered with a gaussian with different sigma values.

Segmentations were done in MeVisLab. We segmented one layer of the retina using a CSO livewire approach and a cavity filled with fluid using region growing. The resulting volumes were again exported as individual bitmap slices.



Usage

The executable requires german windows locale ("," as decimal separator) to run.

Execute bin/OCTVis.exe to run the application.

Open Chrome (other browsers not tested) and visit 127.0.0.1:8080 to display the user interface.

The main application window draws the 3D scene and displays the current 2D slice through the volume.


Navigation
Action Function
Keys WSAD Move camera forward, backward, left, right
Left-Click-Drag Change view direction
Middle-Click-Drag Pan
Right-Click-Drag Move forward/backward
Scroll Move forward/backward

Key Commands

Main application must be focused for key commands to work.

Action Function
P,O Translate current slice plane along its normal vector
K,L Translate second cutting plane along its normal vector
I,U Increase/decrease threshold value for volume rendering
C Toggle cutting
F Change gaussian filter strength
1,2 Decrease/increase voxel transparency (ENHANCED_FULL shader only)
6 Reset
7,8,9,0 Select preset

UI

Open Chrome and visit: 127.0.0.1:8080

The current slice through the volume is displayed at the bottom of the page. It results from cutting the volume with an arbitrary slice plane.

Field Function
Active Shader Select shader for volume rendering
Cut Volume Toggle cutting
Draw Slice Plane Toggle drawing of current slice plane
Shadows Toggle drawing of shadows
Draw Fluid Segmentation Toggle drawing of fluid segmentation
Fluid Transparency Toggle drawing of hidden parts of the fluid segmentation inside the volume
Draw Layer Toggle drawing of the photoreceptor layer (ENHANCED_FULL shader only)
Gauss Texture Change gaussian filter strength
Set Threshold Set the threshold for volume rendering
Set Transparency Set the voxel transparency (0.0-0.45, ENHANCED_FULL shader only)

Field Function
Slice Plane: Set Center Set the center point of the current slice plane
Slice Plane: Translate Along Normal Translate the current slice plane along its normal vector
Slice Plane: Set Normal Set the normal vector (x,y,z) of the current slice plane
Slice Plane: Set Size Set the size of the current slice plane (value > 0.0)
Slice Plane: Set Opacity Set the opacity of the current slice plane (0.0-1.0)
Cutting Plane: Translate Along Normal Translate the second cutting plane along its normal vector
Cutting Plane: Set Normal Set the normal vector (x,y,z) of the second cutting plane


Examples

  • Shader: ENHANCED
  • Draw Fluid Segmentation: true
  • Draw Slice Plane: true
  • Threshold: 0.15
  • Gauss: 3
  • Cutting: true
  • Normal Slice: (0,1,1)
  • Normal Cut2: (0,1,0)

  • Shader: ENHANCED_FULL
  • Draw Fluid Segmentation: false
  • Draw Photoreceptor Layer: true
  • Draw Slice Plane: false
  • Threshold: 0.15
  • Gauss: Off
  • Cutting: true
  • Normal Slice: (0,0,1)
  • Shader: ENHANCED_FULL
  • Draw Fluid Segmentation: true
  • Draw Photoreceptor Layer: true
  • Draw Slice Plane: false
  • Threshold: 0.6
  • Gauss: Off
  • Cutting: true
  • Normal Slice: (0,0,1)
  • Normal Cut2: (0,0,-1)
  • Shader: BASIC
  • Draw Fluid Segmentation: true
  • Fluid Transparency: true
  • Draw Slice Plane: false
  • Threshold: 0.0
  • Gauss: Off
  • Cutting: true
  • Normal Slice: (1,1,1)
  • Slice Size: 1.5
  • Shader: ENHANCED_FULL
  • Voxel Transparency: 0.2
  • Draw Fluid Segmentation: true
  • Fluid Transparency: false
  • Draw Slice Plane: true
  • Slice Plane Opacity: 0.7
  • Threshold: 0.15
  • Gauss: Off
  • Cutting: true
  • Normal Slice: (0,0,1)
  • Normal Slice: (1,0,1)
  • Shader: ENHANCED
  • Draw Fluid Segmentation: true
  • Fluid Transparency: false
  • Draw Slice Plane: false
  • Threshold: 0.15
  • Gauss: 5
  • Cutting: true
  • Normal Slice: (0,0,1)
  • Normal Slice: (0,0,-1)
  • Shader: MIP
  • Draw Fluid Segmentation: false
  • Draw Slice Plane: false
  • Gauss: Off
  • Cutting: false

  • Build from Source

    You need to have F# build tools installed to build the application from source. Run build.cmd in the command line to build the project. After that, copy the data, html, and transferfunction folders to bin/Debug/netcoreapp2.0/

    The required folders (data,html,transferfunction) can be found in the binaries



    Links

    Sourcecode

    Binaries

    Zipped Binaries (including data, dlls, tf, ...)

    User Interface

    API Documentation


    References