Read Unknown Image Type

Synopsis

Read one unknown image

Code

C++

#include "itkImageFileReader.h"
#include "itkImageIOBase.h"

template <class TImage>
int
ReadImage(const char * fileName, typename TImage::Pointer image)
{
  using ImageType = TImage;
  using ImageReaderType = itk::ImageFileReader<ImageType>;

  auto reader = ImageReaderType::New();
  reader->SetFileName(fileName);

  try
  {
    reader->Update();
  }
  catch (const itk::ExceptionObject & e)
  {
    std::cerr << e.what() << std::endl;
    return EXIT_FAILURE;
  }

  image->Graft(reader->GetOutput());

  return EXIT_SUCCESS;
}

template <unsigned int VDimension>
int
ReadScalarImage(const char * inputFileName, const itk::IOComponentEnum componentType)
{
  switch (componentType)
  {
    default:
    case itk::IOComponentEnum::UNKNOWNCOMPONENTTYPE:
      std::cerr << "Unknown and unsupported component type!" << std::endl;
      return EXIT_FAILURE;

    case itk::IOComponentEnum::UCHAR:
    {
      using PixelType = unsigned char;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }

    case itk::IOComponentEnum::CHAR:
    {
      using PixelType = char;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }

    case itk::IOComponentEnum::USHORT:
    {
      using PixelType = unsigned short;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }

    case itk::IOComponentEnum::SHORT:
    {
      using PixelType = short;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }

    case itk::IOComponentEnum::UINT:
    {
      using PixelType = unsigned int;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }

    case itk::IOComponentEnum::INT:
    {
      using PixelType = int;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }

    case itk::IOComponentEnum::ULONG:
    {
      using PixelType = unsigned long;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }

    case itk::IOComponentEnum::LONG:
    {
      using PixelType = long;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }

    case itk::IOComponentEnum::FLOAT:
    {
      using PixelType = float;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }

    case itk::IOComponentEnum::DOUBLE:
    {
      using PixelType = double;
      using ImageType = itk::Image<PixelType, VDimension>;

      auto image = ImageType::New();

      if (ReadImage<ImageType>(inputFileName, image) == EXIT_FAILURE)
      {
        return EXIT_FAILURE;
      }

      std::cout << image << std::endl;
      break;
    }
  }
  return EXIT_SUCCESS;
}

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

  const char * inputFileName = argv[1];

  itk::ImageIOBase::Pointer imageIO =
    itk::ImageIOFactory::CreateImageIO(inputFileName, itk::CommonEnums::IOFileMode::ReadMode);

  imageIO->SetFileName(inputFileName);
  imageIO->ReadImageInformation();

  using IOPixelType = itk::IOPixelEnum;
  const IOPixelType pixelType = imageIO->GetPixelType();

  std::cout << "Pixel Type is " << itk::ImageIOBase::GetPixelTypeAsString(pixelType) << std::endl;

  using IOComponentType = itk::IOComponentEnum;
  const IOComponentType componentType = imageIO->GetComponentType();

  std::cout << "Component Type is " << imageIO->GetComponentTypeAsString(componentType) << std::endl;

  const unsigned int imageDimension = imageIO->GetNumberOfDimensions();

  std::cout << "Image Dimension is " << imageDimension << std::endl;

  switch (pixelType)
  {
    case itk::IOPixelEnum::SCALAR:
    {
      if (imageDimension == 2)
      {
        return ReadScalarImage<2>(inputFileName, componentType);
      }
      else if (imageDimension == 3)
      {
        return ReadScalarImage<3>(inputFileName, componentType);
      }
      else if (imageDimension == 4)
      {
        return ReadScalarImage<4>(inputFileName, componentType);
      }
    }

    default:
      std::cerr << "not implemented yet!" << std::endl;
      return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}

Classes demonstrated

class ImageIOBase : public itk::LightProcessObject

Abstract superclass defines image IO interface.

ImageIOBase is a class that reads and/or writes image data of a particular format (such as PNG or raw binary). The ImageIOBase encapsulates both the reading and writing of data. The ImageIOBase is used by the ImageFileReader class (to read data) and the ImageFileWriter (to write data) into a single file. The ImageSeriesReader and ImageSeriesWriter classes are used to read and write data (in conjunction with ImageIOBase) when the data is represented by a series of files. Normally the user does not directly manipulate this class other than to instantiate it, set the FileName, and assign it to a ImageFileReader/ImageFileWriter or ImageSeriesReader/ImageSeriesWriter.

A Pluggable factory pattern is used this allows different kinds of readers to be registered (even at run time) without having to modify the code in this class.

See

ImageFileWriter

See

ImageFileReader

See

ImageSeriesWriter

See

ImageSeriesReader

Subclassed by itk::BioRadImageIO, itk::BMPImageIO, itk::Bruker2dseqImageIO, itk::DCMTKImageIO, itk::GDCMImageIO, itk::GiplImageIO, itk::IPLCommonImageIO, itk::JPEGImageIO, itk::MetaImageIO, itk::MINCImageIO, itk::NiftiImageIO, itk::NrrdImageIO, itk::PNGImageIO, itk::RawImageIO< TPixel, VImageDimension >, itk::StimulateImageIO, itk::StreamingImageIOBase, itk::TIFFImageIO, itk::VideoIOBase, itk::VoxBoCUBImageIO

See itk::ImageIOBase for additional documentation.