Spectral angle classification

Merged Cédric Traizet requested to merge spectral_angle_classif into develop


description wip

Refactor spectral angle functors in otb and add a new application : SpectralAngleClassification

closes #2012 (closed)


The spectral angle mapper (SAM) and spectral information divergence (SID) are widely used in hyperspectral image processing, but otb does not provide an application implementing these algorithms.

The SAM of a pixel x with a reference pixel r is defined by :

sam[x, r] = cos^{-1}(\frac{<x,r>}{\|x\| * \|r\|  } )

where <x,r> denotes the scalar product between x and r. This is also called the spectral angle between x and r. In SAM classification the spectral angle is computed for each pixel with a set of reference pixels, the class associated with the pixel is the index of the reference pixel that has the lowest spectral angle.

In otb there are several classes that computes spectral angle :

  1. BinarySpectralAngleFunctor : computes spectral angle between two pixels.
  2. SpectralAngleFunctor : computes spectral angle between a pixel and a reference (different from the above because the norm of the reference is cached and not computed again for each pixel
  3. SpectralAngleDistanceImageFilter : Filter computing spectral angle on an image (it doesn't use a functor).
  4. sqrtSpectralAngleFunctor : computes the square root of the spectral angle between a pixel and a reference.
  5. waterSqrtSpectralAngleFunctor : computes the square root of the spectral angle between a pixel and a reference, with band indices (blue, green, red and nir). Note that this functor is not available in the RadiometricIndices application.
  6. waterSqrtSpectralAngleFilter : UnaryFunctorImageFilter specialized with waterSqrtSpectralAngleFunctor
  7. ConnectedComponentMuParserImageFunctor : defines the spectralAngle variablr for muParser in the connected component framework.

All these classes re-implement the spectral angle computation. In these merge request, they have been refactored to use the function

template <class TInput, class TReference, class TOutput>
TOutput ComputeSpectralAngle(TInput const & input, typename TInput ::ValueType const & inputNorm, 
                              TReference const & reference, typename TReference::ValueType refNorm)

Note that the norm of input pixels is a parameter of the same norm might be used for several spectral angle computations.

A new functor has been implement for spectral angle with a vector of reference pixels : SpectralAngleMapperFunctor, and is used is the new SpectralAngleClassification application.

WaterSqrtSpectralAngleFunctor has been refactored to be a RadiometricIndex and can be used with a FunctorImageFilter like the other radiometry filters (with the SetBandIndex/GetBandIndex syntax etc)

WaterSqrtSpectralAngleImageFilter has been deprecated to stay coherent with the other radiometry functor. The filters corresponding to the functor are not defined in this module, and are defined on the fly with the NewFunctorFilter(functor) free function.

SpectralAngleDistanceImageFilter has been deprecated because it is a clone of FunctorImageFilter< SpectralAngleFunctor>


The probability mass function p of a pixel x is defined by :

x = [x_1, x_2 ,..., x_L ]^T \\

p = [p_1, p_2 ,..., p_L ]^T \\

p_i = \frac{x_i}{\sum_{j=1}^L x_j}

The spectral information divergence between a pixel x and a reference r is defined by :

sid[x, r] = \sum_{j=1}^{L}  p_j  *log(\frac{p_j}{q_j}) + \sum_{j=1}^{L}  q_j * log(\frac{q_j}{p_j}) 

where p and q are respectively the probability mass function of x and r.

A new functor has been implemented to compute SID on a vector of reference pixel.

Note that SID is only defined for strictly positive pixels. The functor will throw an exception if one of the channel of its input (pixels and reference pixels) is negative or equal to 0.


A new application has been added, it takes as input :

  • in : a hyperspectral image
  • ie : endmembers stored in an image. Possibly the output of VertexComponentAnalysis.
  • mode : sid or sam, the algorithm to be used.

and output :

  • out : the output classification, i.e. the index of the endmember corresponding to the min sid or sam value, starting at 1.
  • measure : the computed sid or sam map.

Note that the two output supports multiwriting.

Additional parameters are :

  • threshold : value of sid or sam above the threshold are not considered for classification and are classified as background (not mandatory, if not set all pixels are classfied).
  • bv : the background value (default 0)

Two tests have been added (sid and sam modes)

Implementation Details

Additional notes


The copyright owner is CNES and has signed the ORFEO ToolBox Contributor License Agreement.

Check before merging:

  • All discussions are resolved
  • At least 2 👍 votes from core developers, no 👎 vote.
  • The feature branch is (reasonably) up-to-date with the base branch
  • Dashboard is green
  • Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
  • Optionally, run git diff develop... -U0 --no-color | clang-format-diff.py -p1 -i on latest changes and commit
Edited by Cédric Traizet

Merge request reports