Medizintechnik II – Exercises

Project Work 2 – Volumes

Getting started

Important: You have to work alone on your project work. No team partners allowed anymore 😔!

CT reconstruction treats the problem of recovering a three-dimensional volume from a set of X-ray images. So we will need two classes that represent our volume and our stack of X-ray projections. It turns out that we can interpret our projections and our volume just as a list of 2-d images.

A volume: very much just multiple images stacked one over another

Create a class mt.Volume

// Your name <your idm>
// No team partner... So sad 😢!

package mt;

import java.util.Arrays;
import java.util.stream.IntStream;

public class Volume {
    // Here we store our images
    protected mt.Image[] slices;

    // Dimensions of our volume
    protected int width, height, depth;

    // Spacing and origin like for mt.Image
    protected float spacing = 1.f; // spacing is now our voxel size
    protected float[] origin = new float[]{0, 0, 0}; // position of the top-left-bottom corner

    // A name for the volume
    protected String name;

}

Create a constructor. Remember: width, height, depth, name must be set and slices must be created as an array. We need depth images of size width $\times$ height for the slices.

    public Volume(int width, int height, int depth, String name)

Getters/setters...

    public int width()
    public int height()
    public int depth()
    public float physicalWidth() // width * spacing()
    public float physicalHeight() // height * spacing()
    public float physicalDepth() // depth * spacing()

    public mt.Image getSlice(int z) 
    public void setSlice(int z, mt.Image slice)

    public float spacing()
    public void setSpacing(float spacing) // should also set spacing also for all slices!
    public String name()
    public float[] origin()

    // should set origin to (-0.5 physicalWidth, -0.5 physicalHeight, -0.5 physicalDepth) and call centerOrigin on each slice
    public void centerOrigin()

Now comes the interesting part: visualize the volume! You will need to update src/main/java/lme/DisplayUtils.java file and use the following command to visualize the volume.

    public void show() {
        lme.DisplayUtils.showVolume(this);
    }

You can download a volume from the Cancer Imaging Archive. Use one of the following links (it does not matter which CT volume you use).

Unzip the folder and drag the whole folder onto a running ImageJ, e.g. by the following code snippet in a file src/main/java/project/Playground.java. (if you have problems unzipping the files you might try the official downloader from the website. You need their downloader to open the *.tcia files).

// This file is only for you to experiment. We will not correct it.

package project;

import mt.Volume;

class Playground {

    public static void main(String[] args) {
        // Starts ImageJ
        (new ij.ImageJ()).exitWhenQuitting(true);

        // You can now use drag & drop to convert the downloaded folder into a *.tif file
        
    }

}

Save it the opened DICOM as a *.tif file (File > Save As > Tiff...). There are more smaller test volumes on studOn.

Open the saved tiff file in the main of a file src/main/java/project/Playground.java:

// This file is only for you to experiment. We will not correct it.

package project;

import mt.Volume;

class Playground {

    public static void main(String[] args) {
        (new ij.ImageJ()).exitWhenQuitting(true);
        
        Volume groundTruth = DisplayUtils.openVolume("path/to/file.tif");
        groundTruth.show();
        
    }

}

You can now scroll through the different slices.

via GIPHY

Here a short summary of handy functions of ImageJ when working with CT images.

  • Ctrl+Shift+C: Brightness and Contrast
  • Ctrl+Shift+H: Orthogonal Views (view volume from three sides)
  • After selecting a line: Ctrl+K Line Plot
  • Ctrl+I: Get patient information of a DICOM
  • Look at a 3-d rendering with ClearVolume

Previous: Introduction

Next: Forward Projection