{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Add Continuous Borders Around Labelled Regions" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from freesurfer_surface import Surface\n", "\n", "SUBJECTS_DIR = '../tests/subjects'\n", "surface = Surface.read_triangular(SUBJECTS_DIR + '/fabian/surf/lh.pial')\n", "surface.load_annotation_file(SUBJECTS_DIR + '/fabian/label/lh.aparc.annot')" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": true }, "outputs": [], "source": [ "import numpy\n", "from freesurfer_surface import PolygonalChain, Vertex\n", "\n", "def unit_vector(vector: numpy.array) -> numpy.array:\n", " return vector / numpy.linalg.norm(vector)\n", "\n", "def add_blocks_along(border_chain: PolygonalChain, length_add_mm: float,\n", " height_mm: float, width_mm: float):\n", " for vertex_triplet_indices in border_chain.adjacent_vertex_indices(3):\n", " vertex_triplet = surface.select_vertices(vertex_triplet_indices)\n", " backward_vector = vertex_triplet[0] - vertex_triplet[1]\n", " forward_vector = vertex_triplet[2] - vertex_triplet[1]\n", " forward_vector = unit_vector(forward_vector) \\\n", " * (numpy.linalg.norm(forward_vector) + length_add_mm)\n", " upward_vector = unit_vector(numpy.cross(backward_vector, forward_vector)) * height_mm / 2\n", " sideward_vector = unit_vector(numpy.cross(upward_vector, forward_vector)) * width_mm / 2\n", " base_corners = [vertex_triplet[1] + v for v in [-upward_vector -sideward_vector,\n", " -upward_vector +sideward_vector,\n", " +upward_vector +sideward_vector,\n", " +upward_vector -sideward_vector]]\n", " top_corners = [v + forward_vector for v in base_corners]\n", " base_indices = [surface.add_vertex(Vertex(*coords)) for coords in base_corners]\n", " top_indices = [surface.add_vertex(Vertex(*coords)) for coords in top_corners]\n", " for surface_indices in [base_indices, top_indices]:\n", " surface.add_rectangle(surface_indices)\n", " for i in range(4):\n", " j = (i + 1) % 4\n", " surface.add_rectangle((base_indices[i], base_indices[j],\n", " top_indices[j], top_indices[i]))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "#8: inferiorparietal (borders: 1)\n", "#17: paracentral (borders: 1)\n", "#22: postcentral (borders: 1)\n", "#24: precentral (borders: 1)\n", "#29: superiorparietal (borders: 1)\n" ] } ], "source": [ "for label in filter(lambda l: 'central' in l.name or 'parietal' in l.name,\n", " surface.annotation.labels.values()):\n", " borders = list(surface.find_label_border_polygonal_chains(label))\n", " print(f'#{label.index}: {label.name} (borders: {len(borders)})')\n", " for border in borders:\n", " add_blocks_along(border, length_add_mm=0.2,\n", " height_mm=1.5, width_mm=1.0)\n", " \n", "surface.write_triangular('border.lh.pial')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```sh\n", "freeview --surface examples/border.lh.pial:annot=tests/subjects/fabian/label/lh.aparc.annot\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.5.10" } }, "nbformat": 4, "nbformat_minor": 2 }