#if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
#endif
#include <itksys/SystemTools.hxx>
#if ITK_VERSION_MAJOR >= 4
#include "gdcmUIDGenerator.h"
#else
#include "gdcm/src/gdcmFile.h"
#include "gdcm/src/gdcmUtil.h"
#endif
#include <string>
#include <sstream>
int main( int argc, char* argv[] )
{
if( argc < 4 )
{
std::cerr << "Usage: "
<< argv[0]
<< " InputDicomDirectory OutputDicomDirectory spacing_x spacing_y spacing_z"
<< std::endl;
return EXIT_FAILURE;
}
constexpr unsigned int InputDimension = 3;
constexpr unsigned int OutputDimension = 2;
using PixelType = signed short;
#if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
#endif
ImageIOType::Pointer gdcmIO = ImageIOType::New();
InputNamesGeneratorType::Pointer inputNames = InputNamesGeneratorType::New();
inputNames->SetInputDirectory( argv[1] );
const ReaderType::FileNamesContainer & filenames =
inputNames->GetInputFileNames();
ReaderType::Pointer reader = ReaderType::New();
reader->SetImageIO( gdcmIO );
reader->SetFileNames( filenames );
try
{
reader->Update();
}
{
std::cerr << "Exception thrown while reading the series" << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
InterpolatorType::Pointer interpolator = InterpolatorType::New();
TransformType::Pointer transform = TransformType::New();
transform->SetIdentity();
const InputImageType::SpacingType& inputSpacing =
reader->GetOutput()->GetSpacing();
reader->GetOutput()->GetLargestPossibleRegion();
std::cout << "The input series in directory " << argv[1]
<< " has " << filenames.size() << " files with spacing "
<< inputSpacing
<< std::endl;
InputImageType::SpacingType outputSpacing;
outputSpacing[0] = atof(argv[3]);
outputSpacing[1] = atof(argv[4]);
outputSpacing[2] = atof(argv[5]);
bool changeInSpacing = false;
for (unsigned int i = 0; i < 3; i++)
{
if (outputSpacing[i] == 0.0)
{
outputSpacing[i] = inputSpacing[i];
}
else
{
changeInSpacing = true;
}
}
outputSize[0] =
static_cast<SizeValueType>(inputSize[0] * inputSpacing[0] / outputSpacing[0] + .5);
outputSize[1] =
static_cast<SizeValueType>(inputSize[1] * inputSpacing[1] / outputSpacing[1] + .5);
outputSize[2] =
static_cast<SizeValueType>(inputSize[2] * inputSpacing[2] / outputSpacing[2] + .5);
ResampleFilterType::Pointer resampler = ResampleFilterType::New();
resampler->SetInput( reader->GetOutput() );
resampler->SetTransform( transform );
resampler->SetInterpolator( interpolator );
resampler->SetOutputOrigin ( reader->GetOutput()->GetOrigin());
resampler->SetOutputSpacing ( outputSpacing );
resampler->SetOutputDirection ( reader->GetOutput()->GetDirection());
resampler->SetSize ( outputSize );
resampler->Update ();
ReaderType::DictionaryRawPointer inputDict = (*(reader->GetMetaDataDictionaryArray()))[0];
ReaderType::DictionaryArrayType outputArray;
#if ITK_VERSION_MAJOR >= 4
gdcm::UIDGenerator suid;
std::string seriesUID = suid.Generate();
gdcm::UIDGenerator fuid;
std::string frameOfReferenceUID = fuid.Generate();
#else
std::string seriesUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
std::string frameOfReferenceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
#endif
std::string studyUID;
std::string sopClassUID;
itk::ExposeMetaData<std::string>(*inputDict, "0020|000d", studyUID);
itk::ExposeMetaData<std::string>(*inputDict, "0008|0016", sopClassUID);
gdcmIO->KeepOriginalUIDOn();
for (unsigned int f = 0; f < outputSize[2]; f++)
{
auto dict = new ReaderType::DictionaryType;
CopyDictionary (*inputDict, *dict);
itk::EncapsulateMetaData<std::string>(*dict,"0020|000d", studyUID);
itk::EncapsulateMetaData<std::string>(*dict,"0020|000e", seriesUID);
itk::EncapsulateMetaData<std::string>(*dict,"0020|0052", frameOfReferenceUID);
#if ITK_VERSION_MAJOR >= 4
gdcm::UIDGenerator sopuid;
std::string sopInstanceUID = sopuid.Generate();
#else
std::string sopInstanceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
#endif
itk::EncapsulateMetaData<std::string>(*dict,"0008|0018", sopInstanceUID);
itk::EncapsulateMetaData<std::string>(*dict,"0002|0003", sopInstanceUID);
std::ostringstream value;
value.str("");
value << f + 1;
itk::EncapsulateMetaData<std::string>(*dict,"0020|0013", value.str());
std::string oldSeriesDesc;
itk::ExposeMetaData<std::string>(*inputDict, "0008|103e", oldSeriesDesc);
value.str("");
value << oldSeriesDesc
<< ": Resampled with pixel spacing "
<< outputSpacing[0] << ", "
<< outputSpacing[1] << ", "
<< outputSpacing[2];
unsigned lengthDesc = value.str().length();
std::string seriesDesc( value.str(), 0,
lengthDesc > 64 ? 64
: lengthDesc);
itk::EncapsulateMetaData<std::string>(*dict,"0008|103e", seriesDesc);
value.str("");
value << 1001;
itk::EncapsulateMetaData<std::string>(*dict,"0020|0011", value.str());
value.str("");
for (int i = 0; i < argc; i++)
{
value << argv[i] << " ";
}
lengthDesc = value.str().length();
std::string derivationDesc( value.str(), 0,
lengthDesc > 1024 ? 1024
: lengthDesc);
itk::EncapsulateMetaData<std::string>(*dict,"0008|2111", derivationDesc);
index[0] = 0;
index[1] = 0;
index[2] = f;
resampler->GetOutput()->TransformIndexToPhysicalPoint(index, position);
value.str("");
value << position[0] << "\\" << position[1] << "\\" << position[2];
itk::EncapsulateMetaData<std::string>(*dict,"0020|0032", value.str());
value.str("");
value << position[2];
itk::EncapsulateMetaData<std::string>(*dict,"0020|1041", value.str());
if (changeInSpacing)
{
value.str("");
value << outputSpacing[2];
itk::EncapsulateMetaData<std::string>(*dict,"0018|0050",
value.str());
itk::EncapsulateMetaData<std::string>(*dict,"0018|0088",
value.str());
}
outputArray.push_back(dict);
}
#if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
std::string interceptTag("0028|1052");
MetaDataStringType::ConstPointer interceptValue =
dynamic_cast<const MetaDataStringType *
>( entry.
GetPointer() );
int interceptShift = 0;
if( interceptValue )
{
std::string tagValue = interceptValue->GetMetaDataObjectValue();
interceptShift = -atoi ( tagValue.c_str() );
}
ShiftScaleType::Pointer shiftScale = ShiftScaleType::New();
shiftScale->SetInput( resampler->GetOutput());
shiftScale->SetShift( interceptShift );
#endif
itksys::SystemTools::MakeDirectory( argv[2] );
OutputNamesGeneratorType::Pointer outputNames = OutputNamesGeneratorType::New();
std::string seriesFormat(argv[2]);
seriesFormat = seriesFormat + "/" + "IM%d.dcm";
outputNames->SetSeriesFormat (seriesFormat.c_str());
outputNames->SetStartIndex (1);
outputNames->SetEndIndex (outputSize[2]);
SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
#if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
seriesWriter->SetInput( shiftScale->GetOutput() );
#else
seriesWriter->SetInput( resampler->GetOutput() );
#endif
seriesWriter->SetImageIO( gdcmIO );
seriesWriter->SetFileNames( outputNames->GetFileNames() );
seriesWriter->SetMetaDataDictionaryArray( &outputArray );
try
{
seriesWriter->Update();
}
{
std::cerr << "Exception thrown while writing the series " << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
std::cout << "The output series in directory " << argv[2]
<< " has " << outputSize[2] << " files with spacing "
<< outputSpacing
<< std::endl;
return EXIT_SUCCESS;
}
{
DictionaryType::ConstIterator itr = fromDict.
Begin();
DictionaryType::ConstIterator end = fromDict.
End();
while( itr != end )
{
MetaDataStringType::Pointer entryvalue =
dynamic_cast<MetaDataStringType *
>( entry.
GetPointer() );
if( entryvalue )
{
std::string tagkey = itr->first;
std::string tagvalue = entryvalue->GetMetaDataObjectValue();
itk::EncapsulateMetaData<std::string>(toDict, tagkey, tagvalue);
}
++itr;
}
}