SNT: Step-By-Step Instructions

Revision as of 18:26, 16 May 2019 by Carshadi (talk | contribs)
Revision as of 18:26, 16 May 2019 by Carshadi (talk | contribs)
Home Manual Walk-throughs Screencasts Shortcuts Rec. Viewer Analysis Scripting Modeling FAQ


These instructions assume that you have read the Overview page, including starting up the plugin, enabling Cursor Auto-snapping, and Auto-tracing options.

Starting A Path

I. Pick The Starting Point

Choosing a starting point

You may notice that, by default, the cursor snaps to the brightest pixel in its vicinity. If you prefer to manually control the placement of nodes, feel free to toggle feature by pressing S. Now, to begin tracing, move through the image stack to find the start point of a path then click there with the left mouse button.

II. Pick A Subsequent Point

First point of a path selected
A* search animated progress

A small circle should appear, highlighting the start of the path. Move through the stack to find a subsequent point further along the same structure to be traced (neuron, blood vessel, etc.), and click there.

If a path between the two points cannot be found immediately, you may see the animated progress of the search. You can scroll through the stack while such a search progresses: If it appears to not be making good progress, it's probably best to press the "Cancel/Esc" button (shortcut: C/ Esc) and pick a point closer to the start point.

Tip: IncreaseZ in the Cursor Auto-snapping panel for automated Z-navigation on signal mouseover.

III. Confirm The Temporary Segment

Once the search has reached the target point, the path is shown in cyan (to indicate that this is still a temporary path) and you are asked to confirm (by clicking "Yes" or pressing Y) that this path is following the route through the image that you expect. If it is not, then click "No" N and you'll go back to the previous step. Assuming you confirmed the path, the confirmed path will appear in red. Now you are essentially back at step II. Normally you will go on to pick further points along the structure. However, if you have finished with that path, click "Finish Path" F and you will go back to step I. If you completed that path it would be shown in magenta.

  • A* search completed
  • A confirmed segment
  • A completed path

Branching: Start A Path On An Existing Path

I. Select The Path To Branch Off

To select the path you want to branch off from, you can either select it in the Path Manager, or press G while the mouse pointer is near the path. When the path is first selected, it will be shown in the default green color.

Holding 'G' will select the closest path to the mouse pointer

II. Select The Fork Point

A newly created fork point

To force the start of the new path to be a branch of the selected path, hold down the Alt+ Shift keys while you move the mouse to find the branch point under the red cross-hairs, now decorated with a "Fork Point" annotation. With Alt+ Shift held down, click with the left mouse button. Finally, release the keys. Note that it is also possible to zoom into the branch point, right-click on the image and choose Fork at Nearest Node from the contextual menu.

III. Extend The Path

From this point on, you can carry on adding nodes to the branched path as above, i.e., Create a temporary path and confirm it. When you decide to complete the path you should see in the Path Manager that it has been recorded as a child of the existing path.

  • 1) Temporary path branching-off
  • 2) Temporary path confirmed
  • 3) Branched (child) path completed

Joining: End A Path On An Existing Path

Supposing you want the end of a path that you're tracing to join onto an existing path, you just use the same modifier key when selecting the end point of the last part of the path. To go into that in more detail, if you're halfway through tracing a path like [1]:

[1] Unfinished join segment, in red - disconnected
... and you want the final part of that path to join up with the existing path running from the top-left to top-right of the image. First, select that path in the path list (or using the G shortcut) as in [2]:
[2] Selected path to join to, in green
Now hold down Alt+ Shift to restrict the endpoint to be a "join" on that existing path. Click (while still holding down the modifier keys) to start the search for that endpoint and make it join the existing path. If the search can find a path to the end point, the result should look like [3]:
[3] Connected path to join, unconfirmed
If you're happy with the result, confirming the temporary path will automatically complete the whole path, since if you're creating an end join there cannot be any more to the path. Note that the path list indicates that this new Path (1) ends on the existing Path (0). The result will look like [4]:
[4] Confirmed join

Merging/Joining Paths

Two paths can be merged or joined in Edit Mode. To do so:

  1. Select a path and enter Edit Mode (by right-clicking on the image canvas to access its Contextual menu)
  2. Activate the node to be merge by hovering over it
  3. Select the second path by using the G shortcut and activate the second merging node by hovering over it
  4. Open the contextual menu and select the initial path from the Connect To (Start Join) / Connect To (End Join) menu.

If both nodes were terminal paths are merged together, otherwise one will become a child of the other. Note that one of the nodes must be terminal, to ensure no loops are created.

  • 1) Select parent path and activate first join node
  • 2) Select child path and activate second join node
  • 3) Use contextual-menu option to connect child path to parent path
  • 4) Joined result

Tracing in the Legacy 3D Viewer

It remains possible to trace in the legacy 3D Viewer.

"Legacy 3D Viewer" widget

I.Starting the Viewer

To open the viewer, select the 3D menu tab in the SNT dialog and look for Legacy 3D Viewer. You will see 3 parameters:

  • Select New with image from the Viewer drop-down menu (selecting New without image would only allow you to look at reconstructions without the underlying signal). Note that you can recycle existing viewers you may have open by choosing there window titles from the drop-down menu.
  • Select the preferred rendering style from the Mode drop-down menu.
  • Once you Apply the viewer choice, a prompt will appear asking you to choose the resampling factor for the image. Then, the viewer window will appear with the currently open image.
3D viewer showing OP_1.tif

II.Tracing and Navigation

  • Selecting points for tracing Select the "Wand" tool in the main Fiji toolbar and click over the region you want to trace. Tracing works the same way as in the 2.5D view, i.e., click somewhere in the image to create a starting point, then click further along the structure of interest to find a path between the two points, then confirm or deny the temporary segment, etc...
  • Rotation Either use the "Hand" tool and left-click while dragging mouse or drag mouse while holding the scroll wheel.
  • Translation Hold Shift and the scroll wheel while dragging the mouse.
  • Adjusting zoom depth Scroll the mouse wheel.

Once you have selected each of these tools (Wand and Hand) once, you should be able to switch between them by pressing the Esc key.


The following key shortcuts also work in the 3D Viewer:

  • Y confirm the temporary path segment
  • N cancel the temporary path segment
  • F complete the current path
  • G select the current path under the mouse pointer

You can still create branches and joins in the 3D Viewer as you would in the 2D viewer. First, select the path you want to branch off, or join to by pressing G while the mouse pointer is over that path. (It should turn green.) Then create the join or branch by holding down the join modifier key ( Alt and clicking at the right point on the selected path.


There is a simple facility in this plugin for "filling out" paths to volumes. This is not particularly sophisticated, but often good enough for a rough visualization of the shape of a neuron beyond what can be seen from the traced path.

I.Starting the Fill

First, select the one or more paths that you want to fill out from in the Path Manager and select "Fill -> Fill Out..." in the Path Manager menu options. The selected paths are shown in green so that you can check that you're starting from the right ones. After a couple of seconds if you scroll through the stack you should be able to see a thick green surround the path:

A few seconds after selecting "Fill Out..." with 1 path selected

The filler continues to explore the image starting from the path until you click "Pause" or "Stop" in the dialog. However, the fill which is shown only includes those points up to a certain threshold distance from the path. (Note that in this section "distance" doesn't mean a real physical distance, but a measure which takes into account the intensity values of the pixels which must be passed through when moving away from the path.) Information about the current threshold and the progress of the search is shown in the dialog.

The filling-related part of the dialog.

The "Cursor position:" state under "Search Status" is updated as you move your mouse over the image. If the point under the mouse has been reached by the search then it will show you that point's distance from the path. Otherwise, it will read "Not reached by search yet". Two lines above, the "Current threshold distance:" shows your current threshold distance: so if this is set to 0.2 then that means that all points less than 0.2 from the path are included in the fill (and shown in green in the image.) The "Max. explored distance:" state under this line shows the maximum distance from the path that has been completely explored.

II.Adjusting the Fill Threshold

You can change the fill threshold in one of three ways:

  • Clicking on a point in the image that has been reached by the search (This is the most intuitive way of altering the threshold). It may be helpful to disable the "Enable Snapping within: XY-Z" feature for the cursor while doing this.
  • Manually changing the threshold in the "Specify manually:" input box and clicking the "Apply" button beside it.
  • Clicking the "Use explored maximum" button below the threshold input box and click "Apply", which sets the threshold to the maximum explored distance (the value shown in "Max. explored distance:" under the "Search Status" dialog).

Anyway, assuming that you want to use the first of these approaches, you should use the approach described below. It is difficult to set the threshold accurately from the image unless you zoom in, so first zoom on part of the path that you want to set the threshold for.

Since the solid green fill obscures the intensity value of the points in the fill, I suggest that you switch to the semi-transparent view of the fill at this stage by selecting the "Transparent overlay" option in the "Rendering Options" dialog. Note that this may slow down filling.

As you can see in the middle image, the threshold is set too far from the path, since there are many completely dark points under the green fill, as well as points on different paths than those of interest. Experiment with clicking on different points closer to the path in order to adjust the threshold until you are happy with it. You might end up with something like the rightmost image:

  • Fill, opaque
  • Fill, with "Transparent overlay" on
  • Fill, refined

III.Completing the Fill

If you are happy with this, then you might as well click "Pause" so that your computer isn't spending all its CPU on continuing to explore the image. Then you can either:

  • Save the fill (which will add it to the fill list) by clicking "Stash Progress".
  • Discard the fill by either clicking "Stop" while filling is in progress or, if you stashed the fill, select it in the fill list and click "Delete Fill(s)".
  • Use the "Image Stack..." button to view the same image stack, but with only the points in that fill preserved. You can choose either a grayscale image or a binary mask. One reason why you might want to do this is that you can then smooth that image and use the 3D Viewer to do a surface rendering of the neuron. Perhaps then you could overlay that onto a volume rendering of the complete image (see available tutorials). Or, you could save those fill stacks for each of the neurons you fill and then combine them in ImageJ using "RGB Merge".

The image stack you would get from the image used in this example might look something like this:

Having selected the "Image Stack... -> As Grayscale Image..." option

Generating Filtered Images

This section describes how to generate Filtered Images outside SNT. Note that the filtering used in this walk-through (Frangi Vesselness) is already supported directly by SNT. This tutorial will assume you need to perform the filtering with adjusted parameters.

A Single Image

To process a single image with the Frangi Vesselness filter, pause SNT, and select Process  › Filters  › Frangi Vesselness. By way of example, let's say you need to enhance strucutres at two scales: twice the x voxel separation and five times that value. We apply a Gaussian convolution at each scale. Assuming your image has isotropic resolution with pixel width = pixel height = pixel depth = 1, the parameters would be:


Save the result using File  › Save As › Tiff... ("test-filtered.tif", for example). Then, in SNT's dialog look for the "Tracing on Filtered Image" widget in the Main tab. Click "Browse" to specify the filtered image, and press "Load Specified File" from the Gear drop-down menu. Finally, toggle the "Trace on filtered Image" checkbox (you can do so using I. Now the pathfinding will occur on the filtered image. To view a MIP of the filtered image "over" the original image during tracing, toggle the "Render in overlay at X% opacity" checkbox.

  • Step 1
  • Step 2

To display the image in a separate window, from the SNT dialog use Show Cached Image from the gear menu or View  › Show Filtered Image.

Side-by-side original and filtered images

Multiple Images

The easiest way to preprocess multiple images is to record a macro for processing a single image, then wrap it in a loop to iterate over all files in a directory. For example, using IJ1 macro language:

d = getDirectory("Select a directory");
files = getFileList(d);
extension = ".tif";
for( i = 0; i < files.length; ++i ) {
    filename = files[i];
    if( endsWith(filename,extension) ) {
        l = lengthOf(filename);
        el = lengthOf(extension);
        basename = substring(filename,0,l-el);
        expected_window_name = "result";
        output_filename = d + File.separator + basename + ".tubes.tif";
        run("Frangi Vesselness"); // arguments can be specified here
        saveAs("Tiff", output_filename);

The same process can be accomplished in a script using ImageJ Ops. For example, in Jython:

# @ImageJ ij
# @File(label="Directory containing your images", style="directory") image_dir
import os

def run(image_directory):
    if image_directory is not None:
        image_directory = str(image_directory)
        extension = ".tif"
        file_list = os.listdir(image_directory)
        for filename in file_list:
            if filename.endswith(extension):  # Only process ".tif" files
                print('Processing ' + str(filename))
                image_path = image_directory + '/' + filename
                input_image =
                # Convert input image to float, since we are dealing with derivatives.
                converted_input = ij.op().run("convert.float32", input_image)

                # Frangi Vesselness parameters
                spacing = [1, 1, 1]  # Assuming the image has isotropic resolution
                scale = 2  # Twice the voxel separation

                # Create placeholder image then run the Frangi op.
                output = ij.op().run("create.img", converted_input)
                ij.op().run("frangiVesselness", output, converted_input, spacing, scale)

                # Save the result using the same base name as the image, adding "_Frangi.tif".
                # For example, the output for OP_1.tif would be named OP_1_Frangi.tif
                l = len(filename)
                el = len(extension)
                basename = filename[0:l - el]
                output_filepath = image_directory + '/' + basename + "_Frangi.tif"
      , output_filepath)


        print('No image directory was selected, exiting...')



  • Filtered Images
    • Use MIPs for side-by-side original and filtered images
    • FIXME: It is confusing that for single images we use Process  › Filters  › Frangi Vesselness for multiple Plugins  › Process  › Frangi Vesselness (imglib, experimental)
    • Update snapshots of the Filtered Images widget
    • Include IJ-ops example
  • Point-accuracy

Accurate Point Placement

This section describes methods to increase the accuracy of node placement.

Step by Step

When starting up, make sure that "Three pane view" is turned on: SNT-Three-Pane-View-Enabled-Startup-Prompt.png

Home Manual Walk-throughs Screencasts Shortcuts Rec. Viewer Analysis Scripting Modeling FAQ