【ITK类学习】使用itk读取DICOM数据序列

ITK读取DICOM数据

1、itkImageSeriesReader

ITK 库中用于读取图像序列的类,该类支持从多个 n-1 维图像文件构建 n 维图像,常用于读取一系列的2D图像文件,并将其组合成一个三维图像。

该类支持读取多种格式的图像文件,例如 DICOM、TIFF、NIFTI 等,读取的文件之间的格式可能有所不同,但图像数据的size必须相同。

使用该类需要指定图像序列的格式以及文件路径,然后调用 Update() 方法进行读取。读取后,可以通过 GetOutput() 方法获取读取的图像数据。此外,还可以通过 SetMetaDataDictionaryArrayUpdate 设置读取元数据,并通过 GetMetaDataDictionaryArray() 方法获取元数据。

2、itkGDCMImageIO

ITK 中的一个图像读写模块,用于读取和写入 DICOM V3.0 和 ACR/NEMA 1&2 未压缩图像的 ImageIO 类,包括单幅多幅图像。

该类使用 GDCM 库实现,GDCM 是一个开源的 DICOM(数字图像和通信医学)库,用于读取和处理医学图像数据,下载网址:https://sourceforge.net/projects/gdcm

使用 itkGDCMImageIO 可以方便地读取和处理 DICOM 格式的医学图像数据,并且能够保存为 DICOM 格式的图像数据。它提供了丰富的功能,包括对图像元数据的读取和修改、对像素数据的访问,以及处理多帧 DICOM 图像等。

使用 itkGDCMImageIO首先需要安装 GDCM 库并配置 ITK。然后,在编写代码时,可以通过包含 “itkGDCMImageIO.h” 头文件来使用 itkGDCMImageIO 类,使用它的成员函数来读取和写入 DICOM 格式的图像数据。

3、itkGDCMSeriesFileNames

该类用于获取DICOM系列文件的文件名。

该类可以获取给定DICOM系列的文件名,并进一步加载和处理这些文件。通过提供DICOM文件夹的路径作为构造函数的参数,可以创建itkGDCMSeriesFileNames对象,并使用GetFileNames方法获取文件名的列表。可以根据需要进一步筛选文件名列表,并使用SetSeriesID方法设置DICOM系列的ID。

此外,还可以使用GetSeriesUID方法获取DICOM系列的唯一标识符。

其中:GetInputFileNames() 函数用于获取输入文件的名称,GetFileNames() 函数用于获取整个系列的文件名称。

例如,如果你有一个包含多个 DICOM 文件的文件夹,GetInputFileNames() 函数将返回该文件夹中的所有文件的名称。而 GetFileNames() 函数将返回整个 DICOM 系列的所有文件的名称,包括子目录中的文件。

总的来说,GetInputFileNames() 函数用于获取单个文件的名称,而 GetFileNames() 函数用于获取整个 DICOM 系列的所有文件的名称。

代码示例:

#include <iostream>
#include <experimental/filesystem>

#include <itkImageFileReader.h>
#include <itkImageSeriesReader.h>
#include <itkGDCMImageIO.h>
#include <itkGDCMSeriesFileNames.h>

bool LoadDicomSerise(std::string seriesDicomDir)
{
    //校验路径是否存在或是否为空
	if (std::experimental::filesystem::exists(seriesDicomDir)==false ||
	    std::experimental::filesystem::is_empty(seriesDicomDir))
	{
	    std::cerr << "Error: Dicom Directory ERROR!Please Chick!" << std::endl;
		return false;
	}
	
	//开始读取DICOM数据序列
    typedef signed short shortPixelType;   
	const unsigned int  Dim = 3;       //数据的Dimension
  
	typedef itk::Image<shortPixelType, Dim> ShortImageType;
	typedef itk::ImageSeriesReader<ShortImageType> ReaderType;
    
	itk::GDCMImageIO::Pointer gdcmIO = itk::GDCMImageIO::New();
	itk::GDCMSeriesFileNames::Pointer seriesFileNames= itk::GDCMSeriesFileNames::New();
    
    //获取DICOM系列文件的文件名
	seriesFileNames->SetDirectory(seriesDicomDir);
    
    //如果文件夹中包含多个序列,使用GetSeriesUIDs获取所有的UID值,再在GetFileNames中指定需要返回的序列的UID,获取该序列的所有文件名
    //FileNamesContainer和SeriesUIDContainerType的定义为:std::vector<std::string> 
    //std::vector<std::string> seriesUIDs = seriesFileNames->GetSeriesUIDs();
    //std::vector<std::string> filenames = seriesFileNames->GetFileNames(seriesUIDs[0])
    const itk::GDCMSeriesFileNames::SeriesUIDContainerType& seriesUIDs = seriesFileNames->GetSeriesUIDs();
	const ReaderType::FileNamesContainer& filenames = seriesFileNames->GetFileNames(seriesUIDs[0]);

    typename ReaderType::Pointer reader = ReaderType::New();
	try
	{
		reader->SetImageIO(gdcmIO);
		reader->SetFileNames(filenames);
		reader->Update();
    }
    catch (itk::ExceptionObject& ex)
    {
       //读取过程发生错误
        std::cerr << "Error: " << ex << std::endl;
        return false;
    }

    return true;
}

读取成功后,可以通过

	auto space = reader->GetOutput()->GetSpacing();
	auto Dims = reader->GetOutput()->GetImageDimension();
	auto origin = reader->GetOutput()->GetOrigin();
	const ReaderType::IndexType index = { 0,0,0 };
	const ReaderType::OutputImagePixelType pixel = reader->GetOutput()->GetPixel(index);
	

等语句,获取体数据的相关信息

读取成功后,可以通过

    typedef itk::MetaDataDictionary DictionaryType;
	const DictionaryType& dictionary = gdcmIO->GetMetaDataDictionary();
	typedef itk::MetaDataObject<std::string> MetaDataStringType;
	typename DictionaryType::ConstIterator itr = dictionary.Begin();
	typename DictionaryType::ConstIterator end = dictionary.End();
    
    //查询所有头文件标签信息
	while (itr != end)
	{
		typename itk::MetaDataObjectBase::Pointer entry = itr->second;
		typename MetaDataStringType::Pointer entryvalue =
			dynamic_cast<MetaDataStringType*>(entry.GetPointer());
		if (entryvalue)
		{
			std::string tagKey = itr->first;
			std::string tagValue = entryvalue->GetMetaDataObjectValue();
			std::cout << tagKey << " = " << tagValue << std::endl;
		}
		++itr;
	}
	

	//查询指定的头文件标签信息
	std::string entryID = "0010|0010";
	DictionaryType::ConstIterator tagItr = dictionary.Find(entryID);
	if (tagItr == end)
	{
		std::cerr << "Tag " << entryID << " not found in the DICOM header" << std::endl;
	}
	typename MetaDataStringType::ConstPointer entryValue = dynamic_cast<const MetaDataStringType*>(tagItr->second.GetPointer());
	if (entryValue)
	{
		std::string tagValue = entryValue->GetMetaDataObjectValue();
		std::cout << entryID << " = " << tagValue << std::endl;
	}

等语句,获取DICOM数据的头文件标签信息,具体标签定义查询DICOM标准格式文件

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值