问题
I am new to ITK and I am trying to read a tif file using ITK and access to its pixels. Here is the piece of my code for this purpose:
typedef float PixelType; // Pixel type
const unsigned char Dimension = 2;
typedef itk::Image< PixelType, Dimension > ImageType;
ImageType::Pointer image;
typedef itk::ImageFileReader< ImageType > ReaderType;
ReaderType::Pointer reader;
reader = ReaderType::New();
const char * filename = "test.tif";
reader->SetImageIO(itk::TIFFImageIO::New());
reader->SetFileName(filename);
try
{
reader->Update();
}
catch (itk::ExceptionObject & excp)
{
std::cerr << excp << std::endl;
}
// Access to a pixel
ImageType::IndexType pixelIndex;
pixelIndex[0] = 103;
pixelIndex[1] = 178;
ImageType::PixelType pixelValue = image->GetPixel(pixelIndex);
std::cout << "pixel : " << pixelValue << std::endl;
The pixel value I am getting does not match the correct value! I have used MATLAB to check my test image. Here is its dimensions: <298x237x4 uint8>.
I tried storing the image(:,:,1) (i.e. <298x237 uint8>) as a new tif image using MATLAB, and then pass this image as input image to above program. It is working and I am getting the correct pixel value I expected!
I kind of know what is the problem, but I don't know how to solve it. I don't know how to modify my program to extract <298x237 uint8> image out of <298x237x4 uint8> input image.
Update:
Here is the information I am getting from tiffinfo :
回答1:
You file contains pixels of RGBA, but you are reading them into an image of just floats.
The quick solution is to just change this typedef:
typedef float PixelType; // Pixel type
to:
typedef itk::RGBAPixel<float> PixelType; // Pixel type
With ITK when you specify an ImageFileReader you are specifying the type you want as output. ITK will implicitly do the conversion to the type you are requesting. In your case you are requesting conversion from RGBA to float.
By directly constructing an ImageIO you can obtain the pixel type information from the file. Here is an example form the Wiki Examples:
std::string inputFilename = argv[1];
typedef itk::ImageIOBase::IOComponentType ScalarPixelType;
itk::ImageIOBase::Pointer imageIO =
itk::ImageIOFactory::CreateImageIO(
inputFilename.c_str(), itk::ImageIOFactory::ReadMode);
imageIO->SetFileName(inputFilename);
imageIO->ReadImageInformation();
const ScalarPixelType pixelType = imageIO->GetComponentType();
std::cout << "Pixel Type is " << imageIO->GetComponentTypeAsString(pixelType) // 'double'
<< std::endl;
const size_t numDimensions = imageIO->GetNumberOfDimensions();
std::cout << "numDimensions: " << numDimensions << std::endl; // '2'
std::cout << "component size: " << imageIO->GetComponentSize() << std::endl; // '8'
std::cout << "pixel type (string): " << imageIO->GetPixelTypeAsString(imageIO->GetPixelType()) << std::endl; // 'vector'
std::cout << "pixel type: " << imageIO->GetPixelType() << std::endl; // '5'
/*
switch (pixelType)
{
case itk::ImageIOBase::COVARIANTVECTOR:
typedef itk::Image<unsigned char, 2> ImageType;
ImageType::Pointer image = ImageType::New();
ReadFile<ImageType>(inputFilename, image);
break;
typedef itk::Image<unsigned char, 2> ImageType;
ImageType::Pointer image = ImageType::New();
ReadFile<ImageType>(inputFilename, image);
break;
default:
std::cerr << "Pixel Type ("
<< imageIO->GetComponentTypeAsString(pixelType)
<< ") not supported. Exiting." << std::endl;
return -1;
}
*/
I also work on the SimpleITK project which provides a simplified layer onto of ITK designed for rapid prototyping and interactive computing such as for scripting languages. It has added a layer which automatically loads the image into the correct type. If you are coming from Matlab it may be an easier transition.
来源:https://stackoverflow.com/questions/26853916/access-to-pixel-values-of-a-tif-image-using-itk