Доступ к пиксельным значениям tif-изображения с помощью ITK

0

Я новичок в 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: Изображение 174551

  • 1
    Трудно сказать, если проблема в том, как Matlab пишет изображение или как ITK читает изображение. В библиотеке libtiff есть инструмент под названием «tiffinfo». Это сбрасывает важные части заголовка TIFF, чтобы определить, как хранится изображение. Пожалуйста, запустите эту утилиту и сообщите результат.
  • 0
    @blowekamp: я обновил вопрос выше, загрузив скриншот вывода tiffinfo.
Теги:
itk

1 ответ

1

Файл содержит пиксели 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, это может быть проще.

  • 0
    Спасибо за помощь. Я попробовал ваш код, но когда он доходит до этой команды: itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(inputFilename.c_str(),itk::ImageIOFactory::ReadMode); , он возвращает нулевой указатель. Я не могу понять, в чем проблема :( У вас есть идеи, что вызывает эту проблему?
  • 0
    Смотря на код. Это может произойти, если имя файла указано неверно или не существует. Я бы порекомендовал распечатать inputFilename, чтобы убедиться, что оно соответствует вашему коду. Это метод более низкого уровня, поэтому некоторые проверки такого типа не выполняются.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню