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 clitkSpect2DicomGenericFilter_txx
19 #define clitkSpect2DicomGenericFilter_txx
21 /* =================================================
22 * @file clitkSpect2DicomGenericFilter.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"
72 #if GDCM_MAJOR_VERSION >= 2
73 #include "gdcmUIDGenerator.h"
74 #include <gdcmImageHelper.h>
75 #include <gdcmAttribute.h>
76 #include <gdcmReader.h>
77 #include <gdcmWriter.h>
78 #include <gdcmDataElement.h>
86 //-----------------------------------------------------------
88 //-----------------------------------------------------------
89 template<class args_info_type>
90 Spect2DicomGenericFilter<args_info_type>::Spect2DicomGenericFilter()
97 //-----------------------------------------------------------
99 //-----------------------------------------------------------
100 template<class args_info_type>
101 void Spect2DicomGenericFilter<args_info_type>::Update()
103 // Read the Dimension and PixelType
105 std::string PixelType;
106 ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
109 // Call UpdateWithDim
110 if(Dimension==2) UpdateWithDim<2>(PixelType);
111 else if(Dimension==3) UpdateWithDim<3>(PixelType);
112 // else if (Dimension==4)UpdateWithDim<4>(PixelType);
114 std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
119 //-------------------------------------------------------------------
120 // Update with the number of dimensions
121 //-------------------------------------------------------------------
122 template<class args_info_type>
123 template<unsigned int Dimension>
125 Spect2DicomGenericFilter<args_info_type>::UpdateWithDim(std::string PixelType)
127 if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
129 if(PixelType == "short") {
130 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
131 UpdateWithDimAndPixelType<Dimension, signed short>();
133 else if(PixelType == "unsigned_short"){
134 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
135 UpdateWithDimAndPixelType<Dimension, unsigned short>();
138 else if (PixelType == "unsigned_char") {
139 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
140 UpdateWithDimAndPixelType<Dimension, unsigned char>();
143 // else if (PixelType == "char"){
144 // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
145 // UpdateWithDimAndPixelType<Dimension, signed char>();
147 else if (PixelType == "double") {
148 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and double..." << std::endl;
149 UpdateWithDimAndPixelType<Dimension, double>();
152 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
153 UpdateWithDimAndPixelType<Dimension, float>();
157 //-------------------------------------------------------------------
158 // Update with the number of dimensions and the pixeltype read from
159 // the dicom files. The MHD files may be resampled to match the
160 // dicom spacing (and number of slices). Rounding errors in resampling
161 // are handled by removing files when generating the output dicom
163 //-------------------------------------------------------------------
164 template<class args_info_type>
165 template <unsigned int Dimension, class PixelType>
167 Spect2DicomGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
171 // Resample a DICOM study
172 // Usage: ResampleDICOM InputDirectory OutputDirectory
173 // xSpacing ySpacing zSpacing
175 // Example: ResampleDICOM CT CTResample 0 0 1.5
176 // will read a series from the CT directory and create a
177 // new series in the CTResample directory. The new series
178 // will have the same x,y spacing as the input series, but
179 // will have a z-spacing of 1.5.
182 // ResampleDICOM resamples a DICOM series with user-specified
183 // spacing. The program outputs a new DICOM series with a series
184 // number set to 1001. All non-private DICOM tags are moved from the input
185 // series to the output series. The Image Position Patient is adjusted
186 // for each slice to reflect the z-spacing. The number of slices in
187 // the output series may be larger or smaller due to changes in the
188 // z-spacing. To retain the spacing for a given dimension, specify 0.
190 // The program progresses as follows:
191 // 1) Read the input series
192 // 2) Resample the series according to the user specified x-y-z
194 // 3) Create a MetaDataDictionary for each slice.
195 // 4) Shift data to undo the effect of a rescale intercept by the
196 // DICOM reader (only for ITK < 4.6)
197 // 5) Write the new DICOM series
203 // Validate input parameters
205 const unsigned int InputDimension = 3;
206 const unsigned int OutputDimension = 3;
209 typedef itk::Image< PixelType, InputDimension >
211 typedef itk::Image< PixelType, OutputDimension >
213 typedef itk::ImageSeriesReader< InputImageType >
215 typedef itk::GDCMImageIO
217 typedef itk::GDCMSeriesFileNames
218 InputNamesGeneratorType;
219 typedef itk::NumericSeriesFileNames
220 OutputNamesGeneratorType;
221 typedef itk::IdentityTransform< double, InputDimension >
223 typedef itk::LinearInterpolateImageFunction< InputImageType, double >
225 typedef itk::ResampleImageFilter< InputImageType, InputImageType >
227 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
228 typedef itk::ShiftScaleImageFilter< InputImageType, InputImageType >
231 typedef itk::ImageSeriesWriter< InputImageType, OutputImageType >
234 ////////////////////////////////////////////////
235 // 1) Read the input series
237 // Read the input (MHD file)
238 typedef typename InputImageType::RegionType RegionType;
239 typedef typename RegionType::SizeType SizeType;
240 typedef itk::ImageFileReader<InputImageType> InputReaderType;
241 typename InputReaderType::Pointer volumeReader = InputReaderType::New();
242 volumeReader->SetFileName( m_ArgsInfo.input_arg );
243 volumeReader->Update();
245 typename InputImageType::Pointer input = volumeReader->GetOutput();
247 ImageIOType::Pointer gdcmIO = ImageIOType::New();
248 gdcmIO->LoadPrivateTagsOn();
249 InputNamesGeneratorType::Pointer inputNames = InputNamesGeneratorType::New();
250 inputNames->SetInputDirectory( m_ArgsInfo.inputDir_arg );
252 const typename ReaderType::FileNamesContainer & filenames =
253 inputNames->GetInputFileNames();
255 typename ReaderType::Pointer reader = ReaderType::New();
257 reader->SetImageIO( gdcmIO );
258 reader->SetFileNames( filenames );
263 catch (itk::ExceptionObject &excp)
265 std::cerr << "Exception thrown while reading the series" << std::endl;
266 std::cerr << excp << std::endl;
269 typename InputImageType::SpacingType outputSpacing;
270 typename InputImageType::SizeType outputSize;
271 for (unsigned int i = 0; i < 3; i++)
273 outputSpacing[i] = input->GetSpacing()[i];
274 outputSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
277 ////////////////////////////////////////////////
278 // 2) Ensure to have value >= -1024
280 typedef itk::ThresholdImageFilter <InputImageType> ThresholdImageFilterType;
281 typename ThresholdImageFilterType::Pointer thresholdFilter = ThresholdImageFilterType::New();
282 thresholdFilter->SetInput(input);
283 thresholdFilter->ThresholdBelow(-1024);
284 thresholdFilter->SetOutsideValue(-1024);
285 thresholdFilter->Update();
287 input=thresholdFilter->GetOutput();
291 ////////////////////////////////////////////////
292 // 2) Resample the series
293 /* typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
295 TransformType::Pointer transform = TransformType::New();
296 transform->SetIdentity();
298 const typename InputImageType::SpacingType& inputSpacing =
299 reader->GetOutput()->GetSpacing();
300 const typename InputImageType::RegionType& inputRegion =
301 reader->GetOutput()->GetLargestPossibleRegion();
302 const typename InputImageType::SizeType& inputSize =
303 inputRegion.GetSize();
305 std::cout << "The input series in directory " << m_ArgsInfo.inputDir_arg
306 << " has " << filenames.size() << " files with spacing "
310 // Compute the size of the output. The user specifies a spacing on
311 // the command line. If the spacing is 0, the input spacing will be
312 // used. The size (# of pixels) in the output is recomputed using
313 // the ratio of the input and output sizes.
314 typename InputImageType::SpacingType outputSpacing;
316 bool changeInSpacing = false;
317 for (unsigned int i = 0; i < 3; i++)
319 outputSpacing[i] = inputSpacing[i];
321 typename InputImageType::SizeType outputSize;
322 typedef typename InputImageType::SizeType::SizeValueType SizeValueType;
323 outputSize[0] = static_cast<SizeValueType>(inputSize[0] * inputSpacing[0] / outputSpacing[0] + .5);
324 outputSize[1] = static_cast<SizeValueType>(inputSize[1] * inputSpacing[1] / outputSpacing[1] + .5);
325 outputSize[2] = static_cast<SizeValueType>(inputSize[2] * inputSpacing[2] / outputSpacing[2] + .5);
327 typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
328 resampler->SetInput( reader->GetOutput() );
329 resampler->SetTransform( transform );
330 resampler->SetInterpolator( interpolator );
331 resampler->SetOutputOrigin ( reader->GetOutput()->GetOrigin());
332 resampler->SetOutputSpacing ( outputSpacing );
333 resampler->SetOutputDirection ( reader->GetOutput()->GetDirection());
334 resampler->SetSize ( outputSize );
335 resampler->Update ();
339 ////////////////////////////////////////////////
340 // 3) Create a MetaDataDictionary for each slice.
342 // Copy the dictionary from the first image and override slice
344 typename ReaderType::DictionaryRawPointer inputDict = (*(reader->GetMetaDataDictionaryArray()))[0];
345 typename ReaderType::DictionaryArrayType outputArray;
347 // To keep the new series in the same study as the original we need
348 // to keep the same study UID. But we need new series and frame of
350 #if ITK_VERSION_MAJOR >= 4
351 gdcm::UIDGenerator suid;
352 std::string seriesUID = suid.Generate();
353 gdcm::UIDGenerator fuid;
354 std::string frameOfReferenceUID = fuid.Generate();
356 std::string seriesUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
357 std::string frameOfReferenceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
359 std::string studyUID;
360 std::string sopClassUID;
361 itk::ExposeMetaData<std::string>(*inputDict, "0020|000d", studyUID);
362 itk::ExposeMetaData<std::string>(*inputDict, "0008|0016", sopClassUID);
363 gdcmIO->KeepOriginalUIDOn();
365 for (unsigned int f = 0; f < nbFile; f++)
367 // Create a new dictionary for this slice
368 typename ReaderType::DictionaryRawPointer dict = new typename ReaderType::DictionaryType;
370 // Copy the dictionary from the first slice
371 //CopyDictionary (*inputDict, *dict);
373 typedef itk::MetaDataDictionary DictionaryType;
375 DictionaryType::ConstIterator itrDic = (*inputDict).Begin();
376 DictionaryType::ConstIterator endDic = (*inputDict).End();
377 typedef itk::MetaDataObject< std::string > MetaDataStringType;
379 while( itrDic != endDic )
381 itk::MetaDataObjectBase::Pointer entry = itrDic->second;
383 MetaDataStringType::Pointer entryvalue =
384 dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;
387 std::string tagkey = itrDic->first;
388 std::string tagvalue = entryvalue->GetMetaDataObjectValue();
389 itk::EncapsulateMetaData<std::string>(*dict, tagkey, tagvalue);
394 // Set the UID's for the study, series, SOP and frame of reference
395 itk::EncapsulateMetaData<std::string>(*dict,"0020|000d", studyUID);
396 itk::EncapsulateMetaData<std::string>(*dict,"0020|000e", seriesUID);
397 itk::EncapsulateMetaData<std::string>(*dict,"0020|0052", frameOfReferenceUID);
399 #if ITK_VERSION_MAJOR >= 4
400 gdcm::UIDGenerator sopuid;
401 std::string sopInstanceUID = sopuid.Generate();
403 std::string sopInstanceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
405 itk::EncapsulateMetaData<std::string>(*dict,"0008|0018", sopInstanceUID);
406 itk::EncapsulateMetaData<std::string>(*dict,"0002|0003", sopInstanceUID);
408 // Change fields that are slice specific
409 std::ostringstream value;
411 //unsigned int f = 0;
415 itk::EncapsulateMetaData<std::string>(*dict,"0020|0013", value.str());
417 // Series Description - Append new description to current series
419 std::string oldSeriesDesc;
420 itk::ExposeMetaData<std::string>(*inputDict, "0008|103e", oldSeriesDesc);
423 value << oldSeriesDesc
424 << ": Resampled with pixel spacing "
425 << outputSpacing[0] << ", "
426 << outputSpacing[1] << ", "
428 // This is an long string and there is a 64 character limit in the
430 unsigned lengthDesc = value.str().length();
432 std::string seriesDesc( value.str(), 0,
435 itk::EncapsulateMetaData<std::string>(*dict,"0008|103e", seriesDesc);
440 itk::EncapsulateMetaData<std::string>(*dict,"0020|0011", value.str());
442 // Derivation Description - How this image was derived
445 value << ": " << ITK_SOURCE_VERSION;
447 lengthDesc = value.str().length();
448 std::string derivationDesc( value.str(), 0,
449 lengthDesc > 1024 ? 1024
451 itk::EncapsulateMetaData<std::string>(*dict,"0008|2111", derivationDesc);
453 // Image Position Patient: This is calculated by computing the
454 // physical coordinate of the first pixel in each slice.
455 typename InputImageType::PointType position;
456 typename InputImageType::IndexType index;
460 input->TransformIndexToPhysicalPoint(index, position);
463 value << position[0] << "\\" << position[1] << "\\" << position[2];
464 itk::EncapsulateMetaData<std::string>(*dict,"0020|0032", value.str());
465 // Slice Location: For now, we store the z component of the Image
468 value << position[2];
469 itk::EncapsulateMetaData<std::string>(*dict,"0020|1041", value.str());
472 // Slice Thickness: For now, we store the z spacing
474 value << outputSpacing[2];
475 itk::EncapsulateMetaData<std::string>(*dict,"0018|0050",
477 // Spacing Between Slices
478 itk::EncapsulateMetaData<std::string>(*dict,"0018|0088",
483 value << 0.999987 << "\\" << -0.005061 << "\\" << 0.000000 << "\\" << 0.000000 << "\\" << 0.000000 << "\\" << -1.000000;
484 itk::EncapsulateMetaData<std::string>(*dict, "0020|0037", value.str());
488 itk::EncapsulateMetaData<std::string>(*dict, "0002|0000", value.str());
491 itk::EncapsulateMetaData<std::string>(*dict, "0008|0000", value.str());
494 itk::EncapsulateMetaData<std::string>(*dict, "0009|0000", value.str());
497 itk::EncapsulateMetaData<std::string>(*dict, "0010|0000", value.str());
500 itk::EncapsulateMetaData<std::string>(*dict, "0011|0000", value.str());
502 value << 0 << "\\" << 0;
503 itk::EncapsulateMetaData<std::string>(*dict, "0011|1011", value.str());
505 value << 1 << "\\" << 1;
506 itk::EncapsulateMetaData<std::string>(*dict, "0011|1015", value.str());
508 value << 1 << "\\" << 2;
509 itk::EncapsulateMetaData<std::string>(*dict, "0011|1016", value.str());
511 value << 0 << "\\" << 0;
512 itk::EncapsulateMetaData<std::string>(*dict, "0011|1017", value.str());
514 value << 0 << "\\" << 0;
515 itk::EncapsulateMetaData<std::string>(*dict, "0011|1018", value.str());
517 value << 0 << "\\" << 0;
518 itk::EncapsulateMetaData<std::string>(*dict, "0011|1019", value.str());
520 value << 0 << "\\" << 0;
521 itk::EncapsulateMetaData<std::string>(*dict, "0011|101a", value.str());
523 value << 0 << "\\" << 0;
524 itk::EncapsulateMetaData<std::string>(*dict, "0011|101f", value.str());
526 value << 0 << "\\" << 0;
527 itk::EncapsulateMetaData<std::string>(*dict, "0011|1026", value.str());
529 value << 0 << "\\" << 0 << "\\" << 0 << "\\" << 0;
530 itk::EncapsulateMetaData<std::string>(*dict, "0011|1027", value.str());
532 value << 0 << "\\" << 0 << "\\" << 0 << "\\" << 0;
533 itk::EncapsulateMetaData<std::string>(*dict, "0011|1028", value.str());
535 value << 0 << "\\" << 0;
536 itk::EncapsulateMetaData<std::string>(*dict, "0011|102c", value.str());
538 value << 0 << "\\" << 0;
539 itk::EncapsulateMetaData<std::string>(*dict, "0011|102d", value.str());
541 value << 0 << "\\" << 0;
542 itk::EncapsulateMetaData<std::string>(*dict, "0011|102e", value.str());
543 std::ostringstream valueVec[2];
545 valueVec[0] << 32767;
547 valueVec[1] << 32767;
548 std::string valueVec2[2];
549 valueVec2[0]=valueVec[0].str();
550 valueVec2[1]=valueVec[1].str();
551 itk::EncapsulateMetaData<std::string*>(*dict, "0011|102f", valueVec2);
554 itk::EncapsulateMetaData<std::string>(*dict, "0020|1011", value.str());
557 itk::EncapsulateMetaData<std::string>(*dict, "0028|0107", value.str());
561 itk::EncapsulateMetaData<std::string>(*dict, "0018|1130", value.str());
564 itk::EncapsulateMetaData<std::string>(*dict, "0018|1131", value.str());
567 itk::EncapsulateMetaData<std::string>(*dict, "0018|1140", value.str());
570 itk::EncapsulateMetaData<std::string>(*dict, "0018|1142", value.str());
573 itk::EncapsulateMetaData<std::string>(*dict, "0018|1143", value.str());
576 itk::EncapsulateMetaData<std::string>(*dict, "0018|1144", value.str());
579 itk::EncapsulateMetaData<std::string>(*dict, "0018|1242", value.str());
582 itk::EncapsulateMetaData<std::string>(*dict, "0054|0053", value.str());
585 itk::EncapsulateMetaData<std::string>(*dict, "0054|0200", value.str());
588 itk::EncapsulateMetaData<std::string>(*dict, "0008|0100", value.str());
591 itk::EncapsulateMetaData<std::string>(*dict, "0008|0102", value.str());
593 value << "recumbent" ;
594 itk::EncapsulateMetaData<std::string>(*dict, "0008|0104", value.str());
597 itk::EncapsulateMetaData<std::string>(*dict, "0054|0014", value.str());
600 itk::EncapsulateMetaData<std::string>(*dict, "0054|0015", value.str());
602 value << "Tc99m_SC" ;
603 itk::EncapsulateMetaData<std::string>(*dict, "0054|0018", value.str());
606 itk::EncapsulateMetaData<std::string>(*dict, "0018|1120", value.str());
609 itk::EncapsulateMetaData<std::string>(*dict, "0018|1145", value.str());
611 value << 0 << "\\" << 0;
612 itk::EncapsulateMetaData<std::string>(*dict, "0018|1149", value.str());
615 itk::EncapsulateMetaData<std::string>(*dict, "0018|1180", value.str());
618 itk::EncapsulateMetaData<std::string>(*dict, "0018|1181", value.str());
621 itk::EncapsulateMetaData<std::string>(*dict, "0018|1182", value.str());
624 itk::EncapsulateMetaData<std::string>(*dict, "0018|1183", value.str());
627 itk::EncapsulateMetaData<std::string>(*dict, "0018|1184", value.str());
629 value << 1.000000 << "\\" << 1.000000 ;
630 itk::EncapsulateMetaData<std::string>(*dict, "0028|0031", value.str());
632 value << 0.000000 << "\\" << 0.000000 ;
633 itk::EncapsulateMetaData<std::string>(*dict, "0028|0032", value.str());
636 itk::EncapsulateMetaData<std::string>(*dict, "0011|101c", value.str());
639 itk::EncapsulateMetaData<std::string>(*dict, "0011|101d", value.str());
642 itk::EncapsulateMetaData<std::string>(*dict, "0013|1016", value.str());
645 itk::EncapsulateMetaData<std::string>(*dict, "0013|1017", value.str());
648 itk::EncapsulateMetaData<std::string>(*dict, "0011|1023", value.str());
651 itk::EncapsulateMetaData<std::string>(*dict, "0011|1024", value.str());
654 itk::EncapsulateMetaData<std::string>(*dict, "0011|1025", value.str());
657 itk::EncapsulateMetaData<std::string>(*dict, "0011|1029", value.str());
660 itk::EncapsulateMetaData<std::string>(*dict, "0011|103e", value.str());
663 itk::EncapsulateMetaData<std::string>(*dict, "0013|1018", value.str());
666 itk::EncapsulateMetaData<std::string>(*dict, "0013|1019", value.str());
669 itk::EncapsulateMetaData<std::string>(*dict, "0013|101a", value.str());
671 value << "GEMS_GENIE_1" ;
672 itk::EncapsulateMetaData<std::string>(*dict, "0035|0010", value.str());
675 itk::EncapsulateMetaData<std::string>(*dict, "0035|1001", value.str());
678 // Save the dictionary
679 outputArray.push_back(inputDict);
682 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
683 ////////////////////////////////////////////////
684 // 4) Shift data to undo the effect of a rescale intercept by the
686 std::string interceptTag("0028|1052");
687 typedef itk::MetaDataObject< std::string > MetaDataStringType;
688 itk::MetaDataObjectBase::Pointer entry = (*inputDict)[interceptTag];
690 MetaDataStringType::ConstPointer interceptValue =
691 dynamic_cast<const MetaDataStringType *>( entry.GetPointer() ) ;
693 int interceptShift = 0;
696 std::string tagValue = interceptValue->GetMetaDataObjectValue();
697 interceptShift = -atoi ( tagValue.c_str() );
700 ShiftScaleType::Pointer shiftScale = ShiftScaleType::New();
701 shiftScale->SetInput( resampler->GetOutput());
702 shiftScale->SetShift( interceptShift );
705 ////////////////////////////////////////////////
706 // 5) Write the new DICOM series
708 // Make the output directory and generate the file names.
709 itksys::SystemTools::MakeDirectory( m_ArgsInfo.outputDir_arg );
711 // Generate the file names
712 OutputNamesGeneratorType::Pointer outputNames = OutputNamesGeneratorType::New();
713 std::string seriesFormat(m_ArgsInfo.outputDir_arg);
714 seriesFormat = seriesFormat + "/" + "IM%03d.dcm";
715 outputNames->SetSeriesFormat (seriesFormat.c_str());
716 outputNames->SetStartIndex (1);
717 outputNames->SetEndIndex (nbFile);
718 //outputNames->SetEndIndex (outputSize[2]);
719 typename ReaderType::FileNamesContainer fileNamesOutput;
720 std::string extension = "output.dcm";
721 fileNamesOutput.push_back(extension);
722 //seriesWriter->SetFileNames( fileNamesOutput );
724 typename SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
725 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
726 seriesWriter->SetInput( input );
728 seriesWriter->SetInput( input );
730 seriesWriter->SetImageIO( gdcmIO );
731 seriesWriter->SetFileNames( outputNames->GetFileNames() );
732 seriesWriter->SetMetaDataDictionaryArray( &outputArray );
735 seriesWriter->Update();
737 catch( itk::ExceptionObject & excp )
739 std::cerr << "Exception thrown while writing the series " << std::endl;
740 std::cerr << excp << std::endl;
743 std::cout << "The output series in directory " << m_ArgsInfo.outputDir_arg
744 << " has " << nbFile << " files with spacing "
748 gdcm::Reader readerModel, readerOutput;
749 readerModel.SetFileName( inputNames->GetInputFileNames()[0].c_str() );
750 readerOutput.SetFileName( outputNames->GetFileNames()[0].c_str() );
753 gdcm::File &fileModel = readerModel.GetFile();
754 gdcm::File &fileOutput = readerOutput.GetFile();
755 gdcm::DataSet &dsModel = fileModel.GetDataSet();
756 gdcm::DataSet &dsOutput = fileOutput.GetDataSet();
757 const unsigned int ptr_len = 42;
758 char *ptr = new char[ptr_len];
759 memset(ptr,0,ptr_len);
761 const gdcm::DataElement &dataOutput = dsOutput.GetDataElement(gdcm::Tag(0x7fe0, 0x10));
762 dsModel.Replace(dataOutput);
764 w.SetFile( fileModel );
765 w.SetFileName( outputNames->GetFileNames()[0].c_str() );
771 /*void CopyDictionary (itk::MetaDataDictionary &fromDict, itk::MetaDataDictionary &toDict)
773 typedef itk::MetaDataDictionary DictionaryType;
775 DictionaryType::ConstIterator itr = fromDict.Begin();
776 DictionaryType::ConstIterator end = fromDict.End();
777 typedef itk::MetaDataObject< std::string > MetaDataStringType;
781 itk::MetaDataObjectBase::Pointer entry = itr->second;
783 MetaDataStringType::Pointer entryvalue =
784 dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;
787 std::string tagkey = itr->first;
788 std::string tagvalue = entryvalue->GetMetaDataObjectValue();
789 itk::EncapsulateMetaData<std::string>(toDict, tagkey, tagvalue);
798 #endif //#define clitkSpect2DicomGenericFilter_txx