A tool for automatic cortical shape identification for QCT scans.

This software is based on "Reinhold S. et al. (2019) [**An Analysis by Synthesis Approach for Automatic Vertebral Shape Identification in Clinical QCT**]( In: Brox T., Bruhn A., Fritz M. (eds) Pattern Recognition. GCPR 2018. Lecture Notes in Computer Science, vol 11269. Springer, Cham." (Full article, preprint)

Binary Releases

The current release is v1.2.2:

Older releases can be found here.

Build from Source

The build instructions below are for *NIX (Unix/Linux/macOS) systems only. For Windows build, the configuration steps (1 to 4) should be the same, but the compilation step might be different, dependent on the compiler used.

C++ Library



CortidQCT uses the Hunter package manager to manage its dependencies. Therefore, it's not required to manually install any dependecies. Hunter builds and installs all dependencies automatically in the ${HOME}/.hunter directory. This can be changed by setting the HUNTER_ROOT environment variable.

It is strongly recommended to install CortidQCT to a custom location. For this, set the CortidQCT_ROOT environment to the desired path.

  1. Clone the repository:
    1 git clone htts://
  2. Init the submodules:
    1 cd CortidQCT
    2 git submodule update --init
  3. Create build directory
    1 mkdir Build
    2 cd build
  4. Run cmake
  5. Run
    1 make
  6. installation
    1 make install

MATLAB Toolbox



Navigate to the installation folder in MATLAB, then open matlab/CortidQCT.prj. This opens the toolbox packaging dialog. Click 'Package' and close the dialog. Double click the new file CortidQCT.mltbx to install the toolbox.


Using CortidQCT is a two step process. First a model for each different protocol must be generated using the MATLAB toolbox. After that, either the command line interface (CLI) tool, the C+++ library or the MATLAB interface can be used to identify the cortex using the generated model.

Model Creation

Model Creation Screen 1
Model Creation Screen 2
General model parameters dialog Per VOI parameters dialog


1 CortidQCT.CreateModel

to start the model creation UI. On the first screen (general tab, see left screenshot above) meta and general information about the model can be entered. In the VOIs tab (see right screenshot above), per VOI prior parameters can be entered. Ensure that each VOI gets an unique label. Since the interpretation of the parameters of log-normally distributed cortex width parameter is not very intuituve, a plot of the current PDF is plotted in the bottom right. The red shaded region shows the 95% confidence interval.

After specifying all VOIs, click the Generate Model button start start the generation process. Depending on the hardware, this process may take a while. When the model generation completed, a green Save Model button will appear. Ensure to save the model before quitting the dialog.

Cortex Identification

You can either write your own program that uses the C++ library, use the built-in CLI tool or use the MATLAB interface that comes with the toolbox.

Command Line interface

After compilation the CortidQCT_CLI executable can be found in build/app. It requires at least three parameters:

  1. A YAML configuration file
  2. The input volume / scan
  3. Path to the output mesh file
  4. Optional: Path to a file where to write the per-vertex labels to
1 app/CortidQCT_CLI <configurationFile> <inputVolume> <outputMesh> [outputLabels]

C++ Library

The API Reference can be found here.

C Bindings

Available since Version v1.1.0. See the C-Bindings module in the API Reference for details. An example can be found in bindings/C/examples/cli.c.

Matlab Interface

Since version 1.2.0 CortidQCT also has MATLAB bindings, enabling the direct interaction with the library from within MATLAB.

An example implementation of the CLI interface can be found in examples/CortidQCT_cli.m:

1 function [resultMesh, volume] = CortidQCT_cli(configFilename, volumeFilename, outputMeshFilename, varargin)
2 %CORTIDQCT-CLI Identifies the cortical shape of the given volume and writes
3 %the output to the given file
5 import CortidQCT.lib.*;
7 % Load volume
8 volume = VoxelVolume.fromFile(volumeFilename);
10 % Create MeshFitter using config file
11 fitter = MeshFitter(configFilename);
13 % fit
14 result =;
16 % write output
17 result.mesh.writeToFile(outputMeshFilename, varargin{:});
19 % plot results
20 volume.plot;
21 hold on;
22 h = result.mesh.plot;
23 axis equal
24 colormap gray
26 h.FaceColor = 'g';
27 h.FaceAlpha = 0.3;
29 resultMesh = result.mesh;
31 end

This function mimics the CLI application with additional visualization of the result:

Example matlab plot

Configuration File

The main purpose of the configuration file is to specify the reference mesh and the model file. Additionally some parameters can be customized. The configuration file must be in the YAML format.

Reference mesh

The following snippet defines a refernece mesh path/to/reference/mesh.coff consisting of a colored object file format mesh. Here each vertex color corresponds to a model label. The mapping is defined in the colorToLabelMap section. The custom mapping is supplied in the map section. Each element must be a two element list that contains a three element list and a single ineteger label: [[R, G, B], Label].

The origin: centerd parameter states that the centroid of the reference mesh should be moved into the center of the image, which is the default behaviour.

1 referenceMesh:
2  mesh: path/to/refernce/mesh.coff
3  colorToLabelMap:
4  type: custom
5  map:
6  - [[255, 0, 0], 1]¬
7  - [[0, 255, 0], 0]¬
8  - [[255, 255, 0], 2]¬
9  - [[0, 0, 255], 3]¬
10  undefinedLabel: 4
11  origin: centered

If a relative path is given, it is interpreted as relative to the configuration file.

Measurement Model

The measurement model is specified by the path to the previously generated model file:

1 measurementModel: path/to/my/model.yml

If a relative path is given, it is interpreted as relative to the configuration file.

Optimization Parameters

There are several optional parameters that can be tuned:

1 sigmaE: 5.4
2 sigmaS: 2
3 maxIterations: 100
4 minNonDecreasing: 3
5 decay: 0.1
Decay Mode

Since an approximate alternating optimization scheme is used, it might happen, that the optimizer oscillates between two solutions and never completely converges. To circumvent this oscillation, the mean absolute displacement is monitored. Everytime it doesn't decrease for at least minNonDecreasing iterations, the current sigmaS is multiplied by decay, resulting in a decay of step size over time, enforcing convergence.


This implementation is, opposed to the original prototype underlying the publication, highly optimized. While the original prototype required a few minutes for about 50 iterations, this implementation can make 50 iterations in about 20 seconds (on an Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz).

The optimization time does of course depends on the size of the model and the scans.