Difference between revisions of "SNT: Step-By-Step Instructions"

(Fitting)
(Generating Filtered Images)
 
(81 intermediate revisions by 2 users not shown)
Line 1: Line 1:
(Return to the main [[SNT]] page)
+
{{SNTNavBar}}
 +
[[Category:SNT]][[Category:Neuroanatomy]]
 
<div class="toclimit-3">
 
<div class="toclimit-3">
  
 
=Tracing=
 
=Tracing=
These instructions assume that you have read the [[SNT: Overview]] page, including starting up the plugin, enabling [[SNT:_Overview#Auto-snapping|Cursor Auto-snapping]], and [[SNT:_Overview#Auto-tracing|Auto-tracing]] options.
+
These instructions assume that you have read the [[SNT: Overview|Overview]] page, including starting up the plugin, enabling [[SNT:_Overview#Auto-snapping|Cursor Auto-snapping]], and [[SNT:_Overview#Auto-tracing|Auto-tracing]] options.
  
==I. Pick A Start Point==
+
==Starting A Path==
 +
===I. Pick The Starting Point===
 
[[Image:Snt-cropped-before-starting-2.png|right|thumb|400px|Choosing a starting point]]
 
[[Image:Snt-cropped-before-starting-2.png|right|thumb|400px|Choosing a starting point]]
You may notice that, by default, the cursor With [[SNT:_Overview#Auto-snapping|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 {{key|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.
+
You may notice that, by default, the cursor [[SNT:_Overview#Auto-snapping|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 {{key|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==
+
===II. Pick A Subsequent Point===
 
[[Image:Snt-cropped-after-starting-2.png|right|thumb|400px|First point of a path selected]]
 
[[Image:Snt-cropped-after-starting-2.png|right|thumb|400px|First point of a path selected]]
 
[[Image:Snt-cropped-mid-tracing-2.png|right|thumb|400px|A* search animated progress]]
 
[[Image:Snt-cropped-mid-tracing-2.png|right|thumb|400px|A* search animated progress]]
Line 17: Line 19:
 
{{Tip| id = external-traces|tip = Increase''Z'' in the ''Cursor Auto-snapping'' panel for automated Z-navigation on signal mouseover.}}
 
{{Tip| id = external-traces|tip = Increase''Z'' in the ''Cursor Auto-snapping'' panel for automated Z-navigation on signal mouseover.}}
  
==III. Confirm A Temporary Segment==
+
===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  {{key|Y}}) that this path is following the route through the image that you expect. If it is not, then click "No" {{key|N}} and you'll go back to the [[#II. Picking a Subsequent Point|previous step]]. Assuming you confirmed the path, the confirmed path will appear in red. Now you are essentially back at [[#II. Picking a Subsequent Point|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" {{key|F}} and you will go back to [[#I. Picking a Start Point|step I]]. If you completed that path it would be shown in magenta.
 
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  {{key|Y}}) that this path is following the route through the image that you expect. If it is not, then click "No" {{key|N}} and you'll go back to the [[#II. Picking a Subsequent Point|previous step]]. Assuming you confirmed the path, the confirmed path will appear in red. Now you are essentially back at [[#II. Picking a Subsequent Point|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" {{key|F}} and you will go back to [[#I. Picking a Start Point|step I]]. If you completed that path it would be shown in magenta.
 
<div align="center">
 
<div align="center">
 
<ul>  
 
<ul>  
<li style="display:inline-block;"> [[Image:Snt-cropped-confirmation-2.png|none|thumb|250px|A* search completed]] </li>
+
<li style="display:inline-block;"> [[Image:Snt-cropped-confirmation-2.png|none|thumb|325px|A* search completed]] </li>
<li style="display:inline-block;"> [[Image:Snt-cropped-confirmed-2.png|none|thumb|250px|A confirmed segment]] </li>
+
<li style="display:inline-block;"> [[Image:Snt-cropped-confirmed-2.png|none|thumb|325px|A confirmed segment]] </li>
<li style="display:inline-block;"> [[Image:Snt-cropped-completed-path-2.png|none|thumb|250px|A completed path]] </li>
+
<li style="display:inline-block;"> [[Image:Snt-cropped-completed-path-2.png|none|thumb|325px|A completed path]] </li>
 
</ul>
 
</ul>
 
</div>
 
</div>
Line 31: Line 33:
 
===I. Select The Path To Branch Off===
 
===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 {{key|G}} while the mouse pointer is near the path. When the path is first selected, it will be shown in the default green color.
 
To select the path you want to branch off from, you can either select it in the Path Manager, or press {{key|G}} while the mouse pointer is near the path. When the path is first selected, it will be shown in the default green color.
[[Image:Snt-sb-selecting-by-G.gif|center|thumb|600px|[[SNT:_Key_Shortcuts#Path_Handling|Holding 'G']] will select the closest path to the mouse pointer]]
+
[[Image:Snt-sb-selecting-by-G.gif|center|thumb|500px|[[SNT:_Key_Shortcuts#Path_Handling|Holding 'G']] will select the closest path to the mouse pointer]]
  
 
===II. Select The Fork Point===
 
===II. Select The Fork Point===
Line 41: Line 43:
 
<div align="center">
 
<div align="center">
 
<ul>  
 
<ul>  
<li style="display:inline-block;"> [[Image:Snt-sb-temporary-path-2.png|none|thumb|250px|1) Temporary path branching-off]] </li>
+
<li style="display:inline-block;"> [[Image:Snt-sb-temporary-path-2.png|none|thumb|325px|1) Temporary path branching-off]] </li>
<li style="display:inline-block;"> [[Image:Snt-sb-confirmed-path-2.png|none|thumb|250px|2) Temporary path confirmed]] </li>
+
<li style="display:inline-block;"> [[Image:Snt-sb-confirmed-path-2.png|none|thumb|325px|2) Temporary path confirmed]] </li>
<li style="display:inline-block;"> [[Image:Snt-sb-completed-branch-2.png|none|thumb|250px|3) Branched (child) path completed]] </li>
+
<li style="display:inline-block;"> [[Image:Snt-sb-completed-branch-2.png|none|thumb|325px|3) Branched (child) path completed]] </li>
 
</ul>
 
</ul>
 
</div>
 
</div>
  
 
==Joining: End A Path On An Existing Path==
 
==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 this:
+
{|
[[Image:Snt-ej-cropped-half-finished-2.png|center|thumb|400px|Unfinished join segment, in red - disconnected]]
+
|-
 +
|
 +
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]:
 +
|[[Image:Snt-ej-cropped-half-finished-2.png|center|thumb|350px|<span style="text-align:center;font-size:90%">[1] Unfinished join segment, in red - disconnected</span>]]
 +
|-
 +
|... 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 {{key|G}} shortcut) as in [2]:
 +
|[[Image:Snt-ej-cropped-selected-destination-path-2.png|center|thumb|350px|<span style="text-align:center;font-size:90%">[2] Selected path to join to, in green</span>]]
 +
|-
 +
|Now hold down {{key|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]:
 +
|[[Image:Snt-ej-cropped-end-join-created-2.png|center|thumb|350px|<span style="text-align:center;font-size:90%">[3] Connected path to join, unconfirmed</span>]]
 +
|-
 +
|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]:
 +
|[[Image:Snt-ej-cropped-path-completed-2.png|center|thumb|350px|<span style="text-align:center;font-size:90%">[4] Confirmed join</span>]]
 +
|}
  
... 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, so that it turns green:
+
==Merging/Joining Paths==
[[Image:Snt-ej-cropped-selected-destination-path-2.png|center|thumb|400px|Selected path to join to, in green]]
+
Two paths can be merged or joined in ''Edit Mode''. To do so:
 +
# Select a path and enter ''Edit Mode'' (by right-clicking on the image canvas to access its [[SNT:_Overview#Contextual_Menu|Contextual menu]])
 +
# Activate the node to be merged by hovering over it
 +
# Select the second path by using the {{Key|G}} [[SNT: Key_Shortcuts|shortcut]] and activate the second merging node by hovering over it
 +
# Open the contextual menu and select the initial path from the ''Connect To (Start Join)'' / ''Connect To (End Join)'' menu.
 +
If both nodes are terminal, the paths are merged together. Otherwise, one path will become a child of the other. Note that one of the nodes must be terminal, to ensure no loops are created.
 +
<div align="center"><ul>
 +
<li style="display: inline-block;"> [[Image:SNT-Edit-Path-Connect-To-Step-1.png|thumb|none|250px|1) Select parent path and activate first join node]] </li>
 +
<li style="display: inline-block;"> [[Image:SNT-Edit-Path-Connect-To-Step-2.png|thumb|none|250px|2) Select child path and activate second join node]] </li>
 +
<li style="display: inline-block;"> [[Image:SNT-Edit-Path-Connect-To-Step-3.png|thumb|none|250px|3) Use contextual-menu option to connect child path to parent path]] </li>
 +
<li style="display: inline-block;"> [[Image:SNT-Edit-Path-Connect-To-Result.png|thumb|none|250px|4) Joined result<br>&nbsp;]] </li>
 +
</ul></div>
  
Now hold down {{key|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 this:
+
==Tracing in the Legacy 3D Viewer==
[[Image:Snt-ej-cropped-end-join-created-2.png|center|thumb|400px|Connected path to join, unconfirmed]]
+
It remains possible to trace in the legacy 3D Viewer.  
 
+
[[File:SNT-3D-Dialog.png|right|thumb|]]
If you're happy with that, 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. The result will look like this:
 
[[Image:Snt-ej-cropped-path-completed-2.png|center|thumb|400px|Confirmed join]]
 
 
 
Note that the path list indicates that this new path (1) ends on the existing one (0).
 
 
 
== Filtered Image==
 
WIP
 
 
 
==Legacy 3D Viewer==
 
SNT comes bundled with a 3D viewer with visualization and tracing capabilities.
 
 
===I.Starting the Viewer===
 
===I.Starting the Viewer===
To open the viewer, navigate to the "3D" menu tab in the SNT dialog and look for "Legacy 3D Viewer". You will see 3 parameters:
+
To open the viewer, select the ''3D'' menu tab in the SNT dialog and look for ''Legacy 3D Viewer''. You will see 3 parameters:
[[File:SNT-3D-Dialog.png|right|thumb|The 3D part of the dialog]]
+
[[File:SNT-Image-Resampling-Factor.png|right|thumb]]
* '''Viewer'''  
+
* 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 their window titles from the drop-down menu.
** ''New with image'' - Instantiate viewer with the currently opened image. This enables one to trace in 3D as well as explore the image stack in an intuitive way.
+
* Select the preferred rendering style from the ''Mode'' drop-down menu.
** ''New without image'' - Instantiate viewer without an image. Useful for visualizing reconstructions and surface meshes (WaveFront or STL).
+
* 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.
* '''Mode''' - the render style for the reconstruction
+
[[File:SNT-Legacy-3D-Viewer.png|right|thumb|300px|3D viewer showing OP_1.tif]]
** ''Lines and discs''
 
** ''Lines'' - Render paths as nodes connected by 1D lines
 
** ''Surface reconstructions'' - Render paths as tubular surfaces
 
* '''Actions'''
 
** ''Apply Color Labels''
 
** ''Compare reconstruction against''
 
If you choose "New with image..." for Viewer and press "Apply", a prompt will appear asking you to choose the resampling factor for the image.
 
[[File:SNT-Image-Resampling-Factor.png|center|thumb]] Then, the viewer window will appear with the currently open image.
 
 
 
[[File:SNT-Legacy-3D-Viewer.png|center|thumb|400px|3D viewer showing OP_1.tif]]
 
  
 
===II.Tracing and Navigation===
 
===II.Tracing and Navigation===
In order to select points for tracing in the 3D Viewer, you need to use the "Wand" tool.  In order to rotate the view, you need to either use the "Hand" tool or drag the mouse while holding the scroll wheel. Once you have selected each of these tools once, you should be able to switch between them by pressing the {{key|Esc}} key. To translate the image, hold {{key|Shift}} and the scroll wheel while dragging the mouse. To adjust zoom depth, scroll the mouse wheel.
+
* '''Selecting points for tracing'''  Select the ''Wand tool'' ({{key|W}} [[SNT:_Key_Shortcuts#Legacy_3D_Viewer|shortcut]]) in the main ImageJ 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 as described [[#Tracing|above]]. Similarly, branching occurs as [[#Branching: Start A Path On An Existing Path|described for 2D canvas(es)]], by holding the {{key|Alt|Shift}} modifier.
 
+
* '''Rotation'''  Either use the ''Hand tool'' ({{key|H}} [[SNT:_Key_Shortcuts#Legacy_3D_Viewer|shortcut]])  tool and left-click while dragging the mouse or drag mouse while holding the scroll wheel.
[[File:Fiji-toolbar-wand-and-hand-2.png]]
+
* '''Translation''' Hold {{key|Shift}} and the scroll wheel while dragging the mouse.
 
+
* '''Adjusting zoom depth''' Scroll the mouse wheel.
The following key shortcuts also work in the 3D Viewer:
+
Once you have selected each of these tools (Wand and Hand) once, you should be able to switch between them by pressing the {{key|Esc}} key. See [[SNT:_Key_Shortcuts#Legacy_3D_Viewer|Key Shortcuts]] for the list of all supported shortcuts.
 
+
[[File:Fiji-toolbar-wand-and-hand-2.png|center]]
* {{key|Y}} confirm the temporary path segment
 
* {{key|N}} cancel the temporary path segment
 
* {{key|F}} complete the current path
 
* {{key|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 {{key|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 ({{key|Alt}} and clicking at the right point on the selected path.
 
 
 
=Fitting=
 
SNT can fit paths, which is the assignment of a circular cross-section to each path node. This allows radius estimation and midpoint refinement for existing nodes with sub-voxel accuracy. To fit path(s), select the desired paths in the Path Manager (or select none if you want to fit all paths) and go to the "Refine/Fit" menu in the same window. There are three options:
 
[[File:Fit-manager.png|right|thumb]]
 
* Fit Paths/Un-fit paths/Apply Existing Fit - 1) Fits the selected paths or 2) un-fits them if they have alredy been fitted. 3) If you generated a preview of the fit you can apply that result. This option will change depending on context.
 
* Explore/Preview Fit - Carves out a region of the image along and around the path. Scrolling through this image will display the result of the fitting operation for each node on the path.
 
* Discard Fit - Deletes the existing fit(s) for the selected path(s), or all fits if no paths are selected.
 
[[File:Explore-fit-preview.png|right|thumb|Slice in "Explore/Preview Fit" image stack]]
 
 
 
Before computing the fit, SNT will prompt you to specify two parameters:
 
* Type of Refinement - SNT can use the fluorescent signal around traced paths to optimize curvatures and estimate the thickness of traced structures. The optimization algorithm uses pixel intensities to fit circular cross-sections around each node. Once computed, fitted cross-sections can be used to: 1) Infer the radius of nodes, and/od 2) refine node positioning, by snapping their coordinates to the cross-section centroid.
 
** 1) Assign radii of fitted cross-sections to nodes
 
** 2) Snap node coordinates to cross-section centroids
 
** 1) & 2) Assign fitted radii and snap node coordinates
 
* Max. Radius - Defines (in pixels) the largest radius allowed in the fit. It constrains the optimization to minimize fitting artifacts caused by neighboring structures
 
** Default = 40px on each side of the path
 
 
 
Assuming you chose options 1) & 2) for "Type of Refinement", a fit path might look like the rightmost image below. Notice how the nodes follow the center line of the structure more closely, and how each node now has a non-zero radius approximating that of the tube.
 
<div align="center">
 
<ul>
 
<li style="display:inline-block;"> [[Image:Before-fitting.png|none|thumb|250px|Before fitting]] </li>
 
<li style="display:inline-block;"> [[Image:After-fitting.png|none|thumb|250px|Fitted path]] </li>
 
</ul>
 
</div>
 
  
 
=Filling=
 
=Filling=
Line 140: Line 116:
 
* 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.
 
* 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.
 
* 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 clicking "Apply", which sets the threshold to the maximum explored distance (the value shown in "Max. explored distance:" under the "Search Status" dialog).
+
* 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.
 
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 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.
+
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:
 
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:
Line 161: Line 137:
 
* Save the fill (which will add it to the fill list) by clicking "Stash Progress".  
 
* 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)".  
 
* 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 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 [[Simple_Neurite_Tracer#Tutorials|tutorials]]). Or, you could save those fill stacks for each of the neurons you fill and then combine them in ImageJ using "RGB Merge".
+
* 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 [[Simple_Neurite_Tracer#Tutorials|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:
 
The image stack you would get from the image used in this example might look something like this:
 
[[Image:Snt-filling-viewed-2.png|center|thumb|500px|Having selected the "Image Stack... -> As Grayscale Image..." option]]
 
[[Image:Snt-filling-viewed-2.png|center|thumb|500px|Having selected the "Image Stack... -> As Grayscale Image..." option]]
  
{{Clear}}
+
=Generating ''Filtered Images''=
 +
This section describes how to generate [[SNT:_Overview#Tracing_on_Filtered_Image|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 {{bc | 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 = voxel depth = 1, the parameters would be:
 +
[[File:frangi-parameters.png|center|thumb|]]
 +
{{Tip| id = image-spacing|tip = To get the spatial calibration for your image, go to {{bc|Image|Properties...}} ({{key|Ctrl}}+{{key|Shift}}+{{key|P}}) in the main Fiji dialog.}}
 +
Save the result using {{bc | File | Save As|Tiff...}} ("test-filtered.tif", for example). Then, in SNT's dialog look for the "Tracing on Secondary Image" widget in the ''Main'' tab. Click the file folder button to specify the secondary image. Next, toggle the "Trace on Secondary Image" checkbox (you can do so using {{key|I}}. Now the pathfinding will occur on the secondary image. To view a MIP of the secondary image "over" the original image during tracing, toggle the "Render in overlay at X% opacity" checkbox.
 +
<div align="center">
 +
<ul>
 +
<li style="display:inline-block;"> [[Image:filtered-image-load.png|none|thumb|300px|Step 1]] </li>
 +
<li style="display:inline-block;"> [[Image:filtered-image-toggle.png|none|thumb|300px|Step 2]] </li>
 +
</ul>
 +
</div>
 +
To display the image in a separate window, from the SNT dialog use {{bc|Show Cached Image}} from the ''gear'' menu or {{bc | View | Show Cached ''Secondary Image''}}.
 +
[[File:display-filtered-image.png|center|thumb|500px|Secondary Image Overlay at 50% Opacity]]
 +
 
 +
====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:
 +
<source lang="java">
 +
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";
 +
        open(filename);
 +
        run("Frangi Vesselness"); // arguments can be specified here
 +
        selectWindow(expected_window_name);
 +
        saveAs("Tiff", output_filename);
 +
    }
 +
}
 +
</source>
 +
The same process can be accomplished in a script using [[ImageJ_Ops|ImageJ Ops]]. For example, in Jython:
 +
<source lang="python">
 +
# @ImageJ ij
 +
# @String(value="<HTML>This script applies the Frangi Vesselness filter to all TIFF images in a directory.<br>Only 2D or 3D grayscale images are supported. Processing log is shown in Console.", visibility="MESSAGE") msg
 +
# @File(label="Directory containing your images", style="directory") input_dir
 +
# @String(label="Consider only filenames containing",description="Clear field for no filtering",value="") name_filter
 +
# @boolean(label="Include subdirectories") recursive
 +
# @float(label="Size of structures to be filtered (spatially calibrated units)",description="The filter kernel will be determined from the average voxel size") scale
 +
# @LogService log
 +
# @StatusService status
 +
# @UIService uiservice
 +
 
 +
"""
 +
file: Filter_Multiple_Images.py
 +
author: Tiago Ferreira, Cameron Arshadi
 +
info: Bulk filtering of image files using Frangi Vesselness
 +
"""
 +
 
 +
from net.imagej.axis import Axes
 +
 
 +
import os
 +
 
 +
 
 +
def get_image_files(directory, filtering_string, extension):
 +
    """Returns a list containing the paths of files in the specified
 +
      directory. The list will only include files with the supplied
 +
      extension whose filename contains the specified string."""
 +
    files = []
 +
    for (dirpath, dirnames, filenames) in os.walk(directory):
 +
        for f in filenames:
 +
            if os.path.basename(f).startswith('.'):
 +
                continue
 +
            if filtering_string in f and f.lower().endswith(extension):
 +
                files.append(os.path.join(dirpath, f))
 +
        if not recursive:
 +
            break  # do not process subdirectories
 +
 
 +
    return files
 +
 
 +
 
 +
def run():
 +
    # First check that scale parameter is > 0, exiting if not
 +
    if scale <= 0:
 +
        log.error('Please select a value > 0 for the scale parameter. Exiting...')
 +
        return
 +
 
 +
    # Get all files with specified name filter and extension in the input directory
 +
    d = str(input_dir)
 +
    extension = ".tif"
 +
    files = get_image_files(d, name_filter, extension)
 +
    if not files or len(files) == 0:
 +
        uiservice.showDialog("No files matched the specified criteria", "Error")
 +
        return
 +
 
 +
    processed = 0
 +
    skipped = 0
 +
    for f in files:
 +
 
 +
        basename = os.path.basename(f)
 +
        msg = 'Processing file %s: %s...' % (processed + skipped + 1, basename)
 +
        status.showStatus(msg)
 +
        log.info(msg)
 +
 
 +
        # Load the input image
 +
        input_image = ij.io().open(f)
 +
 
 +
        # Verify that the image is 2D/3D and grayscale, skipping it if not
 +
        num_dimensions = input_image.numDimensions()
 +
        if num_dimensions > 3 or int(input_image.getChannels()) > 1:
 +
            log.error('Could not process %s...Only 2D/3D grayscale images are supported' % basename)
 +
            skipped += 1
 +
            continue
 +
 
 +
        # Convert input image to float, since we are dealing with derivatives
 +
        float_input = ij.op().run("convert.float32", input_image)
 +
 
 +
        # Obtain spatial calibration of the image
 +
        x_spacing = float_input.averageScale(0)
 +
        y_spacing = float_input.averageScale(1)
 +
        spacing = [x_spacing, y_spacing]
 +
 
 +
        if num_dimensions == 3 and float_input.axis(2).type() == Axes.Z:
 +
            z_spacing = float_input.averageScale(2)
 +
            spacing.append(z_spacing)
 +
 
 +
        # Create placeholder image for the output then run the Frangi Vesselness op
 +
        output = ij.op().run("create.img", float_input)
 +
        pixel_scale = scale / (sum(spacing) / len(spacing))  # average voxel size: convert scale to pixel units
 +
        ij.op().run("frangiVesselness", output, float_input, spacing, pixel_scale)
 +
 
 +
        # Save the result using the same basename as the image, adding "[Frangi].tif"
 +
        # For example, the output for "OP_1.tif" would be named "OP_1[Frangi].tif"
 +
        l = len(f)
 +
        el = len(extension)
 +
        output_filepath = f[0:l - el] + "[Frangi].tif"
 +
        ij.io().save(output, output_filepath)
 +
 
 +
        processed += 1
 +
 
 +
    log.info('Done. %s file(s) processed. %s file(s) skipped...' % (processed, skipped))
 +
 
 +
 
 +
run()
 +
 
 +
</source>
 +
TBD:
 +
* Filtered Images
 +
** Use MIPs for side-by-side original and filtered images
 +
** FIXME: It is confusing that for single images we use {{bc | Process | Filters | Frangi Vesselness}} for multiple {{bc | Plugins | Process | Frangi Vesselness (imglib, experimental)}}
 +
** Update snapshots of the ''Filtered Images'' widget
 +
** Include IJ-ops example
 +
* Point-accuracy
 +
**Make new section based on [[Simple Neurite Tracer: Accurate point placement]]
 +
 
 +
=Accurate Point Placement=
 +
This section describes methods to increase the accuracy of node placement.
 +
 
 +
{|
 +
|-
 +
|Accurate node placement requires ''XY'', ''ZY'' and ''XZ'' views to be visible. You can do so at [[SNT:_Overview#Startup_Prompt|startup]], by making sure that ''Default: XY, ZY and XZ views'' is selected, or by clicking in ''Display ZY/XZ Views'' in the [[SNT:_Overview#Options_Tab|Options tab]] if you have already started SNT.
 +
|[[Image:SNT-Three-Pane-View-Enabled-Startup-Prompt.png]]
 +
|-
 +
|Find the approximate location of your start point by moving your mouse in the XY window, holding down {{key|Shift}} to synchronize the view in the other panes. At this point, you should enable cursor [[SNT:_Overview#Cursor_Auto-snapping|auto-snapping]] in the [[SNT:_Overview#Main_Tab|Main tab]] using suitable parameters for your image.
 +
|[[Image:SNT-Accurate-Point-Placement-Walkthrough-Updated-1.png|350px]]
 +
|-
 +
|When you press {{key|+}} to zoom in, all the panes will zoom in on the point that the crosshair is over, so each time you press {{key|+}}, make sure you move your mouse pointer so that it's still over the structure of interest. You may want to adjust in the [[SNT:_Overview#Views|Views]] widget ([[SNT:_Overview#Options_Tab|Options tab]])  whether all views should zoom synchronously.<br>
 +
At this point, you should adjust a suitable [[SNT:_Overview#Cursor_Auto-snapping|snapping neighborhood]] both in 2D (XY) and 3D (Z). Note that when Z-snapping is enabled, all views become synchronized,
 +
|[[Image:SNT-Accurate-Point-Placement-Walkthrough-Updated-2.png|350px]]
 +
|-
 +
|Locate the center of the structure to be clicked on. If [[SNT:_Overview#Cursor_Auto-snapping|cursor auto-snapping]] is enabled, simply mouse over the structure, otherwise, try moving the mouse and scroll wheel in each of the panes (holding down {{key|Shift}} so synchronize the views in all three panes). Note that you can toggle the cursor auto-snapping feature at will, by pressing the [[SNT:_Key_Shortcuts|shortcut]] {{key|S}}. Also, note that you can "click" on the [[SNT:_Key_Shortcuts#Tracing|brightest voxel]] of a voxel column, by pressing {{key|M}}.
 +
 
 +
When you're happy with the point under the crosshairs, left-click to start the path:
 +
|[[Image:SNT-Accurate-Point-Placement-Walkthrough-Updated-3.png|350px]]
 +
|-
 +
|Zoom out again with the {{key|-}} key, and similarly zoom in on the next point you want to be on your path to place it precisely:
 +
|[[Image:SNT-Accurate-Point-Placement-Walkthrough-Updated-4.png|350px]]
 +
|-
 +
|The path along the neuron may not follow the center line perfectly:
 +
|[[Image:SNT-Accurate-Point-Placement-Walkthrough-Updated-5.png|350px]]
 +
|-
 +
|... but you can later improve that with the {{bc|Refine/Fit|Fit Path...}} option in the [[SNT:_Overview#Path_Manager|Path Manager]], which tries to align the path to the midline of the structure to sub-voxel accuracy:
 +
|[[Image:SNT-Accurate-Point-Placement-Walkthrough-Updated-6.png|350px]]
 +
|-
 +
|}
 +
 
 +
{{SNTNavBar}}

Latest revision as of 19:22, 10 June 2019

SNT Pages: Main User Manual Tutorials Walkthroughs Shortcuts Reconstruction Viewer Scripting FAQ


Tracing

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 merged 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 are terminal, the paths are merged together. Otherwise, one path 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.

SNT-3D-Dialog.png

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:

SNT-Image-Resampling-Factor.png
  • 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 their 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 (W shortcut) in the main ImageJ 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 as described above. Similarly, branching occurs as described for 2D canvas(es), by holding the Alt+ Shift modifier.
  • Rotation Either use the Hand tool (H shortcut) tool and left-click while dragging the 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. See Key Shortcuts for the list of all supported shortcuts.

Fiji-toolbar-wand-and-hand-2.png

Filling

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 = voxel depth = 1, the parameters would be:

Frangi-parameters.png
Tip: To get the spatial calibration for your image, go to Image ▶ Properties... (^ Ctrl+ Shift+P) in the main Fiji dialog.


Save the result using File  ▶ Save As ▶ Tiff... ("test-filtered.tif", for example). Then, in SNT's dialog look for the "Tracing on Secondary Image" widget in the Main tab. Click the file folder button to specify the secondary image. Next, toggle the "Trace on Secondary Image" checkbox (you can do so using I. Now the pathfinding will occur on the secondary image. To view a MIP of the secondary 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 Cached Secondary Image.

Secondary Image Overlay at 50% Opacity

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";
        open(filename);
        run("Frangi Vesselness"); // arguments can be specified here
        selectWindow(expected_window_name);
        saveAs("Tiff", output_filename);
    }
}

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

# @ImageJ ij
# @String(value="<HTML>This script applies the Frangi Vesselness filter to all TIFF images in a directory.<br>Only 2D or 3D grayscale images are supported. Processing log is shown in Console.", visibility="MESSAGE") msg
# @File(label="Directory containing your images", style="directory") input_dir
# @String(label="Consider only filenames containing",description="Clear field for no filtering",value="") name_filter
# @boolean(label="Include subdirectories") recursive
# @float(label="Size of structures to be filtered (spatially calibrated units)",description="The filter kernel will be determined from the average voxel size") scale
# @LogService log
# @StatusService status
# @UIService uiservice

"""
file: Filter_Multiple_Images.py
author: Tiago Ferreira, Cameron Arshadi
info: Bulk filtering of image files using Frangi Vesselness
"""

from net.imagej.axis import Axes

import os


def get_image_files(directory, filtering_string, extension):
    """Returns a list containing the paths of files in the specified
       directory. The list will only include files with the supplied
       extension whose filename contains the specified string."""
    files = []
    for (dirpath, dirnames, filenames) in os.walk(directory):
        for f in filenames:
            if os.path.basename(f).startswith('.'):
                continue
            if filtering_string in f and f.lower().endswith(extension):
                files.append(os.path.join(dirpath, f))
        if not recursive:
            break  # do not process subdirectories

    return files


def run():
    # First check that scale parameter is > 0, exiting if not
    if scale <= 0:
        log.error('Please select a value > 0 for the scale parameter. Exiting...')
        return

    # Get all files with specified name filter and extension in the input directory
    d = str(input_dir)
    extension = ".tif"
    files = get_image_files(d, name_filter, extension)
    if not files or len(files) == 0:
        uiservice.showDialog("No files matched the specified criteria", "Error")
        return

    processed = 0
    skipped = 0
    for f in files:

        basename = os.path.basename(f)
        msg = 'Processing file %s: %s...' % (processed + skipped + 1, basename)
        status.showStatus(msg)
        log.info(msg)

        # Load the input image
        input_image = ij.io().open(f)

        # Verify that the image is 2D/3D and grayscale, skipping it if not
        num_dimensions = input_image.numDimensions()
        if num_dimensions > 3 or int(input_image.getChannels()) > 1:
            log.error('Could not process %s...Only 2D/3D grayscale images are supported' % basename)
            skipped += 1
            continue

        # Convert input image to float, since we are dealing with derivatives
        float_input = ij.op().run("convert.float32", input_image)

        # Obtain spatial calibration of the image
        x_spacing = float_input.averageScale(0)
        y_spacing = float_input.averageScale(1)
        spacing = [x_spacing, y_spacing]

        if num_dimensions == 3 and float_input.axis(2).type() == Axes.Z:
            z_spacing = float_input.averageScale(2)
            spacing.append(z_spacing)

        # Create placeholder image for the output then run the Frangi Vesselness op
        output = ij.op().run("create.img", float_input)
        pixel_scale = scale / (sum(spacing) / len(spacing))  # average voxel size: convert scale to pixel units
        ij.op().run("frangiVesselness", output, float_input, spacing, pixel_scale)

        # Save the result using the same basename as the image, adding "[Frangi].tif"
        # For example, the output for "OP_1.tif" would be named "OP_1[Frangi].tif"
        l = len(f)
        el = len(extension)
        output_filepath = f[0:l - el] + "[Frangi].tif"
        ij.io().save(output, output_filepath)

        processed += 1

    log.info('Done. %s file(s) processed. %s file(s) skipped...' % (processed, skipped))


run()

TBD:

  • 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.

Accurate node placement requires XY, ZY and XZ views to be visible. You can do so at startup, by making sure that Default: XY, ZY and XZ views is selected, or by clicking in Display ZY/XZ Views in the Options tab if you have already started SNT. SNT-Three-Pane-View-Enabled-Startup-Prompt.png
Find the approximate location of your start point by moving your mouse in the XY window, holding down Shift to synchronize the view in the other panes. At this point, you should enable cursor auto-snapping in the Main tab using suitable parameters for your image. SNT-Accurate-Point-Placement-Walkthrough-Updated-1.png
When you press + to zoom in, all the panes will zoom in on the point that the crosshair is over, so each time you press +, make sure you move your mouse pointer so that it's still over the structure of interest. You may want to adjust in the Views widget (Options tab) whether all views should zoom synchronously.

At this point, you should adjust a suitable snapping neighborhood both in 2D (XY) and 3D (Z). Note that when Z-snapping is enabled, all views become synchronized,

SNT-Accurate-Point-Placement-Walkthrough-Updated-2.png
Locate the center of the structure to be clicked on. If cursor auto-snapping is enabled, simply mouse over the structure, otherwise, try moving the mouse and scroll wheel in each of the panes (holding down Shift so synchronize the views in all three panes). Note that you can toggle the cursor auto-snapping feature at will, by pressing the shortcut S. Also, note that you can "click" on the brightest voxel of a voxel column, by pressing M.

When you're happy with the point under the crosshairs, left-click to start the path:

SNT-Accurate-Point-Placement-Walkthrough-Updated-3.png
Zoom out again with the - key, and similarly zoom in on the next point you want to be on your path to place it precisely: SNT-Accurate-Point-Placement-Walkthrough-Updated-4.png
The path along the neuron may not follow the center line perfectly: SNT-Accurate-Point-Placement-Walkthrough-Updated-5.png
... but you can later improve that with the Refine/Fit ▶ Fit Path... option in the Path Manager, which tries to align the path to the midline of the structure to sub-voxel accuracy: SNT-Accurate-Point-Placement-Walkthrough-Updated-6.png
SNT Pages: Main User Manual Tutorials Walkthroughs Shortcuts Reconstruction Viewer Scripting FAQ