Heimdali’s overview

Heimdali is a set of commmand line tools to perform Image processing tools, based on ITK and HDF5.

It also features some helper functions to work with ITK.

Command line tools

Installation

The recommanded way to install Heimdali is using the Conda package manager.

Conda installation

Download the Python 2.7 version of miniconda corresponding to your plateform from http://conda.pydata.org/miniconda.html

Execute the downloaded file: this will install the Conda package manager.

Add the heimdali binstar channel to your config:

conda config --add channels https://conda.binstar.org/heimdali

Heimdali installation

Install the heimdali package in a environment called heim or whather name you want:

conda create -n heim heimdali

Activate the environment:

source activate heim

Your are ready to use Heimdali.

Test Heimdali installation

Download some input data to test:

git clone https://github.com/heimdali/heimdali-data

Execute the par command:

par heimdali-data/imtest_z5_y4_x3_c2.h5

Heimdali update

You can update Heimdali when a new version is released:

conda update heimdali

You may also want to keep the currently installed Heimdali version, and install a new version in another Conda environment:

conda create -n heim0.1 heimdali==0.1.0

You can now switch between the two version of Heimdali:

source activate heim

or

source activate heim0.1

Format options

These are options describing the image format. There are used each time an image is created.

option description
-z N Number of planes
-y N Number of lines
-x N Number of pixel per line
-v N Number of value per pixel
-r Floating point values

h5toinr

h5toinr convert an HDF5 image into INRimage image.

Synopsis

h5toinr  [--] [--version] [-h] <inputFilename> <outputFilename>

inrtoh5

inrtoh5 convert an INRimage image into HDF5 image.

Synopsis

inrtoh5  [--] [--version] [-h] <inputFilename> <outputFilename>

par

par prints format parameters of images.

Synopsis

par  [--wr <output.txt>] [--x0] [--y0] [--z0] [-o] [-x] [-y] [-z] [--]
     [--version] [-h] <INPUT> ...

Description

par print on stdout in the file outout.txt, the format parameters of iamges given as arguments.

The –wr options can be given the special file names stdout and stderr. If the file name output.txt starts with >>, result are written at the end of the file.

If one or more options –x0 –y0 –z0 -x -y -z is given, par print the corresponding parameters, in the Format options. This allow to use par in command subsitution, as for example:

create image-copy.h5 `par -x -y image.h5` -r

If no options are given, all format parameters are printed for all images on argument.

tpr

tpr prints the pixel values of a image subregion

Synopsis

tpr  [-x <NX>] [-y <NY>] [-z <NZ>] [-i <IX>] [-j <IY>] [-k <IZ>] [--]
        [--version] [-h] <IMAGE> ...

Description

tpr prints on standard output pixel values of IMAGE given in argument.

option description
-ix, -iy, -iz Index (counted from 0) of the subregion
-x, -y, -z Size (counted from 0) of the subregion

Artithmetic operations

Arithmetic operations between two images element by element.

Synopsis

ad image0-in image1-in [image-out]
so image0-in image1-in [image-out]
mu image0-in image1-in [image-out]
di image0-in image1-in [image-out]
min image0-in image1-in [image-out]
max image0-in image1-in [image-out]

Description

All of these commands perform an operation between image0-in and image1-in and write result to image-out. If argument image0-in or image1-in is equal to -, the command reads on standard input. If argument image-out is absent, the command writes to standard output.

command description
ad Add two images
so Subtract two images
mu Multiply two images
div Divide two images
min Compute minimum of two images
max Compute maximum of two images

All operation are performed on pixels element by element.

See also

See also Local arithmetic operations.

Local arithmetic operations

Synopsis

bi -n value [image-in] [image-out]
sc -n coeff [image-in] [image-out]
sd -n coeff [image-in] [image-out]
lo value [image-in] [image-out]
exp [image-in] [image-out]
ra [image-in] [image-out]
sba -n threshold [image-in] [image-out]
sha -n threshold [image-in] [image-out]
mb -n threshold [image-in] [image-out]
mh -n threshold [image-in] [image-out]
mo [image-in] [image-out]
car [image-in] [image-out]
vb -n threshold value [image-in] [image-out]
vh -n threshold value [image-in] [image-out]

Description

All of these commands perform an operation on image-in (which can be of any type), and write result in image-out.

image-in and image-out must have the same dimension.

If argument image-in is absent or egal to -, the command reads on standard input.

If argument image-out is absent, the command writes on standard output.

Values passed with -n are float.

command description
bi Add value to each pixel.
sc Multiply each pixel by coeff.
sd Divied each pixel by coeff.
lo Compute logarithm of each pixel.
exp Compute exponential of each pixel.
ra Compute square root of each pixel.
sba Every pixel inferior or egual to threshold is replaced by threshold.
sha Every pixel greater or egual to threshold is replaced by threshold.
mb Every pixel inferior or egual to threshold is replaced by 1 and others by 0.
mh Every pixel greater or egual to threshold is replaced by 1 and others by 0.
mo Compute each pixel modulo
car Compute each pixel square
vb Every pixel inferior or egual to threshold is replaced by value.
vh Every pixel greater or egual to threshold is replaced by value.

cco

cco change pixel type of image

Synopsis

cco  [--] [--version] [-h] <inputFilename> <outputFilename>

Description

cco convert IMAGE-IN into IMAGE-OUT.

extg

extg extract a image subregion

Synopsis

extg  [-x <NX>] [-y <NY>] [-z <NZ>] [-i <IX>] [-j <IY>] [-k <IZ>] [--]
         [--version] [-h] <FILE-IN> <FILE-OUT>

Description

extg extract a subregion in FILE-IN and write it in FILE-OUT.

option description
-ix, -iy, -iz Index (counted from 0) of the subregion
-x, -y, -z Size (counted from 0) of the subregion

raz

raz Fill an image with zero values

Synopsis

raz  [-x <NX>] [-y <NY>] [-z <NZ>] [-i <IX>] [-j <IY>] [-k <IZ>] [--]
        [--version] [-h] <IMAGE> ...

Description

raz fill the image IMAGE given in arguments with zero values.

option description
-x, -y, -z Size (counted from 0) of the subregion

melg

melg mix two images, testing on pixel values.

Synopsis

melg  [--idv <IDV>] [--idx <IDX>] [--idy <IDY>] [--idz <IDZ>] [--ivo
      <IXO>] [--ixo <IXO>] [--iyo <IYO>] [--izo <IZO>] [--ivi <IXI>]
      [--ixi <IXI>] [--iyi <IYI>] [--izi <IZI>] [--] [--version] [-h]
      <IMAGE-IN> <IMAGE-OUT

Description

melg replace pixels of a subregion IMAGE-OUT with pixels of IMAGE-IN.

option description
-ixi, -iyi, -izi Index (counted from 0) of IMAGE-IN subregion
-ixo, -iyo, -izo Index (counted from 0) of IMAGE-OUT subregion
-idx, -idy, -idz Size of subregion

fzoom

fzoom enlarge or reduce an iamge.

Synopsis

fzoom  [--sc <X>] [--] [--version] [-h] <IMAGE-IN> <IMAGE-OUT>

Description

fzoom increse or reduce the size of an image by lineary interpolation.

cim

Example

Fixed point number on 1 byte

To write a file using fixed point representation on 1 byte (char or unsigned char), one enter the fixed_point_factor values:

For example, to write in a file fixed_point_uchar.inr the pixel values 0.1, 0.2 and 0.3 with fixed point representation on 1 byte (uchar):

pixel value fixed_point_exponent fixed_point_nbits fixed_point_factor
0.1 0 8 25
0.2 0 8 51
0.3 0 8 76
echo 25 51 76 | cim -f -o 1 -x 3 > fixed_point_uchar.inr
Fixed point number on 2 or 4 bytes

To write a file using fixed point representation on 2 byte (short or unsigned short), or 4 bytes (int or unsigned int), one enter the pixel_value values.

For example, to write in a file fixed_point_ushort.inr the pixel values 0.1, 0.2 and 0.3 with fixed point representation on 2 byte (ushort):

echo 0.1 0.2 0.3 | cim -f -o 2 -x 3 > fixed_point_ushort.inr

Fixed point representation

Heimdali can write pixel values to HDF5 and Inrimage file using their floating point representation or using a fixed point representation.

The conversion is explained by the formulaes:

\[\text{pixel_value} = \text{fixed_point_factor} \times \frac {2^\text{fixed_point_exponent}} {2^\text{fixed_point_nbits} - 1}\]
\[\text{fixed_point_factor} = round \left( \text{pixel_value} \times \frac {2^\text{fixed_point_nbits} - 1} {2^\text{fixed_point_exponent}} \right)\]

where:

  • pixel_value is a float.

  • fixed_point_exponent is a char of values in \([-100, 100]\) It is a global value for the image.

  • fixed_point_factor is of type fixed_point_type, and is defined on all pixel.

  • fixed_point_nbits is the number of bits of fixed_point_type (so number of bytes times 8). As all pixel are of the same type, it is a global value for the image.

  • fixed_point_type can be:
    • char (1 byte).
    • unsigned char (1 byte).
    • short (2 bytes).
    • unsigned short (2 bytes).
    • int (4 bytes).
    • unsigned int (4 bytes).
  • round convert a floating point to the nearest lower integer.

A file stores the fixed_point_exponent (one value), and an array of fixed_point_factor of type T. When the file is read or written, these values are converted to an array of float back and forth, and computation are performed using float.

Examples (fixed_point_exponent is 0)
pixel value fixed_point_type 2^pixed_point_nbits -1 fixed_point_factor
0.11 [unsigned] char 2^8 - 1 = 255 28
0.22 [unsigned] char 2^8 - 1 = 255 56
0.33 [unsigned] char 2^8 - 1 = 255 84
0.11 [unsigned] short 2^16 - 1 = 65534 7209
0.22 [unsigned] short 2^16 - 1 = 65534 14417
0.33 [unsigned] short 2^16 - 1 = 65534 21626
0.11 [unsigned] int 2^32 - 1 = 4294967294 472446400
0.22 [unsigned] int 2^32 - 1 = 4294967294 944892800
0.33 [unsigned] int 2^32 - 1 = 4294967294 1417339264

Using ITK

Converting INRimage simulation code to ITK

Image definition

The file heimdali/itkhelper.hxx defines the type of an image.

typedef float Heimdali::PixelFloat
const unsigned int Heimdali::ImageDimension

All images are 3-dimensional.

typedef itk::VectorImage<PixelFloat, ImageDimension> Heimdali::ImageFloat

Images are 3-dimensionial, of size (nz, ny, nx).

Images contains nx * ny * nx pixels, and each pixel is a vector of nv value of type float.

nz Number of planes
ny Number of rows
nx Number of columns
nv Number of values per pixel

Internally, the image is stored in a continous block of memory, ie is a float*.

Building

Proving command line interface

Creating image

ImageFloat::Pointer Heimdali::CreateImage(unsigned int nx, unsigned int ny, unsigned int nz, unsigned int nv)

itkhelper.hxx defines the CreateImage function to create an image in the temporary program memory. It does not do any persistant operation on the disk.

For example:

Heimdali::ImageFloat::Pointer image = Heimdali::CreateImage(5,5,5,2);

create a image of 3-dimensional image with 5 planes, 5 rows and 5 columns, where is value is a vector of 2 floats.

The following code:

Heimdali::ImageFloat::Pointer image = Heimdali::CreateImage(5,5);

create a image of 3-dimensional image with 1 planes, 5 rows and 5 columns, where is value is a vector of 1 float.

See the file createInputImage.cxx for a running example.

Read and writting image

Working with the whole image
Working line by line
Working plane by plane

Modifiyting image

Using C pointer
Using wrapped C pointer
Using GetPixel, SetPixel
Using ITK iterators
Using ITK convolution
Using ITK filter

Examples

Description File
Read image using Heimdali::InrImage heimdali-inrimage_read.tar.gz
Write image using Heimdali::InrImage heimdali-inrimage_write.tar.gz
Iterate on image heimdali-inrimage_iterators.tar.gz

Heimdali API

Community

Developer guide

Build Heimdali in development mode

Development mode means building Heimdali from its source code, typically the develop branch of heimdali Git repository.

Working in development mode consists in iterating in the cycle:

  • Modify source code.
  • Build.
  • Run the test.

without having to run the make install step.

Note

You may want to use ccache to speed-up compilation.

Install dependencies

Create a conda enviromnent named heimdali-dev containing all dependencies:

conda config --add channels http://conda.binstar.org/heimdali
conda create -n heimdali-dev h5unixpipe itk-heimdali-dbg libinrimage-dbg tclap cmake pip

Note

As cmake executable is in the conda environment, it will automatically find dependant libraries provided by the conda environment . So using -DCMAKE_PREFIX_PATH=/path/to/conda/env is not required.

Warning

Do not install the heimdali package in the heimdali-dev environment, as it would conflicts with sources files (from your heimdali git repository) you are building.

Activate the conda environment:

source activate heimdali-dev
hash -r

Install lettuce:

pip install lettuce

Get test datas

Get Heimdali data files:

git clone https://github.com/heimdali/heimdali-data

Define directories

For convenience, define these 3 directories:

Variable Description
HEIMDALI_SRC_DIR
Heimdali sources (git repo), containing the
main CMakeLists.txt
HEIMDALI_DATA_DIR
Heimdali data directory (heimdali-data git repo
cloned above)
HEIMDALI_WORK_DIR
Directory for temporary files (building sources,
building examples, running tests).

For example:

cd heimdali
export HEIMDALI_SRC_DIR=$PWD

cd heimdali-data
export HEIMDALI_DATA_DIR=$PWD

export HEIMDALI_WORK_DIR=/path/to/<heimdali-work-dir>

Note

It may be useful to have HEIMDALI_SRC_DIR and HEIMDALI_WORK_DIR if different locations. A typical example is having HEIMDALI_SRC_DIR on a backed-up NAS file system, while HEIMDALI_WORK_DIR on a local hard disk for speed read/write operations.

Warning

The conda environment must be activated and these 3 variables must be defined for the sections bellow.

Build Heimdali

On Mac OS X your will need to install /Developer/SDKs/MacOSX10.6, and use it:

export MACOSX_DEPLOYMENT_TARGET=10.6

Build heidmali:

mkdir -p $HEIMDALI_WORK_DIR/build_debug/src
cd $HEIMDALI_WORK_DIR/build_debug/src
cmake -DCMAKE_BUILD_TYPE=Debug $HEIMDALI_SRC_DIR
make -j 4

Configure examples

Heimdali has been built in HEIMDALI_WORK_DIR/build_debug/src and is not installed (development mode), we need to specified Heimdali path to cmake.

for example in create_input_image inrimage_read inrimage_write
do
    mkdir -p $HEIMDALI_WORK_DIR/build_debug/$example
    cd $HEIMDALI_WORK_DIR/build_debug/$example
    cmake \
        -DCMAKE_BUILD_TYPE=Debug \
        -DHEIMDALI_DIR=$HEIMDALI_WORK_DIR/build_debug/src \
        $HEIMDALI_SRC_DIR/example/$example
done

Example are built latter by lettuce.

Run functional tests

Add path to the built executables:

export PATH=$HEIMDALI_WORK_DIR/build_debug/src/cmd:$PATH

Run the functional tests:

cd $HEIMDALI_SRC_DIR/tests
lettuce

Other CMake usefull variables

Variable Description
CMAKE_PREFIX_PATH
Where CMake will search for dependent
libraries.
CMAKE_INSTALL_PREFIX
Where CMake will install things during
make install.

Dependencies

Here is a summary of Heimdali dependencies, if you want to apply modifications on it:

sources or homepage conda recipe
heimdali heimdali recipe
itk-heimdali itk-heimdali recipe
tclap tclap recipe
h5unixpipe h5unixpipe recipe
libinrimage libinrimage recipe

Conda packages are hosted on binstar heimdali channel.

ccache

You may want to use ccache to speed-up re-compiling after cleaning.

The best option is to install it in your system (ie, outside the conda environment).

Download and extract ccache`.

wget http://samba.org/ftp/ccache/ccache-3.2.2.tar.bz2
tar xvjf ccache-3.2.2.tar.bz2
cd ccache-3.2.2

Configure:

sudo mkdir -p /usr/local/ccache/3.2.2 # for example
./configure --prefix=/usr/local/ccache/3.2.2

Build and install:

make
sudo make install

Create symbolic links:

for COMP in gcc g++ cc c++
do
    sudo ln -s /usr/local/ccache/3.2.2/bin/ccache /usr/local/ccache/3.2.2/bin/$COMP
done

And add /usr/local/ccache/3.2.2/bin to your PATH.

And finally, here is an example of ccache configuration file, in $HOME/.ccache/ccache.conf:

max_size = 5.0G
cache_dir = /local/froger/ccache

Writting documentation

Install Sphinx and Doxygen:

sudo apt-get install doxygen
source activate heimdali-dev
conda install --python=2.7 sphinx sphinx_rtd_theme

Build the documentation:

cd doc
make html

View the documentation:

cd doc
firefox _build/html/index.html

Note that breathe, a Sphinx extension, is already provided in heimdali/doc/ext/breathe.

Releasing a new Heimdali version

Preliminary checks

Check the conda package can build (on both GNU/Linux and OS X):

conda build conda-recipe/heimdali

Update CHANGELOG

Update the changes log file.

Bump version number

Update version number X.X.X in files:

  • conda-recipe/heimdali/meta.yaml
  • libheimdali/heimdali/version.hxx

and commit:

git add conda-recipe/heimdali/meta.yaml libheimdali/heimdali/version.hxx
git commit -m 'Bumped version number to X.X.X'

Tag the new version:

git tag X.X.X

Merge into master

Merge develop into master:

git checkout master
git merge develop

Push to GitHub, with tags:

git push origin --tags develop
git push origin master

Build conda packages

Build and upload the Conda packages for GNU/Linux and OS X.

conda build conda-recipe
binstar upload -u heimdali /path/to/heimdali-X.X.X-X.tar.bz2 # See output of previous command

Note

For portability, GNU/Linux conda packages are built on Centos 5.11, like official conda packages. This can be done on a virtual machine managed by Vagrant, using this box . Conda packages on anaconda.org are tagged with the box version (for example: 0.4.0).

Indices and tables