]> Creatis software - clitk.git/blob - tools/clitkDicom2Image.cxx
GateAsciiImageIO is now cross-platform using itksys::RegularExpression
[clitk.git] / tools / clitkDicom2Image.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
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
8
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.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18
19 // clitk includes
20 #include "clitkDicom2Image_ggo.h"
21 #include "clitkCommon.h"
22 #include "clitkImageCommon.h"
23 #include "vvImageReader.h"
24 #include "vvImageWriter.h"
25 #include <gdcmFile.h>
26 #if GDCM_MAJOR_VERSION == 2
27   #include <gdcmImageHelper.h>
28   #include <gdcmAttribute.h>
29   #include <gdcmReader.h>
30 #endif
31
32 //====================================================================
33 int main(int argc, char * argv[])
34 {
35   // init command line
36   GGO(clitkDicom2Image, args_info);
37   std::vector<std::string> input_files;
38   ///if std_input is given, read the input files from stdin
39   if (args_info.std_input_given) {
40     while (true) {
41       std::string tmp;
42       std::cin >> tmp;
43       if(std::cin.good())
44         input_files.push_back(tmp);
45       else break;
46     }
47     args_info.inputs_num=input_files.size();
48   } else for (unsigned int i=0; i<args_info.inputs_num; i++)
49       input_files.push_back(args_info.inputs[i]);
50
51
52   //===========================================
53   /// Get slices locations ...
54   std::vector<double> sliceLocations;
55   for(unsigned int i=0; i<args_info.inputs_num; i++) {
56     //std::cout << "Reading <" << input_files[i] << std::endl;
57 #if GDCM_MAJOR_VERSION == 2
58     gdcm::Reader hreader;
59     hreader.SetFileName(input_files[i].c_str());
60     hreader.Read();
61     std::vector<double> theorigin = gdcm::ImageHelper::GetOriginValue(hreader.GetFile());
62     sliceLocations.push_back(theorigin[2]);
63     gdcm::Attribute<0x28, 0x100> pixel_size;
64     gdcm::DataSet& ds = hreader.GetFile().GetDataSet();
65     pixel_size.SetFromDataSet(ds);
66     if (pixel_size.GetValue() != 16)
67     {
68       std::cerr << "Pixel type 2 bytes ! " << std::endl;
69       std::cerr << "In file " << input_files[i] << std::endl;
70       exit(0);
71     }
72 #else
73   gdcm::File *header = new gdcm::File();
74   header->SetFileName(input_files[i]);
75   header->SetMaxSizeLoadEntry(16384); // required ?
76   header->Load();
77   sliceLocations.push_back(header->GetZOrigin());
78   if (header->GetPixelSize() != 2) {
79     std::cerr << "Pixel type 2 bytes ! " << std::endl;
80     std::cerr << "In file " << input_files[i] << std::endl;
81     exit(0);
82   }
83 #endif
84   }
85
86   //===========================================
87   // Sort slices locations ...
88   std::vector<int> sliceIndex;
89   clitk::GetSortedIndex(sliceLocations, sliceIndex);
90   if (args_info.verboseSliceLocation_flag) {
91     std::cout << sliceLocations[sliceIndex[0]] << " -> "
92               << sliceIndex[0] << " / " << 0 << " => "
93               << "0 mm "
94               << input_files[sliceIndex[0]]
95               << std::endl;
96     for(unsigned int i=1; i<sliceIndex.size(); i++) {
97       std::cout << sliceLocations[sliceIndex[i]] << " -> "
98                 << sliceIndex[i] << " / " << i << " => "
99                 << sliceLocations[sliceIndex[i]] - sliceLocations[sliceIndex[i-1]]
100                 << "mm "
101                 << input_files[sliceIndex[i]]
102                 << std::endl;
103     }
104   }
105
106   //===========================================
107   // Analyze slices locations ...
108   double currentDist;
109   double dist=0;
110   double tolerance = args_info.tolerance_arg;
111   double previous = sliceLocations[sliceIndex[0]];
112   for(unsigned int i=1; i<sliceIndex.size(); i++) {
113     currentDist = sliceLocations[sliceIndex[i]]-previous;
114     if (i!=1) {
115       if (fabs(dist-currentDist) > tolerance) {
116         std::cout << "ERROR : " << std::endl
117                   << "Current slice pos is  = " << sliceLocations[sliceIndex[i]] << std::endl
118                   << "Previous slice pos is = " << previous << std::endl
119                   << "Current file is       = " << input_files[sliceIndex[i]] << std::endl
120                   << "Current index is      = " << i << std::endl
121                   << "Current sortindex is  = " << sliceIndex[i] << std::endl
122                   << "Current slice diff    = " << dist << std::endl
123                   << "Current error         = " << fabs(dist-currentDist) << std::endl;
124         exit(1);
125       }
126     } else dist = currentDist;
127     previous = sliceLocations[sliceIndex[i]];
128   }
129
130   //===========================================
131   // Create ordered vector of filenames
132   std::vector<std::string> sorted_files;
133   sorted_files.resize(sliceIndex.size());
134   for(unsigned int i=0; i<sliceIndex.size(); i++)
135     sorted_files[i] = input_files[ sliceIndex[i] ];
136
137   //===========================================
138   // Read write serie
139   vvImageReader::Pointer reader = vvImageReader::New();
140   reader->SetInputFilenames(sorted_files);
141   reader->Update(vvImageReader::DICOM);
142   if (reader->GetLastError().size() != 0) {
143     std::cerr << reader->GetLastError() << std::endl;
144     return 1;
145   }
146
147   vvImageWriter::Pointer writer = vvImageWriter::New();
148   writer->SetInput(reader->GetOutput());
149   writer->SetOutputFileName(args_info.output_arg);
150   writer->Update();
151
152   return 0;
153 }