ScalingFilterExample.cxxΒΆ

On one hand, satellite images are commonly coded on more than 8 bits to provide the dynamic range required from shadows to clouds. On the other hand, image formats in use for printing and display are usually limited to 8 bits. We need to convert the value to enable a proper display. This is usually done using linear scaling. Of course, you have to be aware that some information is lost in the process.

image1

image2

On the left, the image obtained by truncated pixel values at the dynamic acceptable for a png file (between 0 and 255). On the right, the same image with a proper rescaling.

Example usage:

./ScalingFilterExample Input/QB_Toulouse_Ortho_PAN.tif Output/QB_Toulouse_Ortho_PAN_rescaled.png Output/QB_Toulouse_Ortho_PAN_casted.png

Example source code (ScalingFilterExample.cxx):

#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkCastImageFilter.h"

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

  if (argc != 4)
  {
    std::cerr << "Usage: " << argv[0] << " <inputImageFile> ";
    std::cerr << " <outputRescaledImageFile> <outputCastedImageFile>" << std::endl;
    return EXIT_FAILURE;
  }

  using InputPixelType  = unsigned short;
  using OutputPixelType = unsigned char;
  using InputImageType  = otb::Image<InputPixelType, 2>;
  using OutputImageType = otb::Image<OutputPixelType, 2>;

  using ReaderType           = otb::ImageFileReader<InputImageType>;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(argv[1]);

  // The RescaleIntensityImageFilter is used to rescale the value
  using RescalerType             = itk::RescaleIntensityImageFilter<InputImageType, OutputImageType>;
  RescalerType::Pointer rescaler = RescalerType::New();
  rescaler->SetInput(reader->GetOutput());

  using WriterType           = otb::ImageFileWriter<OutputImageType>;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName(argv[2]);
  writer->SetInput(rescaler->GetOutput());
  writer->Update();

  using CasterType           = itk::CastImageFilter<InputImageType, OutputImageType>;
  CasterType::Pointer caster = CasterType::New();
  caster->SetInput(reader->GetOutput());

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