{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Surface seeding for tractography\n\nSurface seeding is a way to generate initial position for tractography\nfrom cortical surfaces position [Stonge2018]_.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\nfrom dipy.viz import window, actor\nfrom dipy.data import get_fnames\nfrom dipy.tracking.mesh import (random_coordinates_from_surface,\n seeds_from_surface_coordinates)\n\nfrom fury.io import load_polydata\nfrom fury.utils import (get_polydata_triangles, get_polydata_vertices,\n get_actor_from_polydata, normals_from_v_f)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Fetch and load a surface\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "brain_lh = get_fnames(\"fury_surface\")\npolydata = load_polydata(brain_lh)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Extract the triangles and vertices\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "triangles = get_polydata_triangles(polydata)\nvts = get_polydata_vertices(polydata)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Display the surface\n\nFirst, create an actor from the polydata, to display in the scene\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "scene = window.Scene()\nsurface_actor = get_actor_from_polydata(polydata)\n\nscene.add(surface_actor)\nscene.set_camera(position=(-500, 0, 0),\n view_up=(0.0, 0.0, 1))\n\n# Uncomment the line below to show to display the window\n# window.show(scene, size=(600, 600), reset_camera=False)\nwindow.record(scene, out_path='surface_seed1.png', size=(600, 600))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. figure:: surface_seed1.png\n :align: center\n\n **Initial cortical surface**\n\n\n## Generate a list of seeding positions\n\nChoose the number of seed\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "nb_seeds = 100000\nnb_triangles = len(triangles)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get a list of triangles indices and trilinear coordinates for each seed\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "tri_idx, trilin_co = random_coordinates_from_surface(nb_triangles, nb_seeds)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get the 3d cartesian position from triangles indices and trilinear coordinates\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "seed_pts = seeds_from_surface_coordinates(triangles, vts, tri_idx, trilin_co)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compute normal and get the normal direction for each seeds\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "normals = normals_from_v_f(vts, triangles)\nseed_n = seeds_from_surface_coordinates(triangles, normals, tri_idx, trilin_co)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create dot actor for seeds (blue)\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "seed_actors = actor.dot(seed_pts, colors=(0, 0, 1), dot_size=4.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create line actors for seeds normals (green outside, red inside)\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "normal_length = 0.5\nnormal_in = np.tile(seed_pts[:, np.newaxis, :], (1, 2, 1))\nnormal_out = np.tile(seed_pts[:, np.newaxis, :], (1, 2, 1))\nnormal_in[:, 0] -= seed_n * normal_length\nnormal_out[:, 1] += seed_n * normal_length\n\nnormal_in_actor = actor.line(normal_in, colors=(1, 0, 0))\nnormal_out_actor = actor.line(normal_out, colors=(0, 1, 0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Visualise seeds and normals along the surface\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "scene = window.Scene()\nscene.add(surface_actor)\nscene.add(seed_actors)\nscene.add(normal_in_actor)\nscene.add(normal_out_actor)\nscene.set_camera(position=(-500, 0, 0),\n view_up=(0.0, 0.0, 1))\n\n# Uncomment the line below to show to display the window\n# window.show(scene, size=(600, 600), reset_camera=False)\nwindow.record(scene, out_path='surface_seed2.png', size=(600, 600))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. figure:: surface_seed2.png\n :align: center\n\n **Surface seeds with normal orientation**\n\n\n### References\n.. [Stonge2018] St-Onge, E., Daducci, A., Girard, G., & Descoteaux, M.\n Surface-enhanced tractography (SET). NeuroImage, 169, 524-539, 2018.\n\n.. include:: ../links_names.inc\n\n\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.13" } }, "nbformat": 4, "nbformat_minor": 0 }