Skip to content

PERF: Remove allocation on image casting

Luc Hermitte requested to merge lhermitte/otb:RemoveAllocOnImageCasting into develop


A lot of non necessary allocations are done almost every time an image is read.

This cost can be removed.


No need to pay for computations that can be avoided.

On simple applications, a x2 speed up is easily observed. It was the case with SARComputeLocalIncidenceAngle that reads 2 images, and computes for each pixel 1 cross product, 2 norms, one arcsin.

This MR relates to #2065 (closed).

Implementation Details

Classes and files
  • A new class to iterate over pixel components is provided: PixelComponentIterator. For instance this iterator is able to convert a FixedArray<std::complex<float>> into a VariableLengthArray<double>
  • ClampFilter architecture is changed to efficiently handle VariableLengthVector pixels: it's no longer an UnaryFunctorImageFilter (that calls result = f(in) internally) but a plain filter that calls f(result, in) on each pixel. This permits to avoid creating (and destroying) a new VLV for each pixel, and thus to avoid dynamic allocations. The filter has also been simplified and optimized.
  • ConvertTypeFunctor has been adapted for the new interface of ClampFilter. Internally, it uses the new PixelComponentIterator to copy components from the input pixel to the output pixel. Along the way, it has been simplified and optimized.
  • CastImage application has been simplified. Instead of converting any image into a VectorImage<double> of the same number of components/bands, and then into the output image, it directly converts the input image into the output image -- thanks to ClampFilter.
  • WrapperInputImageParameter and WrapperOutputImageParameter have been simplified

Also a few new helpers functions and classes have been provided:

  • like a C++14 backport of C++17 std::clamp
  • a otb::is_array traits that recognizes itk::VLV and classes that inherits from itk::FixedArray
  • GetNumberOfComponents() that works around shortcomings of itk::DefaultConvertPixelTraits<complex<>>::GetNumberOfComponents(pix) (which doesn't support std::complex and that copies VLV (see
  • a port of gsl::not_null into OTB.

Old tests for ClampFilter (bfTvClampImageFilterConversionTest) still runs.

A new test for PixelComponentIterator has been added.


The copyright owner is CSGroup FRANCE 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 | -p1 -i on latest changes and commit

Merge request reports