├── .coveragerc
├── .flake8
├── .gitattributes
├── .gitignore
├── .pre-commit-config.yaml
├── CMakeLists.txt
├── LICENCE.CeCILL.txt
├── LICENCE.GPLv3.txt
├── README.rst
├── bin
├── ylDistmaps
├── ylFixCortexTopology
├── ylGetExchangedPropvol
├── ylPostProcessEquivolumetricDepth
├── ylRandomizeLabels
├── ylRelabel
└── ylRelabelConjunction
├── brainvisa
└── toolboxes
│ └── highres_cortex
│ ├── highres_cortex.png
│ ├── highres_cortex.py
│ └── processes
│ ├── category_documentation.minf
│ ├── isovolume.procdoc
│ ├── isovolume.py
│ ├── laplacian.procdoc
│ ├── laplacian.py
│ ├── thickness_adv.procdoc
│ ├── thickness_adv.py
│ ├── thickness_upw.procdoc
│ ├── thickness_upw.py
│ ├── traverses.procdoc
│ └── traverses.py
├── doc
├── .gitignore
├── references.bib
└── test-references.tex
├── examples
└── scripts
│ ├── column-regions
│ └── column-regions.sh
│ ├── dist
│ └── distmaps.sh
│ ├── heat
│ └── heat.sh
│ ├── isovolume
│ └── isovolume.sh
│ ├── laplace-euclidean
│ └── laplace-euclidean.sh
│ └── upwind-euclidean
│ └── upwind-euclidean.sh
├── project_info.cmake
├── python
└── highres_cortex
│ ├── __init__.py
│ ├── capsul
│ ├── __init__.py
│ ├── filtered_sumcurvs.xml
│ ├── isovolume.xml
│ ├── processes.py
│ ├── thickness_adv.xml
│ ├── thickness_upw.xml
│ └── traverses.xml
│ ├── cortex_topo.py
│ ├── scripts
│ ├── __init__.py
│ ├── distmaps.py
│ ├── fix_cortex_topology.py
│ ├── get_exchanged_propvol.py
│ ├── postprocess_equivolumetric_depth.py
│ ├── randomize_labels.py
│ ├── relabel.py
│ └── relabel_conjunction.py
│ └── test
│ ├── __init__.py
│ ├── compare_with_reference.py
│ ├── synthetic_data.py
│ └── test_capsul.py
├── soma-env
└── soma-env-recipe.yaml
├── src
├── CMakeLists.txt
├── commands
│ ├── CMakeLists.txt
│ ├── ylAdvectEuclidean.cc
│ ├── ylAdvectPath.cc
│ ├── ylAdvectTubes.cc
│ ├── ylAdvectValues.cc
│ ├── ylIsoCurvature.cc
│ ├── ylLabelEachVoxel.cc
│ ├── ylLaplacian.cc
│ ├── ylMakeTraversePseudoAreaMap.cc
│ ├── ylMergeCortexColumnRegions.cc
│ ├── ylPropagateAlongField.cc
│ └── ylUpwindDistance.cc
└── library
│ ├── CMakeLists.txt
│ ├── advection.cc
│ ├── advection.hh
│ ├── advection.tcc
│ ├── cortex.hh
│ ├── cortex_advection.cc
│ ├── cortex_advection.hh
│ ├── cortex_column_region_quality.cc
│ ├── cortex_column_region_quality.hh
│ ├── cortex_column_region_quality.tcc
│ ├── field.cc
│ ├── field.hh
│ ├── front.cc
│ ├── front.hh
│ ├── iterative_region_merger.cc
│ ├── iterative_region_merger.hh
│ ├── iterative_region_merger.tcc
│ ├── label_volume.cc
│ ├── label_volume.hh
│ ├── label_volume.tcc
│ ├── laplace_solver.cc
│ ├── laplace_solver.hh
│ ├── laplace_solver.tcc
│ ├── propagate_along_field.cc
│ ├── propagate_along_field.hh
│ ├── propagate_along_field.tcc
│ ├── upwinding.cc
│ ├── upwinding.hh
│ ├── volume_util.cc
│ ├── volume_util.hh
│ └── volume_util.tcc
└── tests
├── CMakeLists.txt
├── bootstrap-docker
├── .gitignore
├── casa-dev:ubuntu-12.04
│ ├── Dockerfile
│ └── prepare.sh
├── ubuntu14.04
│ ├── Dockerfile
│ └── prepare.sh
└── ubuntu16.04
│ ├── Dockerfile
│ └── prepare.sh
├── precision
├── cbs-post.sh
├── cbs-pre.sh
└── evaluate.LayoutXML.in
├── run_all_scripts.sh
├── test_all_scripts.sh
└── test_env.sh.in
/.coveragerc:
--------------------------------------------------------------------------------
1 | # .coveragerc to control coverage.py -*- mode: conf-unix; -*-
2 |
3 | [run]
4 | branch = True
5 | omit = python/highres_cortex/test/*
6 |
7 | [report]
8 | # Regexes for lines to exclude from consideration
9 | exclude_lines =
10 | # Have to re-enable the standard pragma
11 | pragma: no cover
12 |
13 | # Don't complain about missing debug-only code:
14 | def __repr__
15 | if self\.debug
16 |
17 | # Don't complain if tests don't hit defensive assertion code:
18 | raise AssertionError
19 | raise NotImplementedError
20 |
21 | # Don't complain if non-runnable code isn't run:
22 | if 0:
23 | if __name__ == .__main__.:
24 |
25 | [html]
26 | directory = python_coverage_report
27 |
28 | [xml]
29 | output = python_coverage.xml
30 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore =
3 | # E203 (whitespace before ':') has false positive for array slicings
4 | E203,
5 | # these are on the default ignore list
6 | E121, E126, E226, E133, E203, E241,
7 | # We want line-break *before* the operator (new PEP8 style similar to math)
8 | W503,
9 | # Gives false positives when a name contains an uppercase acronym
10 | N802
11 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * whitespace="trailing-space,tab-in-indent"
2 |
3 | *.cc text diff=cpp
4 | *.hh text diff=cpp
5 | *.tcc text diff=cpp
6 | *.py text diff=python
7 | *.sh eol=lf
8 | *.cmake text
9 | *.tex text diff=tex
10 | *.bib text diff=bibtex
11 | *.txt text
12 | *.rst text
13 | *.xml text
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # CMake build files
2 | /CMakeCache.txt
3 | /Testing/
4 | CMakeFiles/
5 | Makefile
6 | cmake_install.cmake
7 | install_manifest.txt
8 |
9 | # brainvisa-cmake files
10 | /CMakeDoxyfile.in
11 | /CMakeDoxygenDefaults.cmake
12 | /DartConfiguration.tcl
13 | /include/
14 | /lib/
15 | /python/brainvisa/compilation_info.py
16 | /src/library/Doxyfile
17 | /CPackConfig.cmake
18 | /CPackSourceConfig.cmake
19 | CTestTestfile.cmake
20 |
21 | # generated files
22 | /bin/ylAdvectEuclidean
23 | /bin/ylAdvectPath
24 | /bin/ylAdvectTubes
25 | /bin/ylAdvectValues
26 | /bin/ylIsoCurvature
27 | /bin/ylLabelEachVoxel
28 | /bin/ylLaplacian
29 | /bin/ylMakeTraversePseudoAreaMap
30 | /bin/ylMergeCortexColumnRegions
31 | /bin/ylPropagateAlongField
32 | /bin/ylUpwindDistance
33 | /tests/test_env.sh
34 |
35 | # Python
36 | __pycache__/
37 | *.py[cod]
38 |
39 | # pytest
40 | .cache/
41 | .coverage
42 | coverage.xml
43 | python_coverage_html_report/
44 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: meta
3 | hooks:
4 | - id: check-useless-excludes
5 |
6 | - repo: https://github.com/pre-commit/pre-commit-hooks
7 | rev: v4.1.0
8 | hooks:
9 | - id: check-added-large-files
10 | - id: check-case-conflict
11 | - id: check-executables-have-shebangs
12 | - id: check-json
13 | - id: check-merge-conflict
14 | exclude_types: [rst]
15 | - id: check-shebang-scripts-are-executable
16 | exclude: \.in$
17 | - id: check-symlinks
18 | - id: check-xml
19 | files: \.procdoc$
20 | types: [file]
21 | - id: check-yaml
22 | - id: debug-statements
23 | - id: destroyed-symlinks
24 | - id: end-of-file-fixer
25 | - id: fix-byte-order-marker
26 | - id: fix-encoding-pragma
27 | - id: trailing-whitespace
28 |
29 | - repo: https://github.com/pycqa/flake8
30 | rev: 3.9.2
31 | hooks:
32 | - id: flake8
33 | name: flake8 under python3
34 | language_version: python3
35 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright Forschungszentrum Jülich GmbH (2016, 2017, 2018).
2 | # Copyright Télécom ParisTech (2015).
3 | # Copyright CEA (2014).
4 | # Copyright Université Paris XI (2014).
5 | #
6 | # Contributor: Yann Leprince .
7 | #
8 | # Copying and distribution of this file, with or without modification,
9 | # are permitted in any medium without royalty provided the copyright
10 | # notice and this notice are preserved. This file is offered as-is,
11 | # without any warranty.
12 |
13 | cmake_minimum_required(VERSION 3.10)
14 | find_package(brainvisa-cmake REQUIRED)
15 | BRAINVISA_PROJECT(CXX)
16 |
17 | option(BUILD_SHARED_LIBS "Build highres-cortex as a shared library" ON)
18 |
19 | # The AIMS version-file checks for strict equality of major and minor version
20 | # numbers, so requesting version 4.5 explicitly in the find_package command
21 | # will reject versions 4.6 and later, which we do not want.
22 | BRAINVISA_FIND_PACKAGE(aims-free REQUIRED)
23 | if("${aims-free_VERSION}" VERSION_LESS 4.5)
24 | message(FATAL_ERROR "Required dependency aims-free should be at least version 4.5")
25 | endif()
26 | include("${AIMS-FREE_USE_FILE}")
27 | BRAINVISA_DEPENDENCY(DEV DEPENDS aims-free DEV ">= 4.5")
28 | BRAINVISA_DEPENDENCY(RUN DEPENDS aims-free RUN ">= ${aims-free_VERSION}")
29 |
30 | BRAINVISA_DEPENDENCY(RUN DEPENDS "capsul" RUN ">= 2.0")
31 |
32 |
33 | if( NOT Boost_FOUND )
34 | # if Boost has already been detected (from another project within
35 | # brainvisa-cmake), then we must not change Boost_NO_BOOST_CMAKE nor
36 | # Boost_ADDITIONAL_VERSIONS, otherwise it will reset paths already setup
37 | # in the cache (event manually).
38 |
39 | # Do not use BoostConfig.cmake from boost-cmake, because its behaviour may
40 | # be different from regular FindBoost.cmake.
41 | set(Boost_NO_BOOST_CMAKE ON)
42 | # All suitable Boost versions should be included here, if they are not
43 | # already contained in the FindBoost.cmake module provided with CMake.
44 | # Hence, new versions should be added here as they are released...
45 | set(Boost_ADDITIONAL_VERSIONS
46 | "1.75.0" "1.75" "1.74.0" "1.74" "1.73.0" "1.73" "1.72.0" "1.72"
47 | "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69" "1.68.0" "1.68"
48 | "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65"
49 | "1.64.0" "1.64" "1.63.0" "1.63" "1.62.0" "1.62" "1.61.0" "1.61"
50 | "1.60.0" "1.60" "1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57"
51 | "1.56.0" "1.56" "1.55.0" "1.55" "1.54.0" "1.54" "1.53.0" "1.53"
52 | "1.52.0" "1.52" "1.51.0" "1.51" "1.50.0" "1.50" "1.49.0" "1.49")
53 | find_package(Boost 1.49 REQUIRED)
54 | endif()
55 | # The version of Boost is not checked by find_package if it is in the cache.
56 | if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.49)
57 | message(FATAL_ERROR
58 | "Unsuitable Boost version ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}."
59 | "${Boost_SUBMINOR_VERSION} is already in the CMake cache. "
60 | "Please set the BOOST_ROOT variable to a directory containing "
61 | "Boost 1.49 or newer (under BOOST_ROOT/include).")
62 | endif()
63 | BRAINVISA_DEPENDENCY(DEV DEPENDS libboost DEV ">= 1.49")
64 | # No run-time dependency as we use header-only Boost libraries
65 |
66 |
67 | # OpenMP is optional
68 | find_package(OpenMP)
69 | if(OPENMP_FOUND)
70 | BRAINVISA_DEPENDENCY(RUN DEPENDS openmp RUN)
71 | endif()
72 |
73 | find_package(Doxygen)
74 |
75 | find_package(python REQUIRED)
76 | BRAINVISA_DEPENDENCY(DEV DEPENDS python DEV ">= 2.7")
77 | BRAINVISA_DEPENDENCY(RUN RECOMMENDS python RUN ">= 2.7")
78 | # No need for find_package(NumPy) as that is for C headers
79 | BRAINVISA_DEPENDENCY(RUN RECOMMENDS python-numpy RUN)
80 |
81 | # For fix_cortex_topology
82 | BRAINVISA_DEPENDENCY(RUN SUGGESTS morphologist-nonfree RUN ">= 4.5")
83 |
84 |
85 | BRAINVISA_COPY_PYTHON_DIRECTORY("${CMAKE_CURRENT_SOURCE_DIR}/python"
86 | ${PROJECT_NAME})
87 | BRAINVISA_COPY_PYTHON_DIRECTORY("${CMAKE_CURRENT_SOURCE_DIR}/brainvisa"
88 | ${PROJECT_NAME})
89 |
90 | BRAINVISA_COPY_DIRECTORY("${CMAKE_CURRENT_SOURCE_DIR}/bin"
91 | bin
92 | ${PROJECT_NAME})
93 |
94 |
95 | set(REL_SHARE_DIR "share/${PROJECT_NAME}-${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}")
96 |
97 | # FIXME: These scripts are documentation, but tests depend on it. How can I
98 | # make sure that they are installed by both 'install-test' and 'install-doc'?
99 | brainvisa_copy_directory(
100 | "${CMAKE_CURRENT_SOURCE_DIR}/examples"
101 | "${REL_SHARE_DIR}/examples"
102 | ${PROJECT_NAME}-test
103 | )
104 |
105 | # don't warn on obsolete classes within this library: we still provide obsolete
106 | # features so we have to build them without warnings
107 | add_definitions( "-DAIMSDATA_CLASS_NO_DEPREC_WARNING=1" )
108 |
109 | add_subdirectory(src)
110 |
111 | include(CTest)
112 | if(BUILD_TESTING)
113 | add_subdirectory(tests)
114 | endif()
115 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | ================
2 | highres-cortex
3 | ================
4 |
5 | This is a collection of software designed to process 3D images of the cerebral cortex at a sub-millimetre scale, for example high-resolution MRI. In particular, it implements Bok’s equivolumetric depth, which models the depth of cortical layers while compensating for local cortical curvature. If you use this work in an academic publication, **please cite** the relevant references (see also ``_):
6 |
7 | - Yann Leprince, Fabrice Poupon, Thierry Delzescaux, Dominique Hasboun, Cyril Poupon, and Denis Rivière. *Combined Laplacian-equivolumic model for studying cortical lamination with ultra high field MRI (7 T)*. 2015 IEEE 12th International Symposium on Biomedical Imaging (ISBI), IEEE, Apr 2015, New York, United States. pp.580-583, DOI: `10.1109/ISBI.2015.7163940 `_. https://hal-cea.archives-ouvertes.fr/cea-01119475
8 |
9 | - Yann Leprince, Clara Fischer, Jean-François Mangin, Benoît Larrat, Sébastien Mériaux, Cyril Poupon, Isabel Reillo, Victor Borrell, Ophélie Foubet, Roberto Toro, and Denis Rivière. *Architectonics-informed partition of the cortex at sub-millimetre resolution*. 20th Annual Meeting of the Organization for Human Brain Mapping (OHBM), Jun 2014, Hamburg, Germany. 5, pp.951, 2014, F1000Posters. https://hal-cea.archives-ouvertes.fr/cea-01074735
10 |
11 |
12 |
13 | Installation
14 | ============
15 |
16 | highres-cortex is released as part of the official BrainVISA containers since March 2021 (BrainVISA 5.0.0). Please refer to https://brainvisa.info/web/download.html for installation instructions.
17 |
18 |
19 | Graphical user interface
20 | ========================
21 |
22 | highres-cortex is available as a minimalistic BrainVISA toolbox since BrainVISA
23 | 5.1 (January 2023). Simply launch `brainvisa` and refer to the in-program documentation of the toolbox.
24 |
25 |
26 | Command-line usage
27 | ==================
28 |
29 | This package can be used on the command line, here is a short introduction. It is assumed that you are running the Singularity version on a Linux computer, it should work in the same way in the virtual machine (you just need to remove the `bv` prefix from all commands).
30 |
31 | 1. Prepare your input data: the input that is common to to all processes is ``classif``: a voxel-wise tissue classification image in signed 16-bit pixel type, with 0 for exterior voxels (CSF), 100 for cortical gray matter, and 200 for subcortical white matter.
32 |
33 | 2. Run the process that you are interested in. The common interface to all processes is the `Capsul`_ command-line, which you can call with ``bv python -m capsul``. Use ``bv python -m capsul --process-help `` to get help for a specific process. Use ``bv python -m capsul [parameter=value ...]`` to run a process.
34 |
35 | The most important processes are described below:
36 |
37 | - Equivolumetric depth according to Bok’s model can be computed with ``highres_cortex.capsul.isovolume``. The only mandatory input is ``classif``, the output is ``equivolumetric_depth``. You can fine-tune the process with optional parameters, most importantly ``advection_step_size`` can be adapted to the spatial resolution and required accuracy. For example::
38 |
39 | bv python -m capsul highres_cortex.capsul.isovolume classif=classif.nii.gz advection_step_size=0.03 equivolumetric_depth=equivolumetric_depth.nii.gz
40 |
41 | - Cortical thickness, according to the Laplace model, can be calculated with two different methods:
42 |
43 | - The upwinding method is very fast, and already has sub-pixel accurracy: ``highres_cortex.capsul.thickness_upw``. The only mandatory input is ``classif``, the output is ``thickness_image``.
44 |
45 | - The advection method is slower, but ``advection_step_size`` can be tuned for greater accuracy: ``highres_cortex.capsul.thickness_adv``.
46 |
47 | - For parcellating the cortex into volumetric traverses, ``highres_cortex.capsul.traverses`` can be used. The only mandatory input is ``classif``, the output is ``cortical_traverses``. The ``goal_diameter`` parameter controls the target diameter of merged regions (in millimetres). The ``advection_step_size`` parameter is also relevant for this process.
48 |
49 | If you have used highres-cortex before the Capsul interface was introduced (beginning of 2018), you may be using the old shell scripts. See ``_ for equivalent scripts that make use of the Capsul processes.
50 |
51 |
52 | Contributing
53 | ============
54 |
55 | This repository uses `pre-commit`_ to ensure that all committed code follows minimal quality standards. Please install it and configure it to run as a pre-commit hook in your local repository (note that this is done automatically by ``bv_maker``):
56 |
57 | .. code-block:: shell
58 |
59 | # Install pre-commit in a virtual environment
60 | python3 -m venv venv/
61 | . venv/bin/activate
62 | pip install pre-commit
63 |
64 | pre-commit install # install the pre-commit hook
65 |
66 |
67 | Licence
68 | =======
69 |
70 | The source code of this work is placed under the CeCILL licence (see ``_). This library contains code that is under the GNU LGPL licence (see ``_), as a result, compiled code must be redistributed under the GNU General Public Licence (see ``_).
71 |
72 | External code used in this repository
73 | -------------------------------------
74 |
75 | - Code for numerical diagonalization of 3×3 matrices (``_) is Copyright 2006 Joachim Kopp, under the GNU LGPL v2.1 or later. Reference: Kopp, Joachim. ‘Efficient Numerical Diagonalization of Hermitian 3x3 Matrices’. *International Journal of Modern Physics C* 19, no. 03 (March 2008): 523–48. `arXiv:physics/0610206 `_.
76 |
77 |
78 | .. _BrainVISA: https://brainvisa.info/
79 | .. _Capsul: https://brainvisa.info/capsul/
80 | .. _pre-commit: https://pre-commit.com/
81 | .. _BrainVISA download page: https://brainvisa.info/web/download.html
82 |
83 | .. Copyright CEA (2014, 2015, 2021, 2022).
84 | Copyright Forschungszentrum Jülich GmbH (2016, 2017, 2018).
85 | Copyright Télécom ParisTech (2015, 2016).
86 | Copyright Université Paris XI (2014).
87 |
88 | Author: Yann Leprince .
89 |
90 | Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.
91 |
--------------------------------------------------------------------------------
/bin/ylDistmaps:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | from highres_cortex.scripts.distmaps import main
6 |
7 | if __name__ == "__main__":
8 | sys.exit(main())
9 |
--------------------------------------------------------------------------------
/bin/ylFixCortexTopology:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | from highres_cortex.scripts.fix_cortex_topology import main
6 |
7 | if __name__ == "__main__":
8 | sys.exit(main())
9 |
--------------------------------------------------------------------------------
/bin/ylGetExchangedPropvol:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | from highres_cortex.scripts.get_exchanged_propvol import main
6 |
7 | if __name__ == "__main__":
8 | sys.exit(main())
9 |
--------------------------------------------------------------------------------
/bin/ylPostProcessEquivolumetricDepth:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | from highres_cortex.scripts.postprocess_equivolumetric_depth import main
6 |
7 | if __name__ == "__main__":
8 | sys.exit(main())
9 |
--------------------------------------------------------------------------------
/bin/ylRandomizeLabels:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | from highres_cortex.scripts.randomize_labels import main
6 |
7 | if __name__ == "__main__":
8 | sys.exit(main())
9 |
--------------------------------------------------------------------------------
/bin/ylRelabel:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | from highres_cortex.scripts.relabel import main
6 |
7 | if __name__ == "__main__":
8 | sys.exit(main())
9 |
--------------------------------------------------------------------------------
/bin/ylRelabelConjunction:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys
5 | from highres_cortex.scripts.relabel_conjunction import main
6 |
7 | if __name__ == "__main__":
8 | sys.exit(main())
9 |
--------------------------------------------------------------------------------
/brainvisa/toolboxes/highres_cortex/highres_cortex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neurospin/highres-cortex/a2d6a7d2b0b1d07a3a3333d7826a6f607024d5aa/brainvisa/toolboxes/highres_cortex/highres_cortex.png
--------------------------------------------------------------------------------
/brainvisa/toolboxes/highres_cortex/highres_cortex.py:
--------------------------------------------------------------------------------
1 | userName = "highres-cortex"
2 | icon = "highres_cortex.png"
3 | description = "Analysis tools for sub-millimetre MRI of the cerebral cortex"
4 |
--------------------------------------------------------------------------------
/brainvisa/toolboxes/highres_cortex/processes/category_documentation.minf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
highres-cortex toolbox
6 |
7 |
This is a collection of software designed to process 3D images of the cerebral cortex at a sub-millimetre scale, for example high-resolution MRI. In particular, it implements Bok’s equivolumetric depth, which models the depth of cortical layers while compensating for local cortical curvature.
8 |
9 |
Basic usage
10 |
11 |
12 |
Prepare your input data: the input that is common to to all processes is classif: a voxel-wise tissue classification image in signed 16-bit pixel type, with 0 for exterior voxels (CSF), 100 for cortical gray matter, and 200 for subcortical white matter.
13 |
The most important processes are described below:
14 |
15 |
Equivolumetric depth according to Bok’s model can be computed with (highres_cortex.capsul.isovolume).
16 |
Cortical thickness, according to the Laplace model, can be calculated with two different methods:
17 |
18 |
The upwinding method is very fast, and already has sub-pixel accurracy: (highres_cortex.capsul.thickness_upw).
19 |
The advection method is slower, but advection_step_size can be tuned for greater accuracy: (highres_cortex.capsul.thickness_adv).
20 |
21 |
For parcellating the cortex into volumetric traverses, (highres_cortex.capsul.traverses) can be used.
22 |
23 |
24 |
25 |
Technical note
26 |
The BrainVISA processes in highres-cortex are a bit different from other toolboxes, because they are implemented as Capsul processes, which are merely exposed in BrainVISA for convenience, but only support a limited subset of features. For example, they do not support BrainVISA databases, so you should not use the green or red database buttons for choosing files (use the file browser, or directly input the file names instead). Also, running these process always happens in a soma-workflow interface.
27 |
You can call these processes from the command-line with bv python -m capsul; use bv python -m capsul --process-help <process_name> to get help for a specific process. For example:
28 |
Compute Bok’s equivolumetric depth, which models the depth of cortical layers while compensating for local cortical curvature.
6 |
The only mandatory input is classif, the output is equivolumetric_depth. You can fine-tune the process with optional parameters, most importantly advection_step_size can be adapted to the spatial resolution and required accuracy.
7 |
8 |
For a full description of this method, see this poster:
9 |
Yann Leprince, Fabrice Poupon, Thierry Delzescaux, Dominique Hasboun, Cyril Poupon, Denis Rivière. Combined Laplacian-equivolumic model for studying cortical lamination with ultra high field MRI (7 T). 2015 IEEE 12th International Symposium on Biomedical Imaging (ISBI), IEEE, Apr 2015, New York, United States. pp.580-583, DOI: 10.1109/ISBI.2015.7163940. https://hal-cea.archives-ouvertes.fr/cea-01119475
10 |
11 |
12 |
classification image of the cortex (100 inside, 0 in CSF, 200 in white matter)
13 |
14 |
Verbosity level
15 |
16 |
target maximum relative error in first-order finite differences
17 |
18 |
typical thickness of the cortex (mm), used for accelerating convergence
19 |
20 |
X standard deviation of the gaussian filter [default=largest voxel size]
Compute the cortical thickness along Laplace field lines from a classification volume, using Eulerian advection (slightly more precise than upwinding, but much slower)
6 |
7 |
8 |
classification image of the cortex (100 inside, 0 in CSF, 200 in white matter)
9 |
10 |
Verbosity level
11 |
12 |
target maximum relative error in first-order finite differences
13 |
14 |
typical thickness of the cortex (mm), used for accelerating convergence
Compute the cortical thickness along Laplace field lines from a classification volume, using upwinding (much faster than advection, but slightly less precise)
6 |
The only mandatory input is classif, the output is thickness_image.
7 |
8 |
classification image of the cortex (100 inside, 0 in CSF, 200 in white matter)
9 |
10 |
Verbosity level
11 |
12 |
target maximum relative error in first-order finite differences
13 |
14 |
typical thickness of the cortex (mm), used for accelerating convergence
The only mandatory input is classif, the output is cortical_traverses. The goal_diameter parameter controls the target diameter of merged regions (in millimetres). The advection_step_size parameter is also relevant for this process.
8 |
9 |
For a full description of this method, see this poster:
10 |
11 | Yann Leprince, Clara Fischer, Jean-François Mangin, Benoît Larrat, Sébastien Mériaux, Cyril Poupon, Isabel Reillo, Victor Borrell, Ophélie Foubet, Roberto Toro, and Denis Rivière. Architectonics-informed partition of the cortex at sub-millimetre resolution. 20th Annual Meeting of the Organization for Human Brain Mapping (OHBM), Jun 2014, Hamburg, Germany. 5, pp.951, 2014, F1000Posters. https://hal-cea.archives-ouvertes.fr/cea-01074735
12 |
13 |
14 |
classification image of the cortex (100 inside, 0 in CSF, 200 in white matter)
15 |
16 |
Verbosity level
17 |
18 |
target maximum relative error in first-order finite differences
19 |
20 |
typical thickness of the cortex (mm), used for accelerating convergence
21 |
22 |
size of the advection step (millimetres)
23 |
24 |
goal region diameter (millimetres)
25 |
26 |
output label image
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/brainvisa/toolboxes/highres_cortex/processes/traverses.py:
--------------------------------------------------------------------------------
1 | from brainvisa.processes import *
2 | from brainvisa.processing import capsul_process
3 |
4 | name = "Generate cortical traverses"
5 | userLevel = 0
6 |
7 | base_class = capsul_process.CapsulProcess
8 | capsul_process = "highres_cortex.capsul.traverses"
9 |
--------------------------------------------------------------------------------
/doc/.gitignore:
--------------------------------------------------------------------------------
1 | test-references.aux
2 | test-references.bbl
3 | test-references.blg
4 | test-references.fdb_latexmk
5 | test-references.fls
6 | test-references.log
7 | test-references.pdf
8 |
--------------------------------------------------------------------------------
/doc/references.bib:
--------------------------------------------------------------------------------
1 | % -*- mode: bibtex; coding: us-ascii; -*-
2 |
3 | @InProceedings{leprince14_isbi,
4 | author = {Yann Leprince and Fabrice Poupon and Thierry Delzescaux and
5 | Dominique Hasboun and Cyril Poupon and Denis Rivi{\`e}re},
6 | title = {Combined {L}aplacian-equivolumic model for studying cortical
7 | lamination with ultra high field {MRI} (7\,{T})},
8 | year = 2015,
9 | booktitle = {IEEE International Symposium on Biomedical Imaging (ISBI)},
10 | organization = {IEEE},
11 | address = {New York, United States},
12 | month = apr,
13 | url = {https://hal-cea.archives-ouvertes.fr/cea-01119475},
14 | }
15 |
16 | @InProceedings{leprince14_ohbm_poster,
17 | author = {Leprince, Yann and Fischer, Clara and Mangin, Jean-Fran{\c
18 | c}ois and Larrat, Beno{\^i}t and M{\'e}riaux, S{\'e}bastien
19 | and Poupon, Cyril and Reillo, Isabel and Borrell, Victor and
20 | Foubet, Oph{\'e}lie and Toro, Roberto and Rivi{\`e}re, Denis},
21 | title = {Architectonics-informed partition of the cortex at
22 | sub-millimetre resolution},
23 | booktitle = {20th Annual Meeting of the Organization for Human Brain
24 | Mapping (OHBM)},
25 | year = 2014,
26 | month = jun,
27 | address = {Hamburg, Germany},
28 | url = {https://hal-cea.archives-ouvertes.fr/cea-01074735},
29 | note = {hal-cea.archives-ouvertes.fr/cea-01074735},
30 | }
31 |
32 | @PhdThesis{leprince15_phdthesis,
33 | author = {Yann Leprince},
34 | title = {Imagerie des couches corticales par r{\'e}sonance
35 | magn{\'e}tique {\`a} 7~teslas},
36 | school = {Universit{\'e} Paris-Sud},
37 | year = 2015,
38 | url = {http://www.theses.fr/2015PA112022},
39 | month = feb,
40 | }
41 |
42 | @Misc{highres-cortex,
43 | author = {Yann Leprince and others},
44 | title = {{highres-cortex}: analysis tools for high resolution cortical
45 | {MRI}},
46 | url = {https://github.com/neurospin/highres-cortex},
47 | howpublished = {github.com/neurospin/highres-cortex},
48 | year = 2014,
49 | }
50 |
51 | Local Variables:
52 | bibtex-field-delimiters: braces
53 | bibtex-align-at-equal-sign: t
54 | End:
55 |
--------------------------------------------------------------------------------
/doc/test-references.tex:
--------------------------------------------------------------------------------
1 | \documentclass{article}
2 | \begin{document}
3 | \nocite{*}
4 | \bibliographystyle{plain}
5 | \bibliography{references}
6 | \end{document}
7 |
--------------------------------------------------------------------------------
/examples/scripts/column-regions/column-regions.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh -e
2 | #
3 | # Copyright Forschungszentrum Jülich GmbH (2018).
4 | #
5 | # Contributor: Yann Leprince .
6 | #
7 | # Copying and distribution of this file, with or without modification,
8 | # are permitted in any medium without royalty provided the copyright
9 | # notice and this notice are preserved. This file is offered as-is,
10 | # without any warranty.
11 |
12 | python -m capsul highres_cortex.capsul.traverses \
13 | classif=../classif.nii.gz \
14 | goal_traverse_diameter=1.0 \
15 | verbosity=1 \
16 | advection_step_size=0.05 \
17 | cortical_traverses=merged_randomized.nii.gz
18 |
--------------------------------------------------------------------------------
/examples/scripts/dist/distmaps.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh -e
2 | #
3 | # Copyright Forschungszentrum Jülich GmbH (2018).
4 | # Copyright CEA (2014).
5 | # Copyright Université Paris XI (2014).
6 | #
7 | # Contributor: Yann Leprince .
8 | #
9 | # Copying and distribution of this file, with or without modification,
10 | # are permitted in any medium without royalty provided the copyright
11 | # notice and this notice are preserved. This file is offered as-is,
12 | # without any warranty.
13 |
14 | python -m capsul highres_cortex.capsul.processes.Distmaps \
15 | classif=../classif.nii.gz \
16 | distwhite=distwhite.nii.gz \
17 | distCSF=distCSF.nii.gz \
18 | classif_with_outer_boundaries=../classif_with_outer_boundaries.nii.gz
19 |
--------------------------------------------------------------------------------
/examples/scripts/heat/heat.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh -e
2 | #
3 | # Copyright Forschungszentrum Jülich GmbH (2018).
4 | #
5 | # Contributor: Yann Leprince .
6 | #
7 | # Copying and distribution of this file, with or without modification,
8 | # are permitted in any medium without royalty provided the copyright
9 | # notice and this notice are preserved. This file is offered as-is,
10 | # without any warranty.
11 |
12 | python -m capsul highres_cortex.capsul.processes.Laplacian \
13 | classif=../classif.nii.gz \
14 | verbosity=1 \
15 | laplace_field=heat.nii.gz
16 |
--------------------------------------------------------------------------------
/examples/scripts/isovolume/isovolume.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh -e
2 | #
3 | # Copyright Forschungszentrum Jülich GmbH (2018).
4 | #
5 | # Contributor: Yann Leprince .
6 | #
7 | # Copying and distribution of this file, with or without modification,
8 | # are permitted in any medium without royalty provided the copyright
9 | # notice and this notice are preserved. This file is offered as-is,
10 | # without any warranty.
11 |
12 | python -m capsul highres_cortex.capsul.isovolume \
13 | classif=../classif.nii.gz \
14 | verbosity=1 \
15 | advection_step_size=0.05 \
16 | equivolumetric_depth=equivolumic_depth.nii.gz
17 |
--------------------------------------------------------------------------------
/examples/scripts/laplace-euclidean/laplace-euclidean.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh -e
2 | #
3 | # Copyright Forschungszentrum Jülich GmbH (2018).
4 | #
5 | # Contributor: Yann Leprince .
6 | #
7 | # Copying and distribution of this file, with or without modification,
8 | # are permitted in any medium without royalty provided the copyright
9 | # notice and this notice are preserved. This file is offered as-is,
10 | # without any warranty.
11 |
12 | python -m capsul highres_cortex.capsul.thickness_adv \
13 | classif=../classif.nii.gz \
14 | advection_step_size=0.05 \
15 | verbosity=1 \
16 | thickness_image=total-length.nii.gz \
17 | equidistant_depth=pial-fraction.nii.gz
18 |
--------------------------------------------------------------------------------
/examples/scripts/upwind-euclidean/upwind-euclidean.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh -e
2 | #
3 | # Copyright Forschungszentrum Jülich GmbH (2018).
4 | #
5 | # Contributor: Yann Leprince .
6 | #
7 | # Copying and distribution of this file, with or without modification,
8 | # are permitted in any medium without royalty provided the copyright
9 | # notice and this notice are preserved. This file is offered as-is,
10 | # without any warranty.
11 |
12 | python -m capsul highres_cortex.capsul.thickness_upw \
13 | classif=../classif.nii.gz \
14 | verbosity=1 \
15 | thickness_image=total-length.nii.gz \
16 | equidistant_depth=pial-fraction.nii.gz
17 |
--------------------------------------------------------------------------------
/project_info.cmake:
--------------------------------------------------------------------------------
1 | # Copyright CEA (2014).
2 | # Copyright Université Paris XI (2014).
3 | #
4 | # Contributor: Yann Leprince .
5 | #
6 | # Copying and distribution of this file, with or without modification,
7 | # are permitted in any medium without royalty provided the copyright
8 | # notice and this notice are preserved. This file is offered as-is,
9 | # without any warranty.
10 |
11 | set( BRAINVISA_PACKAGE_NAME highres-cortex )
12 | set( BRAINVISA_PACKAGE_MAIN_PROJECT highres-cortex )
13 | set( BRAINVISA_PACKAGE_LICENCES "CeCILL-v2.1" )
14 | set( BRAINVISA_PACKAGE_MAINTAINER "CEA - Yann Leprince" )
15 | set( BRAINVISA_PACKAGE_VERSION_MAJOR 5 )
16 | set( BRAINVISA_PACKAGE_VERSION_MINOR 2 )
17 | set( BRAINVISA_PACKAGE_VERSION_PATCH 0 )
18 |
--------------------------------------------------------------------------------
/python/highres_cortex/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Copyright CEA (2014).
3 | # Copyright Université Paris XI (2014).
4 | #
5 | # Contributor: Yann Leprince .
6 | #
7 | # This file is part of highres-cortex, a collection of software designed
8 | # to process high-resolution magnetic resonance images of the cerebral
9 | # cortex.
10 | #
11 | # This software is governed by the CeCILL licence under French law and
12 | # abiding by the rules of distribution of free software. You can use,
13 | # modify and/or redistribute the software under the terms of the CeCILL
14 | # licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | # .
16 | #
17 | # As a counterpart to the access to the source code and rights to copy,
18 | # modify and redistribute granted by the licence, users are provided only
19 | # with a limited warranty and the software's author, the holder of the
20 | # economic rights, and the successive licensors have only limited
21 | # liability.
22 | #
23 | # In this respect, the user's attention is drawn to the risks associated
24 | # with loading, using, modifying and/or developing or reproducing the
25 | # software by the user in light of its specific status of scientific
26 | # software, that may mean that it is complicated to manipulate, and that
27 | # also therefore means that it is reserved for developers and experienced
28 | # professionals having in-depth computer knowledge. Users are therefore
29 | # encouraged to load and test the software's suitability as regards their
30 | # requirements in conditions enabling the security of their systems and/or
31 | # data to be ensured and, more generally, to use and operate it in the
32 | # same conditions as regards security.
33 | #
34 | # The fact that you are presently reading this means that you have had
35 | # knowledge of the CeCILL licence and that you accept its terms.
36 |
37 | """Tools to process high-resolution images of the cerebral cortex."""
38 |
--------------------------------------------------------------------------------
/python/highres_cortex/capsul/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neurospin/highres-cortex/a2d6a7d2b0b1d07a3a3333d7826a6f607024d5aa/python/highres_cortex/capsul/__init__.py
--------------------------------------------------------------------------------
/python/highres_cortex/capsul/filtered_sumcurvs.xml:
--------------------------------------------------------------------------------
1 |
37 |
38 |
39 | Compute the filtered sum of principal curvatures of isophote surfaces
40 |
41 | This is equivalent to computing the divergence of the normalized gradient
42 | of the input scalar field.
43 |
44 | .. note::
45 |
46 | A Gaussian smoothing of width sigma is first applied to the input
47 | image, in order to limit the appearance of local high curvature values
48 | (e.g. due to the discontinuity of second-order derivative at the
49 | borders of the cortex).
50 |
51 |
53 |
54 |
55 |
56 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/python/highres_cortex/capsul/isovolume.xml:
--------------------------------------------------------------------------------
1 |
38 |
39 |
40 | Compute equivolumetric depth
41 |
42 |
44 |
46 |
47 |
49 |
51 |
52 |
53 |
54 |
56 |
57 |
58 |
59 |
60 |
61 |
63 |
64 |
65 |
67 |
68 |
69 |
71 |
72 |
73 |
74 |
75 |
76 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
93 |
94 |
95 |
96 |
98 |
99 |
100 |
101 |
103 |
104 |
106 |
108 |
109 |
111 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/python/highres_cortex/capsul/thickness_adv.xml:
--------------------------------------------------------------------------------
1 |
38 |
39 |
40 | Compute the cortical thickness along Laplace field lines from a classification volume, using Eulerian advection (slightly more precise than upwinding, but much slower)
41 |
42 |
44 |
46 |
48 |
49 |
50 |
51 |
53 |
54 |
55 |
56 |
58 |
59 |
60 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
87 |
89 |
90 |
92 |
94 |
95 |
96 |
97 |
98 |
99 |
101 |
103 |
104 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/python/highres_cortex/capsul/thickness_upw.xml:
--------------------------------------------------------------------------------
1 |
39 |
40 |
41 | Compute the cortical thickness along Laplace field lines from a classification volume, using upwinding (much faster than advection, but slightly less precise)
42 |
43 |
45 |
47 |
48 |
49 |
50 |
51 |
53 |
54 |
55 |
56 |
57 |
59 |
60 |
61 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
82 |
84 |
85 |
87 |
89 |
90 |
91 |
92 |
93 |
94 |
96 |
98 |
99 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/python/highres_cortex/scripts/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neurospin/highres-cortex/a2d6a7d2b0b1d07a3a3333d7826a6f607024d5aa/python/highres_cortex/scripts/__init__.py
--------------------------------------------------------------------------------
/python/highres_cortex/scripts/distmaps.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright Forschungszentrum Jülich GmbH (2018).
5 | # Copyright CEA (2014).
6 | # Copyright Université Paris XI (2014).
7 | #
8 | # Contributor: Yann Leprince .
9 | #
10 | # This file is part of highres-cortex, a collection of software designed
11 | # to process high-resolution magnetic resonance images of the cerebral
12 | # cortex.
13 | #
14 | # This software is governed by the CeCILL licence under French law and
15 | # abiding by the rules of distribution of free software. You can use,
16 | # modify and/or redistribute the software under the terms of the CeCILL
17 | # licence as circulated by CEA, CNRS and INRIA at the following URL:
18 | # .
19 | #
20 | # As a counterpart to the access to the source code and rights to copy,
21 | # modify and redistribute granted by the licence, users are provided only
22 | # with a limited warranty and the software's author, the holder of the
23 | # economic rights, and the successive licensors have only limited
24 | # liability.
25 | #
26 | # In this respect, the user's attention is drawn to the risks associated
27 | # with loading, using, modifying and/or developing or reproducing the
28 | # software by the user in light of its specific status of scientific
29 | # software, that may mean that it is complicated to manipulate, and that
30 | # also therefore means that it is reserved for developers and experienced
31 | # professionals having in-depth computer knowledge. Users are therefore
32 | # encouraged to load and test the software's suitability as regards their
33 | # requirements in conditions enabling the security of their systems and/or
34 | # data to be ensured and, more generally, to use and operate it in the
35 | # same conditions as regards security.
36 | #
37 | # The fact that you are presently reading this means that you have had
38 | # knowledge of the CeCILL licence and that you accept its terms.
39 |
40 | from __future__ import absolute_import, division, print_function
41 |
42 | import sys
43 |
44 | from soma import aims
45 |
46 | import highres_cortex.cortex_topo
47 |
48 |
49 | def compute_distmaps_files(classif_filename, output_distwhite_filename,
50 | output_distCSF_filename, output_classif_filename):
51 | classif = aims.read(classif_filename)
52 |
53 | dist_from_white = highres_cortex.cortex_topo.signed_distance(
54 | classif, [100], [200], 150)
55 | aims.write(dist_from_white, output_distwhite_filename)
56 |
57 | dist_from_CSF = highres_cortex.cortex_topo.signed_distance(
58 | classif, [100], [0], 50)
59 | aims.write(dist_from_CSF, output_distCSF_filename)
60 |
61 | aims.write(classif, output_classif_filename)
62 |
63 |
64 | def parse_command_line(argv=sys.argv):
65 | """Parse the script's command line."""
66 | import argparse
67 | parser = argparse.ArgumentParser(
68 | description="""\
69 | Compute the signed distance to white matter and to CSF
70 | """)
71 | parser.add_argument("classif", help="classification image of the cortex "
72 | "(100 inside, 0 in CSF, 200 in white matter)")
73 | parser.add_argument("output_distwhite", help="signed Euclidean distance "
74 | "to the white matter boundary")
75 | parser.add_argument("output_distCSF", help="signed Euclidean distance "
76 | "to the CSF boundary")
77 | parser.add_argument("output_classif_with_boundaries",
78 | help="classification image of the cortex (100 inside, "
79 | "0 in CSF, 200 in white matter, 50 on the CSF "
80 | "boundary, 150 on the white matter boundary)")
81 |
82 | args = parser.parse_args(argv[1:])
83 | return args
84 |
85 |
86 | def main(argv=sys.argv):
87 | """The script's entry point."""
88 | args = parse_command_line(argv)
89 | return compute_distmaps_files(
90 | args.classif,
91 | args.output_distwhite,
92 | args.output_distCSF,
93 | args.output_classif_with_boundaries) or 0
94 |
95 |
96 | if __name__ == "__main__":
97 | sys.exit(main())
98 |
--------------------------------------------------------------------------------
/python/highres_cortex/scripts/fix_cortex_topology.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright Télécom ParisTech (2015).
5 | #
6 | # Contributor: Yann Leprince .
7 | #
8 | # This file is part of highres-cortex, a collection of software designed
9 | # to process high-resolution magnetic resonance images of the cerebral
10 | # cortex.
11 | #
12 | # This software is governed by the CeCILL licence under French law and
13 | # abiding by the rules of distribution of free software. You can use,
14 | # modify and/or redistribute the software under the terms of the CeCILL
15 | # licence as circulated by CEA, CNRS and INRIA at the following URL:
16 | # .
17 | #
18 | # As a counterpart to the access to the source code and rights to copy,
19 | # modify and redistribute granted by the licence, users are provided only
20 | # with a limited warranty and the software's author, the holder of the
21 | # economic rights, and the successive licensors have only limited
22 | # liability.
23 | #
24 | # In this respect, the user's attention is drawn to the risks associated
25 | # with loading, using, modifying and/or developing or reproducing the
26 | # software by the user in light of its specific status of scientific
27 | # software, that may mean that it is complicated to manipulate, and that
28 | # also therefore means that it is reserved for developers and experienced
29 | # professionals having in-depth computer knowledge. Users are therefore
30 | # encouraged to load and test the software's suitability as regards their
31 | # requirements in conditions enabling the security of their systems and/or
32 | # data to be ensured and, more generally, to use and operate it in the
33 | # same conditions as regards security.
34 | #
35 | # The fact that you are presently reading this means that you have had
36 | # knowledge of the CeCILL licence and that you accept its terms.
37 |
38 | from __future__ import absolute_import, division, print_function
39 |
40 | import argparse
41 | import sys
42 |
43 | import soma.subprocess as subprocess
44 | from soma import aims
45 |
46 | import highres_cortex.cortex_topo
47 |
48 |
49 | def fix_cortex_topology_files(input_filename, output_filename,
50 | filling_size, fclosing):
51 | """Call highres_cortex.cortex_topo.fix_cortex_topology on files."""
52 | input_volume = aims.read(input_filename)
53 |
54 | try:
55 | output = highres_cortex.cortex_topo.fix_cortex_topology(
56 | input_volume, filling_size, fclosing)
57 | except OSError as exc:
58 | print("error: the VipHomotopic command cannot be"
59 | " found or executed ({0}). Please make sure that"
60 | " Morphologist is properly installed and that the"
61 | " command is in your PATH.".format(exc.strerror))
62 | return 1
63 | except subprocess.CalledProcessError as exc:
64 | print("error: the VipHomotopic command returned an error code ({0})."
65 | " Please inspect its output above for more information."
66 | .format(exc.returncode))
67 | return 1
68 |
69 | # BUG: aims.write offers no error checking, so the program will exit
70 | # successfully even if writing fails
71 | aims.write(output, output_filename)
72 |
73 |
74 | def parse_command_line(argv=sys.argv):
75 | """Parse the script's command line."""
76 | parser = argparse.ArgumentParser(
77 | description="""\
78 | Impose the topology of a hollow sphere onto the cortex in a voxelwise
79 | segmentation, which uses the following labels: 100 in the cortex itself, 0
80 | outside (CSF), 200 inside (white matter). In the output, the cortex is defined
81 | using 6-connectivity, each other compartment using 26-connectivity.
82 | """)
83 | parser.add_argument("input",
84 | help="3D volume containing the input segmentation")
85 | parser.add_argument("output",
86 | help="output 3D volume")
87 | parser.add_argument("--filling-size", type=float, default=2.,
88 | help="""\
89 | The size, in millimetres, of the largest holes in either cortical boundary that
90 | will be filled. This must be smaller than the thinnest cortex in the image. The
91 | default value is 2 mm, which is appropriate for a human brain.""")
92 | parser.add_argument("--fclosing", type=float, default=10.,
93 | help="""\
94 | The radius of the morphological closing which is used by VipHomotopic in
95 | Cortical surface mode to retrieve the brain's outer envelope. The default
96 | value, 10 mm, is appropriate for a human brain.""")
97 |
98 | args = parser.parse_args(argv[1:])
99 | if not args.filling_size >= 0:
100 | parser.error("filling_size must be a non-negative number")
101 | if not args.fclosing >= 0:
102 | parser.error("fclosing must be a non-negative number")
103 | return args
104 |
105 |
106 | def main(argv=sys.argv):
107 | """The script's entry point."""
108 | args = parse_command_line(argv)
109 | return fix_cortex_topology_files(
110 | args.input, args.output, args.filling_size, args.fclosing) or 0
111 |
112 |
113 | if __name__ == "__main__":
114 | sys.exit(main())
115 |
--------------------------------------------------------------------------------
/python/highres_cortex/scripts/get_exchanged_propvol.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright Forschungszentrum Jülich GmbH (2018).
5 | # Copyright CEA (2014).
6 | # Copyright Université Paris XI (2014).
7 | #
8 | # Contributor: Yann Leprince .
9 | #
10 | # This file is part of highres-cortex, a collection of software designed
11 | # to process high-resolution magnetic resonance images of the cerebral
12 | # cortex.
13 | #
14 | # This software is governed by the CeCILL licence under French law and
15 | # abiding by the rules of distribution of free software. You can use,
16 | # modify and/or redistribute the software under the terms of the CeCILL
17 | # licence as circulated by CEA, CNRS and INRIA at the following URL:
18 | # .
19 | #
20 | # As a counterpart to the access to the source code and rights to copy,
21 | # modify and redistribute granted by the licence, users are provided only
22 | # with a limited warranty and the software's author, the holder of the
23 | # economic rights, and the successive licensors have only limited
24 | # liability.
25 | #
26 | # In this respect, the user's attention is drawn to the risks associated
27 | # with loading, using, modifying and/or developing or reproducing the
28 | # software by the user in light of its specific status of scientific
29 | # software, that may mean that it is complicated to manipulate, and that
30 | # also therefore means that it is reserved for developers and experienced
31 | # professionals having in-depth computer knowledge. Users are therefore
32 | # encouraged to load and test the software's suitability as regards their
33 | # requirements in conditions enabling the security of their systems and/or
34 | # data to be ensured and, more generally, to use and operate it in the
35 | # same conditions as regards security.
36 | #
37 | # The fact that you are presently reading this means that you have had
38 | # knowledge of the CeCILL licence and that you accept its terms.
39 |
40 | from __future__ import absolute_import, division, print_function
41 |
42 | import os.path
43 | import shutil
44 | import sys
45 | import tempfile
46 | import six
47 |
48 | import numpy as np
49 | import soma.subprocess as subprocess
50 | from soma import aims
51 |
52 |
53 | def relabel_positive_labels(volume):
54 | size_x = volume.getSizeX()
55 | size_y = volume.getSizeY()
56 | size_z = volume.getSizeZ()
57 | old_to_new_labels = {}
58 | next_label = 1
59 | for z in six.moves.xrange(size_z):
60 | for y in six.moves.xrange(size_y):
61 | for x in six.moves.xrange(size_x):
62 | old_label = volume.at(x, y, z)
63 | if old_label > 0:
64 | try:
65 | new_label = old_to_new_labels[old_label]
66 | except KeyError:
67 | new_label = next_label
68 | old_to_new_labels[old_label] = new_label
69 | next_label += 1
70 | volume.setValue(new_label, x, y, z)
71 |
72 |
73 | def get_exchanged_propvol_files(classif_filename,
74 | CSF_labels_on_white_filename,
75 | white_labels_on_CSF_filename,
76 | output_filename):
77 | classif = aims.read(classif_filename)
78 | CSF_labels_on_white = aims.read(CSF_labels_on_white_filename)
79 | white_labels_on_CSF = aims.read(white_labels_on_CSF_filename)
80 | output = aims.Volume(CSF_labels_on_white)
81 |
82 | np_CSF_labels_on_white = np.asarray(CSF_labels_on_white)
83 | np_white_labels_on_CSF = np.asarray(white_labels_on_CSF)
84 | np_classif = np.asarray(classif)
85 | np_output = np.asarray(output)
86 |
87 | white_mask = (np_classif == 150)
88 | CSF_mask = (np_classif == 50)
89 |
90 | np_output[white_mask] = np_CSF_labels_on_white[white_mask]
91 | np_output[CSF_mask] = np_white_labels_on_CSF[CSF_mask]
92 |
93 | temp_dir = None
94 | try:
95 | temp_dir = tempfile.mkdtemp(prefix="hcortex")
96 | temp_filename = os.path.join(temp_dir, 'raw_exchanged_labels.nii')
97 | aims.write(output, temp_filename)
98 |
99 | # These “failed components” will probably be separated by connexity
100 | # AimsReplaceLevel -i raw_exchanged_labels.nii.gz \
101 | # -o exchanged_labels.nii.gz \
102 | # -g 100000000 -n 0 -g 200000000 -n 0
103 |
104 | subprocess.check_call(["AimsConnectComp",
105 | "-i", "raw_exchanged_labels.nii",
106 | "-o", "connected_exchanged_labels.nii"],
107 | cwd=temp_dir)
108 |
109 | # The background is cut in one big region + many small, restore it then
110 | # relabel
111 | propvol = aims.read(
112 | os.path.join(temp_dir, "connected_exchanged_labels.nii"))
113 | finally:
114 | if temp_dir:
115 | shutil.rmtree(temp_dir)
116 | np_propvol = np.asarray(propvol)
117 | exclusion_mask = (np_CSF_labels_on_white == -1)
118 | bulk_mask = (np_CSF_labels_on_white == 0)
119 | np_propvol[bulk_mask] = 0
120 | np_propvol[exclusion_mask] = -1
121 |
122 | relabel_positive_labels(propvol)
123 | aims.write(propvol, output_filename)
124 |
125 |
126 | def parse_command_line(argv=sys.argv):
127 | """Parse the script's command line."""
128 | import argparse
129 | parser = argparse.ArgumentParser(
130 | description="""\
131 | Get exchanged propagation volume
132 | """)
133 | parser.add_argument("classif_with_outer_boundaries", help="classification "
134 | "image of the cortex (100 inside, 0 in CSF, 200 in "
135 | "white matter, 50 on the CSF border, 150 on the white "
136 | "matter border)")
137 | parser.add_argument("CSF_labels_on_white", help="labels of the CSF "
138 | "projected onto the white matter boundary")
139 | parser.add_argument("white_labels_on_CSF", help="labels of the white "
140 | "matter projected onto the CSF boundary")
141 | parser.add_argument("output", help="volume where each interface is "
142 | "labelled with connected components facing the same "
143 | "voxels of the other interface")
144 |
145 | args = parser.parse_args(argv[1:])
146 | return args
147 |
148 |
149 | def main(argv=sys.argv):
150 | """The script's entry point."""
151 | args = parse_command_line(argv)
152 | return get_exchanged_propvol_files(
153 | args.classif_with_outer_boundaries,
154 | args.CSF_labels_on_white,
155 | args.white_labels_on_CSF,
156 | args.output) or 0
157 |
158 |
159 | if __name__ == "__main__":
160 | sys.exit(main())
161 |
--------------------------------------------------------------------------------
/python/highres_cortex/scripts/postprocess_equivolumetric_depth.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright CEA (2019).
5 | #
6 | # Contributor: Yann Leprince .
7 | #
8 | # This file is part of highres-cortex, a collection of software designed
9 | # to process high-resolution magnetic resonance images of the cerebral
10 | # cortex.
11 | #
12 | # This software is governed by the CeCILL licence under French law and
13 | # abiding by the rules of distribution of free software. You can use,
14 | # modify and/or redistribute the software under the terms of the CeCILL
15 | # licence as circulated by CEA, CNRS and INRIA at the following URL:
16 | # .
17 | #
18 | # As a counterpart to the access to the source code and rights to copy,
19 | # modify and redistribute granted by the licence, users are provided only
20 | # with a limited warranty and the software's author, the holder of the
21 | # economic rights, and the successive licensors have only limited
22 | # liability.
23 | #
24 | # In this respect, the user's attention is drawn to the risks associated
25 | # with loading, using, modifying and/or developing or reproducing the
26 | # software by the user in light of its specific status of scientific
27 | # software, that may mean that it is complicated to manipulate, and that
28 | # also therefore means that it is reserved for developers and experienced
29 | # professionals having in-depth computer knowledge. Users are therefore
30 | # encouraged to load and test the software's suitability as regards their
31 | # requirements in conditions enabling the security of their systems and/or
32 | # data to be ensured and, more generally, to use and operate it in the
33 | # same conditions as regards security.
34 | #
35 | # The fact that you are presently reading this means that you have had
36 | # knowledge of the CeCILL licence and that you accept its terms.
37 |
38 | from __future__ import absolute_import, division, print_function
39 |
40 | import sys
41 |
42 | import numpy as np
43 | from soma import aims
44 |
45 | from highres_cortex.cortex_topo import CSF_LABEL, WHITE_LABEL
46 |
47 |
48 | def postprocess_equivolumetric_depth(input_filename, classif_filename,
49 | output_filename):
50 | depth_vol = aims.read(input_filename)
51 | classif_vol = aims.read(classif_filename)
52 |
53 | depth_arr = np.asarray(depth_vol)
54 | classif_arr = np.asarray(classif_vol)
55 |
56 | depth_arr[classif_arr == CSF_LABEL] = 0.0
57 | depth_arr[classif_arr == WHITE_LABEL] = 1.0
58 |
59 | header = depth_vol.header()
60 | header['cal_min'] = 0.0
61 | header['cal_max'] = 1.0
62 | header['intent_code'] = 1001 # NIFTI_INTENT_ESTIMATE
63 | header['intent_name'] = 'Equivol. depth'
64 | header['descrip'] = (
65 | 'Equivolumetric cortical depth computed with highres-cortex'
66 | )
67 |
68 | aims.write(depth_vol, output_filename)
69 |
70 |
71 | def parse_command_line(argv=sys.argv):
72 | """Parse the script's command line."""
73 | import argparse
74 | parser = argparse.ArgumentParser(
75 | description="""\
76 | Post-process an equivolumetric depth image.
77 |
78 | - Set the outside of the brain (CSF) to 0.0
79 | - Set the white matter to 1.0
80 | - Set various Nifti header fields
81 | """)
82 | parser.add_argument("input_image",
83 | help="input image of equivolumetric depth")
84 | parser.add_argument("classif", help="classification image of the cortex "
85 | "(100 inside, 0 in CSF, 200 in white matter)")
86 | parser.add_argument("output_image")
87 |
88 | args = parser.parse_args(argv[1:])
89 | return args
90 |
91 |
92 | def main(argv=sys.argv):
93 | """The script's entry point."""
94 | args = parse_command_line(argv)
95 | return postprocess_equivolumetric_depth(
96 | args.input_image,
97 | args.classif,
98 | args.output_image) or 0
99 |
100 |
101 | if __name__ == "__main__":
102 | sys.exit(main())
103 |
--------------------------------------------------------------------------------
/python/highres_cortex/scripts/randomize_labels.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright Forschungszentrum Jülich GmbH (2018).
5 | # Copyright CEA (2014).
6 | # Copyright Université Paris XI (2014).
7 | #
8 | # Contributor: Yann Leprince .
9 | #
10 | # This file is part of highres-cortex, a collection of software designed
11 | # to process high-resolution magnetic resonance images of the cerebral
12 | # cortex.
13 | #
14 | # This software is governed by the CeCILL licence under French law and
15 | # abiding by the rules of distribution of free software. You can use,
16 | # modify and/or redistribute the software under the terms of the CeCILL
17 | # licence as circulated by CEA, CNRS and INRIA at the following URL:
18 | # .
19 | #
20 | # As a counterpart to the access to the source code and rights to copy,
21 | # modify and redistribute granted by the licence, users are provided only
22 | # with a limited warranty and the software's author, the holder of the
23 | # economic rights, and the successive licensors have only limited
24 | # liability.
25 | #
26 | # In this respect, the user's attention is drawn to the risks associated
27 | # with loading, using, modifying and/or developing or reproducing the
28 | # software by the user in light of its specific status of scientific
29 | # software, that may mean that it is complicated to manipulate, and that
30 | # also therefore means that it is reserved for developers and experienced
31 | # professionals having in-depth computer knowledge. Users are therefore
32 | # encouraged to load and test the software's suitability as regards their
33 | # requirements in conditions enabling the security of their systems and/or
34 | # data to be ensured and, more generally, to use and operate it in the
35 | # same conditions as regards security.
36 | #
37 | # The fact that you are presently reading this means that you have had
38 | # knowledge of the CeCILL licence and that you accept its terms.
39 |
40 | from __future__ import absolute_import, division, print_function
41 |
42 | import random
43 | import sys
44 |
45 | from six.moves import range
46 |
47 | from soma import aims
48 |
49 |
50 | def randomize_labels(labels):
51 | import numpy as np
52 | np_input_labels = np.asarray(labels)
53 | max_label = np.max(np_input_labels)
54 | nonzero_labels = list(range(1, max_label + 1))
55 | random.shuffle(nonzero_labels)
56 | new_labels = [0] + nonzero_labels
57 |
58 | output = aims.Volume(labels)
59 | size_x = output.getSizeX()
60 | size_y = output.getSizeY()
61 | size_z = output.getSizeZ()
62 | for z in range(size_z):
63 | for y in range(size_y):
64 | for x in range(size_x):
65 | old_label = labels.at(x, y, z)
66 | if old_label >= 0:
67 | new_label = new_labels[old_label]
68 | else:
69 | new_label = 0
70 | output.setValue(new_label, x, y, z)
71 | return output
72 |
73 |
74 | def randomize_labels_files(input_filename, output_filename):
75 | input_vol = aims.read(input_filename)
76 | output_vol = randomize_labels(input_vol)
77 | aims.write(output_vol, output_filename)
78 |
79 |
80 | def parse_command_line(argv=sys.argv):
81 | """Parse the script's command line."""
82 | import argparse
83 | parser = argparse.ArgumentParser(
84 | description="""\
85 | Randomize the labels of an image with consecutive labels
86 | """)
87 | parser.add_argument("input", help="input label image")
88 | parser.add_argument("output", help="output label image")
89 |
90 | args = parser.parse_args(argv[1:])
91 | return args
92 |
93 |
94 | def main(argv=sys.argv):
95 | """The script's entry point."""
96 | args = parse_command_line(argv)
97 | return randomize_labels_files(
98 | args.input,
99 | args.output) or 0
100 |
101 |
102 | if __name__ == "__main__":
103 | sys.exit(main())
104 |
--------------------------------------------------------------------------------
/python/highres_cortex/scripts/relabel.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright Forschungszentrum Jülich GmbH (2018).
5 | # Copyright CEA (2014).
6 | # Copyright Université Paris XI (2014).
7 | #
8 | # Contributor: Yann Leprince .
9 | #
10 | # This file is part of highres-cortex, a collection of software designed
11 | # to process high-resolution magnetic resonance images of the cerebral
12 | # cortex.
13 | #
14 | # This software is governed by the CeCILL licence under French law and
15 | # abiding by the rules of distribution of free software. You can use,
16 | # modify and/or redistribute the software under the terms of the CeCILL
17 | # licence as circulated by CEA, CNRS and INRIA at the following URL:
18 | # .
19 | #
20 | # As a counterpart to the access to the source code and rights to copy,
21 | # modify and redistribute granted by the licence, users are provided only
22 | # with a limited warranty and the software's author, the holder of the
23 | # economic rights, and the successive licensors have only limited
24 | # liability.
25 | #
26 | # In this respect, the user's attention is drawn to the risks associated
27 | # with loading, using, modifying and/or developing or reproducing the
28 | # software by the user in light of its specific status of scientific
29 | # software, that may mean that it is complicated to manipulate, and that
30 | # also therefore means that it is reserved for developers and experienced
31 | # professionals having in-depth computer knowledge. Users are therefore
32 | # encouraged to load and test the software's suitability as regards their
33 | # requirements in conditions enabling the security of their systems and/or
34 | # data to be ensured and, more generally, to use and operate it in the
35 | # same conditions as regards security.
36 | #
37 | # The fact that you are presently reading this means that you have had
38 | # knowledge of the CeCILL licence and that you accept its terms.
39 |
40 | from __future__ import absolute_import, division, print_function
41 |
42 | import sys
43 |
44 | from soma import aims
45 |
46 | from six.moves import range
47 |
48 |
49 | def relabel(labels):
50 | output = aims.Volume(labels)
51 | size_x = output.getSizeX()
52 | size_y = output.getSizeY()
53 | size_z = output.getSizeZ()
54 | old_to_new_labels = {}
55 | next_label = 1
56 | for z in range(size_z):
57 | for y in range(size_y):
58 | for x in range(size_x):
59 | label = labels.at(x, y, z)
60 | if label == 0:
61 | new_label = 0
62 | else:
63 | try:
64 | new_label = old_to_new_labels[label]
65 | except KeyError:
66 | new_label = next_label
67 | old_to_new_labels[label] = new_label
68 | next_label += 1
69 | output.setValue(new_label, x, y, z)
70 | return output
71 |
72 |
73 | def relabel_files(input_filename, output_filename):
74 | input_vol = aims.read(input_filename)
75 | output_vol = relabel(input_vol)
76 | aims.write(output_vol, output_filename)
77 |
78 |
79 | def parse_command_line(argv=sys.argv):
80 | """Parse the script's command line."""
81 | import argparse
82 | parser = argparse.ArgumentParser(
83 | description="""\
84 | Assign new consecutive labels to an existing label image
85 | """)
86 | parser.add_argument("input", help="input label image")
87 | parser.add_argument("output", help="output label image")
88 |
89 | args = parser.parse_args(argv[1:])
90 | return args
91 |
92 |
93 | def main(argv=sys.argv):
94 | """The script's entry point."""
95 | args = parse_command_line(argv)
96 | return relabel_files(
97 | args.input,
98 | args.output) or 0
99 |
100 |
101 | if __name__ == "__main__":
102 | sys.exit(main())
103 |
--------------------------------------------------------------------------------
/python/highres_cortex/scripts/relabel_conjunction.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright Forschungszentrum Jülich GmbH (2018).
5 | # Copyright CEA (2014).
6 | # Copyright Université Paris XI (2014).
7 | #
8 | # Contributor: Yann Leprince .
9 | #
10 | # This file is part of highres-cortex, a collection of software designed
11 | # to process high-resolution magnetic resonance images of the cerebral
12 | # cortex.
13 | #
14 | # This software is governed by the CeCILL licence under French law and
15 | # abiding by the rules of distribution of free software. You can use,
16 | # modify and/or redistribute the software under the terms of the CeCILL
17 | # licence as circulated by CEA, CNRS and INRIA at the following URL:
18 | # .
19 | #
20 | # As a counterpart to the access to the source code and rights to copy,
21 | # modify and redistribute granted by the licence, users are provided only
22 | # with a limited warranty and the software's author, the holder of the
23 | # economic rights, and the successive licensors have only limited
24 | # liability.
25 | #
26 | # In this respect, the user's attention is drawn to the risks associated
27 | # with loading, using, modifying and/or developing or reproducing the
28 | # software by the user in light of its specific status of scientific
29 | # software, that may mean that it is complicated to manipulate, and that
30 | # also therefore means that it is reserved for developers and experienced
31 | # professionals having in-depth computer knowledge. Users are therefore
32 | # encouraged to load and test the software's suitability as regards their
33 | # requirements in conditions enabling the security of their systems and/or
34 | # data to be ensured and, more generally, to use and operate it in the
35 | # same conditions as regards security.
36 | #
37 | # The fact that you are presently reading this means that you have had
38 | # knowledge of the CeCILL licence and that you accept its terms.
39 |
40 | from __future__ import absolute_import, division, print_function
41 |
42 | import sys
43 |
44 | from six.moves import range
45 |
46 | from soma import aims
47 |
48 |
49 | def relabel_conjunction(labels1, labels2):
50 | output = aims.Volume(labels1)
51 | output.fill(0)
52 | size_x = output.getSizeX()
53 | size_y = output.getSizeY()
54 | size_z = output.getSizeZ()
55 | old_to_new_labels = {}
56 | next_label = 1
57 | for z in range(size_z):
58 | for y in range(size_y):
59 | for x in range(size_x):
60 | labels = (labels1.at(x, y, z), labels2.at(x, y, z))
61 | # Negative means outside propagation region
62 | if labels[0] < 0 or labels[1] < 0:
63 | continue
64 | # Zeros are failed propagations, they should not be aggregated
65 | # together
66 | if labels[0] == 0 or labels[1] == 0:
67 | new_label = next_label
68 | next_label += 1
69 | else:
70 | try:
71 | new_label = old_to_new_labels[labels]
72 | except KeyError:
73 | new_label = next_label
74 | old_to_new_labels[labels] = new_label
75 | next_label += 1
76 | output.setValue(new_label, x, y, z)
77 | sys.stderr.write("{0}: {1} regions in conjunction\n"
78 | .format(sys.argv[0], next_label - 1))
79 | return output
80 |
81 |
82 | def relabel_conjunction_files(labels1_filename, labels2_filename,
83 | output_filename):
84 | labels1_vol = aims.read(labels1_filename)
85 | labels2_vol = aims.read(labels2_filename)
86 | output_vol = relabel_conjunction(labels1_vol, labels2_vol)
87 | aims.write(output_vol, output_filename)
88 |
89 |
90 | def parse_command_line(argv=sys.argv):
91 | """Parse the script's command line."""
92 | import argparse
93 | parser = argparse.ArgumentParser(
94 | description="""\
95 | Assign new labels to voxels that have the same pair of labels in both
96 | input images.
97 | """)
98 | parser.add_argument("labels1", help="input label image")
99 | parser.add_argument("labels2", help="input label image")
100 | parser.add_argument("output", help="output label image")
101 |
102 | args = parser.parse_args(argv[1:])
103 | return args
104 |
105 |
106 | def main(argv=sys.argv):
107 | """The script's entry point."""
108 | args = parse_command_line(argv)
109 | return relabel_conjunction_files(
110 | args.labels1,
111 | args.labels2,
112 | args.output) or 0
113 |
114 |
115 | if __name__ == "__main__":
116 | sys.exit(main())
117 |
--------------------------------------------------------------------------------
/python/highres_cortex/test/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neurospin/highres-cortex/a2d6a7d2b0b1d07a3a3333d7826a6f607024d5aa/python/highres_cortex/test/__init__.py
--------------------------------------------------------------------------------
/soma-env/soma-env-recipe.yaml:
--------------------------------------------------------------------------------
1 | package:
2 | name: highres-cortex
3 |
4 | soma-env:
5 | publication: neuro-forge
6 | components:
7 | - highres-cortex
8 | internal-dependencies:
9 | - soma
10 | - anatomist
11 |
12 | type: compiled
13 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright CEA (2014).
2 | # Copyright Université Paris XI (2014).
3 | #
4 | # Contributor: Yann Leprince .
5 | #
6 | # Copying and distribution of this file, with or without modification,
7 | # are permitted in any medium without royalty provided the copyright
8 | # notice and this notice are preserved. This file is offered as-is,
9 | # without any warranty.
10 |
11 | add_subdirectory(library)
12 | add_subdirectory(commands)
13 |
--------------------------------------------------------------------------------
/src/commands/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright Forschungszentrum Jülich GmbH (2016).
2 | # Copyright Télécom ParisTech (2015).
3 | # Copyright CEA (2014).
4 | # Copyright Université Paris XI (2014).
5 | #
6 | # Contributor: Yann Leprince .
7 | #
8 | # Copying and distribution of this file, with or without modification,
9 | # are permitted in any medium without royalty provided the copyright
10 | # notice and this notice are preserved. This file is offered as-is,
11 | # without any warranty.
12 |
13 | set(OpenMP_commands
14 | ylLaplacian
15 | ylIsoCurvature
16 | )
17 | set(_commands
18 | ${OpenMP_commands}
19 | ylAdvectEuclidean
20 | ylAdvectPath
21 | ylAdvectTubes
22 | ylAdvectValues
23 | ylPropagateAlongField
24 | ylLabelEachVoxel
25 | ylMergeCortexColumnRegions
26 | ylMakeTraversePseudoAreaMap
27 | ylUpwindDistance
28 | )
29 |
30 | include_directories("${CMAKE_BINARY_DIR}/include")
31 |
32 | foreach(_command ${_commands})
33 | BRAINVISA_ADD_EXECUTABLE(${_command} ${_command}.cc)
34 | target_link_libraries(${_command} ${PROJECT_NAME} ${AIMS_AIMSDATA_LIBRARIES})
35 | BRAINVISA_INSTALL(TARGETS ${_command}
36 | DESTINATION bin
37 | COMPONENT ${PROJECT_NAME})
38 | endforeach()
39 |
40 | if(OPENMP_FOUND)
41 | set_source_files_properties(${OpenMP_commands} PROPERTIES
42 | COMPILE_FLAGS ${OpenMP_CXX_FLAGS})
43 | if(OpenMP_CXX_LIBRARIES)
44 | foreach(_command ${OpenMP_commands})
45 | target_link_libraries(${_command} ${OpenMP_CXX_LIBRARIES})
46 | endforeach()
47 | else()
48 | # Old versions of FindOpenMP.cmake (before CMake 3.9) do not define
49 | # _LIBRARIES. This works with GCC and clang.
50 | set_target_properties(${OpenMP_commands} PROPERTIES
51 | LINK_FLAGS ${OpenMP_CXX_FLAGS})
52 | endif()
53 | endif()
54 |
--------------------------------------------------------------------------------
/src/commands/ylLabelEachVoxel.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #include
39 | #include
40 | #include
41 |
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 | using std::clog;
49 | using std::endl;
50 | using carto::VolumeRef;
51 | using carto::verbose;
52 | using soma::AllocatorStrategy;
53 | using soma::AllocatorContext;
54 |
55 | namespace
56 | {
57 | const int EXIT_USAGE_ERROR = 2;
58 | std::string program_name;
59 | } // end of anonymous namespace
60 |
61 | int main(const int argc, const char **argv)
62 | {
63 | // Initialize command-line option parsing
64 | aims::Reader > input_reader;
65 | aims::Writer > output_writer;
66 | int32_t first_label = 1;
67 |
68 | program_name = argv[0];
69 | aims::AimsApplication app(argc, argv,
70 | "Assign a unique label to each voxel of a mask.\n"
71 | "\n"
72 | "Non-zero voxels of the mask are each assigned a positive unique label.");
73 | app.addOption(input_reader, "--input", "input mask");
74 | app.addOption(output_writer, "--output",
75 | "output label volume with S32 datatype");
76 | {
77 | std::ostringstream help_str;
78 | help_str << "assign labels starting with this value [default: "
79 | << first_label << "]";
80 | app.addOption(first_label, "--first", help_str.str(), true);
81 | }
82 | app.alias("-i", "--input");
83 | app.alias("-o", "--output");
84 | app.alias("--first-label", "--first");
85 |
86 |
87 | // Process command-line options
88 | try
89 | {
90 | app.initialize();
91 | }
92 | catch(const carto::user_interruption &)
93 | {
94 | // Exit after printing e.g. help
95 | return EXIT_SUCCESS;
96 | }
97 | catch(const std::runtime_error &e)
98 | {
99 | clog << program_name << ": error processing command-line options: "
100 | << e.what() << endl;
101 | return EXIT_USAGE_ERROR;
102 | }
103 |
104 | VolumeRef input_mask;
105 | input_reader.setAllocatorContext(
106 | AllocatorContext(AllocatorStrategy::ReadOnly));
107 | input_reader.read(input_mask);
108 | const int size_x = input_mask.getSizeX();
109 | const int size_y = input_mask.getSizeY();
110 | const int size_z = input_mask.getSizeZ();
111 | VolumeRef labelled_volume(size_x, size_y, size_z);
112 | labelled_volume->header() = input_mask->header();
113 | labelled_volume->fill(0);
114 |
115 | int32_t next_label = first_label;
116 | for(int z = 0; z < size_z; ++z)
117 | for(int y = 0; y < size_y; ++y)
118 | for(int x = 0; x < size_x; ++x)
119 | {
120 | if(input_mask(x, y, z) != 0) {
121 | labelled_volume(x, y, z) = next_label;
122 | next_label++;
123 | }
124 | }
125 |
126 | if(verbose != 0) {
127 | clog << program_name << ": assigned labels between " << first_label
128 | << " and " << next_label - 1 << "." << endl;
129 | }
130 |
131 | bool success = output_writer.write(labelled_volume);
132 | return success ? EXIT_SUCCESS : EXIT_FAILURE;
133 | }
134 |
--------------------------------------------------------------------------------
/src/commands/ylLaplacian.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright Télécom ParisTech (2015).
3 |
4 | Contributor: Yann Leprince .
5 |
6 | This file is part of highres-cortex, a collection of software designed
7 | to process high-resolution magnetic resonance images of the cerebral
8 | cortex.
9 |
10 | This software is governed by the CeCILL licence under French law and
11 | abiding by the rules of distribution of free software. You can use,
12 | modify and/or redistribute the software under the terms of the CeCILL
13 | licence as circulated by CEA, CNRS and INRIA at the following URL:
14 | .
15 |
16 | As a counterpart to the access to the source code and rights to copy,
17 | modify and redistribute granted by the licence, users are provided only
18 | with a limited warranty and the software's author, the holder of the
19 | economic rights, and the successive licensors have only limited
20 | liability.
21 |
22 | In this respect, the user's attention is drawn to the risks associated
23 | with loading, using, modifying and/or developing or reproducing the
24 | software by the user in light of its specific status of scientific
25 | software, that may mean that it is complicated to manipulate, and that
26 | also therefore means that it is reserved for developers and experienced
27 | professionals having in-depth computer knowledge. Users are therefore
28 | encouraged to load and test the software's suitability as regards their
29 | requirements in conditions enabling the security of their systems and/or
30 | data to be ensured and, more generally, to use and operate it in the
31 | same conditions as regards security.
32 |
33 | The fact that you are presently reading this means that you have had
34 | knowledge of the CeCILL licence and that you accept its terms.
35 | */
36 |
37 | #include
38 | #include
39 | #include
40 | #include
41 |
42 | #include
43 |
44 | #include
45 | #include
46 | #include
47 | #include
48 | #include
49 |
50 | #include
51 |
52 | using std::clog;
53 | using std::endl;
54 | using carto::VolumeRef;
55 | using carto::verbose;
56 | using soma::AllocatorStrategy;
57 | using soma::AllocatorContext;
58 |
59 |
60 | // Anonymous namespace for file-local symbols
61 | namespace
62 | {
63 | const int EXIT_USAGE_ERROR = 2;
64 | std::string program_name;
65 | } // end of anonymous namespace
66 |
67 | int main(const int argc, const char **argv)
68 | {
69 | typedef float Real;
70 | // Initialize command-line option parsing
71 | aims::Reader > classif_reader;
72 | Real relative_precision = 0.001f;
73 | float typical_cortical_thickness = 3;
74 | aims::Writer > output_writer;
75 |
76 | program_name = argv[0];
77 | aims::AimsApplication app(argc, argv,
78 | "Solve the Laplacian model in the cortex");
79 | app.addOption(classif_reader, "--classif",
80 | "classification image of the cortex (100 inside, 0 in CSF, "
81 | "200 in white matter)");
82 | app.addOption(output_writer, "--output",
83 | "output pseudo-temperature field (from 0 in CSF "
84 | "to 1 in the white matter)");
85 | {
86 | std::ostringstream help_str;
87 | help_str << "desired maximum relative error in first-order"
88 | " finite differences (default: " << relative_precision << ")";
89 | app.addOption(relative_precision, "--precision", help_str.str(), true);
90 | }
91 | {
92 | std::ostringstream help_str;
93 | help_str << "typical thickness of the cortex (mm), used for accelerating"
94 | " convergence (default: " << typical_cortical_thickness << "mm)";
95 | app.addOption(typical_cortical_thickness, "--typical-cortical-thickness",
96 | help_str.str(), true);
97 | }
98 | app.alias("-i", "--classif");
99 | app.alias("--input", "--classif");
100 | app.alias("-o", "--output");
101 |
102 |
103 | // Process command-line options
104 | try
105 | {
106 | app.initialize();
107 | }
108 | catch(const carto::user_interruption &)
109 | {
110 | // Exit after printing e.g. help
111 | return EXIT_SUCCESS;
112 | }
113 | catch(const std::runtime_error &e)
114 | {
115 | clog << program_name << ": error processing command-line options: "
116 | << e.what() << endl;
117 | return EXIT_USAGE_ERROR;
118 | }
119 |
120 | if(!(relative_precision > 0 && relative_precision < 1)) {
121 | clog << program_name << ": precision must be strictly between 0 and 1"
122 | << endl;
123 | return EXIT_USAGE_ERROR;
124 | }
125 | if(!(typical_cortical_thickness > 0)) {
126 | clog << program_name << ": typical cortical thickness must be"
127 | " strictly positive" << endl;
128 | return EXIT_USAGE_ERROR;
129 | }
130 |
131 | if(verbose != 0) clog << program_name << ": reading classif..." << endl;
132 | classif_reader.setAllocatorContext(
133 | AllocatorContext(AllocatorStrategy::ReadOnly));
134 | VolumeRef classif;
135 | bool success = classif_reader.read(classif);
136 | if(!success) {
137 | clog << program_name << ": error reading file '"
138 | << classif_reader.fileName()
139 | << "'specified as --classif, aborting" << endl;
140 | return EXIT_FAILURE;
141 | }
142 |
143 | const std::vector voxsize = classif->getVoxelSize();
144 | const float min_voxsize = *std::min_element(voxsize.begin(),
145 | voxsize.begin() + 3);
146 | const Real absolute_precision = relative_precision * min_voxsize
147 | / (2 * typical_cortical_thickness);
148 |
149 | if(absolute_precision < yl::LaplaceSolver::best_precision()) {
150 | clog << program_name
151 | << boost::format(": warning: requested precision (relative %1$.1e, "
152 | "absolute %2$.1e) cannot be guaranteed.")
153 | % relative_precision % absolute_precision << std::endl;
154 | }
155 |
156 | yl::LaplaceSolver solver(classif);
157 |
158 | solver.set_verbosity(verbose);
159 | solver.initialize_solution();
160 | solver.SOR(absolute_precision, typical_cortical_thickness);
161 | solver.clamp_to_range(0, 1);
162 | solver.eliminate_extrema();
163 | VolumeRef solution = solver.solution();
164 |
165 |
166 | if(verbose != 0) clog << program_name << ": writing output..." << endl;
167 | {
168 | bool write_success = output_writer.write(solution);
169 | if(!write_success) {
170 | clog << program_name << ": cannot write output volume" << endl;
171 | }
172 | success = success && write_success;
173 | }
174 |
175 | return success ? EXIT_SUCCESS : EXIT_FAILURE;
176 | }
177 |
--------------------------------------------------------------------------------
/src/commands/ylMakeTraversePseudoAreaMap.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #include
39 | #include
40 | #include
41 |
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 | #include
49 | #include
50 |
51 | using std::clog;
52 | using std::endl;
53 | using carto::VolumeRef;
54 | using soma::AllocatorStrategy;
55 | using soma::AllocatorContext;
56 |
57 | namespace
58 | {
59 | const int EXIT_USAGE_ERROR = 2;
60 | std::string program_name;
61 | } // end of anonymous namespace
62 |
63 | int main(const int argc, const char **argv)
64 | {
65 | typedef yl::CortexColumnRegionQuality QualityCriterion;
66 |
67 | // Initialize command-line option parsing
68 | aims::Reader > input_reader;
69 | aims::Reader > CSF_projections_reader;
70 | aims::Reader > white_projections_reader;
71 | aims::Reader > classif_reader;
72 | float goal_diameter = QualityCriterion::default_goal_diameter();
73 | aims::Writer > output_writer;
74 |
75 | program_name = argv[0];
76 | aims::AimsApplication app(argc, argv,
77 | "Map the quality of cortex column regions");
78 | app.addOption(input_reader, "--input", "input label volume");
79 | app.addOption(CSF_projections_reader, "--proj-csf",
80 | "projected coordinates of the CSF surface");
81 | app.addOption(white_projections_reader, "--proj-white",
82 | "projected coordinates of the white surface");
83 | app.addOption(classif_reader, "--classif",
84 | "grey/white/CSF classification image");
85 | {
86 | std::ostringstream help_str;
87 | help_str << "goal region diameter (in millimetres) [default: "
88 | << goal_diameter << "]";
89 | app.addOption(goal_diameter, "--goal-diameter",
90 | help_str.str(), true);
91 | }
92 | app.addOption(output_writer, "--output", "output quality map");
93 | app.alias("-i", "--input");
94 | app.alias("-o", "--output");
95 |
96 |
97 | // Process command-line options
98 | try
99 | {
100 | app.initialize();
101 | }
102 | catch(const carto::user_interruption &)
103 | {
104 | // Exit after printing e.g. help
105 | return EXIT_SUCCESS;
106 | }
107 | catch(const std::runtime_error &e)
108 | {
109 | clog << program_name << ": error processing command-line options: "
110 | << e.what() << endl;
111 | return EXIT_USAGE_ERROR;
112 | }
113 |
114 | VolumeRef input_regions;
115 | input_reader.setAllocatorContext(
116 | AllocatorContext(AllocatorStrategy::ReadOnly));
117 | input_reader.read(input_regions);
118 | yl::LabelVolume label_volume(input_regions);
119 |
120 | CSF_projections_reader.setAllocatorContext(
121 | AllocatorContext(AllocatorStrategy::ReadOnly));
122 | VolumeRef CSF_projections;
123 | CSF_projections_reader.read(CSF_projections);
124 |
125 | white_projections_reader.setAllocatorContext(
126 | AllocatorContext(AllocatorStrategy::ReadOnly));
127 | VolumeRef white_projections;
128 | white_projections_reader.read(white_projections);
129 |
130 | classif_reader.setAllocatorContext(
131 | AllocatorContext(AllocatorStrategy::ReadOnly));
132 | VolumeRef classif;
133 | classif_reader.read(classif);
134 |
135 | const int extension_x = input_regions.getSizeX();
136 | const int extension_y = input_regions.getSizeY();
137 | const int extension_z = input_regions.getSizeZ();
138 | carto::Volume output_volume(extension_x, extension_y, extension_z);
139 | output_volume.copyHeaderFrom(input_regions->header());
140 | output_volume.fill(0);
141 |
142 | QualityCriterion quality_criterion(CSF_projections,
143 | white_projections,
144 | classif);
145 | quality_criterion.setShapeParametres(goal_diameter);
146 |
147 | for(yl::LabelVolume::const_regions_iterator
148 | labels_it = label_volume.regions_begin(),
149 | labels_end = label_volume.regions_end();
150 | labels_it != labels_end;
151 | ++labels_it)
152 | {
153 | const int32_t label = *labels_it;
154 | const QualityCriterion::Cache cache = quality_criterion.cache(label_volume, label);
155 | const float quality = quality_criterion.pseudo_area(cache);
156 | for(yl::LabelVolume::const_point_iterator
157 | point_it = label_volume.region_begin(label),
158 | point_end = label_volume.region_end(label);
159 | point_it != point_end;
160 | ++point_it)
161 | {
162 | const Point3d& point = *point_it;
163 | const int x = point[0];
164 | const int y = point[1];
165 | const int z = point[2];
166 | output_volume(x, y, z) = quality;
167 | }
168 | }
169 |
170 | bool success = output_writer.write(output_volume);
171 | return success ? EXIT_SUCCESS : EXIT_FAILURE;
172 | }
173 |
--------------------------------------------------------------------------------
/src/commands/ylMergeCortexColumnRegions.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #include
39 | #include
40 | #include
41 |
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 | #include
49 | #include
50 |
51 | using std::clog;
52 | using std::endl;
53 | using carto::VolumeRef;
54 | using carto::verbose;
55 | using soma::AllocatorStrategy;
56 | using soma::AllocatorContext;
57 |
58 | namespace
59 | {
60 | const int EXIT_USAGE_ERROR = 2;
61 | std::string program_name;
62 |
63 | template
64 | float get_smallest_voxel_spacing(const VolumeType& volume)
65 | {
66 | std::vector voxel_size = volume->getVoxelSize();
67 | voxel_size.resize(3);
68 | std::sort(voxel_size.begin(), voxel_size.end());
69 | return voxel_size[0];
70 | }
71 |
72 | } // end of anonymous namespace
73 |
74 |
75 | int main(const int argc, const char **argv)
76 | {
77 | typedef yl::CortexColumnRegionQuality QualityCriterion;
78 |
79 | // Initialize command-line option parsing
80 | aims::Reader > input_reader;
81 | aims::Reader > CSF_projections_reader;
82 | aims::Reader > white_projections_reader;
83 | aims::Reader > classif_reader;
84 | float goal_diameter = QualityCriterion::default_goal_diameter();
85 | aims::Writer > output_writer;
86 |
87 | program_name = argv[0];
88 | aims::AimsApplication app(argc, argv,
89 | "Aggregate over-segmented cortex column regions");
90 | app.addOption(input_reader, "--input", "input label volume");
91 | app.addOption(CSF_projections_reader, "--proj-csf",
92 | "projected coordinates of the CSF surface");
93 | app.addOption(white_projections_reader, "--proj-white",
94 | "projected coordinates of the white surface");
95 | app.addOption(classif_reader, "--classif",
96 | "grey/white/CSF classification image");
97 | {
98 | std::ostringstream help_str;
99 | help_str << "goal region diameter (millimetres) [default: "
100 | << goal_diameter << "]";
101 | app.addOption(goal_diameter, "--goal-diameter",
102 | help_str.str(), true);
103 | }
104 | app.addOption(output_writer, "--output", "output label volume");
105 | app.alias("-i", "--input");
106 | app.alias("-o", "--output");
107 |
108 |
109 | // Process command-line options
110 | try
111 | {
112 | app.initialize();
113 | }
114 | catch(const carto::user_interruption &)
115 | {
116 | // Exit after printing e.g. help
117 | return EXIT_SUCCESS;
118 | }
119 | catch(const std::runtime_error &e)
120 | {
121 | clog << program_name << ": error processing command-line options: "
122 | << e.what() << endl;
123 | return EXIT_USAGE_ERROR;
124 | }
125 |
126 | VolumeRef input_regions_volume;
127 | input_reader.setAllocatorContext(
128 | AllocatorContext(AllocatorStrategy::ReadOnly));
129 | input_reader.read(input_regions_volume);
130 | const yl::LabelVolume input_regions(input_regions_volume);
131 |
132 | CSF_projections_reader.setAllocatorContext(
133 | AllocatorContext(AllocatorStrategy::ReadOnly));
134 | VolumeRef CSF_projections;
135 |
136 | white_projections_reader.setAllocatorContext(
137 | AllocatorContext(AllocatorStrategy::ReadOnly));
138 | CSF_projections_reader.read(CSF_projections);
139 | VolumeRef white_projections;
140 | white_projections_reader.read(white_projections);
141 |
142 | classif_reader.setAllocatorContext(
143 | AllocatorContext(AllocatorStrategy::ReadOnly));
144 | VolumeRef classif;
145 | classif_reader.read(classif);
146 |
147 | QualityCriterion quality_criterion(CSF_projections,
148 | white_projections,
149 | classif);
150 | quality_criterion.setShapeParametres(goal_diameter);
151 |
152 | yl::IterativeRegionMerger
153 | region_merger(input_regions, quality_criterion, verbose);
154 |
155 | region_merger.merge_worst_regions_iteratively();
156 |
157 | VolumeRef output_volume = region_merger.volume();
158 |
159 | bool success = output_writer.write(output_volume);
160 | return success ? EXIT_SUCCESS : EXIT_FAILURE;
161 | }
162 |
--------------------------------------------------------------------------------
/src/library/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Copyright CEA (2014, 2017).
2 | # Copyright Télécom ParisTech (2015).
3 | # Copyright Université Paris XI (2014).
4 | #
5 | # Contributor: Yann Leprince .
6 | #
7 | # Copying and distribution of this file, with or without modification,
8 | # are permitted in any medium without royalty provided the copyright
9 | # notice and this notice are preserved. This file is offered as-is,
10 | # without any warranty.
11 |
12 | set(_headers
13 | cortex.hh
14 | field.hh
15 | front.hh
16 | advection.hh
17 | advection.tcc
18 | cortex_advection.hh
19 | propagate_along_field.hh
20 | propagate_along_field.tcc
21 | label_volume.hh
22 | label_volume.tcc
23 | iterative_region_merger.hh
24 | iterative_region_merger.tcc
25 | cortex_column_region_quality.hh
26 | cortex_column_region_quality.tcc
27 | laplace_solver.hh
28 | laplace_solver.tcc
29 | upwinding.hh
30 | volume_util.hh
31 | volume_util.tcc
32 | )
33 | set(_sources
34 | field.cc
35 | front.cc
36 | advection.cc
37 | cortex_advection.cc
38 | propagate_along_field.cc
39 | label_volume.cc
40 | iterative_region_merger.cc
41 | cortex_column_region_quality.cc
42 | laplace_solver.cc
43 | upwinding.cc
44 | volume_util.cc
45 | )
46 |
47 | BRAINVISA_COPY_AND_INSTALL_HEADERS(_headers ${PROJECT_NAME} headersTarget)
48 |
49 | include_directories(${Boost_INCLUDE_DIRS})
50 |
51 | add_library(${PROJECT_NAME} ${_sources})
52 | add_dependencies(${PROJECT_NAME} ${headersTarget})
53 |
54 | if(OPENMP_FOUND)
55 | set_source_files_properties(${_sources} PROPERTIES
56 | COMPILE_FLAGS ${OpenMP_CXX_FLAGS})
57 | if(OpenMP_CXX_LIBRARIES)
58 | target_link_libraries(${PROJECT_NAME} ${OpenMP_CXX_LIBRARIES})
59 | else()
60 | # Old versions of FindOpenMP.cmake (before CMake 3.9) do not define
61 | # _LIBRARIES. This works with GCC and clang.
62 | set_target_properties(${PROJECT_NAME} PROPERTIES
63 | LINK_FLAGS ${OpenMP_CXX_FLAGS})
64 | endif()
65 | endif()
66 |
67 | set_property(TARGET ${PROJECT_NAME} PROPERTY VERSION ${${PROJECT_NAME}_VERSION})
68 | target_link_libraries(${PROJECT_NAME} ${AIMS_AIMSDATA_LIBRARIES})
69 | BRAINVISA_INSTALL(TARGETS ${PROJECT_NAME}
70 | DESTINATION lib
71 | COMPONENT ${PROJECT_NAME})
72 |
73 | if(DOXYGEN_FOUND)
74 | set( DOXYFILE_PREDEFINED "${AIMS_DEFINITIONS}")
75 | # Enable cross-linking to AIMS documentation (only works for in-tree build)
76 | set(AIMS-FREE_DOC_DIR "${AIMS-FREE_BINARY_DIR}/share/doc")
77 | set(AIMS-FREE_VERSION_MAJMIN
78 | "${aims-free_VERSION_MAJOR}.${aims-free_VERSION_MINOR}")
79 | set(SOMA-IO_DOC_DIR "${SOMA-IO_BINARY_DIR}/share/doc")
80 | set(SOMA-IO_VERSION_MAJMIN "${soma-io_VERSION_MAJOR}.${soma-io_VERSION_MINOR}")
81 |
82 | set(BV_DOC_URL "http://brainvisa.info/" CACHE STRING
83 | "Doxygen documentation links to the BrainVISA documentation at this URL")
84 |
85 | set(DOXYFILE_TAGFILES "${AIMS-FREE_DOC_DIR}/aimsdata-${AIMS-FREE_VERSION_MAJMIN}/doxygen/aimsdata.tag=${BV_DOC_URL}aimsdata-${AIMS-FREE_VERSION_MAJMIN}/doxygen ${AIMS-FREE_DOC_DIR}/aimsalgo-${AIMS-FREE_VERSION_MAJMIN}/doxygen/aimsalgo.tag=${BV_DOC_URL}aimsalgo-${AIMS-FREE_VERSION_MAJMIN}/doxygen ${AIMS-FREE_DOC_DIR}/cartodata-${AIMS-FREE_VERSION_MAJMIN}/doxygen/cartodata.tag=${BV_DOC_URL}cartodata-${AIMS-FREE_VERSION_MAJMIN}/doxygen ${SOMA-IO_DOC_DIR}/cartobase-${SOMA-IO_VERSION_MAJMIN}/doxygen/cartobase.tag=${BV_DOC_URL}cartobase-${SOMA-IO_VERSION_MAJMIN}/doxygen")
86 |
87 | BRAINVISA_GENERATE_DOXYGEN_DOC(_headers
88 | INPUT_PREFIX "${CMAKE_BINARY_DIR}/include/${PROJECT_NAME}")
89 |
90 | if(aims-free_IS_BEING_COMPILED)
91 | add_dependencies(${PROJECT_NAME}-doxygen aimsdata-doxygen aimsalgo-doxygen cartobase-doxygen cartodata-doxygen)
92 | endif(aims-free_IS_BEING_COMPILED)
93 |
94 | endif(DOXYGEN_FOUND)
95 |
--------------------------------------------------------------------------------
/src/library/advection.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #include "advection.hh"
39 | #include
40 |
41 | yl::Advection::Advection(const VectorField3d& advection_field)
42 | : m_vector_field(advection_field), m_verbose(0), m_max_iter(default_max_iter)
43 | {
44 | }
45 |
46 | yl::ConstantStepAdvection::
47 | ConstantStepAdvection(const yl::VectorField3d& advection_field,
48 | const float step)
49 | : Advection(advection_field), m_step(step)
50 | {
51 | }
52 |
53 | void yl::ConstantStepAdvection::
54 | move_one_step(Point3df& point,
55 | const Point3df& local_field) const
56 | {
57 | float gx = local_field[0], gy = local_field[1], gz = local_field[2];
58 | // Normalize the field, stop if too small or infinite or NaN.
59 | const float gn = std::sqrt(gx*gx + gy*gy + gz*gz);
60 | if(!std::isnormal(gn))
61 | throw yl::Advection::AbnormalField();
62 | gx /= gn; gy /= gn; gz /= gn;
63 |
64 | point[0] += m_step * gx;
65 | point[1] += m_step * gy;
66 | point[2] += m_step * gz;
67 | }
68 |
69 | #include "advection.tcc"
70 |
71 | template bool yl::Advection::visitor_advection
72 | (yl::Advection::Visitor& visitor, const Point3df& start_point) const;
73 |
--------------------------------------------------------------------------------
/src/library/advection.hh:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014, 2017, 2019).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 | Contributor: Denis Rivière .
7 |
8 | This file is part of highres-cortex, a collection of software designed
9 | to process high-resolution magnetic resonance images of the cerebral
10 | cortex.
11 |
12 | This software is governed by the CeCILL licence under French law and
13 | abiding by the rules of distribution of free software. You can use,
14 | modify and/or redistribute the software under the terms of the CeCILL
15 | licence as circulated by CEA, CNRS and INRIA at the following URL:
16 | .
17 |
18 | As a counterpart to the access to the source code and rights to copy,
19 | modify and redistribute granted by the licence, users are provided only
20 | with a limited warranty and the software's author, the holder of the
21 | economic rights, and the successive licensors have only limited
22 | liability.
23 |
24 | In this respect, the user's attention is drawn to the risks associated
25 | with loading, using, modifying and/or developing or reproducing the
26 | software by the user in light of its specific status of scientific
27 | software, that may mean that it is complicated to manipulate, and that
28 | also therefore means that it is reserved for developers and experienced
29 | professionals having in-depth computer knowledge. Users are therefore
30 | encouraged to load and test the software's suitability as regards their
31 | requirements in conditions enabling the security of their systems and/or
32 | data to be ensured and, more generally, to use and operate it in the
33 | same conditions as regards security.
34 |
35 | The fact that you are presently reading this means that you have had
36 | knowledge of the CeCILL licence and that you accept its terms.
37 | */
38 |
39 | #ifndef YL_ADVECTION_HH_INCLUDED
40 | #define YL_ADVECTION_HH_INCLUDED
41 |
42 | #include "field.hh"
43 |
44 | namespace yl
45 | {
46 |
47 | /** Advect a visitor along a vector field */
48 | class Advection
49 | {
50 | public:
51 | explicit Advection(const VectorField3d& advection_field);
52 | virtual ~Advection() {};
53 |
54 | /** Advect a visitor along a vector field
55 |
56 | \arg visitor object being taken through all the advection path, see
57 | Visitor. Can be derived from Visitor, or must have all the same methods.
58 | \arg start_point the start of the advection path
59 |
60 | \retval true if the advection is stopped by the visitor without
61 | encountering any error
62 | \retval false if the advection stops for another reason
63 | */
64 | template
65 | bool
66 | visitor_advection(TVisitor& visitor,
67 | const Point3df& start_point) const;
68 |
69 | /** Abstract base class for advection visitors */
70 | class Visitor
71 | {
72 | public:
73 | Visitor() : m_verbosity(0) {};
74 | virtual ~Visitor() {};
75 |
76 | /** Called before visit() on the first point of the advection path */
77 | virtual void first(const Point3df& point) = 0;
78 | /** Called for every point on the advection path, including the first */
79 | virtual void visit(const Point3df& point) = 0;
80 | /** Predicate that decides if the advection will continue or stop */
81 | virtual bool move_on(const Point3df& point) const = 0;
82 | /** Indicates whether the Visitor encountered an error */
83 | virtual bool aborted() const = 0;
84 | /** Called after the advection is stopped by move_on() */
85 | virtual void finished(const Point3df& /*start_point*/) {}
86 | /** Called when the advection cannot finish successfully */
87 | virtual void abort() {}
88 |
89 | int verbosity() const { return m_verbosity; }
90 | /** Set the verbosity level (output to stderr)
91 |
92 | 0: silent (default on instance creation)
93 | 1: show errors
94 | */
95 | void set_verbose(int verbosity) { m_verbosity = verbosity; }
96 |
97 | private:
98 | int m_verbosity;
99 | };
100 |
101 | /** Default iteration limit */
102 | static const unsigned int default_max_iter = 1000;
103 | /** Set the maximum number of iterations */
104 | void set_max_iter(unsigned int max_iter)
105 | {
106 | m_max_iter = max_iter;
107 | };
108 |
109 | /** Set the verbosity level (output to stderr)
110 |
111 | 0: silent (default on instance creation)
112 | 1: errors
113 | 2: informational messages
114 | >=3: debug (needs setting debug_output in advection.tcc)
115 | */
116 | void set_verbose(const int verbosity)
117 | {
118 | m_verbose = verbosity;
119 | };
120 |
121 | /** Thrown by move_one_step() to abort the advection */
122 | class AbnormalField
123 | {
124 | };
125 |
126 | private:
127 | virtual void move_one_step(Point3df& point,
128 | const Point3df& local_field) const = 0;
129 |
130 | const yl::VectorField3d& m_vector_field;
131 | int m_verbose;
132 | unsigned int m_max_iter;
133 | };
134 |
135 | /** Forward advection using a constant step size
136 |
137 | The step size can be negative, in which case the advection is done in the
138 | opposite direction.
139 | */
140 | class ConstantStepAdvection : public Advection
141 | {
142 | public:
143 | ConstantStepAdvection(const yl::VectorField3d& advection_field, float step);
144 | virtual ~ConstantStepAdvection() {};
145 |
146 | /** Change the step length */
147 | void set_step(float step)
148 | {
149 | m_step = step;
150 | };
151 |
152 | private:
153 | virtual void move_one_step(Point3df& point,
154 | const Point3df& local_field) const;
155 |
156 | float m_step;
157 | };
158 |
159 | } // namespace yl
160 |
161 | #endif // !defined(YL_ADVECTION_HH_INCLUDED)
162 |
--------------------------------------------------------------------------------
/src/library/advection.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014, 2017).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 | Contributor: Denis Rivière .
7 |
8 | This file is part of highres-cortex, a collection of software designed
9 | to process high-resolution magnetic resonance images of the cerebral
10 | cortex.
11 |
12 | This software is governed by the CeCILL licence under French law and
13 | abiding by the rules of distribution of free software. You can use,
14 | modify and/or redistribute the software under the terms of the CeCILL
15 | licence as circulated by CEA, CNRS and INRIA at the following URL:
16 | .
17 |
18 | As a counterpart to the access to the source code and rights to copy,
19 | modify and redistribute granted by the licence, users are provided only
20 | with a limited warranty and the software's author, the holder of the
21 | economic rights, and the successive licensors have only limited
22 | liability.
23 |
24 | In this respect, the user's attention is drawn to the risks associated
25 | with loading, using, modifying and/or developing or reproducing the
26 | software by the user in light of its specific status of scientific
27 | software, that may mean that it is complicated to manipulate, and that
28 | also therefore means that it is reserved for developers and experienced
29 | professionals having in-depth computer knowledge. Users are therefore
30 | encouraged to load and test the software's suitability as regards their
31 | requirements in conditions enabling the security of their systems and/or
32 | data to be ensured and, more generally, to use and operate it in the
33 | same conditions as regards security.
34 |
35 | The fact that you are presently reading this means that you have had
36 | knowledge of the CeCILL licence and that you accept its terms.
37 | */
38 |
39 | #include
40 |
41 |
42 | namespace
43 | {
44 | int debug_output = 0;
45 | } // end of anonymous namespace
46 |
47 | template
48 | bool
49 | yl::Advection::
50 | visitor_advection(TVisitor& visitor,
51 | const Point3df& start_point) const
52 | {
53 | using std::clog;
54 | using std::endl;
55 |
56 | if(m_verbose >= 2) {
57 | clog << "yl::Advection::visitor_advection starting at "
58 | << start_point << endl;
59 | }
60 |
61 | unsigned int iter = 0;
62 | Point3df point = start_point;
63 | visitor.first(point);
64 |
65 | while(visitor.move_on(point)) {
66 | if(iter >= m_max_iter) {
67 | if(m_verbose >= 1) {
68 | clog << " advection aborted after " << iter
69 | << " iterations: too many iterations." << endl;
70 | }
71 | visitor.abort();
72 | return false;
73 | }
74 |
75 | if(debug_output >= 3 && m_verbose >= 3) {
76 | clog << " iteration " << iter << " at " << point << endl;
77 | }
78 |
79 | ++iter;
80 | visitor.visit(point);
81 |
82 | // Move along the field
83 | Point3df local_field;
84 | try {
85 | m_vector_field.evaluate(point, local_field);
86 | } catch(const Field::UndefinedField&) {
87 | if(m_verbose >= 1) {
88 | clog << " advection aborted after " << iter
89 | << " iterations: vector field is undefined at " << point << endl;
90 | }
91 |
92 | visitor.abort();
93 | return false;
94 | }
95 |
96 | try {
97 | move_one_step(point, local_field);
98 | } catch(const AbnormalField&) {
99 | if(m_verbose >= 1) {
100 | clog << " advection aborted after " << iter
101 | << " iterations: vector field is abnormal"
102 | " (too small, infinite, or NaN) at "
103 | << point << endl;
104 | }
105 |
106 | visitor.abort();
107 | return false;
108 | }
109 | }
110 |
111 | visitor.finished(start_point);
112 |
113 | if(m_verbose >= 2) {
114 | clog << " advection finished after " << iter << " iterations" << endl;
115 | }
116 | return !visitor.aborted();
117 | }
118 |
--------------------------------------------------------------------------------
/src/library/cortex.hh:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright Télécom ParisTech (2015).
3 |
4 | Contributor: Yann Leprince .
5 |
6 | This file is part of highres-cortex, a collection of software designed
7 | to process high-resolution magnetic resonance images of the cerebral
8 | cortex.
9 |
10 | This software is governed by the CeCILL licence under French law and
11 | abiding by the rules of distribution of free software. You can use,
12 | modify and/or redistribute the software under the terms of the CeCILL
13 | licence as circulated by CEA, CNRS and INRIA at the following URL:
14 | .
15 |
16 | As a counterpart to the access to the source code and rights to copy,
17 | modify and redistribute granted by the licence, users are provided only
18 | with a limited warranty and the software's author, the holder of the
19 | economic rights, and the successive licensors have only limited
20 | liability.
21 |
22 | In this respect, the user's attention is drawn to the risks associated
23 | with loading, using, modifying and/or developing or reproducing the
24 | software by the user in light of its specific status of scientific
25 | software, that may mean that it is complicated to manipulate, and that
26 | also therefore means that it is reserved for developers and experienced
27 | professionals having in-depth computer knowledge. Users are therefore
28 | encouraged to load and test the software's suitability as regards their
29 | requirements in conditions enabling the security of their systems and/or
30 | data to be ensured and, more generally, to use and operate it in the
31 | same conditions as regards security.
32 |
33 | The fact that you are presently reading this means that you have had
34 | knowledge of the CeCILL licence and that you accept its terms.
35 | */
36 |
37 | #ifndef CORTEX_HH_INCLUDED
38 | #define CORTEX_HH_INCLUDED
39 |
40 | namespace yl
41 | {
42 |
43 | enum {
44 | CSF_LABEL = 0,
45 | CORTEX_LABEL = 100,
46 | WHITE_LABEL = 200
47 | };
48 |
49 | } // namespace yl
50 |
51 | #endif // !defined(CORTEX_HH_INCLUDED)
52 |
--------------------------------------------------------------------------------
/src/library/cortex_column_region_quality.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #include "cortex_column_region_quality.hh"
39 |
40 |
41 | #include "cortex_column_region_quality.tcc"
42 |
43 | template yl::CortexColumnRegionQuality::Cache
44 | yl::CortexColumnRegionQuality::cache(
45 | const LabelVolume&, int32_t) const;
46 | template float yl::CortexColumnRegionQuality::fusion_ordering(
47 | const LabelVolume&, int32_t) const;
48 | template float yl::CortexColumnRegionQuality::fusion_ordering(
49 | const LabelVolume&, int32_t, int32_t) const;
50 |
51 |
52 | #include
53 |
54 |
55 | using carto::VolumeRef;
56 |
57 | namespace
58 | {
59 |
60 | float diameter_to_pseudo_area(float diameter)
61 | {
62 | return 0.125f * square(diameter);
63 | }
64 |
65 | } // end of anonymous namespace
66 |
67 | yl::CortexColumnRegionQuality::
68 | CortexColumnRegionQuality(const VolumeRef& CSF_projections,
69 | const VolumeRef& white_projections,
70 | const VolumeRef& classif)
71 | : m_CSF_projections(CSF_projections),
72 | m_white_projections(white_projections),
73 | m_classif(classif)
74 | {
75 | setShapeParametres(default_goal_diameter());
76 | assert(m_CSF_projections.getSizeT() == 3);
77 | assert(m_white_projections.getSizeT() == 3);
78 | }
79 |
80 | void
81 | yl::CortexColumnRegionQuality::
82 | setShapeParametres(float goal_diameter)
83 | {
84 | assert(goal_diameter >= 0.f);
85 | m_pseudo_area_cutoff = diameter_to_pseudo_area(goal_diameter);
86 | }
87 |
88 | float yl::CortexColumnRegionQuality::default_goal_diameter()
89 | {
90 | return 0.5f;
91 | }
92 |
--------------------------------------------------------------------------------
/src/library/cortex_column_region_quality.hh:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | // TODO rename this to cortical_traverse_quality
39 |
40 | #ifndef CORTEX_COLUMN_REGION_QUALITY_HH_INCLUDED
41 | #define CORTEX_COLUMN_REGION_QUALITY_HH_INCLUDED
42 |
43 | #include
44 | #include "label_volume.hh"
45 |
46 | namespace yl
47 | {
48 |
49 | struct MomentAccumulator
50 | {
51 | public:
52 | MomentAccumulator()
53 | : m_000(0.f),
54 | m_100(0.f), m_010(0.f), m_001(0.f),
55 | m_200(0.f),
56 | m_110(0.f), m_020(0.f),
57 | m_101(0.f), m_011(0.f), m_002(0.f) {}
58 |
59 | MomentAccumulator(float m000,
60 | float m100, float m010, float m001,
61 | float m200,
62 | float m110, float m020,
63 | float m101, float m011, float m002)
64 | : m_000(m000),
65 | m_100(m100), m_010(m010), m_001(m001),
66 | m_200(m200),
67 | m_110(m110), m_020(m020),
68 | m_101(m101), m_011(m011), m_002(m002) {}
69 |
70 | void update(float x, float y, float z)
71 | {
72 | m_000 += 1;
73 | m_100 += x; m_010 += y; m_001 += z;
74 | m_200 += x * x;
75 | m_110 += y * x; m_020 += y * y;
76 | m_101 += z * x; m_011 += z * y; m_002 += z * z;
77 | };
78 |
79 | MomentAccumulator operator + (const MomentAccumulator& other) const
80 | {
81 | return MomentAccumulator(m_000 + other.m_000,
82 | m_100 + other.m_100,
83 | m_010 + other.m_010,
84 | m_001 + other.m_001,
85 | m_200 + other.m_200,
86 | m_110 + other.m_110,
87 | m_020 + other.m_020,
88 | m_101 + other.m_101,
89 | m_011 + other.m_011,
90 | m_002 + other.m_002);
91 | };
92 |
93 | std::size_t m_000;
94 | float m_100, m_010, m_001;
95 | float m_200;
96 | float m_110, m_020;
97 | float m_101, m_011, m_002;
98 | };
99 |
100 |
101 | class CortexColumnRegionQuality
102 | {
103 | public:
104 | CortexColumnRegionQuality(const carto::VolumeRef& CSF_projections,
105 | const carto::VolumeRef& white_projections,
106 | const carto::VolumeRef& classif);
107 |
108 | void setShapeParametres(float goal_diameter);
109 |
110 | template
111 | float fusion_ordering(const LabelVolume& /*label_vol*/, Tlabel /*label*/) const;
112 |
113 | template
114 | float fusion_ordering(const LabelVolume& /*label_vol*/, Tlabel /*label1*/, Tlabel /*label2*/) const;
115 |
116 | template
117 | inline float fusion_ordering(const PointIterator& point_it_begin,
118 | const PointIterator& point_it_end) const;
119 |
120 | class Cache
121 | {
122 | public:
123 | Cache()
124 | : m_CSF_moments(),
125 | m_white_moments(),
126 | m_region_size(0),
127 | m_touches_CSF(false),
128 | m_touches_white(false)
129 | {};
130 | Cache(const MomentAccumulator& CSF_moments,
131 | const MomentAccumulator& white_moments,
132 | std::size_t region_size,
133 | bool touches_CSF,
134 | bool touches_white)
135 | : m_CSF_moments(CSF_moments),
136 | m_white_moments(white_moments),
137 | m_region_size(region_size),
138 | m_touches_CSF(touches_CSF),
139 | m_touches_white(touches_white)
140 | {};
141 |
142 | Cache operator + (const Cache& other) const
143 | {
144 | return Cache(CSF_moments() + other.CSF_moments(),
145 | white_moments() + other.white_moments(),
146 | region_size() + other.region_size(),
147 | touches_CSF() || other.touches_CSF(),
148 | touches_white() || other.touches_white());
149 | };
150 |
151 | const MomentAccumulator& CSF_moments() const {return m_CSF_moments;};
152 | MomentAccumulator& CSF_moments() {return m_CSF_moments;};
153 | const MomentAccumulator& white_moments() const {return m_white_moments;};
154 | MomentAccumulator& white_moments() {return m_white_moments;};
155 | std::size_t region_size() const {return m_region_size;};
156 | std::size_t& region_size() {return m_region_size;};
157 | bool touches_CSF() const {return m_touches_CSF;};
158 | bool& touches_CSF() {return m_touches_CSF;};
159 | bool touches_white() const {return m_touches_white;};
160 | bool& touches_white() {return m_touches_white;};
161 | private:
162 | MomentAccumulator m_CSF_moments;
163 | MomentAccumulator m_white_moments;
164 | std::size_t m_region_size;
165 | bool m_touches_CSF;
166 | bool m_touches_white;
167 | };
168 | float fusion_ordering(const Cache& /*cache*/) const;
169 | bool want_fusion (const Cache& /*cache*/) const;
170 | float pseudo_area(const Cache& /*cache*/) const;
171 | template
172 | Cache cache(const PointIterator& point_it_begin,
173 | const PointIterator& point_it_end) const;
174 | template
175 | Cache cache(const LabelVolume& /*label_vol*/, Tlabel /*label*/) const;
176 |
177 | static float default_goal_diameter();
178 |
179 | private:
180 | carto::VolumeRef m_CSF_projections;
181 | carto::VolumeRef m_white_projections;
182 | carto::VolumeRef m_classif;
183 | float m_pseudo_area_cutoff;
184 | }; // class CortexColumnRegionQuality
185 |
186 | }; // namespace yl
187 |
188 | #endif // !defined(CORTEX_COLUMN_REGION_QUALITY_HH_INCLUDED)
189 |
--------------------------------------------------------------------------------
/src/library/field.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014, 2017).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 | Contributor: Denis Rivière .
7 |
8 | This file is part of highres-cortex, a collection of software designed
9 | to process high-resolution magnetic resonance images of the cerebral
10 | cortex.
11 |
12 | This software is governed by the CeCILL licence under French law and
13 | abiding by the rules of distribution of free software. You can use,
14 | modify and/or redistribute the software under the terms of the CeCILL
15 | licence as circulated by CEA, CNRS and INRIA at the following URL:
16 | .
17 |
18 | As a counterpart to the access to the source code and rights to copy,
19 | modify and redistribute granted by the licence, users are provided only
20 | with a limited warranty and the software's author, the holder of the
21 | economic rights, and the successive licensors have only limited
22 | liability.
23 |
24 | In this respect, the user's attention is drawn to the risks associated
25 | with loading, using, modifying and/or developing or reproducing the
26 | software by the user in light of its specific status of scientific
27 | software, that may mean that it is complicated to manipulate, and that
28 | also therefore means that it is reserved for developers and experienced
29 | professionals having in-depth computer knowledge. Users are therefore
30 | encouraged to load and test the software's suitability as regards their
31 | requirements in conditions enabling the security of their systems and/or
32 | data to be ensured and, more generally, to use and operate it in the
33 | same conditions as regards security.
34 |
35 | The fact that you are presently reading this means that you have had
36 | knowledge of the CeCILL licence and that you accept its terms.
37 | */
38 |
39 | #include "field.hh"
40 |
41 | #include
42 | #include
43 |
44 | using namespace aims;
45 |
46 | yl::LinearlyInterpolatedVectorField3d::
47 | LinearlyInterpolatedVectorField3d(const carto::VolumeRef& fieldx,
48 | const carto::VolumeRef& fieldy,
49 | const carto::VolumeRef& fieldz)
50 | : m_interp_fieldx(fieldx), m_interp_fieldy(fieldy), m_interp_fieldz(fieldz)
51 | {
52 | }
53 |
54 | void
55 | yl::LinearlyInterpolatedVectorField3d::
56 | evaluate(const Point3df& pos, Point3df& output) const
57 | {
58 | if(! m_interp_fieldx.isValid(pos[0], pos[1], pos[2])
59 | || ! m_interp_fieldy.isValid(pos[0], pos[1], pos[2])
60 | || ! m_interp_fieldz.isValid(pos[0], pos[1], pos[2]))
61 | {
62 | throw UndefinedField();
63 | }
64 | output[0] = m_interp_fieldx.value(pos);
65 | output[1] = m_interp_fieldy.value(pos);
66 | output[2] = m_interp_fieldz.value(pos);
67 | }
68 |
69 | yl::LinearlyInterpolatedScalarFieldGradient::
70 | LinearlyInterpolatedScalarFieldGradient(const carto::VolumeRef& scalar_field)
71 | : m_interp_gradx(), m_interp_grady(), m_interp_gradz()
72 | {
73 | AimsGradient gradient(AIMS_GRADIENT_DPLUS);
74 | carto::VolumeRef gradx = gradient.X(scalar_field);
75 | m_interp_gradx = getLinearInterpolator(gradx);
76 | carto::VolumeRef grady = gradient.Y(scalar_field);
77 | m_interp_grady = getLinearInterpolator(grady);
78 | carto::VolumeRef gradz = gradient.Z(scalar_field);
79 | m_interp_gradz = getLinearInterpolator(gradz);
80 |
81 | // Problem: the last line of each gradient is filled with zeros, which
82 | // means that the interpolation is meaningless near these borders.
83 | // This is worked around non-elegantly in the evaluate method.
84 |
85 | const std::vector voxel_size = scalar_field->getVoxelSize();
86 | m_xoffset = -0.5f * voxel_size[0];
87 | m_yoffset = -0.5f * voxel_size[1];
88 | m_zoffset = -0.5f * voxel_size[2];
89 | }
90 |
91 | void
92 | yl::LinearlyInterpolatedScalarFieldGradient::
93 | evaluate(const Point3df& pos, Point3df& output) const
94 | {
95 | if(! m_interp_gradx->isValid(pos[0] + m_xoffset, pos[1], pos[2])
96 | || ! m_interp_grady->isValid(pos[0], pos[1] + m_yoffset, pos[2])
97 | || ! m_interp_gradz->isValid(pos[0], pos[1], pos[2] + m_zoffset))
98 | {
99 | throw UndefinedField();
100 | }
101 |
102 | // Workaround for problem described in the constructor: test if we are near
103 | // the border. Should work, but not elegant...
104 | if(! m_interp_gradx->isValid(pos[0] - m_xoffset, pos[1], pos[2])
105 | || ! m_interp_grady->isValid(pos[0], pos[1] - m_yoffset, pos[2])
106 | || ! m_interp_gradz->isValid(pos[0], pos[1], pos[2] - m_zoffset))
107 | {
108 | throw UndefinedField();
109 | }
110 |
111 | output[0] = m_interp_gradx->value(pos[0] + m_xoffset, pos[1], pos[2]);
112 | output[1] = m_interp_grady->value(pos[0], pos[1] + m_yoffset, pos[2]);
113 | output[2] = m_interp_gradz->value(pos[0], pos[1], pos[2] + m_zoffset);
114 | }
115 |
116 | yl::LinearlyInterpolatedScalarField::
117 | LinearlyInterpolatedScalarField(const carto::VolumeRef& field_volume)
118 | : m_interp_field(field_volume)
119 | {
120 | }
121 |
122 | float
123 | yl::LinearlyInterpolatedScalarField::
124 | evaluate(const Point3df& pos) const
125 | {
126 | if(! m_interp_field.isValid(pos[0], pos[1], pos[2]))
127 | {
128 | throw UndefinedField();
129 | }
130 | return m_interp_field.value(pos);
131 | }
132 |
133 |
134 | yl::BooleanScalarField::
135 | BooleanScalarField(const carto::VolumeRef& field_volume)
136 | : m_field(field_volume)
137 | {
138 | std::vector vs = field_volume->getVoxelSize();
139 | m_voxel_size[0] = vs[0];
140 | m_voxel_size[1] = vs[1];
141 | m_voxel_size[2] = vs[2];
142 | }
143 |
144 | float
145 | yl::BooleanScalarField::
146 | evaluate(const Point3df& pos) const
147 | {
148 | return m_field->at(lround(pos[0] / m_voxel_size[0]),
149 | lround(pos[1] / m_voxel_size[1]),
150 | lround(pos[2] / m_voxel_size[2])) == 0 ? 0.f : 1.f;
151 | }
152 |
--------------------------------------------------------------------------------
/src/library/field.hh:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014, 2017).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 | Contributor: Denis Rivière .
7 |
8 | This file is part of highres-cortex, a collection of software designed
9 | to process high-resolution magnetic resonance images of the cerebral
10 | cortex.
11 |
12 | This software is governed by the CeCILL licence under French law and
13 | abiding by the rules of distribution of free software. You can use,
14 | modify and/or redistribute the software under the terms of the CeCILL
15 | licence as circulated by CEA, CNRS and INRIA at the following URL:
16 | .
17 |
18 | As a counterpart to the access to the source code and rights to copy,
19 | modify and redistribute granted by the licence, users are provided only
20 | with a limited warranty and the software's author, the holder of the
21 | economic rights, and the successive licensors have only limited
22 | liability.
23 |
24 | In this respect, the user's attention is drawn to the risks associated
25 | with loading, using, modifying and/or developing or reproducing the
26 | software by the user in light of its specific status of scientific
27 | software, that may mean that it is complicated to manipulate, and that
28 | also therefore means that it is reserved for developers and experienced
29 | professionals having in-depth computer knowledge. Users are therefore
30 | encouraged to load and test the software's suitability as regards their
31 | requirements in conditions enabling the security of their systems and/or
32 | data to be ensured and, more generally, to use and operate it in the
33 | same conditions as regards security.
34 |
35 | The fact that you are presently reading this means that you have had
36 | knowledge of the CeCILL licence and that you accept its terms.
37 | */
38 |
39 | #ifndef YL_FIELD_HH_INCLUDED
40 | #define YL_FIELD_HH_INCLUDED
41 |
42 | #include
43 | #include
44 |
45 | namespace yl
46 | {
47 |
48 | /** Store and access a field (scalar or vector) defined over a 3D domain */
49 | class Field
50 | {
51 | public:
52 | /** Exception thrown when the field has no defined value */
53 | class UndefinedField
54 | {
55 | };
56 | };
57 |
58 | /** Store a vector field and access it at any coordinates */
59 | class VectorField3d : public Field
60 | {
61 | public:
62 | // A virtual destructor is needed because this is a polymorphic class
63 | ~VectorField3d() {};
64 |
65 | /** Evaluate the field's value at possibly non-integer coordinates
66 |
67 | \exception UndefinedField if the field cannot be evaluated at the
68 | given position.
69 | */
70 | Point3df evaluate(const Point3df& pos) const
71 | {
72 | Point3df ret;
73 | evaluate(pos, ret);
74 | return ret;
75 | };
76 |
77 | /** Evaluate the field's value at possibly non-integer coordinates
78 |
79 | \exception UndefinedField if the field cannot be evaluated at the
80 | given position.
81 | */
82 | virtual void evaluate(const Point3df& pos, Point3df& output) const = 0;
83 | };
84 |
85 | /** Store a scalar field and access it at any coordinates */
86 | class ScalarField : public Field
87 | {
88 | public:
89 | // A virtual destructor is needed because this is a polymorphic class
90 | ~ScalarField() {};
91 |
92 | /** Evaluate the field's value at possibly non-integer coordinates
93 |
94 | \exception UndefinedField if the field cannot be evaluated at the
95 | given position.
96 | */
97 | virtual float evaluate(const Point3df& pos) const = 0;
98 |
99 | };
100 |
101 | /** Access a vector field stored as three volumes
102 |
103 | The components are linearly interpolated between integer coordinates.
104 | */
105 | class LinearlyInterpolatedVectorField3d : public VectorField3d
106 | {
107 | public:
108 | LinearlyInterpolatedVectorField3d(const carto::VolumeRef& fieldx,
109 | const carto::VolumeRef& fieldy,
110 | const carto::VolumeRef& fieldz);
111 |
112 | virtual void evaluate(const Point3df& pos, Point3df& output) const;
113 | private:
114 | aims::LinearInterpolator m_interp_fieldx;
115 | aims::LinearInterpolator m_interp_fieldy;
116 | aims::LinearInterpolator m_interp_fieldz;
117 | };
118 |
119 | class LinearlyInterpolatedScalarFieldGradient : public VectorField3d
120 | {
121 | public:
122 | explicit LinearlyInterpolatedScalarFieldGradient(
123 | const carto::VolumeRef& scalar_field);
124 | virtual void evaluate(const Point3df& pos, Point3df& output) const;
125 | private:
126 | carto::rc_ptr m_interp_gradx;
127 | carto::rc_ptr m_interp_grady;
128 | carto::rc_ptr m_interp_gradz;
129 | float m_xoffset, m_yoffset, m_zoffset;
130 | };
131 |
132 | /** Access a scalar field stored in a volume
133 |
134 | The field's value is linearly interpolated between integer coordinates.
135 | */
136 | class LinearlyInterpolatedScalarField : public ScalarField
137 | {
138 | public:
139 | explicit LinearlyInterpolatedScalarField(const carto::VolumeRef& field_volume);
140 |
141 | virtual float evaluate(const Point3df& pos) const;
142 | private:
143 | aims::LinearInterpolator m_interp_field;
144 | };
145 |
146 | /** Access a boolean field stored in a volume
147 |
148 | The boolean field is using nearest neighbour interpolation, any non-zero
149 | value (including NaN) is returned as true (1.0f).
150 | */
151 | class BooleanScalarField : public ScalarField
152 | {
153 | public:
154 | explicit BooleanScalarField(const carto::VolumeRef& field_volume);
155 |
156 | virtual float evaluate(const Point3df& pos) const;
157 | private:
158 | const carto::VolumeRef& m_field;
159 | Point3df m_voxel_size;
160 | };
161 |
162 | } // namespace yl
163 |
164 | #endif // !defined(YL_FIELD_HH_INCLUDED)
165 |
--------------------------------------------------------------------------------
/src/library/front.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright Télécom ParisTech (2015).
3 |
4 | Contributor: Yann Leprince .
5 |
6 | This file is part of highres-cortex, a collection of software designed
7 | to process high-resolution magnetic resonance images of the cerebral
8 | cortex.
9 |
10 | This software is governed by the CeCILL licence under French law and
11 | abiding by the rules of distribution of free software. You can use,
12 | modify and/or redistribute the software under the terms of the CeCILL
13 | licence as circulated by CEA, CNRS and INRIA at the following URL:
14 | .
15 |
16 | As a counterpart to the access to the source code and rights to copy,
17 | modify and redistribute granted by the licence, users are provided only
18 | with a limited warranty and the software's author, the holder of the
19 | economic rights, and the successive licensors have only limited
20 | liability.
21 |
22 | In this respect, the user's attention is drawn to the risks associated
23 | with loading, using, modifying and/or developing or reproducing the
24 | software by the user in light of its specific status of scientific
25 | software, that may mean that it is complicated to manipulate, and that
26 | also therefore means that it is reserved for developers and experienced
27 | professionals having in-depth computer knowledge. Users are therefore
28 | encouraged to load and test the software's suitability as regards their
29 | requirements in conditions enabling the security of their systems and/or
30 | data to be ensured and, more generally, to use and operate it in the
31 | same conditions as regards security.
32 |
33 | The fact that you are presently reading this means that you have had
34 | knowledge of the CeCILL licence and that you accept its terms.
35 | */
36 |
37 | #include "front.hh"
38 |
39 |
40 | yl::SortedFront::
41 | SortedFront(carto::VolumeRef& domain,
42 | const int16_t front_label,
43 | const int16_t done_label)
44 | : m_domain(domain),
45 | m_front_label(front_label),
46 | m_done_label(done_label)
47 | {
48 | }
49 |
50 | Point3d
51 | yl::SortedFront::
52 | pop()
53 | {
54 | const Point3d point = get();
55 | // TODO decide where to put this
56 | m_domain(point[0], point[1], point[2]) = m_done_label;
57 | m_queue.pop();
58 | return point;
59 | }
60 |
61 | void
62 | yl::SortedFront::
63 | add(const Point3d& point, const float priority)
64 | {
65 | assert(m_domain(point[0], point[1], point[2]) != m_front_label);
66 |
67 | m_queue.push(std::make_pair(priority, point));
68 | m_domain(point[0], point[1], point[2]) = m_front_label;
69 | }
70 |
--------------------------------------------------------------------------------
/src/library/front.hh:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright Télécom ParisTech (2015).
3 |
4 | Contributor: Yann Leprince .
5 |
6 | This file is part of highres-cortex, a collection of software designed
7 | to process high-resolution magnetic resonance images of the cerebral
8 | cortex.
9 |
10 | This software is governed by the CeCILL licence under French law and
11 | abiding by the rules of distribution of free software. You can use,
12 | modify and/or redistribute the software under the terms of the CeCILL
13 | licence as circulated by CEA, CNRS and INRIA at the following URL:
14 | .
15 |
16 | As a counterpart to the access to the source code and rights to copy,
17 | modify and redistribute granted by the licence, users are provided only
18 | with a limited warranty and the software's author, the holder of the
19 | economic rights, and the successive licensors have only limited
20 | liability.
21 |
22 | In this respect, the user's attention is drawn to the risks associated
23 | with loading, using, modifying and/or developing or reproducing the
24 | software by the user in light of its specific status of scientific
25 | software, that may mean that it is complicated to manipulate, and that
26 | also therefore means that it is reserved for developers and experienced
27 | professionals having in-depth computer knowledge. Users are therefore
28 | encouraged to load and test the software's suitability as regards their
29 | requirements in conditions enabling the security of their systems and/or
30 | data to be ensured and, more generally, to use and operate it in the
31 | same conditions as regards security.
32 |
33 | The fact that you are presently reading this means that you have had
34 | knowledge of the CeCILL licence and that you accept its terms.
35 | */
36 |
37 | #ifndef FRONT_HH_INCLUDED
38 | #define FRONT_HH_INCLUDED
39 |
40 | #include
41 |
42 | #include
43 | #include
44 |
45 | #include
46 | #include
47 |
48 |
49 | namespace yl
50 | {
51 |
52 | /** Helper class to use Point3d & friends in hash tables */
53 | template
54 | struct PointHasher : std::unary_function
55 | {
56 | std::size_t operator()(const Point& point) const
57 | {
58 | std::size_t seed = 0;
59 | for(int i = 0; i < point.size(); ++i)
60 | boost::hash_combine(seed, point[i]);
61 | return seed;
62 | }
63 | };
64 |
65 | enum {
66 | DEFAULT_FRONT_LABEL = -123,
67 | DEFAULT_DONE_LABEL = -10
68 | };
69 |
70 |
71 | class SortedFront
72 | {
73 | public:
74 | SortedFront(carto::VolumeRef& domain,
75 | int16_t front_label,
76 | int16_t done_label);
77 |
78 | const Point3d& get() const
79 | {
80 | return m_queue.top().second;
81 | };
82 | Point3d pop();
83 |
84 | void add(const Point3d& /*point*/, float priority);
85 |
86 | bool empty() const
87 | {
88 | return m_queue.empty();
89 | };
90 |
91 | std::size_t size() const
92 | {
93 | return m_queue.size();
94 | };
95 |
96 | private:
97 | struct VoxelOrdering {
98 | bool operator() (const std::pair& left,
99 | const std::pair& right) const
100 | {
101 | return left.first > right.first;
102 | };
103 | };
104 |
105 | typedef boost::heap::priority_queue,
106 | boost::heap::compare >
107 | FrontQueue;
108 | FrontQueue m_queue;
109 |
110 | carto::VolumeRef m_domain;
111 | const int16_t m_front_label;
112 | const int16_t m_done_label;
113 |
114 | public:
115 | static const bool constant_time_size = FrontQueue::constant_time_size;
116 | };
117 |
118 | } // namespace yl
119 |
120 | #endif // !defined(FRONT_HH_INCLUDED)
121 |
--------------------------------------------------------------------------------
/src/library/iterative_region_merger.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #include "iterative_region_merger.hh"
39 | #include "cortex_column_region_quality.hh"
40 |
41 | #include "iterative_region_merger.tcc"
42 |
43 | template class yl::IterativeRegionMerger;
44 |
--------------------------------------------------------------------------------
/src/library/iterative_region_merger.hh:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #ifndef ITERATIVE_REGION_MERGER_HH_INCLUDED
39 | #define ITERATIVE_REGION_MERGER_HH_INCLUDED
40 |
41 | #include
42 |
43 | #include "label_volume.hh"
44 |
45 | namespace yl
46 | {
47 |
48 | template
49 | class IterativeRegionMerger
50 | {
51 | public:
52 | explicit IterativeRegionMerger(
53 | const LabelVolume& label_vol,
54 | const RegionQualityCriterion& criterion=RegionQualityCriterion(),
55 | int verbosity=0);
56 | virtual ~IterativeRegionMerger() {};
57 |
58 | void setVerbose(int verbosity=1);
59 |
60 | void merge_worst_regions_iteratively();
61 |
62 | carto::VolumeRef volume() const
63 | {
64 | return m_label_volume.volume();
65 | }
66 |
67 | private:
68 | LabelVolume m_label_volume;
69 | RegionQualityCriterion m_criterion;
70 | int m_verbosity;
71 | }; // class IterativeRegionMerger
72 |
73 | }; // namespace yl
74 |
75 | #endif // !defined(ITERATIVE_REGION_MERGER_HH_INCLUDED)
76 |
--------------------------------------------------------------------------------
/src/library/label_volume.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #include "label_volume.hh"
39 |
40 | #include "label_volume.tcc"
41 |
42 | template class yl::LabelVolume;
43 |
--------------------------------------------------------------------------------
/src/library/label_volume.hh:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #ifndef YL_LABEL_VOLUME_HH_INCLUDED
39 | #define YL_LABEL_VOLUME_HH_INCLUDED
40 |
41 | #include
42 | #include
43 | #include
44 |
45 | #include
46 | #include
47 |
48 | namespace yl
49 | {
50 |
51 | /** Return the first element of a std::pair, like non-standard std::select1st */
52 | template
53 | class select1st : public std::unary_function
54 | {
55 | public:
56 | typename TPair::first_type&
57 | operator()(TPair& pair) const
58 | {
59 | return pair.first;
60 | }
61 |
62 | const typename TPair::first_type&
63 | operator()(const TPair& pair) const
64 | {
65 | return pair.first;
66 | }
67 | };
68 |
69 |
70 | template
71 | class LabelVolume
72 | {
73 | public:
74 | typedef aims::BucketMap BucketMap;
75 | typedef BucketMap::Bucket Bucket;
76 |
77 | typedef boost::transform_iterator,
78 | BucketMap::const_iterator> const_regions_iterator;
79 | /** Iterator through a Bucket's points (yields Point3d) */
80 | typedef boost::transform_iterator,
81 | Bucket::const_iterator> const_point_iterator;
82 |
83 | explicit LabelVolume(const carto::VolumeRef &vol, Tlabel background = 0);
84 | virtual ~LabelVolume() {};
85 |
86 | void merge_regions(Tlabel eating_label, Tlabel eaten_label);
87 | void discard_region(Tlabel label);
88 |
89 | Tlabel background_label() const
90 | {
91 | return m_background_label;
92 | }
93 |
94 | const carto::VolumeRef& volume() const
95 | {
96 | return m_volume;
97 | }
98 |
99 | BucketMap::size_type n_regions() const
100 | {
101 | return m_bucketmap.size();
102 | }
103 |
104 | /** Iterate through all region labels */
105 | const_regions_iterator regions_begin() const
106 | {
107 | return const_regions_iterator(m_bucketmap.begin(),
108 | select1st());
109 | };
110 |
111 | /** Iterate through all region labels */
112 | const_regions_iterator regions_end() const
113 | {
114 | return const_regions_iterator(m_bucketmap.end(),
115 | select1st());
116 | };
117 |
118 | BucketMap::size_type region_size(Tlabel label) const
119 | {
120 | const BucketMap::const_iterator region_bucket_it = m_bucketmap.find(label);
121 | assert(region_bucket_it != m_bucketmap.end());
122 | return region_bucket_it->second.size();
123 | };
124 |
125 | /** Iterate through the coordinates of a region's voxels */
126 | const_point_iterator region_begin(Tlabel label) const
127 | {
128 | const BucketMap::const_iterator region_bucket_it = m_bucketmap.find(label);
129 | assert(region_bucket_it != m_bucketmap.end());
130 | return const_point_iterator(region_bucket_it->second.begin(),
131 | select1st());
132 | };
133 |
134 | /** Iterate through the coordinates of a region's voxels */
135 | const_point_iterator region_end(Tlabel label) const
136 | {
137 | const BucketMap::const_iterator region_bucket_it = m_bucketmap.find(label);
138 | assert(region_bucket_it != m_bucketmap.end());
139 | return const_point_iterator(region_bucket_it->second.end(),
140 | select1st());
141 | };
142 |
143 | private:
144 | const Tlabel m_background_label;
145 | carto::VolumeRef m_volume;
146 | aims::BucketMap m_bucketmap;
147 | }; // class LabelVolume
148 |
149 | }; // namespace yl
150 |
151 | #endif // !defined(YL_LABEL_VOLUME_HH_INCLUDED)
152 |
--------------------------------------------------------------------------------
/src/library/label_volume.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | namespace yl
39 | {
40 |
41 | template
42 | LabelVolume::
43 | LabelVolume(const carto::VolumeRef &vol,
44 | Tlabel background)
45 | : m_background_label(background), m_volume(vol), m_bucketmap()
46 | {
47 | const int size_x = m_volume.getSizeX();
48 | const int size_y = m_volume.getSizeY();
49 | const int size_z = m_volume.getSizeZ();
50 |
51 | for(int z = 0; z < size_z; ++z)
52 | for(int y = 0; y < size_y; ++y)
53 | for(int x = 0; x < size_x; ++x)
54 | {
55 | const Tlabel label = m_volume.at(x, y, z);
56 | if(label != background) {
57 | m_bucketmap[label].insert(Bucket::value_type(Point3d(x, y, z), Void()));
58 | }
59 | }
60 | }
61 |
62 | template
63 | void LabelVolume::
64 | merge_regions(Tlabel eating_label, Tlabel eaten_label)
65 | {
66 | const BucketMap::iterator eating_bucket_it = m_bucketmap.find(eating_label);
67 | BucketMap::iterator eaten_bucket_it = m_bucketmap.find(eaten_label);
68 |
69 | assert(eating_bucket_it != m_bucketmap.end());
70 | assert(eaten_bucket_it != m_bucketmap.end());
71 |
72 | Bucket & eating_bucket = eating_bucket_it->second;
73 | Bucket & eaten_bucket = eaten_bucket_it->second;
74 |
75 | for(Bucket::iterator
76 | point_it = eaten_bucket.begin(),
77 | point_it_end = eaten_bucket.end();
78 | point_it != point_it_end;
79 | ++point_it) {
80 | const Point3d & point = point_it->first;
81 | const int & x = point[0];
82 | const int & y = point[1];
83 | const int & z = point[2];
84 | m_volume.at(x, y, z) = eating_label;
85 | eating_bucket.insert(*point_it);
86 | }
87 |
88 | m_bucketmap.erase(eaten_bucket_it);
89 | }
90 |
91 | template
92 | void LabelVolume::
93 | discard_region(Tlabel label)
94 | {
95 | BucketMap::iterator bucket_it = m_bucketmap.find(label);
96 | assert(bucket_it != m_bucketmap.end());
97 |
98 | Bucket & bucket = bucket_it->second;
99 |
100 | for(Bucket::iterator
101 | point_it = bucket.begin(),
102 | point_it_end = bucket.end();
103 | point_it != point_it_end;
104 | ++point_it) {
105 | const Point3d & point = point_it->first;
106 | const int & x = point[0];
107 | const int & y = point[1];
108 | const int & z = point[2];
109 | m_volume.at(x, y, z) = m_background_label;
110 | }
111 |
112 | m_bucketmap.erase(bucket_it);
113 | }
114 |
115 | } // namespace yl
116 |
--------------------------------------------------------------------------------
/src/library/laplace_solver.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright Télécom ParisTech (2015).
3 |
4 | Contributor: Yann Leprince .
5 |
6 | This file is part of highres-cortex, a collection of software designed
7 | to process high-resolution magnetic resonance images of the cerebral
8 | cortex.
9 |
10 | This software is governed by the CeCILL licence under French law and
11 | abiding by the rules of distribution of free software. You can use,
12 | modify and/or redistribute the software under the terms of the CeCILL
13 | licence as circulated by CEA, CNRS and INRIA at the following URL:
14 | .
15 |
16 | As a counterpart to the access to the source code and rights to copy,
17 | modify and redistribute granted by the licence, users are provided only
18 | with a limited warranty and the software's author, the holder of the
19 | economic rights, and the successive licensors have only limited
20 | liability.
21 |
22 | In this respect, the user's attention is drawn to the risks associated
23 | with loading, using, modifying and/or developing or reproducing the
24 | software by the user in light of its specific status of scientific
25 | software, that may mean that it is complicated to manipulate, and that
26 | also therefore means that it is reserved for developers and experienced
27 | professionals having in-depth computer knowledge. Users are therefore
28 | encouraged to load and test the software's suitability as regards their
29 | requirements in conditions enabling the security of their systems and/or
30 | data to be ensured and, more generally, to use and operate it in the
31 | same conditions as regards security.
32 |
33 | The fact that you are presently reading this means that you have had
34 | knowledge of the CeCILL licence and that you accept its terms.
35 | */
36 |
37 | #include "laplace_solver.hh"
38 |
39 | #include "laplace_solver.tcc"
40 |
41 | template class yl::LaplaceSolver;
42 |
--------------------------------------------------------------------------------
/src/library/laplace_solver.hh:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright Télécom ParisTech (2015).
3 |
4 | Contributor: Yann Leprince .
5 |
6 | This file is part of highres-cortex, a collection of software designed
7 | to process high-resolution magnetic resonance images of the cerebral
8 | cortex.
9 |
10 | This software is governed by the CeCILL licence under French law and
11 | abiding by the rules of distribution of free software. You can use,
12 | modify and/or redistribute the software under the terms of the CeCILL
13 | licence as circulated by CEA, CNRS and INRIA at the following URL:
14 | .
15 |
16 | As a counterpart to the access to the source code and rights to copy,
17 | modify and redistribute granted by the licence, users are provided only
18 | with a limited warranty and the software's author, the holder of the
19 | economic rights, and the successive licensors have only limited
20 | liability.
21 |
22 | In this respect, the user's attention is drawn to the risks associated
23 | with loading, using, modifying and/or developing or reproducing the
24 | software by the user in light of its specific status of scientific
25 | software, that may mean that it is complicated to manipulate, and that
26 | also therefore means that it is reserved for developers and experienced
27 | professionals having in-depth computer knowledge. Users are therefore
28 | encouraged to load and test the software's suitability as regards their
29 | requirements in conditions enabling the security of their systems and/or
30 | data to be ensured and, more generally, to use and operate it in the
31 | same conditions as regards security.
32 |
33 | The fact that you are presently reading this means that you have had
34 | knowledge of the CeCILL licence and that you accept its terms.
35 | */
36 |
37 | #ifndef LAPLACE_SOLVER_HH_INCLUDED
38 | #define LAPLACE_SOLVER_HH_INCLUDED
39 |
40 | #include
41 |
42 | #include
43 |
44 | #include
45 |
46 | namespace yl
47 | {
48 |
49 | template
50 | class LaplaceSolver
51 | {
52 | BOOST_STATIC_ASSERT_MSG(std::numeric_limits::is_specialized,
53 | "LaplaceSolver can only be specialized for types"
54 | " with std::numeric_limits support");
55 | BOOST_STATIC_ASSERT_MSG(!std::numeric_limits::is_integer,
56 | "LaplaceSolver can only be specialized for "
57 | " floating-point (non-integer) types");
58 |
59 | public:
60 | explicit LaplaceSolver(const carto::VolumeRef& classif);
61 |
62 | /** Initialize the output volume to a reasonable value
63 | *
64 | * 0 in CSF, 1 in white matter, 0.5 in the cortex
65 | */
66 | void initialize_solution();
67 |
68 | void SOR(Real absolute_precision,
69 | float typical_cortical_thickness);
70 | void clamp_to_range(Real min, Real max);
71 | void eliminate_extrema();
72 |
73 | carto::VolumeRef solution() const;
74 |
75 | static Real best_precision() {
76 | return 11 * std::numeric_limits::epsilon();
77 | }
78 |
79 | void set_verbosity(const int verbosity) {
80 | m_verbosity = verbosity;
81 | }
82 |
83 | private:
84 | static const int s_border_width = 1;
85 |
86 | const carto::VolumeRef m_classif;
87 | carto::VolumeRef m_solution;
88 | int m_verbosity;
89 | };
90 |
91 | } // namespace yl
92 |
93 | #endif // !defined(LAPLACE_SOLVER_HH_INCLUDED)
94 |
--------------------------------------------------------------------------------
/src/library/propagate_along_field.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright CEA (2014).
3 | Copyright Université Paris XI (2014).
4 |
5 | Contributor: Yann Leprince .
6 |
7 | This file is part of highres-cortex, a collection of software designed
8 | to process high-resolution magnetic resonance images of the cerebral
9 | cortex.
10 |
11 | This software is governed by the CeCILL licence under French law and
12 | abiding by the rules of distribution of free software. You can use,
13 | modify and/or redistribute the software under the terms of the CeCILL
14 | licence as circulated by CEA, CNRS and INRIA at the following URL:
15 | .
16 |
17 | As a counterpart to the access to the source code and rights to copy,
18 | modify and redistribute granted by the licence, users are provided only
19 | with a limited warranty and the software's author, the holder of the
20 | economic rights, and the successive licensors have only limited
21 | liability.
22 |
23 | In this respect, the user's attention is drawn to the risks associated
24 | with loading, using, modifying and/or developing or reproducing the
25 | software by the user in light of its specific status of scientific
26 | software, that may mean that it is complicated to manipulate, and that
27 | also therefore means that it is reserved for developers and experienced
28 | professionals having in-depth computer knowledge. Users are therefore
29 | encouraged to load and test the software's suitability as regards their
30 | requirements in conditions enabling the security of their systems and/or
31 | data to be ensured and, more generally, to use and operate it in the
32 | same conditions as regards security.
33 |
34 | The fact that you are presently reading this means that you have had
35 | knowledge of the CeCILL licence and that you accept its terms.
36 | */
37 |
38 | #include "propagate_along_field.hh"
39 |
40 | #include
41 | #include
42 |
43 | #include
44 |
45 | using carto::VolumeRef;
46 | using std::clog;
47 | using std::endl;
48 | using boost::shared_ptr;
49 | using boost::make_shared;
50 |
51 |
52 | const float yl::PropagateAlongField::default_step = 0.03f;
53 | const unsigned int yl::PropagateAlongField::default_max_iter = 1000;
54 |
55 | yl::PropagateAlongField::
56 | PropagateAlongField(const shared_ptr& vector_field)
57 | : m_vector_field(vector_field),
58 | m_max_iter(default_max_iter), m_step(default_step), m_verbose(debug_output)
59 | {
60 | }
61 |
62 | yl::PropagateAlongField::
63 | PropagateAlongField(const VolumeRef& fieldx,
64 | const VolumeRef& fieldy,
65 | const VolumeRef& fieldz)
66 | : m_vector_field(make_shared(fieldx,
67 | fieldy,
68 | fieldz)),
69 | m_max_iter(default_max_iter), m_step(default_step), m_verbose(debug_output)
70 | {
71 | }
72 |
73 | yl::PropagateAlongField::~PropagateAlongField()
74 | {
75 | }
76 |
77 | void
78 | yl::PropagateAlongField::setVerbose(int verbosity)
79 | {
80 | m_verbose = verbosity;
81 | }
82 |
83 | void
84 | yl::PropagateAlongField::setStep(float step)
85 | {
86 | m_step = step;
87 | }
88 |
89 | void
90 | yl::PropagateAlongField::setMaxIter(unsigned int max_iter)
91 | {
92 | m_max_iter = max_iter;
93 | }
94 |
95 |
96 | #include "propagate_along_field.tcc"
97 |
98 | template
99 | int16_t yl::PropagateAlongField::ascend_until_nonzero(
100 | const Point3df &start_point,
101 | const carto::VolumeRef &seeds,
102 | int16_t ignore_label
103 | ) const;
104 | template
105 | carto::VolumeRef
106 | yl::PropagateAlongField::propagate_regions(
107 | const carto::VolumeRef &seeds,
108 | int16_t target_label
109 | ) const;
110 | template
111 | std::pair, carto::VolumeRef >
112 | yl::PropagateAlongField::propagate_regions_keeping_dests