Getting started
Important: You have to work alone on your project work. No team partners allowed anymore 😔!
MR reconstruction for a three-dimensional volume can be done with two different methods. We are using slice selection in this project. So we will need one class that represents our volume of the MRI images. It turns out that we can interpret our volume just as a list of 2-d images.
Explain in you report the method of slice selection:
- Which field of the MRI scanner is used to encode specific positions in the patient?
- How many of these fields exist and which directions do they cover?
- How is a specific slice selected?
This part should be about a quarter to half a page long.
![]() |
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()
We need also another setter Method in our image
class:
public void setSpacing(float spacing) // set spacing for the image
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);
}
We will work for our upcoming post-processing tasks with a magnetic resonance angiography (MRA) dataset. MRA is a special method in MRI to visualize vessels in images. You can download a volume from https://www.nitrc.org/projects/icbmmra.
Note: The data set is in the NIfTI (Neuroimaging Informatics Technology Initiative) format, which you need to convert into our .tif format. ImageJ has a Plugin for it, which you would need to install.
You can also use one of the three already converted image sets:
Open the saved tiff file in the main of a file src/main/java/project/Playground.java
:
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.
Here a short summary of handy functions of ImageJ when working with MRI 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