GraphCuts is the name for a collection of energy minimization algorithms (https://en.wikipedia.org/wiki/Graph_cuts_in_computer_vision). We employ it here for image segmentation.
This scripts performs a marker based image segmentation by constructing a graph from the images voxels and then looking for the globally optimal cut to seperate the marker areas.
Various versions are provided (http://pythonhosted.org/MedPy/graphcut.html), but we will concentrate here on only two.
Original image | Foreground (red) and background (green) marker on original image | Gradient image |
Let's assume we want to segment the ventricle from a brain scan (left image). We first create some (manual or automatic) markers (middle image). We furthermore require a gradient magnitude image of the brain scan, which we can obtain with
In [2]:
medpy_gradient.py resources/b0.nii.gz output/gradient.nii.gz
To execute the graphcut, we call
In [4]:
medpy_graphcut_voxel.py 10 output/gradient.nii.gz resources/b0markers.nii.gz output/graphcut_voxel_gradient.nii.gz --boundary diff_pow
Which results in
Which is acceptable, considering the ad-hoc usage we just performed. The first parameter passed to the script defines the sigma, i.e., the smoothness of the cut. Setting it to high will result in very smooth cuts, lower values allow the graphcut more freedom at the risk of leakages.
Another usage of the script does not require the magnitude gradient, but rather the original image. It can be used by calling
In [7]:
medpy_graphcut_voxel.py 1 resources/b0.nii.gz resources/b0markers.nii.gz output/graphcut_voxel_grayvalues.nii.gz --boundary=max_div
Which results in
This result is smoother and dooes better represent the real outline of the ventricles. But it failed to connect one of the foreground markers with the remaining foreground object.
Graphcuts are a frickle thing. They depend on the quality of the markers and the employed parameters. The examples shown here provide quite acceptable results that could be easily improved with further parameter tuning.
Furthermore, this script only uses the boundary term of graphcut, ignoring the regional term. MedPy does of course support both terms, see the package description for more details: http://pythonhosted.org/MedPy/graphcut.html
For very large (e.g. 4D) images, the voxel based graphcut might be too memory consuming for a standard computer. You might want to consider using the label/region based grapcut shipped with MedPy instead. The label/region version is additionally faster and often produces superior results.
In [ ]: