Fast Marching in 3D

This tour explores the use of Fast Marching methods in 2D.

Contents

Installing toolboxes and setting up the path.

You need to download the following files: signal toolbox, general toolbox and graph toolbox.

You need to unzip these toolboxes in your working directory, so that you have toolbox_signal, toolbox_general and toolbox_graph in your directory.

For Scilab user: you must replace the Matlab comment '%' by its Scilab counterpart '//'.

Recommandation: You should create a text file named for instance numericaltour.sce (in Scilab) or numericaltour.m (in Matlab) to write all the Scilab/Matlab command you want to execute. Then, simply run exec('numericaltour.sce'); (in Scilab) or numericaltour; (in Matlab) to run the commands.

Execute this line only if you are using Matlab.

getd = @(p)path(p,path); % scilab users must *not* execute this

Then you can add the toolboxes to the path.

getd('toolbox_signal/');
getd('toolbox_general/');
getd('toolbox_graph/');

3D Volumetric Datasets

A volumetric data is simply a 3D array.

We load a volumetric data.

name = 'vessels';
options.nbdims = 3;
M = read_bin(name, options);
M = rescale(M);

Size of the image (here it is a cube).

n = size(M,1);

Such a volumetric dataset is more difficult to visualize than a standard 2D image. You can render slices along each X/Y/Z direction.

clf;
imageplot(M(:,:,50), 'X/Y slice', 1, 3, 1);
imageplot(squeeze(M(:,50,:)), 'X/Z slice', 1, 3, 2);
imageplot(squeeze(M(50,:,:)), 'Y/Z slice', 1, 3, 3);

We can display some horizontal slices.

slices = round(linspace(10,n-10,4));
clf;
for i=1:length(slices)
    s = slices(i);
    imageplot( M(:,:,s), strcat(['Z=' num2str(s)]), 2,2,i );
end

You can also perform a volumetric rendering. In order to do so, you need to set up a correct alpha mapping to make transparent some parts of the volume. Here, each time the options.center value is increased.

clf;
h = vol3d('cdata',M,'texture','2D');
view(3); axis off;
% set up a colormap
colormap bone(256);
% set up an alpha map
options.sigma = .08; % control the width of the non-transparent region
options.center = .4; % here a value in [0,1]
a = compute_alpha_map('gaussian', options); % you can plot(a) to see the alphamap
% refresh the rendering
vol3d(h);

Exercice 1: (the solution is exo1.m) Try with other alphamapping and colormapping

exo1;

We can display an isosurface of the dataset (here we sub-sample to speed up the computation).

sel = 1:2:n;
clf;
isosurface( M(sel,sel,sel), .5);
axis('off');

3D Shortest Paths

The definition of shortest path extend to any dimension, for instance 3D.

Geodesic distances can be computed on a 3D volume using the Fast Marching. The important point here is to define the correct potential field W that should be large in the region where you want the front to move fast. It means that geodesic will follow these regions.

Select the starting points.

delta = 5;
start_point = [107;15;delta];

Compute the (inverse of the) potential that is small close to the value of M at the selected point

W = abs( M - M(start_point(1),start_point(2),start_point(3)) );

Rescale above some threshold to avoid too small potentials.

W = rescale(W,1e-2,1);

Perform the front propagation.

options.nb_iter_max = Inf;
[D,S] = perform_fast_marching(1./W, start_point, options);

In order to extract a geodesic, we need to select an ending point and perform a descent of the distance function D from this starting point. The selection is done by choosing a point of low distance value in the slice D(:,:,n-delta).

clf;
imageplot(D(:,:,delta), '', 1,2,1);
imageplot(D(:,:,n-delta), '', 1,2,2);
colormap(jet(256));

Exercice 2: (the solution is exo2.m) select the point (x,y) of minimum value in the slice D(:,:,n-delta). hint: use functions 'min' and 'ind2sub'

exo2;

Extract the geodesic by discrete descent.

options.method = 'discrete';
minpath = compute_geodesic(D,end_point,options);

Draw the path.

Dend = D(end_point(1),end_point(2),end_point(3));
D1 = double( D<=Dend );
clf;
plot_fast_marching_3d(M,D1,minpath,start_point,end_point);

Exercice 3: (the solution is exo3.m) Select other starting points. In order to do so, ask the user to click on a starting point in a given horizontal slice W(:,:,delta). You can do this by using ginput(1) on the plane Z=delta.

exo3;