Я новичок в ITK, и я пытаюсь прочитать файл tif с помощью ITK и доступа к его пикселям. Вот часть моего кода для этой цели:
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;
Значение пикселя, которое я получаю, не соответствует правильному значению! Я использовал MATLAB для проверки моего тестового изображения. Вот его размеры: <298x237x4 uint8>.
Я попытался сохранить изображение (:,:, 1) (т.е. <298x237 uint8>) в качестве нового изображения tif с использованием MATLAB, а затем передать это изображение в качестве входного изображения в вышеуказанную программу. Он работает, и я получаю правильное значение пикселей, которое я ожидал!
Я знаю, в чем проблема, но я не знаю, как ее решить. Я не знаю, как изменить мою программу, чтобы извлечь изображение <298x237 uint8> из входного изображения <298x237x4 uint8>.
Обновить:
Вот информация, которую я получаю от tiffinfo:
Файл содержит пиксели RGBA, но вы читаете их в виде только плавающих.
Быстрое решение - просто изменить этот typedef:
typedef float PixelType; // Pixel type
чтобы:
typedef itk::RGBAPixel<float> PixelType; // Pixel type
С ITK, когда вы указываете ImageFileReader, вы указываете тип, который хотите в качестве вывода. ITK неявно выполняет преобразование к типу, который вы запрашиваете. В вашем случае вы запрашиваете преобразование из RGBA в float.
Путем прямого построения ImageIO вы можете получить информацию о типе пикселя из файла. Вот пример формы Wiki:
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;
}
*/
Я также работаю над проектом SimpleITK, который обеспечивает упрощенный слой ITK, предназначенный для быстрого прототипирования и интерактивных вычислений, таких как языки сценариев. Он добавил слой, который автоматически загружает изображение в правильный тип. Если вы приехали из Matlab, это может быть проще.
itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(inputFilename.c_str(),itk::ImageIOFactory::ReadMode);
, он возвращает нулевой указатель. Я не могу понять, в чем проблема :( У вас есть идеи, что вызывает эту проблему?