我需要使用GDCM库生成一系列CT DICOM图像(512x512,MONOCHROME)。由于我正在处理的应用程序的结构,我最好为每个图像单独准备gdcm::Image
和gdcm::File
个实例,最后将它们传递给gdcmImageWriter
使用SetFile()
和SetImage()
方法。
gdcmImageWriter::write()
无法写入DICOM图像。我已经查看了VTKGDCMImageWriter类的源代码和this GDCM example的提示。问题似乎源于gdcm::Image
和gdcm::File
实例之间的某些不兼容性(例如,两个类都包含有关我传递的DICOM图像的光度学解释的信息)到gdcmImageWriter
,但我不确定那些是什么。
以下简化的C ++代码重现了我遇到的错误:
#include <gdcmFile.h>
#include <gdcmImage.h>
#include <gdcmTag.h>
#include "gdcmDataElement.h"
#include "gdcmByteValue.h"
#include "gdcmPixelFormat.h"
#include "gdcmImageWriter.h"
#include "gdcmAnonymizer.h"
#include <iostream>
#include <string>
InitializeGDCMImage(gdcm::Image* imagePtr);
InitializeGDCMFile( gdcm::File* filePtr );
WriteFile( gdcm::Image* imagePtr , gdcm::File* filePtr , std::string fileName );
int main()
{
std::string fileName = "./TEST.dcm";
// Will be deleted by gdcm::writer.
gdcm::Image* imagePtr = new gdcm::Image;
gdcm::File* filePtr = new gdcm::File;
InitializeGDCMImage(imagePtr);
InitializeGDCMFile( filePtr );
WriteFile( imagePtr , filePtr , fileName );
return 0;
}
其中,
void WriteFile( gdcm::Image* imagePtr , gdcm::File* filePtr , std::string fileName )
{
gdcm::ImageWriter* writer = new gdcm::ImageWriter;
writer->SetFileName( fileName.c_str() );
writer->SetImage( *imagePtr );
writer->SetFile( *filePtr );
if( !writer->Write() ){
std::cerr << "ERROR: Could not write to \"" << fileName << "\"" << std::endl;
}
delete writer;
}
WriteFile()
设置gdcm::File
和gdcm::Image
并调用write()
。
InitializeGDCMFile()
使用gdcm::Anonymizer
修改了一些DICOM标记,InitializeGDCMImage()
设置了实际的像素值(为简洁起见,此处略过)。
void InitializeGDCMFile( gdcm::File* origianlFilePtr )
{
gdcm::File* filePtr = new gdcm::File;
gdcm::Anonymizer anon;
anon.SetFile( *filePtr );
anon.Replace( gdcm::Tag(0x0028,0x0002) , "1" ); //SamplesperPixel
anon.Replace( gdcm::Tag(0x0028,0x0004) , "MONOCHROME2" ); //PhotometricInterpretation
anon.Replace( gdcm::Tag(0x0028,0x0010) , "512" ); //Rows
anon.Replace( gdcm::Tag(0x0028,0x0011) , "512" ); //Columns
anon.Replace( gdcm::Tag(0x0028,0x0030) , "0.781\\0.781" ); //PixelSpacing
anon.Replace( gdcm::Tag(0x0028,0x1050) , "0" ); //WindowCenter
anon.Replace( gdcm::Tag(0x0028,0x1051) , "100" ); //WindowWidth
anon.Replace( gdcm::Tag(0x0028,0x1052) , "0" ); //RescaleIntercept
anon.Replace( gdcm::Tag(0x0028,0x1053) , "1" ); //RescaleSlope
*origianlFilePtr = *filePtr;
}
void InitializeGDCMImage(gdcm::Image* imagePtr)
{
imagePtr->SetPhotometricInterpretation( gdcm::PhotometricInterpretation::MONOCHROME2 );
imagePtr->SetNumberOfDimensions(2);
unsigned int dims[2]={512,512};
imagePtr->SetDimensions( dims );
imagePtr->SetSpacing( 0 , 1. );
imagePtr->SetSpacing( 1 , 1. );
imagePtr->SetIntercept(0.);
imagePtr->SetSlope(1.);
double dirCos[6]={1.,0.,0.,0.,1.,0.};
imagePtr->SetDirectionCosines( dirCos );
char *buffer = new char[512*512*sizeof(int16_t)];
imagePtr->SetPixelFormat( gdcm::PixelFormat::INT16 );
imagePtr->GetDataElement().SetByteValue( buffer , 512*512*sizeof(int16_t) );
imagePtr->GetPixelFormat().SetSamplesPerPixel(1);
delete[] buffer;
}