ITK Configuring and Building for Ubuntu Linux

From KitwarePublic
Revision as of 15:55, 3 October 2016 by Matt.mccormick (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Introduction

These notes comprise developing ITK projects in Ubuntu GNU/Linux v9.04 (Jaunty Jackalope), and are linked from ITK Configuring and Building.

The Insight Segmentation and Registration Toolkit (ITK) is "an open-source, cross-platform system that provides developers with an extensive suite of software tools for image analysis".

Implementation details: "ITK is implemented in C++. ITK is cross-platform, using the CMake build environment to manage the configuration process. In addition, an automated wrapping process generates interfaces between C++ and interpreted programming languages such as Tcl, Java, and Python (using CableSwig)."

Licence: "ITK is copyrighted by the Insight Software Consortium, a non-profit alliance of organizations and individuals interested in supporting ITK. The software is distributed as open source under the OSI-approved BSD license."

Note that there's a closed source project also called ITK, and in the same field: Image Registration Toolkit (ITK). But these notes document the Insight Segmentation and Registration Toolkit, and that's what I'll refer to by ITK unless otherwise specified.

Resources:

Building and installing ITK from source code

My own experience is that sooner or later you will need to upgrade to the latest version of ITK, or make some configuration change, or add "Review" or "Patented" functions, etc. So I'd say that if you are in for any serious usage of ITK, you are better off downloading, compiling and installing the source code. The rest of this section explains how to do this. (If you don't really need to hack into ITK, there are some notes on how to install using Ubuntu packages in the next section).

Assuming that you are fine with Released code and don't need the latest CVS version, first download the ITK source code. As of this writing, the latest version is Release 3.14, so download the tarball InsightToolkit-3.14.0.tar.gz. (If you need the latest CVS version, see the file GettingStarted.txt that comes with the Released source code.)

Save the tarball to some directory, e.g. I use /usr/local/itk, and untar it

$ sudo tar xvzf InsightToolkit-3.14.0.tar.gz

This will create a directory called /usr/local/itk/InsightToolkit-3.14.0, and you can delete the tarball

$ sudo rm -rf InsightToolkit-3.14.0.tar.gz

Create a binary directory to compile the code, for example

$ sudo mkdir /usr/local/itk/InsightToolkit-3.14.0/bin

Change directory to the binary directory, and run the CMake configuration tool

$ cd /usr/local/itk/InsightToolkit-3.14.0/bin
$ sudo ccmake -DITK_USE_REVIEW=ON ..

Initially, you get the CMake interface with an "EMPTY CACHE" message. Press "c" to configure. Configuration may take for a little bit. At the end, the following options are available by default

BUILD_DOXYGEN                   *OFF
BUILD_EXAMPLES                  *ON
BUILD_SHARED_LIBS               *OFF
BUILD_TESTING                   *ON
CMAKE_BACKWARDS_COMPATIBILITY   *2.4
CMAKE_BUILD_TYPE                *
CMAKE_INSTALL_PREFIX            */usr/local
ITK_USE_KWSTYLE                 *OFF

I personally had to build ITK with the following options to make the Symmetric Log-Domain Diffeomorphic Demons Algorithm work, but you may want to use different options

BUILD_DOXYGEN                   *OFF
BUILD_EXAMPLES                  *ON
BUILD_SHARED_LIBS               *ON
BUILD_TESTING                   *ON
CMAKE_BACKWARDS_COMPATIBILITY   *2.4
CMAKE_BUILD_TYPE                *Release
CMAKE_INSTALL_PREFIX            */usr/local
ITK_USE_KWSTYLE                 *OFF

Note that CMAKE_INSTALL_PREFIX contains the root directory where compiled code and include files will be installed under. With the option selected above, for example, once you install you will get files copied to

/usr/local/bin
/usr/local/include/InsightToolkit
/usr/local/lib/InsightToolkit

Press "c" to configure. Because of the command line option -DITK_USE_REVIEW=ON that we used above to build the "Review" files too, a warning message is displayed

Attention: You have chosen to use the files in the Review directory. The Copyright of these files has not been cleared up, and the coding style and API of the classes in the Review directory may change drastically as it get code reviews from the developers. Please set ITK_USE_REVIEW to OFF if you don't want to use these files.

Press "e" to exit the help screen, and then "g" to generate the Makefiles. (If the "g" command is not available, you may need to press "c" to configure again). This will also exit CMake if successful. Then, run make to compile ITK

$ sudo make -j4

The -j4 option will use parallel compilation if you have more than 1 processor. Compilation will take for a long time, even on a fast desktop (I have 4 processors, 16G of RAM and a 64 bit architecture). Once it finishes successfully you can install the files. Note that with the options above, the files will be installed to the same places where the Ubuntu package would put them.

$ sudo make install

The libraries compiled this way are

$ ls /usr/local/include/InsightToolkit/
Algorithms  BasicFilters  Common  gdcm  IO  itkConfigure.h  Numerics  Review  SpatialObject  Utilities

Installing ITK from Ubuntu packages

As mentioned in the previous section, if you are going to develop in ITK, you probably want to build and installing ITK from source code. Among other reasons, the Ubuntu packages don't include the "Review" and "Patented" functions. If you however want to go for a simple install using the Ubuntu package system, keep reading.

Ubuntu has the following packages available:

$ sudo apt-get install cmake insighttoolkit3-examples libfftw3-dev libinsighttoolkit3-dev \
libinsighttoolkit3.6 python-insighttoolkit3 tcl8.4 tcl8.4-insighttoolkit3 \
tk8.4

ITK files are installed in

$ find /usr/ -iname "*insight*"
/usr/share/tcltk/tcl8.4/insighttoolkit3
/usr/share/doc/insighttoolkit3-examples
/usr/share/doc/libinsighttoolkit3.6
/usr/share/doc/libinsighttoolkit3.6/InsightLogo.gif
/usr/share/doc/tcl8.4-insighttoolkit3
/usr/share/doc/libinsighttoolkit3-dev
/usr/share/doc/libinsighttoolkit3-dev/InsightDeveloperStart.doc.gz
/usr/share/doc/libinsighttoolkit3-dev/InsightDeveloperStart.pdf.gz
/usr/share/doc/python-insighttoolkit3
/usr/share/python-support/python-insighttoolkit3
/usr/share/python-support/python-insighttoolkit3/InsightToolkit.py
/usr/share/man/man3/insighttoolkit.3.gz
/usr/share/lintian/overrides/libinsighttoolkit3.6
/usr/share/lintian/overrides/tcl8.4-insighttoolkit3
/usr/share/lintian/overrides/python-insighttoolkit3
/usr/include/InsightToolkit
/usr/lib/python-support/python-insighttoolkit3
/usr/lib/InsightToolkit

Probably the most interesting directory for the moment is the directory of the header files

$ ls /usr/include/InsightToolkit
Algorithms    Common  IO              Numerics       Utilities
BasicFilters  gdcm    itkConfigure.h  SpatialObject

Dependencies and interesting libraries and programs

C++ compiler (dependency)

In this section I comment on some libraries and programs that, despite not being automatically installed with the basic ITK toolkit, are very useful.

You also need to have a C++ compiler

$ sudo apt-get install g++

libpng, libtiff (dependency)

I was trying to compile some legacy code from Martin Bishop (i.e running 'make' after creating the Makefile with 'cmake'), and some libraries are required. I don't know whether this is a dependency of ITK in general, or Martin's code only. The libraries can be installed using (note that you need the development packages)

$ sudo apt-get install libpng12-dev libtiff4-dev

uuid (dependency)

The universally unique id library (UUID) is required for the ITKIO library (i.e. reading from and writing to file). You can install it running

$ sudo apt-get install uuid-dev

Without this library, you will get the following error when you try to build your program (in this example, I'm trying to build an ITK project CoronaryVesselsProject from a C++ file CoronaryVessels.cxx)

 /usr/bin/make all 
 /usr/bin/cmake -H/path/to/project/src -B/path/to/project/bin --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /path/to/project/bin/CMakeFiles /path/to/project/bin/CMakeFiles/progress.make
/usr/bin/make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/path/to/project/bin'
/usr/bin/make -f CMakeFiles/CoronaryVessels.dir/build.make CMakeFiles/CoronaryVessels.dir/depend
make[2]: Entering directory `/path/to/project/bin'
cd /path/to/project/bin && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /path/to/project/src /path/to/project/src /path/to/project/bin /path/to/project/bin /path/to/project/bin/CMakeFiles/CoronaryVessels.dir/DependInfo.cmake --color=
make[2]: *** No rule to make target `/usr/lib/libuuid.so', needed by `CoronaryVessels'. Stop.
make[2]: Leaving directory `/path/to/project/bin'
make[1]: *** [CMakeFiles/CoronaryVessels.dir/all] Error 2
/usr/bin/make -f CMakeFiles/CoronaryVessels.dir/build.make CMakeFiles/CoronaryVessels.dir/build
make: *** [all] Error 2
make[2]: Entering directory `/path/to/project/bin'
make[2]: Leaving directory `/path/to/project/bin'
make[1]: Leaving directory
 `/path/to/project/bin'

Update 10 June 2011: Even if uuid-dev is installed, this error can appear. Run the following

$ grep -r uuid CMakeFiles/*

and search the output for something like

FiltersToolbox/CMakeFiles/bwregiongrow.dir/build.make:FiltersToolbox/bwregiongrow.mexa64: /usr/lib/libuuid.so

This means that the build system created by CMake is expecting the library in /usr/lib. But in a 64-bit Ubuntu Natty system, for example, libuuid.so can be found in /usr/lib/x86_64-linux-gnu instead.

A work-around is to create a symbolic link to the library where it is expected to be found

$ cd /usr/lib
$ sudo ln -s /usr/lib/x86_64-linux-gnu/libuuid.so

TCLAP

The Templatized C++ Command Line Parser is a C++ library that makes it easy to parse the command line for your ITK binary. You also get a syntax summary of your program, e.g.

$ test1 --help

USAGE:

   test1  [-r] -n <string> [--] [-v] [-h]


Where:

   -r,  --reverse
     Print name backwards

   -n <string>  --name <string>
     (required)  (value required)  Name to print

   --,  --ignore_rest
     Ignores the rest of the labeled arguments following this flag.

   -v,  --version
     Displays version information and exits.

   -h,  --help
     Displays usage information and exits.


   Command description message

You need to install the package libtclap-dev

$ sudo apt-get install libtclap-dev

TCLAP is provided as header files, so as long as you make the include path visible to the compiler, you don't need to link to any library (in fact, there's no library to link to). To make the path available, you need to edit your CMakeLists.txt file and add the line

INCLUDE_DIRECTORIES(/usr/include/tclap)

Symmetric Log-Domain Diffeomorphic Demons Algorithm

As of this writing, the Log-Domain Diffeomorphic Demons algorithm is the latest registration algorithm proposed by Vercauteren and Dru. It builds on the Diffeomorphic Demons algorithm. The proposed code is not included in ITK yet, not even in "Review". It requires ITK version 3.14 or greater.

To build the example code, first download the zip file SourceCode3_LogDomainDemonsRegistration-0.0.3-Source.zip from the Insight Journal in "An ITK Implementation of the Symmetric Log-Domain Diffeomorphic Demons Algorithm", save locally and unzip

$ unzip SourceCode3_LogDomainDemonsRegistration-0.0.3-Source.zip

Change to the unzipped directory. You don't need to create a directory for binaries (the Makefiles will create it for you)

$ cd LogDomainDemonsRegistration-0.0.3-Source/
$ ls
Applications    Code              IJMacros.txt         sd_kwstyle.kws.xml  TestingData
Documents       README.txt        sd_kwstyle.txt       CMakeLists.txt  
FindMatlab.cmake  SDCMakeMacros.cmake  Testing

Build instructions can be found in the file README.txt. Basically, you need to configure with CMake. Assuming that you have Matlab (not mandatory) and want to create a project that can be opened from Eclipse (see section "Compiling an ITK project from the Eclipse open development platform" for more information), type the following

$ cmake -DITK_DIR=/usr/local/lib/InsightToolkit -DMATLAB_ROOT=/usr/local/matlab/R2008b \
-G"Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE=Release  .

(You may need to modify the paths above, depending on your system configuration). CMake will produce many warning messages, that we can ignore, for instance

[...]
WARNING: ITKCommon_LIBRARY and ITKCommon_LIBRARIES are undefined. Using ITKCommon in linker
WARNING: ITKCommon_INCLUDE_DIR and ITKCommon_INCLUDE_DIR are undefined. No specific include dir will be used for ITKCommon
WARNING: ITKIO_LIBRARY and ITKIO_LIBRARIES are undefined. Using ITKIO in linker
WARNING: ITKIO_INCLUDE_DIR and ITKIO_INCLUDE_DIR are undefined. No specific include dir will be used for ITKIO
WARNING: ITKStatistics_LIBRARY and ITKStatistics_LIBRARIES are undefined. Using ITKStatistics in linker
[...]

Note that this code requires that "Review" has been compiled in ITK, using the option -DITK_USE_REVIEW=ON as explained in section "Building and installing ITK from source code" above

Then compile the code

$ make -j4
[...Output removed...]
$ ls bin/
DemonsRegistration  ImageCompare  LogDomainDemonsRegistration

Create a new subversion ITK project

The HelloWorld files of the example in section "2.1.1. Hello World!" of the ITK guide are in

$ ls /usr/share/doc/insighttoolkit3-examples/examples/Installation
CMakeLists.txt  HelloWorld.cxx

Create the subversion directory structure (trunk is for the development version of the project)

$ mkdir -p itk-helloworld/trunk/bin
$ mkdir -p itk-helloworld/trunk/src

Copy the ITK example files to the source directory

$ cp /usr/share/doc/insighttoolkit3-examples/examples/Installation/* itk-helloworld/trunk/src

Edit CMakeLists.txt to add the following line to the top of the file (to remove warning message)

cmake_minimum_required(VERSION 2.6)

Create an empty ChangeLog file to keep a log of the project evolution

$ touch itk-helloworld/trunk/ChangeLog

Add everything to the subversion repository. This can be done in different ways (see the Subversion Book for full documentation on how to use subversion), for example

$ export SVNREP=svn://foo.comlab.ox.ac.uk/johndoe
$ svn mkdir $SVNREP/itk-helloworld

Committed revision 11093.

$ svn co $SVNREP/itk-helloworld itk-helloworld
Checked out revision 11093.

$ svn add itk-helloworld/*
A         itk-helloworld/trunk
A         itk-helloworld/trunk/bin
A         itk-helloworld/trunk/ChangeLog
A         itk-helloworld/trunk/src
A         itk-helloworld/trunk/src/CMakeLists.txt
A         itk-helloworld/trunk/src/HelloWorld.cxx

$ svn ci itk-helloworld -m "Create new ITK project"
Adding         itk-helloworld/trunk
Adding         itk-helloworld/trunk/ChangeLog
Adding         itk-helloworld/trunk/bin
Adding         itk-helloworld/trunk/src
Adding         itk-helloworld/trunk/src/CMakeLists.txt
Adding         itk-helloworld/trunk/src/HelloWorld.cxx
Transmitting file data ...
Committed revision 11094.

Compiling an ITK project from the command line

Change directory to the binary directory

$ cd itk-helloworld/trunk/bin

Now start CMake in order to create the Makefile

$ ccmake ../src

This will show a console interface with the options

CMAKE_BUILD_TYPE       Debug
CMAKE_INSTALL_PREFIX   /usr/local
ITK_DIR                /usr/lib/InsightToolkit

Press 'c' to configure, and then 'g' to generate the Makefile. Now you should have

$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile

Now compile the project

$ make
/usr/bin/cmake -H/path-to-project/itk-helloworld/trunk/src -B/path-to-project/itk-helloworld/trunk/bin --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /path-to-project/itk-helloworld/trunk/bin/CMakeFiles /path-to-project/itk-helloworld/trunk/bin/CMakeFiles/progress.make
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/path-to-project/itk-helloworld/trunk/bin'
make -f CMakeFiles/HelloWorld.dir/build.make CMakeFiles/HelloWorld.dir/depend
make[2]: Entering directory `/path-to-project/itk-helloworld/trunk/bin'
cd /path-to-project/itk-helloworld/trunk/bin && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /path-to-project/itk-helloworld/trunk/src /path-to-project/itk-helloworld/trunk/src /path-to-project/itk-helloworld/trunk/bin /path-to-project/itk-helloworld/trunk/bin /path-to-project/itk-helloworld/trunk/bin/CMakeFiles/HelloWorld.dir/DependInfo.cmake --color=
Scanning dependencies of target HelloWorld
make[2]: Leaving directory `/path-to-project/itk-helloworld/trunk/bin'
make -f CMakeFiles/HelloWorld.dir/build.make CMakeFiles/HelloWorld.dir/build
make[2]: Entering directory `/path-to-project/itk-helloworld/trunk/bin'
/usr/bin/cmake -E cmake_progress_report /path-to-project/itk-helloworld/trunk/bin/CMakeFiles 1
[100%] Building CXX object CMakeFiles/HelloWorld.dir/HelloWorld.cxx.o
/usr/bin/c++    -ftemplate-depth-50 -Wall -g -I/usr/include/InsightToolkit/gdcm/src -I/usr/include/InsightToolkit/gdcm -I/usr/include/InsightToolkit/Utilities/vxl/core -I/usr/include/InsightToolkit/Utilities/vxl/vcl -I/usr/include/InsightToolkit/Utilities/vxl/v3p/netlib -I/usr/include/InsightToolkit/Utilities -I/usr/include/InsightToolkit/Utilities/itkExtHdrs -I/usr/include/InsightToolkit/Utilities/nifti/znzlib -I/usr/include/InsightToolkit/Utilities/nifti/niftilib -I/usr/include/InsightToolkit/Utilities/expat -I/usr/include/InsightToolkit/Utilities/DICOMParser -I/usr/include/InsightToolkit/Utilities/NrrdIO -I/usr/include/InsightToolkit/Utilities/MetaIO -I/usr/include/InsightToolkit/SpatialObject -I/usr/include/InsightToolkit/Numerics/NeuralNetworks -I/usr/include/InsightToolkit/Numerics/Statistics -I/usr/include/InsightToolkit/Numerics/FEM -I/usr/include/InsightToolkit/IO -I/usr/include/InsightToolkit/Numerics -I/usr/include/InsightToolkit/Common -I/usr/include/InsightToolkit/BasicFilters -I/usr/include/InsightToolkit/Algorithms -I/usr/include/InsightToolkit   -o CMakeFiles/HelloWorld.dir/HelloWorld.cxx.o -c /path-to-project/itk-helloworld/trunk/src/HelloWorld.cxx
Linking CXX executable HelloWorld
/usr/bin/cmake -E cmake_link_script CMakeFiles/HelloWorld.dir/link.txt --verbose=1
/usr/bin/c++     -ftemplate-depth-50 -Wall -g    CMakeFiles/HelloWorld.dir/HelloWorld.cxx.o  -o HelloWorld -rdynamic -L/usr/lib/InsightToolkit -lITKCommon -litkvnl_inst -litkvnl_algo -litkvnl -litkv3p_netlib -litkvcl -lm -litksys -lpthread -ldl -lm -Wl,-rpath,/usr/lib/InsightToolkit 
make[2]: Leaving directory `/path-to-project/itk-helloworld/trunk/bin'
/usr/bin/cmake -E cmake_progress_report /path-to-project/itk-helloworld/trunk/bin/CMakeFiles  1
[100%] Built target HelloWorld
make[1]: Leaving directory `/path-to-project/itk-helloworld/trunk/bin'
/usr/bin/cmake -E cmake_progress_start /path-to-project/itk-helloworld/trunk/bin/CMakeFiles 0

Now you should have

$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  HelloWorld  Makefile

(note the new binary HelloWorld). Run the binary to check that it works

$ ./HelloWorld 
ITK Hello World !

Compiling an ITK project from the Eclipse open development platform

The Eclipse open development platform and its C/C++ Development Tools can be installed with

$ sudo apt-get install eclipse eclipse-cdt

There are different options for those who want to use CMake and Eclipse for CMake enabled projects. Here we describe the Eclipse CDT4 Generator option.

Change to the build directory

$ cd itk-helloworld/trunk/bin

Run cmake

$ cmake -G"Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../src
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /path-to-project/itk-helloworld/trunk/bin

You need to edit CMakeLists.txt and make the project name different from the executable name. For example, edit the file so that it looks like this

cmake_minimum_required(VERSION 2.6)

# This project is designed to be built outside the Insight source tree.
PROJECT(HelloWorldProject)

# Find ITK.
FIND_PACKAGE(ITK REQUIRED)
IF(ITK_FOUND)
  INCLUDE(${ITK_USE_FILE})
ENDIF(ITK_FOUND)

ADD_EXECUTABLE(HelloWorld HelloWorld.cxx )

TARGET_LINK_LIBRARIES(HelloWorld ITKCommon)

Re-run cmake

$ cmake -G"Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../src
-- Configuring done
-- Generating done
-- Build files have been written to: /path-to-project/itk-helloworld/trunk/bin

Now the project files have been created as hidden files (.cproject, .project)

$ ls -a
.  ..  CMakeCache.txt  CMakeFiles  cmake_install.cmake  .cproject  Makefile  .project  .svn

Launch the Eclipse GUI, and import the CMake project as described in the Eclipse CDT4 Generator:

  1. Import project using Menu File->Import
  2. Select General->Existing projects into workspace:
  3. Browse where your build tree is and select the root build tree directory. Keep "Copy projects into workspace" unchecked.
  4. You get a fully functional eclipse project

Now you can

  • open the C++ source file HelloWorld.cxx from HelloWorldProject-Debug@bin -> HelloWorldProject -> HelloWorld.cxx
  • compile the code with the button "Build all", also as the menu option Project -> Build all, or with the keyboard shortcut CTRL+B
  • run the code with Project -> Run (or the corresponding button). This will ask you to create a launch configuration. Select "Name: HelloWorldProject-Debug", "Project: HelloWorldProject-Debug@bin", "C/C++ Application: HelloWorld". Clicking on the button "Run" will show in the terminal the stdout and stderr output
ITK Hello World !

Notes

Adding external code directories (not in the include path)

If you have some code in a directory that is not in the include path (typically, because it was not created when compiling ITK), you need to edit your CMakeLists.txt file and add a line like the following

# The non-standard ITK include file directories.
INCLUDE_DIRECTORIES(/path/to/external/directory)