]> Creatis software - clitk.git/commitdiff
convert a DicomStruct into a binary image
authordsarrut <dsarrut>
Thu, 22 Jul 2010 09:22:08 +0000 (09:22 +0000)
committerdsarrut <dsarrut>
Thu, 22 Jul 2010 09:22:08 +0000 (09:22 +0000)
tools/clitkDicomRTStruct2BinaryImage.cxx [new file with mode: 0644]
tools/clitkDicomRTStruct2BinaryImage.ggo [new file with mode: 0644]
tools/clitkDicomRTStructInfo.cxx [new file with mode: 0644]
tools/clitkDicomRTStructInfo.ggo [new file with mode: 0644]
tools/clitkDicomRT_ROI.cxx [new file with mode: 0644]
tools/clitkDicomRT_ROI.h [new file with mode: 0644]
tools/clitkDicomRT_ROI_ConvertToImageFilter.cxx [new file with mode: 0644]
tools/clitkDicomRT_ROI_ConvertToImageFilter.h [new file with mode: 0644]

diff --git a/tools/clitkDicomRTStruct2BinaryImage.cxx b/tools/clitkDicomRTStruct2BinaryImage.cxx
new file mode 100644 (file)
index 0000000..1201bd5
--- /dev/null
@@ -0,0 +1,65 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs to: 
+  - University of LYON           http://www.universite-lyon.fr/
+  - Léon Bérard cancer center    http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory      http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#include "clitkDicomRT_ROI_ConvertToImageFilter.h"
+#include "clitkDicomRT_StructureSet.h"
+#include "clitkDicomRTStruct2BinaryImage_ggo.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+  // Init command line
+  GGO(clitkDicomRTStruct2BinaryImage, args_info);
+
+  // Read and display information
+  clitk::DicomRT_StructureSet s;
+  s.Read(args_info.input_arg);
+  // s.Print(std::cout);
+  
+  // New filter to convert to binary image
+  clitk::DicomRT_ROI_ConvertToImageFilter filter;
+  filter.SetCropMaskEnabled(args_info.crop_flag);
+  filter.SetImageFilename(args_info.image_arg);  // Used to get spacing + origin
+  if (args_info.roi_arg != -1) {
+    filter.SetROI(s.GetROI(args_info.roi_arg)); 
+    filter.SetOutputImageFilename(args_info.output_arg);
+  filter.Update();  
+  }
+  else {
+    for(unsigned int i=0; i<s.GetListOfROI().size(); i++) {
+      std::string name = s.GetListOfROI()[i]->GetName();
+      int num = s.GetListOfROI()[i]->GetROINumber();
+      filter.SetROI(s.GetListOfROI()[i]); 
+      name.erase(remove_if(name.begin(), name.end(), isspace), name.end());
+      std::string n = std::string(args_info.output_arg).append
+        (clitk::toString(num)).append
+        ("_").append
+        (name).append
+        (".mhd");
+      if (args_info.verbose_flag) {
+        std::cout << i << " " << s.GetListOfROI()[i]->GetName() << " num=" << num << " : " << n << std::endl;
+      }
+      filter.SetOutputImageFilename(n);
+      filter.Update();  
+    }
+  }
+
+  // This is the end my friend 
+  return 0;
+}
diff --git a/tools/clitkDicomRTStruct2BinaryImage.ggo b/tools/clitkDicomRTStruct2BinaryImage.ggo
new file mode 100644 (file)
index 0000000..74e5a7e
--- /dev/null
@@ -0,0 +1,17 @@
+# file clitkDicomRTStruct2BinaryImage.ggo
+Package "clitk"
+version "Convert DICOM RT Structure Set (contours) to binary image"
+
+option "config"                 - "Config file"                     string     no
+option "verbose"         v "Verbose"                        flag       off
+option "input"          i "Input Dicom file"                string     yes
+option "image"          j "Used to read image info (spacing, origin)"    string        yes
+option "roi"            r "ROI to binarize (if -1 = all roi)"            int    no default="-1"
+option "output"                 o "Output image filename"       string yes
+
+option "crop"           c "Crop binary mask"            flag off
+
+#option "roi"           r "ROI to print (ID)"           int            no
+#option "contour"       c "contour to print (ID)"       int            no
+#option "offset"                o "to display points as image offsets" flag    off
+
diff --git a/tools/clitkDicomRTStructInfo.cxx b/tools/clitkDicomRTStructInfo.cxx
new file mode 100644 (file)
index 0000000..e449348
--- /dev/null
@@ -0,0 +1,36 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs to: 
+  - University of LYON           http://www.universite-lyon.fr/
+  - Léon Bérard cancer center    http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory      http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#include "clitkDicomRT_StructureSet.h"
+#include "clitkDicomRTStructInfo_ggo.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+  // Init command line
+  GGO(clitkDicomRTStructInfo, args_info);
+
+  // Read and display information
+  clitk::DicomRT_StructureSet s;
+  s.Read(args_info.input_arg);
+  s.Print(std::cout);
+
+  // This is the end my friend 
+  return 0;
+}
diff --git a/tools/clitkDicomRTStructInfo.ggo b/tools/clitkDicomRTStructInfo.ggo
new file mode 100644 (file)
index 0000000..594de5d
--- /dev/null
@@ -0,0 +1,11 @@
+# file clitkDicomRTStructInfo.ggo
+Package "clitk"
+version "Read and print DICOM RT Structure set file (contours)"
+
+option "config"                 - "Config file"                 string         no
+option "input"          i "Input Dicom file"            string         yes
+
+#option "roi"           r "ROI to print (ID)"           int            no
+#option "contour"       c "contour to print (ID)"       int            no
+#option "offset"                o "to display points as image offsets" flag    off
+
diff --git a/tools/clitkDicomRT_ROI.cxx b/tools/clitkDicomRT_ROI.cxx
new file mode 100644 (file)
index 0000000..d140398
--- /dev/null
@@ -0,0 +1,117 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs to: 
+  - University of LYON           http://www.universite-lyon.fr/
+  - Léon Bérard cancer center    http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory      http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#include "clitkDicomRT_ROI.h" 
+#include <vtkSmartPointer.h>
+#include <vtkAppendPolyData.h>
+
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI::DicomRT_ROI() {
+  mName = "NoName";
+  mNumber = -1;
+  mColor.resize(3);
+  mColor[0] = mColor[1] = mColor[2] = 0;
+  mMeshIsUpToDate = false;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI::~DicomRT_ROI() {
+  
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+int clitk::DicomRT_ROI::GetROINumber() const {
+  return mNumber;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::string & clitk::DicomRT_ROI::GetName() const {
+  return mName;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::vector<double> & clitk::DicomRT_ROI::GetDisplayColor() const {
+  return mColor;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI::Print(std::ostream & os) const {
+  os << "ROI " << mNumber << "\t" << mName 
+     << "\t(" << mColor[0] << " " << mColor[1] << " " << mColor[2] << ")"
+     << "\t Contours = " << mListOfContours.size() << std::endl;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::SQItem * item) {
+  
+  // ROI number [Referenced ROI Number]
+  mNumber = atoi(item->GetEntryValue(0x3006,0x0084).c_str());
+  
+  // Retrieve ROI Name
+  mName = rois[mNumber];
+
+  // ROI Color [ROI Display Color]
+  mColor = clitk::parse_string<double>(item->GetEntryValue(0x3006,0x002a),'\\');
+
+  // Read contours [Contour Sequence]
+  gdcm::SeqEntry * contours=item->GetSeqEntry(0x3006,0x0040);
+  for(gdcm::SQItem* j=contours->GetFirstSQItem();j!=0;j=contours->GetNextSQItem()) {
+    DicomRT_Contour * c = new DicomRT_Contour;    
+    bool b = c->Read(j);
+    if (b) mListOfContours.push_back(c);
+  }
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+vtkPolyData * clitk::DicomRT_ROI::GetMesh() {
+  if (!mMeshIsUpToDate) {
+    ComputeMesh();
+  }
+  return mMesh;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI::ComputeMesh() {
+  vtkAppendPolyData * append = vtkAppendPolyData::New();
+  for(unsigned int i=0; i<mListOfContours.size(); i++) {
+    append->AddInput(mListOfContours[i]->GetMesh());
+  }
+  append->Update();
+  mMesh = append->GetOutput();
+  mMeshIsUpToDate = true;
+}
+//--------------------------------------------------------------------
+
diff --git a/tools/clitkDicomRT_ROI.h b/tools/clitkDicomRT_ROI.h
new file mode 100644 (file)
index 0000000..0b8d6dc
--- /dev/null
@@ -0,0 +1,55 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs to: 
+  - University of LYON           http://www.universite-lyon.fr/
+  - Léon Bérard cancer center    http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory      http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#ifndef CLITKDICOMRT_ROI_H
+#define CLITKDICOMRT_ROI_H
+
+#include "clitkDicomRT_Contour.h"
+
+namespace clitk {
+
+  //--------------------------------------------------------------------
+  class DicomRT_ROI {
+    
+  public:
+    DicomRT_ROI();
+    ~DicomRT_ROI();
+
+    void Print(std::ostream & os = std::cout) const;
+    void Read(std::map<int, std::string> & rois, gdcm::SQItem * item);
+
+    int GetROINumber() const;
+    const std::string & GetName() const;
+    const std::vector<double> & GetDisplayColor() const;
+    vtkPolyData * GetMesh();
+    
+  protected:
+    void ComputeMesh();
+    std::string mName;
+    int mNumber;
+    std::vector<double> mColor;
+    std::vector<DicomRT_Contour*> mListOfContours;
+    vtkPolyData * mMesh;
+    bool mMeshIsUpToDate;
+  };
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+#endif // CLITKDICOMRT_ROI_H
+
diff --git a/tools/clitkDicomRT_ROI_ConvertToImageFilter.cxx b/tools/clitkDicomRT_ROI_ConvertToImageFilter.cxx
new file mode 100644 (file)
index 0000000..cedef81
--- /dev/null
@@ -0,0 +1,191 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs to: 
+  - University of LYON           http://www.universite-lyon.fr/
+  - Léon Bérard cancer center    http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory      http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#include "clitkDicomRT_ROI_ConvertToImageFilter.h" 
+#include <vtkPolyDataToImageStencil.h>
+#include <vtkSmartPointer.h>
+#include <vtkImageStencil.h>
+#include <vtkLinearExtrusionFilter.h>
+#include <itkVTKImageToImageFilter.h>
+#include "clitkImageCommon.h"
+
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI_ConvertToImageFilter::DicomRT_ROI_ConvertToImageFilter() {
+  mROI = NULL;
+  mImageInfoIsSet = false;
+  mWriteOutput = false;
+  mCropMask = true;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI_ConvertToImageFilter::~DicomRT_ROI_ConvertToImageFilter() {
+  
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::SetROI(clitk::DicomRT_ROI * roi) {
+  mROI = roi;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::SetCropMaskEnabled(bool b) {
+  mCropMask = b;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::SetOutputImageFilename(std::string s) {
+  mOutputFilename = s;
+  mWriteOutput = true;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::SetImageFilename(std::string f) {
+  itk::ImageIOBase::Pointer header = clitk::readImageHeader(f);
+  if (header->GetNumberOfDimensions() < 3) {
+    std::cerr << "Error. Please provide a 3D image instead of " << f << std::endl;
+    exit(0);
+  }
+  if (header->GetNumberOfDimensions() > 3) {
+    std::cerr << "Warning dimension > 3 are ignored" << std::endl;
+  }
+  mSpacing.resize(3);
+  mOrigin.resize(3);
+  mSize.resize(3);
+  for(unsigned int i=0; i<3; i++) {
+    mSpacing[i] = header->GetSpacing(i);
+    mOrigin[i] = header->GetOrigin(i);
+    mSize[i] = header->GetDimensions(i);
+  }
+  mImageInfoIsSet = true;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::Update() {
+  if (!mROI) {
+    std::cerr << "Error. No ROI set, please use SetROI." << std::endl;
+    exit(0);
+  }
+  if (!mImageInfoIsSet) {
+    std::cerr << "Error. Please provide image info (spacing/origin) with SetImageFilename" << std::endl;
+    exit(0);
+  }
+  // DD("Update");
+  
+  // Get Mesh
+  vtkPolyData * mesh = mROI->GetMesh();
+  //  DD(mesh->GetNumberOfCells());
+  
+  // Get bounds
+  double *bounds=mesh->GetBounds(); 
+  // for(int i=0; i<6; i++){
+//     DD(bounds[i]);
+//   }
+
+  // Compute origin
+  std::vector<double> origin; 
+  origin.resize(3);
+  origin[0] = floor((bounds[0]-mOrigin[0])/mSpacing[0]-2)*mSpacing[0]+mOrigin[0];
+  origin[1] = floor((bounds[2]-mOrigin[1])/mSpacing[1]-2)*mSpacing[1]+mOrigin[1];
+  origin[2] = floor((bounds[4]-mOrigin[2])/mSpacing[2]-2)*mSpacing[2]+mOrigin[2];
+  
+  // Compute extend
+  std::vector<double> extend; 
+  extend.resize(3);
+  extend[0] = ceil((bounds[1]-origin[0])/mSpacing[0]+4);
+  extend[1] = ceil((bounds[3]-origin[1])/mSpacing[1]+4);
+  extend[2] = ceil((bounds[5]-origin[2])/mSpacing[2]+4);
+  
+  // If no crop, set initial image size/origin
+  if (!mCropMask) {
+    for(int i=0; i<3; i++) {
+      origin[i] = mOrigin[i];
+      extend[i] = mSize[i]-1;
+    }
+  }
+  
+  // Create new output image
+  mBinaryImage = vtkImageData::New();
+  mBinaryImage->SetScalarTypeToUnsignedChar();
+  mBinaryImage->SetOrigin(&origin[0]);
+  mBinaryImage->SetSpacing(&mSpacing[0]);
+  mBinaryImage->SetExtent(0, extend[0], 
+                          0, extend[1], 
+                          0, extend[2]);
+  mBinaryImage->AllocateScalars();
+
+  // for(int i=0; i<3; i++){
+  //     DD(origin[i]);
+  //     DD(extend[i]);
+  //     DD(mBinaryImage->GetDimensions()[i]);
+  //   }
+  memset(mBinaryImage->GetScalarPointer(), 0,
+         mBinaryImage->GetDimensions()[0]*mBinaryImage->GetDimensions()[1]*mBinaryImage->GetDimensions()[2]*sizeof(unsigned char));
+  
+  // Extrude
+  vtkSmartPointer<vtkLinearExtrusionFilter> extrude=vtkSmartPointer<vtkLinearExtrusionFilter>::New();
+  extrude->SetInput(mesh);
+  ///We extrude in the -slice_spacing direction to respect the FOCAL convention // ?????????????
+  extrude->SetVector(0, 0, -mSpacing[2]);
+
+  // Binarization  
+  vtkSmartPointer<vtkPolyDataToImageStencil> sts=vtkSmartPointer<vtkPolyDataToImageStencil>::New();
+  //The following line is extremely important
+  //http://www.nabble.com/Bug-in-vtkPolyDataToImageStencil--td23368312.html#a23370933
+  sts->SetTolerance(0);
+  sts->SetInformationInput(mBinaryImage);
+  sts->SetInput(extrude->GetOutput());
+  //sts->SetInput(mesh);
+
+  vtkSmartPointer<vtkImageStencil> stencil=vtkSmartPointer<vtkImageStencil>::New();
+  stencil->SetStencil(sts->GetOutput());  
+  stencil->SetInput(mBinaryImage);
+  stencil->ReverseStencilOn();
+  stencil->Update();
+  mBinaryImage->ShallowCopy(stencil->GetOutput());
+  
+  if (mWriteOutput) {
+     typedef itk::Image<unsigned char, 3> ImageType;
+     typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
+     ConnectorType::Pointer connector = ConnectorType::New();
+     connector->SetInput(GetOutput());
+     connector->Update();
+     clitk::writeImage<ImageType>(connector->GetOutput(), mOutputFilename);  
+  }
+}
+//--------------------------------------------------------------------
+
+
+    
+//--------------------------------------------------------------------
+vtkImageData * clitk::DicomRT_ROI_ConvertToImageFilter::GetOutput() {
+  return mBinaryImage;
+}
+//--------------------------------------------------------------------
diff --git a/tools/clitkDicomRT_ROI_ConvertToImageFilter.h b/tools/clitkDicomRT_ROI_ConvertToImageFilter.h
new file mode 100644 (file)
index 0000000..d5d27b3
--- /dev/null
@@ -0,0 +1,58 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs to: 
+  - University of LYON           http://www.universite-lyon.fr/
+  - Léon Bérard cancer center    http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory      http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#ifndef CLITKDICOMRT_ROI_CONVERTTOIMAGEFILTER_H
+#define CLITKDICOMRT_ROI_CONVERTTOIMAGEFILTER_H
+
+#include "clitkDicomRT_ROI.h"
+#include "clitkImageCommon.h"
+#include <vtkImageData.h>
+
+namespace clitk {
+
+  //--------------------------------------------------------------------
+  class DicomRT_ROI_ConvertToImageFilter {
+    
+  public:
+    DicomRT_ROI_ConvertToImageFilter();
+    ~DicomRT_ROI_ConvertToImageFilter();
+
+    void SetROI(clitk::DicomRT_ROI * roi);
+    void SetImageFilename(std::string s);
+    void SetOutputImageFilename(std::string s);
+    void Update();    
+    vtkImageData * GetOutput();
+    void SetCropMaskEnabled(bool b);
+
+  protected:
+    bool mImageInfoIsSet;
+    bool mWriteOutput;
+    bool mCropMask;
+    std::string mOutputFilename;
+    std::vector<double> mSpacing;
+    std::vector<double> mOrigin;
+    std::vector<int> mSize;
+    clitk::DicomRT_ROI * mROI;
+    vtkImageData * mBinaryImage;
+  };
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+#endif // CLITKDICOMRT_ROI_CONVERTTOIMAGEFILTER_H
+