1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18 #ifndef clitkImage2DicomSeriesGenericFilter_txx
19 #define clitkImage2DicomSeriesGenericFilter_txx
21 /* =================================================
22 * @file clitkImage2DicomSeriesGenericFilter.txx
28 ===================================================*/
31 #include "clitkResampleImageWithOptionsFilter.h"
32 #if GDCM_MAJOR_VERSION >= 2
33 #include "gdcmUIDGenerator.h"
38 #include "itkVersion.h"
41 #include "itkMinimumMaximumImageFilter.h"
43 #include "itkGDCMImageIO.h"
44 #include "itkGDCMSeriesFileNames.h"
45 #include "itkNumericSeriesFileNames.h"
47 #include "itkImageSeriesReader.h"
48 #include "itkImageSeriesWriter.h"
50 #include <itkThresholdImageFilter.h>
52 #include "itkResampleImageFilter.h"
54 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
55 #include "itkShiftScaleImageFilter.h"
58 #include "itkIdentityTransform.h"
59 #include "itkLinearInterpolateImageFunction.h"
61 #include <itksys/SystemTools.hxx>
63 #if ITK_VERSION_MAJOR >= 4
64 #include "gdcmUIDGenerator.h"
66 #include "gdcm/src/gdcmFile.h"
67 #include "gdcm/src/gdcmUtil.h"
77 //-----------------------------------------------------------
79 //-----------------------------------------------------------
80 template<class args_info_type>
81 Image2DicomSeriesGenericFilter<args_info_type>::Image2DicomSeriesGenericFilter()
88 //-----------------------------------------------------------
90 //-----------------------------------------------------------
91 template<class args_info_type>
92 void Image2DicomSeriesGenericFilter<args_info_type>::Update()
94 // Read the Dimension and PixelType
96 std::string PixelType;
97 ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
100 // Call UpdateWithDim
101 if(Dimension==2) UpdateWithDim<2>(PixelType);
102 else if(Dimension==3) UpdateWithDim<3>(PixelType);
103 // else if (Dimension==4)UpdateWithDim<4>(PixelType);
105 std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
110 //-------------------------------------------------------------------
111 // Update with the number of dimensions
112 //-------------------------------------------------------------------
113 template<class args_info_type>
114 template<unsigned int Dimension>
116 Image2DicomSeriesGenericFilter<args_info_type>::UpdateWithDim(std::string PixelType)
118 if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
120 if(PixelType == "short") {
121 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
122 UpdateWithDimAndPixelType<Dimension, signed short>();
124 else if(PixelType == "unsigned_short"){
125 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
126 UpdateWithDimAndPixelType<Dimension, unsigned short>();
129 else if (PixelType == "unsigned_char") {
130 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
131 UpdateWithDimAndPixelType<Dimension, unsigned char>();
134 // else if (PixelType == "char"){
135 // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
136 // UpdateWithDimAndPixelType<Dimension, signed char>();
138 else if (PixelType == "double") {
139 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and double..." << std::endl;
140 UpdateWithDimAndPixelType<Dimension, double>();
143 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
144 UpdateWithDimAndPixelType<Dimension, float>();
148 //-------------------------------------------------------------------
149 // Update with the number of dimensions and the pixeltype read from
150 // the dicom files. The MHD files may be resampled to match the
151 // dicom spacing (and number of slices). Rounding errors in resampling
152 // are handled by removing files when generating the output dicom
154 //-------------------------------------------------------------------
155 template<class args_info_type>
156 template <unsigned int Dimension, class PixelType>
158 Image2DicomSeriesGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
162 // Resample a DICOM study
163 // Usage: ResampleDICOM InputDirectory OutputDirectory
164 // xSpacing ySpacing zSpacing
166 // Example: ResampleDICOM CT CTResample 0 0 1.5
167 // will read a series from the CT directory and create a
168 // new series in the CTResample directory. The new series
169 // will have the same x,y spacing as the input series, but
170 // will have a z-spacing of 1.5.
173 // ResampleDICOM resamples a DICOM series with user-specified
174 // spacing. The program outputs a new DICOM series with a series
175 // number set to 1001. All non-private DICOM tags are moved from the input
176 // series to the output series. The Image Position Patient is adjusted
177 // for each slice to reflect the z-spacing. The number of slices in
178 // the output series may be larger or smaller due to changes in the
179 // z-spacing. To retain the spacing for a given dimension, specify 0.
181 // The program progresses as follows:
182 // 1) Read the input series
183 // 2) Resample the series according to the user specified x-y-z
185 // 3) Create a MetaDataDictionary for each slice.
186 // 4) Shift data to undo the effect of a rescale intercept by the
187 // DICOM reader (only for ITK < 4.6)
188 // 5) Write the new DICOM series
194 // Validate input parameters
196 const unsigned int InputDimension = 3;
197 const unsigned int OutputDimension = 2;
200 typedef itk::Image< PixelType, InputDimension >
202 typedef itk::Image< PixelType, OutputDimension >
204 typedef itk::ImageSeriesReader< InputImageType >
206 typedef itk::GDCMImageIO
208 typedef itk::GDCMSeriesFileNames
209 InputNamesGeneratorType;
210 typedef itk::NumericSeriesFileNames
211 OutputNamesGeneratorType;
212 typedef itk::IdentityTransform< double, InputDimension >
214 typedef itk::LinearInterpolateImageFunction< InputImageType, double >
216 typedef itk::ResampleImageFilter< InputImageType, InputImageType >
218 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
219 typedef itk::ShiftScaleImageFilter< InputImageType, InputImageType >
222 typedef itk::ImageSeriesWriter< InputImageType, OutputImageType >
225 ////////////////////////////////////////////////
226 // 1) Read the input series
228 // Read the input (MHD file)
229 typedef typename InputImageType::RegionType RegionType;
230 typedef typename RegionType::SizeType SizeType;
231 typedef itk::ImageFileReader<InputImageType> InputReaderType;
232 typename InputReaderType::Pointer volumeReader = InputReaderType::New();
233 volumeReader->SetFileName( m_ArgsInfo.input_arg );
234 volumeReader->Update();
236 typename InputImageType::Pointer input = volumeReader->GetOutput();
238 ImageIOType::Pointer gdcmIO = ImageIOType::New();
239 gdcmIO->LoadPrivateTagsOn();
240 InputNamesGeneratorType::Pointer inputNames = InputNamesGeneratorType::New();
241 inputNames->SetInputDirectory( m_ArgsInfo.inputDir_arg );
243 const typename ReaderType::FileNamesContainer & filenames =
244 inputNames->GetInputFileNames();
246 typename ReaderType::Pointer reader = ReaderType::New();
248 reader->SetImageIO( gdcmIO );
249 reader->SetFileNames( filenames );
254 catch (itk::ExceptionObject &excp)
256 std::cerr << "Exception thrown while reading the series" << std::endl;
257 std::cerr << excp << std::endl;
260 typename InputImageType::SpacingType outputSpacing;
261 typename InputImageType::SizeType outputSize;
262 for (unsigned int i = 0; i < 3; i++)
264 outputSpacing[i] = input->GetSpacing()[i];
265 outputSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
268 ////////////////////////////////////////////////
269 // 2) Ensure to have value >= -1024
271 typedef itk::ThresholdImageFilter <InputImageType> ThresholdImageFilterType;
272 typename ThresholdImageFilterType::Pointer thresholdFilter = ThresholdImageFilterType::New();
273 thresholdFilter->SetInput(input);
274 thresholdFilter->ThresholdBelow(-1024);
275 thresholdFilter->SetOutsideValue(-1024);
276 thresholdFilter->Update();
278 input=thresholdFilter->GetOutput();
282 ////////////////////////////////////////////////
283 // 2) Resample the series
284 /* typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
286 TransformType::Pointer transform = TransformType::New();
287 transform->SetIdentity();
289 const typename InputImageType::SpacingType& inputSpacing =
290 reader->GetOutput()->GetSpacing();
291 const typename InputImageType::RegionType& inputRegion =
292 reader->GetOutput()->GetLargestPossibleRegion();
293 const typename InputImageType::SizeType& inputSize =
294 inputRegion.GetSize();
296 std::cout << "The input series in directory " << m_ArgsInfo.inputDir_arg
297 << " has " << filenames.size() << " files with spacing "
301 // Compute the size of the output. The user specifies a spacing on
302 // the command line. If the spacing is 0, the input spacing will be
303 // used. The size (# of pixels) in the output is recomputed using
304 // the ratio of the input and output sizes.
305 typename InputImageType::SpacingType outputSpacing;
307 bool changeInSpacing = false;
308 for (unsigned int i = 0; i < 3; i++)
310 outputSpacing[i] = inputSpacing[i];
312 typename InputImageType::SizeType outputSize;
313 typedef typename InputImageType::SizeType::SizeValueType SizeValueType;
314 outputSize[0] = static_cast<SizeValueType>(inputSize[0] * inputSpacing[0] / outputSpacing[0] + .5);
315 outputSize[1] = static_cast<SizeValueType>(inputSize[1] * inputSpacing[1] / outputSpacing[1] + .5);
316 outputSize[2] = static_cast<SizeValueType>(inputSize[2] * inputSpacing[2] / outputSpacing[2] + .5);
318 typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
319 resampler->SetInput( reader->GetOutput() );
320 resampler->SetTransform( transform );
321 resampler->SetInterpolator( interpolator );
322 resampler->SetOutputOrigin ( reader->GetOutput()->GetOrigin());
323 resampler->SetOutputSpacing ( outputSpacing );
324 resampler->SetOutputDirection ( reader->GetOutput()->GetDirection());
325 resampler->SetSize ( outputSize );
326 resampler->Update ();
330 ////////////////////////////////////////////////
331 // 3) Create a MetaDataDictionary for each slice.
333 // Copy the dictionary from the first image and override slice
335 typename ReaderType::DictionaryRawPointer inputDict = (*(reader->GetMetaDataDictionaryArray()))[0];
336 typename ReaderType::DictionaryArrayType outputArray;
338 // To keep the new series in the same study as the original we need
339 // to keep the same study UID. But we need new series and frame of
341 #if ITK_VERSION_MAJOR >= 4
342 gdcm::UIDGenerator suid;
343 std::string seriesUID = suid.Generate();
344 gdcm::UIDGenerator fuid;
345 std::string frameOfReferenceUID = fuid.Generate();
347 std::string seriesUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
348 std::string frameOfReferenceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
350 std::string studyUID;
351 std::string sopClassUID;
352 itk::ExposeMetaData<std::string>(*inputDict, "0020|000d", studyUID);
353 itk::ExposeMetaData<std::string>(*inputDict, "0008|0016", sopClassUID);
354 gdcmIO->KeepOriginalUIDOn();
356 for (unsigned int f = 0; f < outputSize[2]; f++)
358 // Create a new dictionary for this slice
359 typename ReaderType::DictionaryRawPointer dict = new typename ReaderType::DictionaryType;
361 // Copy the dictionary from the first slice
362 //CopyDictionary (*inputDict, *dict);
364 typedef itk::MetaDataDictionary DictionaryType;
366 DictionaryType::ConstIterator itrDic = (*inputDict).Begin();
367 DictionaryType::ConstIterator endDic = (*inputDict).End();
368 typedef itk::MetaDataObject< std::string > MetaDataStringType;
370 while( itrDic != endDic )
372 itk::MetaDataObjectBase::Pointer entry = itrDic->second;
374 MetaDataStringType::Pointer entryvalue =
375 dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;
378 std::string tagkey = itrDic->first;
379 std::string tagvalue = entryvalue->GetMetaDataObjectValue();
380 itk::EncapsulateMetaData<std::string>(*dict, tagkey, tagvalue);
385 // Set the UID's for the study, series, SOP and frame of reference
386 itk::EncapsulateMetaData<std::string>(*dict,"0020|000d", studyUID);
387 itk::EncapsulateMetaData<std::string>(*dict,"0020|000e", seriesUID);
388 itk::EncapsulateMetaData<std::string>(*dict,"0020|0052", frameOfReferenceUID);
390 #if ITK_VERSION_MAJOR >= 4
391 gdcm::UIDGenerator sopuid;
392 std::string sopInstanceUID = sopuid.Generate();
394 std::string sopInstanceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
396 itk::EncapsulateMetaData<std::string>(*dict,"0008|0018", sopInstanceUID);
397 itk::EncapsulateMetaData<std::string>(*dict,"0002|0003", sopInstanceUID);
399 // Change fields that are slice specific
400 std::ostringstream value;
402 //unsigned int f = 0;
406 itk::EncapsulateMetaData<std::string>(*dict,"0020|0013", value.str());
408 // Series Description - Append new description to current series
410 std::string oldSeriesDesc;
411 itk::ExposeMetaData<std::string>(*inputDict, "0008|103e", oldSeriesDesc);
414 value << oldSeriesDesc
415 << ": Resampled with pixel spacing "
416 << outputSpacing[0] << ", "
417 << outputSpacing[1] << ", "
419 // This is an long string and there is a 64 character limit in the
421 unsigned lengthDesc = value.str().length();
423 std::string seriesDesc( value.str(), 0,
426 itk::EncapsulateMetaData<std::string>(*dict,"0008|103e", seriesDesc);
431 itk::EncapsulateMetaData<std::string>(*dict,"0020|0011", value.str());
433 // Derivation Description - How this image was derived
436 value << ": " << ITK_SOURCE_VERSION;
438 lengthDesc = value.str().length();
439 std::string derivationDesc( value.str(), 0,
440 lengthDesc > 1024 ? 1024
442 itk::EncapsulateMetaData<std::string>(*dict,"0008|2111", derivationDesc);
444 // Image Position Patient: This is calculated by computing the
445 // physical coordinate of the first pixel in each slice.
446 typename InputImageType::PointType position;
447 typename InputImageType::IndexType index;
451 input->TransformIndexToPhysicalPoint(index, position);
454 value << position[0] << "\\" << position[1] << "\\" << position[2];
455 itk::EncapsulateMetaData<std::string>(*dict,"0020|0032", value.str());
456 // Slice Location: For now, we store the z component of the Image
459 value << position[2];
460 itk::EncapsulateMetaData<std::string>(*dict,"0020|1041", value.str());
463 // Slice Thickness: For now, we store the z spacing
465 value << outputSpacing[2];
466 itk::EncapsulateMetaData<std::string>(*dict,"0018|0050",
468 // Spacing Between Slices
469 itk::EncapsulateMetaData<std::string>(*dict,"0018|0088",
474 value << 0.999987 << "\\" << -0.005061 << "\\" << 0.000000 << "\\" << 0.000000 << "\\" << 0.000000 << "\\" << -1.000000;
475 itk::EncapsulateMetaData<std::string>(*dict, "0020|0037", value.str());
479 itk::EncapsulateMetaData<std::string>(*dict, "0002|0000", value.str());
482 itk::EncapsulateMetaData<std::string>(*dict, "0008|0000", value.str());
485 itk::EncapsulateMetaData<std::string>(*dict, "0009|0000", value.str());
488 itk::EncapsulateMetaData<std::string>(*dict, "0010|0000", value.str());
491 itk::EncapsulateMetaData<std::string>(*dict, "0011|0000", value.str());
493 value << 0 << "\\" << 0;
494 itk::EncapsulateMetaData<std::string>(*dict, "0011|1011", value.str());
496 value << 1 << "\\" << 1;
497 itk::EncapsulateMetaData<std::string>(*dict, "0011|1015", value.str());
499 value << 1 << "\\" << 2;
500 itk::EncapsulateMetaData<std::string>(*dict, "0011|1016", value.str());
502 value << 0 << "\\" << 0;
503 itk::EncapsulateMetaData<std::string>(*dict, "0011|1017", value.str());
505 value << 0 << "\\" << 0;
506 itk::EncapsulateMetaData<std::string>(*dict, "0011|1018", value.str());
508 value << 0 << "\\" << 0;
509 itk::EncapsulateMetaData<std::string>(*dict, "0011|1019", value.str());
511 value << 0 << "\\" << 0;
512 itk::EncapsulateMetaData<std::string>(*dict, "0011|101a", value.str());
514 value << 0 << "\\" << 0;
515 itk::EncapsulateMetaData<std::string>(*dict, "0011|101f", value.str());
517 value << 0 << "\\" << 0;
518 itk::EncapsulateMetaData<std::string>(*dict, "0011|1026", value.str());
520 value << 0 << "\\" << 0 << "\\" << 0 << "\\" << 0;
521 itk::EncapsulateMetaData<std::string>(*dict, "0011|1027", value.str());
523 value << 0 << "\\" << 0 << "\\" << 0 << "\\" << 0;
524 itk::EncapsulateMetaData<std::string>(*dict, "0011|1028", value.str());
526 value << 0 << "\\" << 0;
527 itk::EncapsulateMetaData<std::string>(*dict, "0011|102c", value.str());
529 value << 0 << "\\" << 0;
530 itk::EncapsulateMetaData<std::string>(*dict, "0011|102d", value.str());
532 value << 0 << "\\" << 0;
533 itk::EncapsulateMetaData<std::string>(*dict, "0011|102e", value.str());
534 std::ostringstream valueVec[2];
536 valueVec[0] << 32767;
538 valueVec[1] << 32767;
539 std::string valueVec2[2];
540 valueVec2[0]=valueVec[0].str();
541 valueVec2[1]=valueVec[1].str();
542 itk::EncapsulateMetaData<std::string*>(*dict, "0011|102f", valueVec2);
545 itk::EncapsulateMetaData<std::string>(*dict, "0020|1011", value.str());
548 itk::EncapsulateMetaData<std::string>(*dict, "0028|0107", value.str());
552 itk::EncapsulateMetaData<std::string>(*dict, "0018|1130", value.str());
555 itk::EncapsulateMetaData<std::string>(*dict, "0018|1131", value.str());
558 itk::EncapsulateMetaData<std::string>(*dict, "0018|1140", value.str());
561 itk::EncapsulateMetaData<std::string>(*dict, "0018|1142", value.str());
564 itk::EncapsulateMetaData<std::string>(*dict, "0018|1143", value.str());
567 itk::EncapsulateMetaData<std::string>(*dict, "0018|1144", value.str());
570 itk::EncapsulateMetaData<std::string>(*dict, "0018|1242", value.str());
573 itk::EncapsulateMetaData<std::string>(*dict, "0054|0053", value.str());
576 itk::EncapsulateMetaData<std::string>(*dict, "0054|0200", value.str());
579 itk::EncapsulateMetaData<std::string>(*dict, "0008|0100", value.str());
582 itk::EncapsulateMetaData<std::string>(*dict, "0008|0102", value.str());
584 value << "recumbent" ;
585 itk::EncapsulateMetaData<std::string>(*dict, "0008|0104", value.str());
588 itk::EncapsulateMetaData<std::string>(*dict, "0054|0014", value.str());
591 itk::EncapsulateMetaData<std::string>(*dict, "0054|0015", value.str());
593 value << "Tc99m_SC" ;
594 itk::EncapsulateMetaData<std::string>(*dict, "0054|0018", value.str());
597 itk::EncapsulateMetaData<std::string>(*dict, "0018|1120", value.str());
600 itk::EncapsulateMetaData<std::string>(*dict, "0018|1145", value.str());
602 value << 0 << "\\" << 0;
603 itk::EncapsulateMetaData<std::string>(*dict, "0018|1149", value.str());
606 itk::EncapsulateMetaData<std::string>(*dict, "0018|1180", value.str());
609 itk::EncapsulateMetaData<std::string>(*dict, "0018|1181", value.str());
612 itk::EncapsulateMetaData<std::string>(*dict, "0018|1182", value.str());
615 itk::EncapsulateMetaData<std::string>(*dict, "0018|1183", value.str());
618 itk::EncapsulateMetaData<std::string>(*dict, "0018|1184", value.str());
620 value << 1.000000 << "\\" << 1.000000 ;
621 itk::EncapsulateMetaData<std::string>(*dict, "0028|0031", value.str());
623 value << 0.000000 << "\\" << 0.000000 ;
624 itk::EncapsulateMetaData<std::string>(*dict, "0028|0032", value.str());
627 itk::EncapsulateMetaData<std::string>(*dict, "0011|101c", value.str());
630 itk::EncapsulateMetaData<std::string>(*dict, "0011|101d", value.str());
633 itk::EncapsulateMetaData<std::string>(*dict, "0013|1016", value.str());
636 itk::EncapsulateMetaData<std::string>(*dict, "0013|1017", value.str());
639 itk::EncapsulateMetaData<std::string>(*dict, "0011|1023", value.str());
642 itk::EncapsulateMetaData<std::string>(*dict, "0011|1024", value.str());
645 itk::EncapsulateMetaData<std::string>(*dict, "0011|1025", value.str());
648 itk::EncapsulateMetaData<std::string>(*dict, "0011|1029", value.str());
651 itk::EncapsulateMetaData<std::string>(*dict, "0011|103e", value.str());
654 itk::EncapsulateMetaData<std::string>(*dict, "0013|1018", value.str());
657 itk::EncapsulateMetaData<std::string>(*dict, "0013|1019", value.str());
660 itk::EncapsulateMetaData<std::string>(*dict, "0013|101a", value.str());
662 value << "GEMS_GENIE_1" ;
663 itk::EncapsulateMetaData<std::string>(*dict, "0035|0010", value.str());
666 itk::EncapsulateMetaData<std::string>(*dict, "0035|1001", value.str());
669 // Save the dictionary
670 outputArray.push_back(dict);
673 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
674 ////////////////////////////////////////////////
675 // 4) Shift data to undo the effect of a rescale intercept by the
677 std::string interceptTag("0028|1052");
678 typedef itk::MetaDataObject< std::string > MetaDataStringType;
679 itk::MetaDataObjectBase::Pointer entry = (*inputDict)[interceptTag];
681 MetaDataStringType::ConstPointer interceptValue =
682 dynamic_cast<const MetaDataStringType *>( entry.GetPointer() ) ;
684 int interceptShift = 0;
687 std::string tagValue = interceptValue->GetMetaDataObjectValue();
688 interceptShift = -atoi ( tagValue.c_str() );
691 ShiftScaleType::Pointer shiftScale = ShiftScaleType::New();
692 shiftScale->SetInput( resampler->GetOutput());
693 shiftScale->SetShift( interceptShift );
696 ////////////////////////////////////////////////
697 // 5) Write the new DICOM series
699 // Make the output directory and generate the file names.
700 itksys::SystemTools::MakeDirectory( m_ArgsInfo.outputDir_arg );
702 // Generate the file names
703 OutputNamesGeneratorType::Pointer outputNames = OutputNamesGeneratorType::New();
704 std::string seriesFormat(m_ArgsInfo.outputDir_arg);
705 seriesFormat = seriesFormat + "/" + "IM%03d.dcm";
706 outputNames->SetSeriesFormat (seriesFormat.c_str());
707 outputNames->SetStartIndex (1);
708 //outputNames->SetEndIndex (1);
709 outputNames->SetEndIndex (outputSize[2]);
711 typename SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
712 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
713 seriesWriter->SetInput( input );
715 seriesWriter->SetInput( input );
717 seriesWriter->SetImageIO( gdcmIO );
718 seriesWriter->SetFileNames( outputNames->GetFileNames() );
719 seriesWriter->SetMetaDataDictionaryArray( &outputArray );
722 seriesWriter->Update();
724 catch( itk::ExceptionObject & excp )
726 std::cerr << "Exception thrown while writing the series " << std::endl;
727 std::cerr << excp << std::endl;
730 std::cout << "The output series in directory " << m_ArgsInfo.outputDir_arg
731 << " has " << outputSize[2] << " files with spacing "
738 /*void CopyDictionary (itk::MetaDataDictionary &fromDict, itk::MetaDataDictionary &toDict)
740 typedef itk::MetaDataDictionary DictionaryType;
742 DictionaryType::ConstIterator itr = fromDict.Begin();
743 DictionaryType::ConstIterator end = fromDict.End();
744 typedef itk::MetaDataObject< std::string > MetaDataStringType;
748 itk::MetaDataObjectBase::Pointer entry = itr->second;
750 MetaDataStringType::Pointer entryvalue =
751 dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;
754 std::string tagkey = itr->first;
755 std::string tagvalue = entryvalue->GetMetaDataObjectValue();
756 itk::EncapsulateMetaData<std::string>(toDict, tagkey, tagvalue);
765 #endif //#define clitkImage2DicomSeriesGenericFilter_txx