Create a Custom Color Map#

Synopsis#

Create and apply a custom colormap.

Note

Python wrapping for CustomColormapFunction and the MersenneTwisterRandomVariateGenerator was introduced in ITK 4.8.0.

Results#

Input image

Input image#

Output image

Output image#

Code#

Python#

#!/usr/bin/env python

import sys
import itk
import argparse

from distutils.version import StrictVersion as VS

if VS(itk.Version.GetITKVersion()) < VS("4.8.0"):
    print("ITK 4.8.0 is required (see example documentation).")
    sys.exit(1)

parser = argparse.ArgumentParser(description="Create A Custom Colormap.")
parser.add_argument("input_image")
parser.add_argument("output_image")
args = parser.parse_args()

PixelType = itk.UC
Dimension = 2

ImageType = itk.Image[PixelType, Dimension]

RGBPixelType = itk.RGBPixel[PixelType]
RGBImageType = itk.Image[RGBPixelType, Dimension]

ReaderType = itk.ImageFileReader[ImageType]
reader = ReaderType.New()
reader.SetFileName(args.input_image)

ColormapType = itk.CustomColormapFunction[PixelType, RGBPixelType]
colormap = ColormapType.New()

random = itk.MersenneTwisterRandomVariateGenerator.New()
random.SetSeed(0)

redChannel = []
greenChannel = []
blueChannel = []

for i in range(255):
    redChannel.append(random.GetUniformVariate(0.0, 1.0))
    greenChannel.append(random.GetUniformVariate(0.0, 1.0))
    blueChannel.append(random.GetUniformVariate(0.0, 1.0))

colormap.SetRedChannel(redChannel)
colormap.SetGreenChannel(greenChannel)
colormap.SetBlueChannel(blueChannel)

ColormapFilterType = itk.ScalarToRGBColormapImageFilter[ImageType, RGBImageType]
colormapFilter1 = ColormapFilterType.New()

colormapFilter1.SetInput(reader.GetOutput())
colormapFilter1.SetColormap(colormap)

WriterType = itk.ImageFileWriter[RGBImageType]
writer = WriterType.New()
writer.SetFileName(args.output_image)
writer.SetInput(colormapFilter1.GetOutput())

writer.Update()

C++#

#include "itkCustomColormapFunction.h"
#include "itkScalarToRGBColormapImageFilter.h"

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkCustomColormapFunction.h"
#include "itkScalarToRGBColormapImageFilter.h"
#include "itkRGBPixel.h"
#include "itkMersenneTwisterRandomVariateGenerator.h"


int
main(int argc, char * argv[])
{
  if (argc != 3)
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " <InputFileName> <OutputFileName>" << std::endl;

    return EXIT_FAILURE;
  }

  using PixelType = unsigned char;
  using RGBPixelType = itk::RGBPixel<unsigned char>;

  using RGBImageType = itk::Image<RGBPixelType, 2>;
  using ImageType = itk::Image<PixelType, 2>;

  const auto input = itk::ReadImage<ImageType>(argv[1]);

  using ColormapType = itk::Function::CustomColormapFunction<PixelType, RGBPixelType>;
  auto colormap = ColormapType::New();

  ColormapType::ChannelType redChannel;
  ColormapType::ChannelType greenChannel;
  ColormapType::ChannelType blueChannel;

  itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer random =
    itk::Statistics::MersenneTwisterRandomVariateGenerator::New();

  random->SetSeed(0);

  for (unsigned int i = 0; i < 255; ++i)
  {
    redChannel.push_back(static_cast<ColormapType::RealType>(random->GetUniformVariate(0., 1.0)));

    greenChannel.push_back(static_cast<ColormapType::RealType>(random->GetUniformVariate(0., 1.0)));

    blueChannel.push_back(static_cast<ColormapType::RealType>(random->GetUniformVariate(0., 1.0)));
  }

  colormap->SetRedChannel(redChannel);
  colormap->SetGreenChannel(greenChannel);
  colormap->SetBlueChannel(blueChannel);

  using ColormapFilterType = itk::ScalarToRGBColormapImageFilter<ImageType, RGBImageType>;
  auto colormapFilter1 = ColormapFilterType::New();

  colormapFilter1->SetInput(input);
  colormapFilter1->SetColormap(colormap);

  try
  {
    itk::WriteImage(colormapFilter1->GetOutput(), argv[2]);
  }
  catch (const itk::ExceptionObject & error)
  {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

Classes demonstrated#

template<typename TScalar, typename TRGBPixel>
class CustomColormapFunction : public itk::Function::ColormapFunction<TScalar, TRGBPixel>

Function object which maps a scalar value into an RGB colormap value.

This code was contributed in the Insight Journal paper:

Author

Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and James C. Gee

“Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK” https://www.insight-journal.org/browse/publication/285

ITK Sphinx Examples:

See itk::Function::CustomColormapFunction for additional documentation.
template<typename TInputImage, typename TOutputImage>
class ScalarToRGBColormapImageFilter : public itk::ImageToImageFilter<TInputImage, TOutputImage>

Implements pixel-wise intensity->rgb mapping operation on one image.

This class is parameterized over the type of the input image and the type of the output image.

The input image’s scalar pixel values are mapped into a color map. The color map is specified by passing the SetColormap function one of the predefined maps. The following selects the “RGBColormapFilterEnum::Hot” colormap:

RGBFilterType::Pointer colormapImageFilter = RGBFilterType::New();
colormapImageFilter->SetColormap( RGBFilterType::Hot );

You can also specify a custom color map. This is done by creating a CustomColormapFunction, and then creating lists of values for the red, green, and blue channel. An example of setting the red channel of a colormap with only 2 colors is given below. The blue and green channels should be specified in the same manner.

// Create the custom colormap
using ColormapType = itk::Function::CustomColormapFunction<RealImageType::PixelType,
RGBImageType::PixelType>;
ColormapType::Pointer colormap = ColormapType::New();
// Setup the red channel of the colormap
ColormapType::ChannelType redChannel;
redChannel.push_back(0); redChannel.push_back(255);
colormap->SetRedChannel( channel );

The range of values present in the input image is the range that is mapped to the entire range of colors.

This code was contributed in the Insight Journal paper: “Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK” by Tustison N., Zhang H., Lehmann G., Yushkevich P., Gee J. https://www.insight-journal.org/browse/publication/285

See

BinaryFunctionImageFilter TernaryFunctionImageFilter

ITK Sphinx Examples:

See itk::ScalarToRGBColormapImageFilter for additional documentation.
class MersenneTwisterRandomVariateGenerator : public itk::Statistics::RandomVariateGeneratorBase

MersenneTwisterRandom random variate generator.

It is recommended to create a separate object in each thread. By default, each instantiated class will have a different seed created by the GetNextSeed method. The creation of the initial seeds are initialized once from the time. For deterministic behavior, the individual instances’ seeds should be manual set to separate values in each thread.

It is no longer recommended to use this class using a “Singleton-like” GetInstance method for the global instance of this class. This usage may result in unsafe concurrent access to the global instance.

This notice was included with the original implementation. The only changes made were to obfuscate the author’s email addresses.

Warning

This class’s instance methods are NEITHER reentrant nor concurrent thread-safe, except where marked as thread-safe. That is to say you can still use separate objects concurrently.

MersenneTwister.h Mersenne Twister random number generator a C++ class MTRand Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus Richard J. Wagner v1.0 15 May 2003 rjwagner at writeme dot com

The Mersenne Twister is an algorithm for generating random numbers. It was designed with consideration of the flaws in various other generators. The period, 2^19937-1, and the order of equidistribution, 623 dimensions, are far greater. The generator is also fast; it avoids multiplication and division, and it benefits from caches and pipelines. For more information see the inventors’ web page at http:*www.math.keio.ac.jp/~matumoto/emt.html

Reference M. Matsumoto and T. Nishimura, “Mersenne Twister: A 623-Dimensionally

Equidistributed Uniform Pseudo-Random Number Generator”, ACM Transactions on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.

Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, Copyright (C) 2000 - 2003, Richard J. Wagner All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The original code included the following notice:

When you use this, send an email to: matumoto at math dot keio dot ac dot jp
with an appropriate reference to your work.

It would be nice to CC: rjwagner at writeme dot com and Cokus at math dot washington dot edu when you write.

ITK Sphinx Examples:

See itk::Statistics::MersenneTwisterRandomVariateGenerator for additional documentation.