]> Creatis software - clitk.git/commitdiff
clitkDicomToImage added to clitk3
authorbouilhol <bouilhol>
Fri, 5 Nov 2010 00:04:59 +0000 (00:04 +0000)
committerbouilhol <bouilhol>
Fri, 5 Nov 2010 00:04:59 +0000 (00:04 +0000)
tools/CMakeLists.txt
tools/clitkDicom2Image.cxx [new file with mode: 0644]
tools/clitkDicom2Image.ggo [new file with mode: 0644]

index 02a0511ab60a4bbdc045ff2eafdba0f2e9e7167d..8157242b51e3f0e03a8af1cdb20b70dd9b1c10f2 100644 (file)
@@ -24,7 +24,11 @@ TARGET_LINK_LIBRARIES(clitkBinarizeImageLib clitkToolsGgoLib)
 IF (CLITK_BUILD_TOOLS)
     WRAP_GGO(clitkDicomInfo_GGO_C clitkDicomInfo.ggo)
     ADD_EXECUTABLE(clitkDicomInfo clitkDicomInfo.cxx ${clitkDicomInfo_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkDicomInfo clitkCommon ITKIO) 
+    TARGET_LINK_LIBRARIES(clitkDicomInfo clitkCommon ITKIO)
+
+    WRAP_GGO(clitkDicom2Image_GGO_C clitkDicom2Image.ggo)
+    ADD_EXECUTABLE(clitkDicom2Image clitkDicom2Image.cxx ${clitkDicom2Image_GGO_C})
+    TARGET_LINK_LIBRARIES(clitkDicom2Image clitkCommon ITKIO)
 
     WRAP_GGO(clitkImageInfo_GGO_C clitkImageInfo.ggo)
     ADD_EXECUTABLE(clitkImageInfo clitkImageInfo.cxx ${clitkImageInfo_GGO_C})
diff --git a/tools/clitkDicom2Image.cxx b/tools/clitkDicom2Image.cxx
new file mode 100644 (file)
index 0000000..bb38458
--- /dev/null
@@ -0,0 +1,188 @@
+/*=========================================================================
+                                                                                
+Program:   clitk
+Module:    $RCSfile: clitkDicom2Image.cxx,v $
+Language:  C++
+Date:      $Date: 2010/11/05 00:05:00 $
+Version:   $Revision: 1.1 $
+                                                                                
+Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+l'Image). All rights reserved. See Doc/License.txt or
+http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
+                                                                                
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.  See the above copyright notices for more information.
+                                                                             
+=========================================================================*/
+
+/**
+   =================================================
+   * @file   clitkDicom2Image.cxx
+   * @author David Sarrut <David.Sarrut@creatis.insa-lyon.fr>
+   * @date   26 Oct 2006
+   * 
+   * @brief  
+   * 
+   =================================================*/
+
+// clitk includes
+#include "clitkDicom2Image_ggo.h"
+#include <clitkCommon.h>
+#include "clitkImageCommon.h"
+
+// itk include
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+
+// Why this is needed ???
+//const double itk::NumericTraits<double>::Zero = 0.0;
+
+//====================================================================
+int main(int argc, char * argv[]) {
+
+  // init command line
+  GGO(clitkDicom2Image, args_info);
+  std::vector<std::string> input_files;
+  ///if std_input is given, read the input files from stdin
+  if (args_info.std_input_given)
+  {
+      while (true)
+      {
+          std::string tmp;
+          std::cin >> tmp;
+          if(std::cin.good())
+              input_files.push_back(tmp);
+          else break;
+      }
+      args_info.inputs_num=input_files.size();
+  }
+  else for (unsigned int i=0;i<args_info.inputs_num;i++)
+      input_files.push_back(args_info.inputs[i]);
+
+  
+  //===========================================
+  /// Get slices locations ...
+    std::vector<double> sliceLocations;
+    for(unsigned int i=0; i<args_info.inputs_num; i++) {
+      //std::cout << "Reading <" << input_files[i] << std::endl;       
+      gdcm::File * header = clitk::readDicomHeader(input_files[i]);
+      sliceLocations.push_back(header->GetZOrigin());
+      // check
+      /*if (!header->IsSignedPixelData()) {
+       std::cerr << "Pixel type not signed ! " << std::endl;
+       std::cerr << "In file " << input_files[i] << std::endl;
+       exit(0);
+       }*/
+      if (header->GetPixelSize() != 2) {
+       std::cerr << "Pixel type 2 bytes ! " << std::endl;
+       std::cerr << "In file " << input_files[i] << std::endl;
+       exit(0);
+      }
+    }
+
+    //===========================================
+    // Sort slices locations ...
+    std::vector<int> sliceIndex;
+    clitk::GetSortedIndex(sliceLocations, sliceIndex);
+    if (args_info.verboseSliceLocation_flag) {
+      std::cout << sliceLocations[sliceIndex[0]] << " -> " 
+               << sliceIndex[0] << " / " << 0 << " => " 
+               << "0 mm " 
+               << input_files[sliceIndex[0]]
+               << std::endl;
+      for(unsigned int i=1; i<sliceIndex.size(); i++) {
+       std::cout << sliceLocations[sliceIndex[i]] << " -> " 
+                 << sliceIndex[i] << " / " << i << " => " 
+                 << sliceLocations[sliceIndex[i]] - sliceLocations[sliceIndex[i-1]] 
+                 << "mm " 
+                 << input_files[sliceIndex[i]]
+                 << std::endl;
+      }
+    }
+
+    //===========================================
+    // Analyze slices locations ...
+    double currentDist;
+    double dist=0;
+    double tolerance = args_info.tolerance_arg;
+    double previous = sliceLocations[sliceIndex[0]];
+    for(unsigned int i=1; i<sliceIndex.size(); i++) {
+      currentDist = sliceLocations[sliceIndex[i]]-previous;
+      if (i!=1) {
+       if (fabs(dist-currentDist) > tolerance) {
+         std::cout << "ERROR : " << std::endl
+                   << "Current slice pos is  = " << sliceLocations[sliceIndex[i]] << std::endl
+                   << "Previous slice pos is = " << previous << std::endl
+                   << "Current file is       = " << input_files[sliceIndex[i]] << std::endl
+                   << "Current index is      = " << i << std::endl
+                   << "Current sortindex is  = " << sliceIndex[i] << std::endl
+                   << "Current slice diff    = " << dist << std::endl
+                   << "Current error         = " << fabs(dist-currentDist) << std::endl;
+         exit(1);
+       }
+      }
+      else dist = currentDist;
+      previous = sliceLocations[sliceIndex[i]];
+    }
+
+    //===========================================
+    // Create image  
+    gdcm::File * header = clitk::readDicomHeader(input_files[sliceIndex.front()]);
+    typedef itk::Image<float, 3> ImageType;
+    typedef itk::Image<signed short, 3> ImageTypeOutput;
+    ImageType::SpacingType spacing;
+    ImageType::SizeType    size;
+    ImageType::PointType    origin;
+    spacing[0] = header->GetXSpacing();
+    spacing[1] = header->GetYSpacing();
+    spacing[2] = dist;
+    size[0]    = header->GetXSize();
+    size[1]    = header->GetYSize();
+    size[2]    = sliceIndex.size();
+    ///Optional use of special origin scheme used at CLB
+    if (args_info.focal_origin_flag)
+    {
+        origin[0]  = -spacing[0]*size[0]/2;
+        origin[1]  = -spacing[1]*size[1]/2;
+    }
+    else
+    {
+        origin[0]  = header->GetXOrigin();
+        origin[1]  = header->GetYOrigin();
+    }
+    origin[2]  = header->GetZOrigin();
+    ImageTypeOutput::Pointer output = ImageTypeOutput::New();
+    itk::ImageRegion<3> region;
+    region.SetSize(size);
+    output->SetRegions(region);
+    output->SetOrigin(origin);
+    output->SetSpacing(spacing);
+    output->Allocate();
+  
+    //===========================================
+    // Fill image
+    ImageType::Pointer slice;
+    typedef itk::ImageRegionIterator<ImageTypeOutput> IteratorType;
+    typedef itk::ImageRegionConstIterator<ImageType> ConstIteratorType;
+    IteratorType po(output, output->GetLargestPossibleRegion());
+    po.Begin();
+    for(unsigned int i=0; i<sliceIndex.size(); i++) {
+      slice = clitk::readImage<ImageType>(input_files[sliceIndex[i]]);
+      ConstIteratorType pi(slice, slice->GetLargestPossibleRegion());
+      while ( !pi.IsAtEnd() ) {
+       po.Set((signed short)pi.Get());
+       ++po;
+       ++pi;
+      }
+    }
+
+    //===========================================
+    // Write image
+    clitk::writeImage<ImageTypeOutput>(output, 
+                                      args_info.output_arg, 
+                                      args_info.verbose_flag);
+  
+    // this is the end my friend 
+    return 0;
+}
diff --git a/tools/clitkDicom2Image.ggo b/tools/clitkDicom2Image.ggo
new file mode 100644 (file)
index 0000000..fb51135
--- /dev/null
@@ -0,0 +1,12 @@
+# file clitkDicom2Image.ggo
+package "clitk"
+version "Try to convert a DICOM into an image (.hdr, .vox...)"
+
+option "config"                 -      "Config file"            string         no
+option "verbose"        v "Verbose"                     flag off
+option "verboseSliceLocation"   - "Verbose slices locations"            flag off
+option "name"           n "Display filename"    flag off
+option "tolerance"      t "Tolerance for slice position"        double default="0" no
+option "output"      o "Output image filename"         string  yes
+option "std_input"   - "Take the like of input file from stdin, to support huge lists of filenames" flag off
+option "focal_origin" - "Output files with FOCAL-like origin, instead of the origin present in the dicom files" flag off