%
% Complete documentation on the extended LaTeX markup used for Insight
% documentation is available in ``Documenting Insight'', which is part
% of the standard documentation for Insight.  It may be found online
% at:
%
%     http://www.itk.org/

\documentclass{InsightArticle}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  hyperref should be the last package to be loaded.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage[dvips,
bookmarks,
bookmarksopen,
backref,
colorlinks,linkcolor={blue},citecolor={blue},urlcolor={blue},
]{hyperref}
% to be able to use options in graphics
\usepackage{graphicx}
% for pseudo code
\usepackage{listings}
% subfigures
\usepackage{subfigure}


%  This is a template for Papers to the Insight Journal. 
%  It is comparable to a technical report format.

% The title should be descriptive enough for people to be able to find
% the relevant document. 
\title{Labeled object representation and manipulation with ITK}

% Increment the release number whenever significant changes are made.
% The author and/or editor can define 'significant' however they like.
%\release{0.00}

% At minimum, give your name and an email address.  You can include a
% snail-mail address if you like.
\author{Ga\"etan Lehmann{$^2$}}
\authoraddress{{$^1$}INRA, UMR 1198; ENVA; CNRS, FRE 2857, Biologie du
D\'eveloppement et 
Reproduction, Jouy en Josas, F-78350, France.}

\begin{document}
\maketitle

\ifhtml
\chapter*{Front Matter\label{front}}
\fi


\begin{abstract}
\noindent

Richard Beare has recently introduced a new filter to efficiently labelize the
connected component with ITK, and has also proposed to use the run-length
encoding used in that filter to implement some of the most useful binary
mathematical morphology operators: the opening by attribute.
Following that idea, and after have searched a way to use the ITK's spatial
objects for this task, a new set of classes have been developed to represent and
manipulate the labeled images and the objects within them in ITK.
Those new classes have been used to implement several labeled images
manipulation based on object attributes, as well as the binary specialization of
some mathematical morphology filter already included in ITK, and not related to
the attribute of the objects. With those last filters, this contribution comes
with 49 new classes, and should greatly enhance the binary mathematical
morphology in ITK.

All the source codes are provided, as well as a full set of tests and several
usage examples of the new classes.

\end{abstract}

\tableofcontents

\section{Introduction}

Identifying the objects in an image is a very common task, often realized by
producing an image of the same size with a single pixel value per object. This
image is called a labeled image. There are several way to create this image. It
can be done by searching the connected components in a binary image, it can be
produced directly by some algorithms, like the watershed transform, it can even
be simply done by hand, etc.

\section{Definitions}

In that article, some terms will be cited very frequently. I will try to define
them, in the context of the image analysis.

\subsection{Label}

A label is an identifier of something with the same caracteristics in the image.
Those caracteristics can be whatever you want, for example, the range of pixel
values, the same object in sense of connected component, etc.
A label can be represented by anything and only need to be unique in the image.
It doesn't even require to be ordered. In practice, we choose to use the
integral number types, for several reasons: they are commonly used in image
analysis, they efficiently reprensent the label in memory, and its easy to find
the next label by adding 1.

\subsection{Labeled image}

A label image is an image which contains several labeled pixels. Often, the
labels are representing some objects placed on a background, and so the label
image may use a particular label for the background.


\subsection{Binary image}

A binary image is an image with two labels: a foreground label and a background
label. In practice, the binary images are using a pixel type able to store more
than those two values. The foreground is thus defined with a particular label,
and the other label in the image are considered as the background. A side effect
of that is that a labeled image can be considered as a binary image, and so, it
let us manipulate a single object in a labeled image.

\subsection{Attribute}

An attribute is a value of any type associated with a label. It can be for
example the size of an object, the mean of its pixels intensities, etc.

\section{Existing classes and naming convention in ITK}

In ITK, the labeled and the binary images are implemented as a simple {\em
itk::Image}. The pixel types used are most of the time integral, signed or
unsigned, but may be of other types.
Several definitions of a binary image or used in ITK. Depending of the class
which implement it, a binary image can be:
\begin{itemize}
  \item All the pixels with a given value are in the foreground. The others are
in the background. That's the definition proposed in that article.
  \item All the pixels with a given value are in the background. The others are
in the foreground.
  \item All the pixels greater than a value (zero by default, or the mean of the maximum value in the image
and the minimum value in the image) are in the foreground. The other are in the
background. This definition is often used in the levelset framework, where a border
can be defined at a subpixel resolution.
\end{itemize}
All those definitions should be uniformized to enhance user experience with ITK.
In that article (and all the others from the same author), the first one is the
only one used.

The filter which are mainpulating binary images are often prefixed with the word
"Binary", to differenciate the grayscale version which don't have a prefix. It
seem to be a quite good practice which have been kept in that article.

The filter dedicated to the manipulation of labeled images have the word "Label"
somewhere in there name. Again, it seem to be a good practice which have been
kept in that article.


\section{Data representation}

The labeled images are often used the represent the connected components of an
image. In this contribution, another representation has been chosen.

The objects contained in the image, as connected component, can be efficiently stored in memory as a set
of lines, using the run-length encoding: a starting point for each line, and the
length of the line on a given dimension (by convention, the dimension 0).

The image is a collection of those objects, which also store some values of the image, like its size, its spacing, etc.

\subsection{itk::LabelCollectionImage}

The {\em itk::LabelCollectionImage} class is in charge of managing the
collection of labeled
objects of the image, as well as storing the metadata associated with the image
like
the spacing, the physical position - all the metadata found in {\em itk::Image}.

The {\em itk::LabelCollectionImage} provide a part of the API of the {\em
itk::Image} class, and so can be manipulated as an image\footnote{It doesn't
support the itk::Image iterators though} in many cases. The performance can be
very different however, because of the very different data structure used.

The {\em itk::LabelCollectionImage} is a templated class, which take a single
parameter: the type of {\em labeled object} stored by that class. The dimension
of the image is took from the {\em labeled object} class, and thus don't need to
be defined as template parameter of that class. The pixel type of the image
also comes from the {\em labeled object} class.

\subsection{itk::LabelObject and its specializations}

The {\em itk::LabelObject} class represent the label obejcts. It has two main
features:
\begin{itemize}
  \item It manage the set pixels which compose the object. The pixels are stored
using the run-length encoding.
  \item It has a label.
\end{itemize}

No attribute are stored in this class, which can thus be seen as the base class
for the objects with attributes, or which can be used when no attributes
are required.

The {\em itk::LabelObject} class is templated and takes to required template parameters:
\begin{itemize}
  \item the type of the label,
  \item the dimension of the image.
\end{itemize}

Several subclasses are provided with that contribution, to cover the most common
usages of the labeled objects manipulation:
\begin{itemize}
  \item {\em itk::AttributeLabelObject} is able to store a generic attribute. It
is generic in the sense that its type is given in template parameter.
  \item {\em itk::ShapeLabelObject} contains numerous attribute related to the
shape of the labeled object. Computing the values of those attributes does not
require a feaure image.
  \item {\em itk::StatisticsLabelObject} contains numerous statistics about the
grey values of a feature image in the same place than the labeled object.
Computing the values of those attributes {\em does} require a feature image.
\end{itemize}

The classes {\em itk::ShapeLabelObject} and {\em itk::StatisticsLabelObject} have been
created to reduce the number of filters made to manipulate the attributes, and to make
the computation of all the set of attributes much efficient. In the early stage of
development, all the attributes were managed as in {\em AttributeLabelObject}, and
a set of 8 classes made to manipulate a single attribute were provided, leading to a huge
number of classes.

The scalar values of the attributes of the {\em itk::ShapeLabelObject} and the
{\em itk::StatisticsLabelObject} classes are often given both in pixel and in physical units,
in order to be able to give some parameter independant of the image spacing.

Both {\em itk::ShapeLabelObject} and {\em itk::StatisticsLabelObject} are templated classes.
They take the same template parameters than the {\em itk::LabelObject} class.
The 2 first template parameters of the {\em itk::AttributeLabelObject} class or the same
than the {\em itk::LabelObject} class. The third one is the attribute type.

\subsubsection{itk::ShapeLabelObject attributes}

\begin{itemize}
  \item {\em Size} is the size of the object in number of pixels. Its type is
{\em unsigned long}.
  \item {\em PhysicalSize} is the size of the object in physical unit. It is equal
to the {\em Size} multiplicated by the physical pixel size. Its type is {\em double}.
  \item {\em Centroid} is the position of the center of the shape in physical coordinates. It is not
constrained to be in the object, and thus can be outside if the object is not convex.
Its type is {\em Point< double, ImageDimension >}. 
  \item {\em Region} is the bounding box of the object given in the pixel coordinates.
The physical coordinate can easily be computed from it. Its type is
{\em ImageRegion< ImageDimension >}.
  \item {\em RegionElongation} is the ratio of the longest physical size of the region
on one dimension and its smallest physical size. This descriptor is not robust, and in
particular is sensitive to rotation. Its type is {\em double}.
  \item {\em SizeRegionRatio} is the ratio of the size of the object region (the
bounding box) and the real size of the object. Its type is {\em double}.
  \item {\em SizeOnBorder} is the number of pixels in the objects which are on the border
of the image. This attribute is particulary useful to remove the objects which are touching
too much the border. Its type is {\em unsigned long}.
  \item {\em FeretDiameter} is the diameter in physical units of the sphere which include
all the object. The feret diameter is computed by default only if the dimension of the image
is $2$, because of its high computation cost for higher dimensions. Its type is {\em double}.
%   \item {\em Perimeter}
\end{itemize}


\subsubsection{itk::StatisticsLabelObject attributes}

\begin{itemize}
  \item {\em Minimum} is the minimum value in the feature image for the object. Its type is
the feature image pixel type.
  \item {\em MinimumIndex} is the index position in the image where the first minimum was
found. Its type is{\em Index< ImageDimension >}.
  \item {\em Maximum} is the maximum value in the feature image for the object. Its type is
the feature image pixel type.
  \item {\em MaximumIndex} is the index position in the image where the first maximum was
found. Its type is{\em Index< ImageDimension >}.
  \item {\em Mean} is the mean of the pixel values in the object. Its type is {\em double}.
  \item {\em Sum} is the sum of all the pixel values in the objects. Its type is {\em double}.
  \item {\em Sigma} is the standard deviation of the pixels values in the objects. Its type
is {\em double}.
  \item {\em Variance} is the variance of the pixels values in the objects. Its type is
{\em double}.
  \item {\em Median} is the median of the pixels values in the obejct. Its type is
{\em double}
  \item {\em CenterOfGravity} is the center of gravity of the object. It type is
{\em Point< double >}.
%   \item {\em CentralMoments}
%   \item {\em PrincipalMoments}
%   \item {\em PrincipalAxes}
  \item {\em Kurtosis} is the kurtosis of the pixel values in the objects. Its type is
{\em double}.
  \item {\em Skewness} is the skewness of the pixel values in the objects. Its type is
{\em double}.
\end{itemize}


\subsection{itk::LabelObjectLine}

{\em itk::LabelObjectLine} is the object used to store the position and the size
of a single line.

\section{General view of the usage}

\subsection{Generating the itk::LabelCollectionImage}

The {\em itk::LabelCollectionImage} class provide some methods to fill the
image "by hand", like the usual {\em SetPixel()} method. However, the most efficient way is to convert a labeled image or a binary
image stored in an {\em itk::Image} to a {\em itk::LabelCollectionImage}, by
using {\em itk::BinaryImageToLabelCollectionImageFilter} or {\em
itk::LabelImageToLabelCollectionImageFilter}.

\subsection{Valuating the attributes}

The label objects produced by those filters have no attribute value set, and
thus, the attributes must be valuated. Some filters are provided for the most
common used ones:

\begin{itemize}
  \item {\em itk::ShapeLabelCollectionImageFilter} to fill the
attributes of the {\em itk::ShapeLabelObject}s, 
  \item and {\em itk::ShapeLabelCollectionImageFilter} to fill the attributes of the {\em
itk::StatisticsLabelObject}s.
\end{itemize}

For the {\em itk::AttributeLabelObject} class or
other classes, the user must set the value by himself, for example by
implementing a subclass of {\em itk::InPlaceLabelCollectionImageFilter}.

\subsection{Manipulating the itk::LabelCollectionImage}

Once created and, optionally, valuated, several filters are provided to manipulate
the {\em itk::LabelCollectionImage}:

\begin{itemize}
  \item An opening can be performed with the {\em
OpeningLabelCollectionImageFilter} classes. Those classes will remove all the
objects with an attribute value lower or greater than a given value.
Because we often can use some criteria  which have not been used during the segmentation
procedure, like the size of the object, the mean value of its pixels, etc., the attribute
opening is often a very efficient way to enhance a segmentation. For example, after
a thresholding of a grayscale image, the objects too small or too beg to be of interest
can be removed that way.

  \item A fixed number of objects can be kept, with the {\em
KeepNObjectsLabelCollectionImageFilter} classes. They are chosen according to
the value of their attribute. The user can choose to keep the ones with the
highest, or with the lowest attribute values.

  \item The objects can be relabel, with the {\em
RelabelLabelCollectionImageFilter} classes. The order of the label is dependant
of the value of the attribute. Again, the user can choose to have the objects
with the highest attribute value in the first labels, or to have the objects
with the lowest attribute values in the first labels.
\end{itemize}

It can also be useful to simply get the attribute values associated with the
objects. In that case, the classes provided in with that article can be used in
place of {\em itk::LabelStatisticsImageFilter}, or to get some data about the
shape or the position of the object.

Finally, it has been chosen to develop a specific filter for the morphological
reconstruction. It would have been possible to implement the reconstruction
with the most common case (build the object collection, valuate the attributes
filter the object, and rebuild the image), but in order to make it compatible
with the {\em ShapeLabelObject} and {\em StatisticsLabelObject}, the reconstruction
filter filters the collection directly, without setting an attribute in the objects
\footnote{I'm not really pleased with that design though, and I'thinking about
reimplementing it using the generic attributes. It would have no impact on the
binary filters API.}.

\subsection{Generating an itk::Image from the itk::LabelCollectionImage}

Once the manipulation of the objects is done, it can be useful to go back to a
more classic {\em itk::Image}. Several classes are provided to do that:
\begin{itemize}
  \item The {\em itk::LabelCollectionImageToLabelImageFilter} class simply
convert a {\em itk::LabelCollectionImage} to a labeled image stored in a {\em
itk::Image}.
  \item The {\em itk::LabelCollectionImageToBinaryImageFilter} put all the
objects in the foreground of a binary image stored in a {itk::Image}. It is
intended to be used with an image produced by the {\em
itk::BinaryImageToLabelCollectionImageFilter}. The background values of the
original image can also be restored by this filter.
  \item The {\em itk::LabelCollectionImageToMaskImageFilter} class can be used
to mask an image with the objects of the {\em itk::LabelCollectionImage}.
  \item Finally, {\em itk::LabelCollectionImageToAttributeImageFilter} produce
an {\em itk::Image} with the value of the attribute of the objects of the {\em
itk::LabelCollectionImage}. This filter is mostly useful to have a global view
of the attribute values in the image.
\end{itemize}

\section{Prebuilt mini-pipeline filters}

The general view of the previous section show a very common way to use those
classes. To make easier to use, some prebuilt classes have been made, to perform
the mini-pipeline:
\begin{itemize}
  \item creation of the {\em itk::LabelCollectionImage} from an {\em
itk::Image},
  \item valuation of the attribute(s) of the objects,
  \item filtering of the {\em itk::LabelCollectionImage},
  \item creation of an {\em itk::Image} from the filtered {\em
itk::LabelCollectionImage},
\end{itemize}
with a specific attribute.

Because the objects are often get from a labeled image or from a binary image,
those filters have been made for binary, and labeled images.

\subsection{Binary filters}

\begin{itemize}
  \item {\em itk::BinaryAttributeKeepNObjectsImageFilter}
  \item {\em itk::BinaryAttributeOpeningImageFilter}
  \item {\em itk::BinaryShapeKeepNObjectsImageFilter}
  \item {\em itk::BinaryShapeOpeningImageFilter}
  \item {\em itk::BinaryStatisticsKeepNObjectsImageFilter}
  \item {\em itk::BinaryStatisticsOpeningImageFilter}
\end{itemize}

\subsection{Label filters}

\begin{itemize}
  \item {\em itk::LabelAttributeKeepNObjectsImageFilter}
  \item {\em itk::LabelAttributeOpeningImageFilter}
  \item {\em itk::LabelShapeKeepNObjectsImageFilter}
  \item {\em itk::LabelShapeOpeningImageFilter}
  \item {\em itk::LabelStatisticsKeepNObjectsImageFilter}
  \item {\em itk::LabelStatisticsOpeningImageFilter}
  \item {\em itk::ShapeRelabelImageFilter}
  \item {\em itk::StatisticsRelabelImageFilter}
\end{itemize}

\section{Binary specialization of mathematical morphology filters}

\begin{itemize}
  \item {\em itk::BinaryClosingByReconstructionImageFilter}
  \item {\em itk::BinaryFillholeImageFilter}
  \item {\em itk::BinaryGrindPeakImageFilter}
  \item {\em itk::BinaryOpeningByReconstructionImageFilter}
  \item {\em itk::BinaryReconstructionByDilationImageFilter}
  \item {\em itk::BinaryReconstructionByErosionImageFilter}
\end{itemize}

\section{Usage examples}

\subsection{Prebuilt pipelines}

\subsubsection{Binary shape opening}

The source code is available in the file {\em binary\_shape\_opening.cxx}.

\small \begin{verbatim}
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkSimpleFilterWatcher.h"

#include "itkBinaryShapeOpeningImageFilter.h"


int main(int argc, char * argv[])
{

  if( argc != 9 )
    {
    std::cerr << "usage: " << argv[0] << " input output foreground background lambda reverseOrdering connectivity attribute" << std::endl;
    // std::cerr << "  : " << std::endl;
    exit(1);
    }

  const int dim = 3;

  typedef itk::Image< unsigned char, dim > IType;

  typedef itk::ImageFileReader< IType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  typedef itk::BinaryShapeOpeningImageFilter< IType > BinaryOpeningType;
  BinaryOpeningType::Pointer opening = BinaryOpeningType::New();
  opening->SetInput( reader->GetOutput() );
  opening->SetForegroundValue( atoi(argv[3]) );
  opening->SetBackgroundValue( atoi(argv[4]) );
  opening->SetLambda( atof(argv[5]) );
  opening->SetReverseOrdering( atoi(argv[6]) );
  opening->SetFullyConnected( atoi(argv[7]) );
  opening->SetAttribute( argv[8] );
  itk::SimpleFilterWatcher watcher(opening, "filter");

  typedef itk::ImageFileWriter< IType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( opening->GetOutput() );
  writer->SetFileName( argv[2] );
  writer->Update();
  return 0;
}

\end{verbatim} \normalsize

\subsubsection{Statistics relabel}

The source code is available in the file {\em statistics\_relabel.cxx}.

\small \begin{verbatim}
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkSimpleFilterWatcher.h"

#include "itkStatisticsRelabelImageFilter.h"


int main(int argc, char * argv[])
{

  if( argc != 8 )
    {
    std::cerr << "usage: " << argv[0] << " input input output background useBg reverseOrdering attribute" << std::endl;
    // std::cerr << "  : " << std::endl;
    exit(1);
    }

  const int dim = 3;

  typedef itk::Image< unsigned char, dim > IType;

  typedef itk::ImageFileReader< IType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  ReaderType::Pointer reader2 = ReaderType::New();
  reader2->SetFileName( argv[2] );

  typedef itk::StatisticsRelabelImageFilter< IType, IType > RelabelType;
  RelabelType::Pointer relabel = RelabelType::New();
  relabel->SetInput( reader->GetOutput() );
  relabel->SetFeatureImage( reader2->GetOutput() );
  relabel->SetBackgroundValue( atoi(argv[4]) );
  relabel->SetUseBackground( atoi(argv[5]) );
  relabel->SetReverseOrdering( atoi(argv[6]) );
  relabel->SetAttribute( argv[7] );
  itk::SimpleFilterWatcher watcher(relabel, "filter");

  typedef itk::ImageFileWriter< IType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( relabel->GetOutput() );
  writer->SetFileName( argv[3] );
  writer->Update();
  return 0;
}
\end{verbatim} \normalsize


\subsubsection{Label shape keep N obejcts}

The source code is available in the file {\em label\_shape\_keep\_n\_objects.cxx}.

\small \begin{verbatim}
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkSimpleFilterWatcher.h"

#include "itkLabelShapeKeepNObjectsImageFilter.h"


int main(int argc, char * argv[])
{

  if( argc != 7 )
    {
    std::cerr << "usage: " << argv[0] << " input output background nb reverseOrdering attribute" << std::endl;
    // std::cerr << "  : " << std::endl;
    exit(1);
    }

  const int dim = 3;

  typedef itk::Image< unsigned char, dim > IType;

  typedef itk::ImageFileReader< IType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  typedef itk::LabelShapeKeepNObjectsImageFilter< IType > LabelOpeningType;
  LabelOpeningType::Pointer opening = LabelOpeningType::New();
  opening->SetInput( reader->GetOutput() );
  opening->SetBackgroundValue( atoi(argv[3]) );
  opening->SetNumberOfObjects( atoi(argv[4]) );
  opening->SetReverseOrdering( atoi(argv[5]) );
  opening->SetAttribute( argv[6] );
  itk::SimpleFilterWatcher watcher(opening, "filter");

  typedef itk::ImageFileWriter< IType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( opening->GetOutput() );
  writer->SetFileName( argv[2] );
  writer->Update();
  return 0;
}
\end{verbatim} \normalsize

\subsubsection{Binary fill holes}

The source code is available in the file {\em binary\_fillhole.cxx}.

\small \begin{verbatim}
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkCommand.h"
#include "itkSimpleFilterWatcher.h"

#include "itkLabelObject.h"
#include "itkLabelCollectionImage.h"
#include "itkBinaryFillholeImageFilter.h"


int main(int argc, char * argv[])
{

  if( argc != 5 )
    {
    std::cerr << "usage: " << argv[0] << " input output conn fg" << std::endl;
    // std::cerr << "  : " << std::endl;
    exit(1);
    }

  const int dim = 2;

  typedef itk::Image< unsigned char, dim > IType;

  typedef itk::ImageFileReader< IType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
  reader->Update();

 typedef itk::BinaryFillholeImageFilter< IType > I2LType;
  I2LType::Pointer reconstruction = I2LType::New();
  reconstruction->SetInput( reader->GetOutput() );
  reconstruction->SetFullyConnected( atoi(argv[3]) );
  reconstruction->SetForegroundValue( atoi(argv[4]) );
//   reconstruction->SetBackgroundValue( atoi(argv[5]) );
  itk::SimpleFilterWatcher watcher(reconstruction, "filter");

  typedef itk::ImageFileWriter< IType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( reconstruction->GetOutput() );
  writer->SetFileName( argv[2] );
  writer->Update();
  return 0;
}
\end{verbatim} \normalsize

\subsection{LabelObject and LabelCollectionImage manipulation}

% \subsubsection{LabelObject}
% 
% TODO
% 
% \subsubsection{ShapeLabelObject}
% 
% TODO
% 
% \subsubsection{StatisticsLabelObject}
% 
% TODO
% 
\subsubsection{AttributeLabelObject}

The {\em AttributeLabelObject} let the user specify the type of the attribute
he wants to use, and thus is the good choice to implement a new attribute.

The source code is available in the file {\em generic\_attribute.cxx}.

First we include the headers of the class we will use, and parse the command line.

\small \begin{verbatim}
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

#include "itkAttributeLabelObject.h"
#include "itkLabelCollectionImage.h"

#include "itkLabelImageToLabelCollectionImageFilter.h"

#include "itkAttributeKeepNObjectsLabelCollectionImageFilter.h"
#include "itkAttributeOpeningLabelCollectionImageFilter.h"
#include "itkAttributeRelabelLabelCollectionImageFilter.h"

#include "itkLabelCollectionImageToAttributeImageFilter.h"
#include "itkLabelCollectionImageToLabelImageFilter.h"


int main(int argc, char * argv[])
{

  if( argc != 10 )
    {
    std::cerr << "usage: " << argv[0] << " label input attr keep open relabel bg lambda nb" << std::endl;
    // std::cerr << "  : " << std::endl;
    exit(1);
    }
\end{verbatim} \normalsize
Declare the dimension used, and the type of the image for input and output.
\small \begin{verbatim}
  const int dim = 2;
  typedef unsigned char PType;
  typedef itk::Image< PType, dim > IType;
\end{verbatim} \normalsize
The AttributeLabelObject class take 3 template parameters: the 2 ones
from the LabelObject class, and the type of the attribute associated
with each node. Here we have chosen a double. We then declares the
type of the LabelCollectionImage with the type of the label object.
\small \begin{verbatim}
  typedef itk::AttributeLabelObject< unsigned long, dim, double > LOType;
  typedef itk::LabelCollectionImage< LOType > LCIType;
\end{verbatim} \normalsize
We read the input images.
\small \begin{verbatim}
  typedef itk::ImageFileReader< IType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  ReaderType::Pointer reader2 = ReaderType::New();
  reader2->SetFileName( argv[2] );
\end{verbatim} \normalsize
And convert the label image to a LabelCollectionImage.
\small \begin{verbatim}
  typedef itk::LabelImageToLabelCollectionImageFilter< IType, LCIType > I2LType;
  I2LType::Pointer i2l = I2LType::New();
  i2l->SetInput( reader->GetOutput() );
  i2l->SetBackgroundValue( atoi(argv[7]) );
\end{verbatim} \normalsize
The next step is made outside the pipeline model, so we call Update() now.
\small \begin{verbatim}
  i2l->Update();
  reader2->Update();
\end{verbatim} \normalsize
Now we will valuate the attribute. The attribute will be the mean of the pixels
values in the 2nd image. Note that the StatisticsLabelObject can give us that value, without
having to code that by hand - that's an example.

Lets begin by declaring the iterator for the objects in the image, and get the object container, to reuse it later.
\small \begin{verbatim}
  LCIType::LabelObjectContainerType::const_iterator it;
  LCIType::Pointer labelCollection = i2l->GetOutput();
  const LCIType::LabelObjectContainerType & labelObjectContainer = labelCollection->GetLabelObjectContainer();
\end{verbatim} \normalsize
Now iterate over all the objects in the image.
\small \begin{verbatim}
  for( it = labelObjectContainer.begin(); it != labelObjectContainer.end(); it++ )
    {
\end{verbatim} \normalsize
The label is there if we need it, but it can also be found at labelObject->GetLabel().
\small \begin{verbatim}
    const PType & label = it->first;
    LOType * labelObject = it->second;
\end{verbatim} \normalsize
Init the variables used for the computation.
\small \begin{verbatim}
    double mean = 0;
    unsigned long size = 0;
\end{verbatim} \normalsize
Create the iterator for the lines, and iterate over them
\small \begin{verbatim}
    LOType::LineContainerType::const_iterator lit;
    LOType::LineContainerType lineContainer = labelObject->GetLineContainer();

    for( lit = lineContainer.begin(); lit != lineContainer.end(); lit++ )
      {
      const LCIType::IndexType & firstIdx = lit->GetIndex();
      const unsigned long & length = lit->GetLength();

      size += length;
\end{verbatim} \normalsize
Then iterate over all the pixels in the line, and get the pixel values in the feature image to compute their mean.
\small \begin{verbatim}
      long endIdx0 = firstIdx[0] + length;
      for( LCIType::IndexType idx = firstIdx; idx[0]<endIdx0; idx[0]++)
        {
        mean += reader2->GetOutput()->GetPixel( idx );
        }
      }
\end{verbatim} \normalsize
Complete the compuation of the mean, and set it as attibute value for the current object.
\small \begin{verbatim}
    mean /= size;
    labelObject->SetAttribute( mean );
\end{verbatim} \normalsize
The LabelObject class provides a Print() method to display its ivars.
\small \begin{verbatim}
    labelObject->Print( std::cout );

    }
\end{verbatim} \normalsize
Now that the objects have their attribute, we are free to manipulate them with
the common filters, or by hand. The default accessor (AttributeLabelObject)
is the wright one when using AttributeLabelObject so we don't have to specify it.
A different one can be used if needed though.
\small \begin{verbatim}
  typedef itk::AttributeKeepNObjectsLabelCollectionImageFilter< LCIType > KeepType;
  KeepType::Pointer keep = KeepType::New();
  keep->SetInput( labelCollection );
  keep->SetReverseOrdering( true );
  keep->SetNumberOfObjects( atoi(argv[9]) );
\end{verbatim} \normalsize
Prevent the filter to run in place, so the input image is not modified.
\small \begin{verbatim}
  keep->SetInPlace( false );

  typedef itk::AttributeOpeningLabelCollectionImageFilter< LCIType > OpeningType;
  OpeningType::Pointer opening = OpeningType::New();
  opening->SetInput( labelCollection );
  opening->SetLambda( atof(argv[8]) );
  keep->SetInPlace( false );

  typedef itk::AttributeRelabelLabelCollectionImageFilter< LCIType > RelabelType;
  RelabelType::Pointer relabel = RelabelType::New();
  relabel->SetInput( labelCollection );
  keep->SetInPlace( false );
\end{verbatim} \normalsize
The attribute values can be put directly in a classic image.
\small \begin{verbatim}
  typedef itk::LabelCollectionImageToAttributeImageFilter< LCIType, IType > A2IType;
  A2IType::Pointer a2i = A2IType::New();
  a2i->SetInput( labelCollection );
\end{verbatim} \normalsize
Or the label collection can be converted back to an label image, or to a binary image
(not shown here)
\small \begin{verbatim}
  typedef itk::LabelCollectionImageToLabelImageFilter< LCIType, IType > L2IType;
  L2IType::Pointer l2i = L2IType::New();
\end{verbatim} \normalsize
Finally, write the results
\small \begin{verbatim}
  typedef itk::ImageFileWriter< IType > WriterType;
  WriterType::Pointer writer = WriterType::New();

  writer->SetInput( a2i->GetOutput() );
  writer->SetFileName( argv[3] );
  writer->Update();

  writer->SetInput( l2i->GetOutput() );

  l2i->SetInput( keep->GetOutput() );
  writer->SetFileName( argv[4] );
  writer->Update();

  l2i->SetInput( opening->GetOutput() );
  writer->SetFileName( argv[5] );
  writer->Update();

  l2i->SetInput( relabel->GetOutput() );
  writer->SetFileName( argv[6] );
  writer->Update();

  return 0;
}
\end{verbatim} \normalsize

\subsection{Reading attribute values}

In that example, we will read a binary image, and get some of attributes
about the obejcts contained in that image.
The source code is available in the file {\em attribute\_values.cxx}.

First include the classes we'll use
\small \begin{verbatim}
#include "itkImageFileReader.h"
#include "itkShapeLabelObject.h"
#include "itkLabelCollectionImage.h"
#include "itkBinaryImageToLabelCollectionImageFilter.h"
#include "itkShapeLabelCollectionImageFilter.h"

int main(int, char * argv[])
{
  const int dim = 2;
\end{verbatim} \normalsize
then declare the type of the input image
\small \begin{verbatim}
  typedef unsigned char PixelType;
  typedef itk::Image< PixelType, dim >    ImageType;
  
\end{verbatim} \normalsize
read the input image
\small \begin{verbatim}
  typedef itk::ImageFileReader< ImageType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
  
\end{verbatim} \normalsize
define the object type. Here the ShapeLabelObject type
is chosen in order to read some attribute related to the shape
of the objects (by opposition to the content of the object, with
the StatisticsLabelObejct).
\small \begin{verbatim}
  typedef unsigned long LabelType;
  typedef itk::ShapeLabelObject< LabelType, dim > LabelObjectType;
  typedef itk::LabelCollectionImage< LabelObjectType > LabelCollectionType;

\end{verbatim} \normalsize
convert the image in a collection of objects
\small \begin{verbatim}
  typedef itk::BinaryImageToLabelCollectionImageFilter< ImageType, LabelCollectionType > ConverterType;
  ConverterType::Pointer converter = ConverterType::New();
  converter->SetInput( reader->GetOutput() );
  converter->SetForegroundValue( 200 );

\end{verbatim} \normalsize
and valuate the attributes with the dedicated filter: ShapeLabelCollectionImageFilter
\small \begin{verbatim}
  typedef itk::ShapeLabelCollectionImageFilter< LabelCollectionType > ShapeFilterType;
  ShapeFilterType::Pointer shape = ShapeFilterType::New();
  shape->SetInput( converter->GetOutput() );

\end{verbatim} \normalsize
update the shape filter, so its output will be up to date
\small \begin{verbatim}
  shape->Update();

\end{verbatim} \normalsize
then we can read the attribute values we're interested in. {\em BinaryImageToLabelCollectionImageFilter}
produces consecutives labels, so a simple {for} loop will do the job.
\small \begin{verbatim}
  LabelCollectionType::Pointer collection = shape->GetOutput();
  for( int label=1; label<collection->GetNumberOfObjects(); label++ )
    {
    LabelObjectType::Pointer labelObject = collection->GetLabelObject( label );
    std::cout << label << "\t" << labelObject->GetPhysicalSize() << "\t" << labelObject->GetCentroid() << std::endl;
    }
  
  return 0;
}
\end{verbatim} \normalsize


\section{Threading support}

When possible, the filters provided with that contribution have been multithreaded.
Some of them however, are not (easily) threadable (the {\em KeepNObjects} and {\em Relabel}
filters), are shouldn't get any performance improvement in a threaded version
(the {\em Opening} filters).

The {\em BinaryImageToLabelCollectionImageFilter} class is a slight modification of the
Richard Beare's {\em ConnectedComponentImageFilter}, and thus, has not been threaded.
It should however be possible to increase its performance that way.

The classical thread architecture is used when the input image is an {\em Image}: the image
is splitted in several regions (one per thread), and each thread work on its own region.

Because the {\em LabelCollectionImage} image is not an array of pixels, it can't be splitted
that way. Instead, several threads are created, and try to take an object in the collection.
If they get one, they process that object individually, and try to get another one when the
object is processed. If no object can be get, the thread ends. A {\em FastMutexLock} is used
to ensure that only one thread take an object at a time.

For the developer, the usage of the threading support is made very simple, by subclassing
{\em LabelCollectionImageFilter}, or {\em InPlaceLabelCollectionImageFilter}, and implementing
the method {\em virtual void ThreadedGenerateData( LabelObjectType * labelObject )} in the
new class. This method only has to process the labelObject passed in parameter. All the
threading code and mutex lock management is already implemented. The mutex lock remain
accessible if the subclass need to use it, as the {\em m\_LabelObjectContainerLock} ivar.

\section{In place filtering}

All the filters which are taking a {\em LabelCollectionImage} as input, and are producing a {\em LabelCollectionImage} as output, are implemented as a subclass of {\em InPlaceLabelCollectionImageFilter} and
thus are running in place by default.

The use can modify this behavior with the {\em SetInPlace( bool )}, {\em InPlaceOn()}, and {\em InPlaceOff()} methods, as with the usual {\em InPlaceImageFilter}.

To use that feature, a developer only have to subclass {\em InPlaceLabelCollectionImageFilter} and
implement the {\em virtual void ThreadedGenerateData( LabelObjectType * labelObject )}, to get easy thread
support \footnote{see the previous section}, or the {\em virtual void GenerateData()} if the filter is not threadable. In that last case,
the only image to manipulate is the one get with the {\em GetOutput()} method, which is the input image if the filter runs in place, or a copy of the input image if the filter is not running in place.


\section{Wrappers support}

All the classes provided with that article, excepted the most generic ones made
to help the developer to implement some new features, can be used with WrapITK,
and have been fully tested with python.

% \section{Performance}
% 
% TODO

\section{Known bugs and future work}

To fit the ITK style, some iterators should be implemented to be able to iterate
over all the 
\begin{itemize}
  \item objects,
  \item lines,
  \item or pixels
\end{itemize}

of an image, starting from 
\begin{itemize}
  \item an image,
  \item an object,
  \item or a line.
\end{itemize}

Doing that require a good knownledge of the iterator design. Any help on that point is
welcome.

Also, more attributes will be implemented, like the perimeter estimation, the usual image moments, etc. It may be useful to implement the most commonly used opening, keep N objects and relabel transforms in a more efficient way, by using an {\em AttributeLabelObject} instead of a {\em ShapeLabelObject} or a {\em StatisticsLabelObject}.

The computation of the moments is partially implemented. The help of someone with a good knownledge of that subject would be very helpful to complete that work. The moments for the binary shape should also be implemented.

All the {\em Shape} filters are currently able to use the Feret diameter only in 2D images. For the other dimensions, the feret diameter is not computed, and so always get a value of $0$. The computation of the Feret diameter should be forced if the user want to use it.

The {\em BinaryImageToLabelCollectionImageFilter} class should be threaded to get the best of that filter on multiprocessors systems.

Finally, all the binary and label filters should be implemented as a subclass of {\em InPlaceImageFilter}.

\section{Conclusion}

ITK is currently lacking a good way to manipulate the binary objects. With that contribution I hope to have mostly
filled that lack.

\section{Acknowledgments}
I thank Richard Beare for his suggestion to use the run length encoding to represent the binary objects, and Julien Jomier for his help for the choice to {\em not} use the {\em SpatialObject} class as base class of the {\em LabelObejct} class.

I thank Dr Pierre Adenot and MIMA2 confocal facilities
(\url{http://mima2.jouy.inra.fr}) for providing the 3D test image.
I am grateful to the INRA MIGALE bioinformatics platform
(\url{http://migale.jouy.inra.fr}) for providing the computational resources
used for the timing tests.


\appendix



\bibliographystyle{plain}
\bibliography{InsightJournal}
\nocite{ITKSoftwareGuide}

\end{document}

