如何使用 ITK 将调色板图像读取为标量图像?

Posted

技术标签:

【中文标题】如何使用 ITK 将调色板图像读取为标量图像?【英文标题】:How to read a palette image as a scalar image with ITK? 【发布时间】:2017-05-09 16:45:51 【问题描述】:

当我读取图像时,itk::ImageIOBase(如实现 here)告诉我该图像具有 RGB 像素类型。图片的格式是TIFF,但也可以是png或gif。

itk::ImageIOBase::Pointer imageIO =
    itk::ImageIOFactory::CreateImageIO(
        fileName, itk::ImageIOFactory::ReadMode);

如何知道,通过ITK,图像是否实际上是调色板图像,标量图像连同调色板,并将图像读取为标量图像+调色板?我需要检索存储在文件中的索引以及文件中使用的调色板。

目前,我唯一的解决方案是使用 freeImagePlus 来识别和读取这种类型的图像。我在 ImageIOBase 类中没有找到任何与此相关的函数。

任何帮助将不胜感激,我在互联网上没有找到太多这方面的信息!

【问题讨论】:

【参考方案1】:

您是否尝试将其读取为灰度图像?如果没有明确设置 IO,这个 reader 会产生什么结果?

typedef itk::Image<unsigned char, 2> uc2Type;
typedef itk::ImageFileReader<uc2Type> ReaderType;

除非您需要调色板来做某事,否则这就足够了。

【讨论】:

感谢您的帮助!获取用于每个像素的确切索引以及关联的颜色图对我来说很重要。不幸的是,在测试您的代码示例后,图像会根据其调色板中提供的 RGB 值转换为灰色。因此,我无法找回索引... ITK 可能不是最好的库。您是否尝试过直接使用 libpng 或 libtiff? 谢谢。我确实注意到了!但是我正在开发一个注册程序,所以无论如何我都需要将图像转换为 ITK。目前,我正在使用 freeImage 来读取这些图像并将内存复制到 itk。集成在 ITK 中的东西会更方便。【参考方案2】:

为了回答我自己的问题,该功能现在在 ITK 中的 master 分支中实现,并为 png tif 和 bmp 图像提供调色板支持

这是一个工作示例,供感兴趣的人参考:

#include "itkImage.h"
#include <iostream>
#include <string>

#include "itkPNGImageIOFactory.h"
#include "itkImageFileReader.h"
#include "itkPNGImageIO.h"

int main()

    std::string filename("testImage_palette.png");

    auto io = itk::PNGImageIO::New();

    // tell the reader not to expand palette to RGB, if possible
    io->SetExpandRGBPalette(false);

    typedef unsigned short PixelType;
    typedef itk::Image<PixelType, 2> imageType;
    typedef itk::ImageFileReader<imageType> ReaderType;
    ReaderType::Pointer reader = ReaderType::New();

    reader->SetFileName(filename);
    reader->SetImageIO(io);

    try 
        reader->Update();
     catch (itk::ExceptionObject &err) 
        std::cerr << "ExceptionObject caught !" << std::endl;
        std::cerr << err << std::endl;
        return EXIT_FAILURE;
    

    std::cout<< std::endl << "IsReadAsScalarPlusPalette:" <<io->GetIsReadAsScalarPlusPalette() << std::endl;

    if (io->GetIsReadAsScalarPlusPalette()) 
        auto palette(io->GetColorPalette());
        std::cout<< "palette (size="<< palette.size()<<"):"<< std::endl;
        auto m(std::min(static_cast<size_t>(10),palette.size()));
        for (size_t i=0; i<m;++i) 
            std::cout << "["<<palette[i]<< "]"<< std::endl;
        
        if (m< palette.size())
            std::cout<< "[...]"<< std::endl;
    
    // if io->GetIsReadAsScalarPlusPalette() im will be the index of the palette image
    auto im(reader->GetOutput()); 

【讨论】:

以上是关于如何使用 ITK 将调色板图像读取为标量图像?的主要内容,如果未能解决你的问题,请参考以下文章

ITK例子-jpg图像读写

十ITK读取一张dcm图像然后通过vtk显示

如何在 Python 中实现 itk 图像和 SimpleITK 图像之间的转换?

如何从 5-6-5 位图图像中提取调色板?

如何将调色板图像从另一个线程生成到 WPF UI 线程?

如何将颜色减少到指定的调色板