[Insight-users] how to read images with unknown number of channels at build time ?

Kent Williams kent at psychiatry.uiowa.edu
Fri Mar 3 16:36:24 EST 2006


It is better, on the whole, to know what you're reading and then respond 
accordingly.

Presently there is no itk::FileSniffer, as it were. itk::ImageFileReader 
does try to load whatever path you ask it to and do something reasonable 
with the data. But there are a couple of  'gotchas' if you want to keep 
things completely general:

1. File formats where images of dimension > 3 are stored as 
two-dimensional slices. Then, itk::ImageSeriesReader is the tool of 
choice, instead of itk::ImageFileReader.
2. Cases such as yours, where some attribute of the file on disk affects 
how you will process it.

The workaround is to use an itk:ImageFileReader instance to sneak a look 
at the files attributes, before actually reading the image. Below is a 
function that illustrates how to snoop around for information about the 
file you're trying to load.  This feels to me like breaking 
encapsulation, but there currently isn't any other way. 

To get even more nefarious, you can call 
itk::ImageIOBase::GetNameOfClass() to find out which file reader claims 
to be able to read the file.  We use this in order to handle DICOM 
images specially. Our application (which didn't originally use ITK Image 
I/O) had the convention that when you give the name of a slice of a 
DICOM file, then you want to read all the slices in the containing 
directory that are members of the same DICOM series.

int FileInfo(const std::string &path)
{
  typedef itk::Image<char,4> TestImageType; // pixel type doesn't matter 
for current purpose
  typedef itk::ImageFileReader<TestImageType> TestFileReaderType; // 
reader for testing a file
  TestFileReaderType::Pointer onefileReader = TestFileReaderType::New();
   onefileReader->SetFileName(path.c_str());
  try
    {
    onefileReader->GenerateOutputInformation();
    }
  catch(itk::ExceptionObject &excp)
    {
    return -1;
    }
    // grab the ImageIO instance for the reader
  itk::ImageIOBase *imageIO = onefileReader->GetImageIO();
    unsigned int NumberOfDimensions =  imageIO->GetNumberOfDimensions() 
std::endl;
    unsigned dims[32];   // almost always no more than 4 dims, but ...
    unsigned origin[32];
    double spacing[32];
    std::vector<double> directions[32];
    for(unsigned i = 0; i < NumberOfDimensions && i < 32; i++)
      {
      dims[i] = imageIO->GetDimensions(i);
      origin[i] = imageIO->GetOrigin(i);
      spacing[i] = imageIO->GetSpacing(i);
      directions[i] = imageIO->GetDirection(i);
      }
   // PixelType is SCALAR, RGB, RGBA, VECTOR, COVARIANTVECTOR, POINT, INDEX
   itk::ImageIOBase::PixelType pixelType = imageIO->GetPixelType();
   // IOComponentType is UCHAR, CHAR, USHORT, SHORT, UINT, INT, ULONG, 
LONG, FLOAT, DOUBLE
   itk::ImageIOBase::IOComponentType componentType = 
imageIO->GetIOComponentType();
    const std::type_info &typeinfo typeInfo = 
imageIO->GetComponentTypeInfo();
    // NumberOfComponents is usually one, but for non-scalar pixel 
types, it can be anything
   unsigned int NumberOfComponents = imageIO->GetNumberOfComponents();
   return 0;
}

Gaetan Lehmann wrote:

>Hi,
>
>Is it possible to write code able to read an image with an unknown number of 
>channels at build time, and to extract each channel in an individual image ?
>If yes, with which classes can it be done ?
>
>Thanks,
>
>Gaetan
>  
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Insight-users mailing list
>Insight-users at itk.org
>http://www.itk.org/mailman/listinfo/insight-users
>  
>



More information about the Insight-users mailing list