[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