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标准格式文件