]> Creatis software - clitk.git/commitdiff
First version to convert image to dicomrtstruct
authorDavid Sarrut <david.sarrut@gmail.com>
Fri, 3 Feb 2012 06:57:12 +0000 (07:57 +0100)
committerDavid Sarrut <david.sarrut@creatis.insa-lyon.fr>
Mon, 3 Jun 2013 11:52:05 +0000 (13:52 +0200)
common/clitkDicomRTStruct2ImageFilter.cxx
common/clitkImage2DicomRTStructFilter.h
common/clitkImage2DicomRTStructFilter.txx
itk/clitkBinaryImageToMeshFilter.h [new file with mode: 0644]
itk/clitkBinaryImageToMeshFilter.txx [new file with mode: 0644]

index fa66cfb31361de6d96bea75d01676c0295901b67..e52fc0f17be8a3e16acee8517409b5b224205615 100644 (file)
@@ -160,6 +160,7 @@ void clitk::DicomRTStruct2ImageFilter::SetOutputSize(const unsigned long* size)
 //--------------------------------------------------------------------
 void clitk::DicomRTStruct2ImageFilter::Update()
 {
+  DD("DicomRTStruct2ImageFilter::Update");
   if (!mROI) {
     std::cerr << "Error. No ROI set, please use SetROI." << std::endl;
     exit(0);
@@ -170,7 +171,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
   }
 
   // Get Mesh
-  vtkPolyData * mesh = mROI->GetMesh();
+  vtkPolyData * mesh = mROI->GetMesh();  
 
   // Get bounds
   double *bounds=mesh->GetBounds();
index 749a0be5f9685fbd9ec752e7436943060bf7bada..5eb6ddc7974514d70b8eea40ebfde684df01a972 100644 (file)
@@ -43,16 +43,19 @@ namespace clitk {
     // Set inputs
     itkSetMacro(Input, ImagePointer);
     itkGetConstMacro(Input, ImagePointer);
+    itkSetMacro(StructureSetFilename, std::string);
+    itkSetMacro(DicomFolder, std::string);
+    itkSetMacro(OutputFilename, std::string);
     
     // Run filter
     void Update();    
     
-    // Get output
-    itkGetConstMacro(DicomRTStruct, DicomRTStructPointer);
-
   protected:
     ImagePointer m_Input;
-    DicomRTStructPointer m_DicomRTStruct;
+    std::string m_StructureSetFilename;
+    std::string m_DicomFolder;
+    std::string m_OutputFilename;
+
   };
   //--------------------------------------------------------------------
 
index 6ab72e2ed6916e48a6ce8978d7016508baea85e8..cc90104216d6ca2ef9d37f77e92156bf47c4fe9f 100644 (file)
@@ -23,6 +23,7 @@
 
 // clitk
 #include "clitkImage2DicomRTStructFilter.h"
+#include "clitkBinaryImageToMeshFilter.h"
 #include "clitkImageCommon.h"
 #include "vvFromITK.h"
 
 #include <vtkMetaImageWriter.h>
 #include <vtkImageData.h>
 
+// FIXME to remove
+#include "vtkPolyDataMapper.h"
+#include "vtkPolyDataMapper2D.h"
+#include "vtkRenderWindowInteractor.h"
+#include "vtkPolyDataReader.h"
+#include "vtkRenderWindow.h"
+#include "vtkRenderer.h"
+#include "vtkCamera.h"
+#include "vtkProperty.h"
+#include "vtkProperty2D.h"
+
 // itk
 #include <itkImage.h>
 #include <itkVTKImageToImageFilter.h>
 
+// gdcm
+#include <vtkGDCMPolyDataWriter.h>
+
 //--------------------------------------------------------------------
 template<class PixelType>
 clitk::Image2DicomRTStructFilter<PixelType>::Image2DicomRTStructFilter()
@@ -62,23 +77,150 @@ void clitk::Image2DicomRTStructFilter<PixelType>::Update()
 {
   DD("Image2DicomRTStructFilter::GenerateData");
 
-  // Read DicomRTStruct
-  std::string filename = "RS.zzQAnotmt_french01_.dcm";
-  clitk::DicomRT_StructureSet::Pointer structset = clitk::DicomRT_StructureSet::New();
-  structset->Read(filename);
+  // Read rt struct
+  vtkSmartPointer<vtkGDCMPolyDataReader> reader = vtkGDCMPolyDataReader::New();
+  reader->SetFileName(m_StructureSetFilename.c_str());
+  reader->Update();
+  DD("reader done");
+
+  // Get properties
+  vtkRTStructSetProperties * p = reader->GetRTStructSetProperties();
+  DD(p->GetNumberOfStructureSetROIs());
+  DD(p->GetStructureSetROIName(0));
+  DD(p->GetStructureSetROINumber(0));  
+  
+  // Init writer
+  vtkGDCMPolyDataWriter * writer = vtkGDCMPolyDataWriter::New();
+  int numMasks = reader->GetNumberOfOutputPorts() + 1;//add one more
+  DD(numMasks);
+  
+  // numMasks = 3; //FIXME temporary
+
+  writer->SetNumberOfInputPorts(numMasks);    
+  writer->SetFileName(m_OutputFilename.c_str());
+  writer->SetMedicalImageProperties(reader->GetMedicalImageProperties());
+
+  // List of already present rois
+  vtkStringArray* roiNames = vtkStringArray::New();
+  vtkStringArray* roiAlgorithms = vtkStringArray::New();
+  vtkStringArray* roiTypes = vtkStringArray::New();
+  roiNames->SetNumberOfValues(numMasks);
+  roiAlgorithms->SetNumberOfValues(numMasks);
+  roiTypes->SetNumberOfValues(numMasks);
   
-  DD(structset->GetName());
-  clitk::DicomRT_ROI * roi = structset->GetROIFromROINumber(1); // Aorta
+  typedef clitk::BinaryImageToMeshFilter<ImageType> BinaryImageToMeshFilterType;
+  typename BinaryImageToMeshFilterType::Pointer convert = BinaryImageToMeshFilterType::New();
+  convert->SetInput(m_Input);
+  DD("Update");
+  convert->Update();
+  DD("here");
+  DD("end update");
+  vtkPolyData* mesh = convert->GetOutputMesh();
+  DD(mesh->GetNumberOfVerts());
+  DD(mesh->GetNumberOfLines());
+  DD(mesh->GetNumberOfPolys());
+  DD(mesh->GetNumberOfStrips());
+
+  // Add on (FIXME) to replace with binary image
+  // vtkPolyData* blank = vtkPolyData::New();
+  // writer->SetInput(0, blank);
+  writer->SetInput(0, mesh);
+  roiNames->InsertValue(0, "blank");
+  roiAlgorithms->InsertValue(0, "blank");
+  roiTypes->InsertValue(0, "ORGAN");
+
+  for (unsigned int i = 1; i < numMasks; ++i) {
+    // DD(i);
+    writer->SetInput(i, reader->GetOutput(i-1));
+    std::string theString = reader->GetRTStructSetProperties()->GetStructureSetROIName(i-1);
+    roiNames->InsertValue(i, theString);
+    theString = reader->GetRTStructSetProperties()->GetStructureSetROIGenerationAlgorithm(i-1);
+    roiAlgorithms->InsertValue(i, theString);
+    theString = reader->GetRTStructSetProperties()->GetStructureSetRTROIInterpretedType(i-1);
+    roiTypes->InsertValue(i, theString);
+  }
+  
+
+  /*
+  //  Visu
+  vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();
+  cubeMapper->SetInput( mesh );
+  cubeMapper->SetScalarRange(0,7);
+  vtkActor *cubeActor = vtkActor::New();
+  cubeActor->SetMapper(cubeMapper);
+  vtkProperty * property = cubeActor->GetProperty();
+  property->SetRepresentationToWireframe();
+
+  vtkRenderer *renderer = vtkRenderer::New();
+  vtkRenderWindow *renWin = vtkRenderWindow::New();
+  renWin->AddRenderer(renderer);
+
+  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
+  iren->SetRenderWindow(renWin);
+
+  renderer->AddActor(cubeActor);
+  renderer->ResetCamera();
+  renderer->SetBackground(1,1,1);
+
+  renWin->SetSize(300,300);
+
+  renWin->Render();
+  iren->Start();
+  */
+  
+
+  // End visu
+
+
+  vtkRTStructSetProperties* theProperties = vtkRTStructSetProperties::New();
+  DD(p->GetStudyInstanceUID());
+  writer->SetRTStructSetProperties(theProperties);
+  /*writer->InitializeRTStructSet2(p,"./",
+                                 reader->GetRTStructSetProperties()->GetStructureSetLabel(),
+                                 reader->GetRTStructSetProperties()->GetStructureSetName(),
+                                 roiNames, roiAlgorithms, roiTypes);*/  
+  writer->InitializeRTStructSet(m_DicomFolder,
+                                reader->GetRTStructSetProperties()->GetStructureSetLabel(),
+                                reader->GetRTStructSetProperties()->GetStructureSetName(),
+                                roiNames, roiAlgorithms, roiTypes);
+  
+  DD("after init");
+  writer->Write();
+  DD("write done");
+
+  reader->Delete();
+  roiNames->Delete();
+  roiTypes->Delete();
+  //theProperties->Delete();
+  roiAlgorithms->Delete();
+  //blank->Delete();
+  writer->Delete();
+  
+  ////////////////////
+  
+
+  /*
+
+  // DicomRTStruct
+  DD(m_StructureSet->GetName());
+  clitk::DicomRT_ROI * roi = m_StructureSet->GetROIFromROINumber(1); // Aorta
   DD(roi->GetName());
   DD(roi->GetROINumber());
 
+
+  // Get 
+  
+
+
+
   // Add an image to the roi
   vvImage::Pointer im = vvImageFromITK<3, PixelType>(m_Input);
   roi->SetImage(im);
 
   // Get one contour
   DD("Compute Mesh");
-  roi->ComputeMeshFromImage();
+  roi->ComputeContoursFromImage(); // FIXME do the set mesh for the moment (to change)
+  // roi->ComputeMeshFromContour();
   vtkSmartPointer<vtkPolyData> mesh = roi->GetMesh();
   DD("done");
   
@@ -91,13 +233,14 @@ void clitk::Image2DicomRTStructFilter<PixelType>::Update()
   //   points->SetPoint(i, p);
   // }
   roi->SetName("TOTO");
-  roi->SetDicomUptodateFlag(false); // indicate that dicom info must be updated from the mesh.
+  roi->SetDicomUptodateFlag(true); // indicate that dicom info must be updated from the mesh.
     
   // Convert to dicom ?
   DD("TODO");
   
   // Write
   structset->Write("toto.dcm");
+  */
 }
 //--------------------------------------------------------------------
 
diff --git a/itk/clitkBinaryImageToMeshFilter.h b/itk/clitkBinaryImageToMeshFilter.h
new file mode 100644 (file)
index 0000000..0a36c36
--- /dev/null
@@ -0,0 +1,131 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.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        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+#ifndef CLITKBINARYIMAGETOMESHFILTER_H
+#define CLITKMESHTOBINARYIMAGEFILTER_H
+
+// clitk
+#include "clitkCommon.h"
+#include "vvFromITK.h"
+
+// itk
+#include <itkProcessObject.h>
+
+// vtk
+#include <vtkSmartPointer.h>
+#include <vtkPolyData.h>
+#include <vtkImageClip.h>
+#include <vtkMarchingSquares.h>
+#include <vtkAppendPolyData.h>
+#include <vtkDecimatePro.h>
+#include <vtkStripper.h>
+
+namespace clitk {
+    
+  /* --------------------------------------------------------------------     
+     Convert a 3D binary image into a list of 2D contours (vtkpolydata)
+     -------------------------------------------------------------------- */
+  
+  template<class ImageType>
+  class ITK_EXPORT BinaryImageToMeshFilter:public itk::Object //:public clitk::FilterBase
+  {
+
+  public:
+    /** Standard class typedefs. */
+    //    typedef itk::ImageToMeshFilter<ImageType, vtkPolyData>   Superclass;
+    typedef itk::ProcessObject   Superclass;
+    typedef BinaryImageToMeshFilter       Self;
+    typedef itk::SmartPointer<Self>       Pointer;
+    typedef itk::SmartPointer<const Self> ConstPointer;
+       
+    /** Method for creation through the object factory. */
+    itkNewMacro(Self);
+    /** Run-time type information (and related methods). */
+    itkTypeMacro(BinaryImageToMeshFilter, Superclass);
+
+    /** ImageDimension constants */
+    itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
+
+    // /** Some convenient typedefs. */
+    // typedef typename ImageType::ConstPointer ImageConstPointer;
+    typedef typename ImageType::Pointer      ImagePointer;
+    // typedef typename ImageType::RegionType   RegionType; 
+    typedef typename ImageType::PixelType    PixelType;
+    // typedef typename ImageType::SpacingType  SpacingType;
+    // typedef typename ImageType::SizeType     SizeType;
+    // typedef typename ImageType::PointType    PointType;
+    //typedef itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType;
+    //    typedef vtkSmartPointer<vtkPolyData> DataObjectPointer;
+
+    //    using Superclass::SetInput;
+    // void SetInput(unsigned int idx, const ImageType *input);
+    // void SetInput(const ImageType *input)
+    // {
+    //   m_this->SetInput(0, input);
+    // }
+    
+    // const ImageType * GetInput(unsigned int idx);
+    // const ImageType * GetInput()
+    // {
+    //   return this->GetInput(0);
+    // }
+    
+    //virtual DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx);
+    //    virtual void GenerateData();
+    //    virtual void GenerateOutputInformation();
+
+    /** Input : initial image and object */
+    // itkSetMacro(Mesh, vtkSmartPointer<vtkPolyData>);
+    // itkGetConstMacro(Mesh, vtkSmartPointer<vtkPolyData>);
+
+    // itkSetMacro(LikeImage, ImagePointer);
+    // itkGetConstMacro(LikeImage, ImagePointer);
+
+    // itkSetMacro(Extrude, bool);
+    // itkGetMacro(Extrude, bool);
+    // itkBooleanMacro(Extrude);    
+    itkSetMacro(Input, ImagePointer);
+    itkGetConstMacro(Input, ImagePointer);
+    itkGetMacro(OutputMesh, vtkSmartPointer<vtkPolyData>);
+
+    // virtual void GenerateOutputInformation();
+    virtual void Update();
+
+  protected:
+    BinaryImageToMeshFilter();
+    virtual ~BinaryImageToMeshFilter() {}
+    
+    ImagePointer m_Input;
+    vtkSmartPointer<vtkPolyData> m_OutputMesh;
+
+  private:
+    BinaryImageToMeshFilter(const Self&); //purposely not implemented
+    void operator=(const Self&); //purposely not implemented
+    
+  }; // end class
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+//--------------------------------------------------------------------
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkBinaryImageToMeshFilter.txx"
+#endif
+
+#endif
diff --git a/itk/clitkBinaryImageToMeshFilter.txx b/itk/clitkBinaryImageToMeshFilter.txx
new file mode 100644 (file)
index 0000000..9ffe4a2
--- /dev/null
@@ -0,0 +1,194 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.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        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+
+//--------------------------------------------------------------------
+template <class ImageType>
+clitk::BinaryImageToMeshFilter<ImageType>::
+BinaryImageToMeshFilter()//:ProcessObject()
+{
+  DD("BinaryImageToMeshFilter constructor");
+  // this->ProcessObject::SetNumberOfRequiredInputs(1);
+  // this->ProcessObject::SetNumberOfRequiredOutputs(1);
+
+  // //m_OutputMesh = vtkPolyData::New();
+
+  // this->ProcessObject::SetNumberOfRequiredOutputs(1);
+  // itk::DataObject::Pointer a = itk::DataObject::New();
+  // this->ProcessObject::SetNthOutput( 0, a);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+/*template <class ImageType>
+  void 
+  clitk::BinaryImageToMeshFilter<ImageType>::
+  GenerateOutputInformation() 
+  {
+  DD("GenerateOutputInformation");
+  // ImagePointer output = this->GetOutput(0);
+  
+  // // Set the region to output
+  // typename ImageType::RegionType m_Region = m_LikeImage->GetLargestPossibleRegion();
+  // typename ImageType::SizeType size = m_Region.GetSize();
+  // size[0]++;
+  // size[1]++;
+  // size[2]++;
+  // m_Region.SetSize(size);  
+  // output->SetLargestPossibleRegion(m_Region);
+  // output->SetRequestedRegion(m_Region);
+  // output->SetBufferedRegion(m_Region);
+  // output->SetRegions(m_Region);
+  // output->Allocate();
+  }
+*/
+//--------------------------------------------------------------------
+
+
+// template <class ImageType>
+// void
+// clitk::BinaryImageToMeshFilter<ImageType>::
+// SetInput(unsigned int idx, const ImageType *input)
+// {
+//   DD(idx);
+//   // process object is not const-correct, the const_cast
+//   // is required here.
+//   this->ProcessObject::SetNthInput( idx,
+//                                     const_cast< ImageType * >( input ) );
+//   DD("end");
+// }
+
+// template <class ImageType>
+// const ImageType *
+// clitk::BinaryImageToMeshFilter<ImageType>::
+// GetInput(unsigned int idx)
+// {
+//   DD("GetInput");
+//   DD(idx);
+//   return dynamic_cast< const ImageType * >
+//          ( this->ProcessObject::GetInput(idx) );
+// }
+
+
+//--------------------------------------------------------------------
+template <class ImageType>
+void
+clitk::BinaryImageToMeshFilter<ImageType>::
+Update()
+//GenerateOutputInformation()
+{
+  DD("Update");
+
+  // Convert itk image into vtk image
+  const ImageType * im = this->GetInput();
+  typedef itk::ImageToVTKImageFilter<ImageType> ConvertType;
+  typename ConvertType::Pointer convert = ConvertType::New();
+  convert->SetInput(im);
+  convert->Update();
+  vtkImageData * input_vtk = convert->GetOutput();
+  
+  // Get extend
+  vtkSmartPointer<vtkImageClip> clipper = vtkSmartPointer<vtkImageClip>::New();
+  clipper->SetInput(input_vtk);
+  int* extent = input_vtk->GetExtent();
+  DDV(extent, 6);
+
+  // Loop on slices
+  vtkSmartPointer<vtkAppendPolyData> append = vtkSmartPointer<vtkAppendPolyData>::New();
+  uint n = input_vtk->GetDimensions()[2];
+  DD(n);
+  std::vector<vtkSmartPointer<vtkPolyData> > contours;
+  for(uint i=0; i<n; i++) {
+    DD(i);
+    // FIXME     vtkDiscreteMarchingCubes INSTEAD ?
+    vtkSmartPointer<vtkMarchingSquares> squares = vtkSmartPointer<vtkMarchingSquares>::New();
+    squares->SetInput(input_vtk);
+    squares->SetImageRange(extent[0], extent[1], extent[2], extent[3], i, i);
+    squares->SetNumberOfContours(1);
+    squares->SetValue(0, 0.5); // FIXME background (?)
+    squares->Update();
+    // DD(squares->GetNumberOfContours());
+    
+    vtkSmartPointer<vtkPolyData> m = squares->GetOutput();
+
+    DD(m->GetMaxCellSize());
+    DD(m->GetNumberOfVerts());
+    DD(m->GetNumberOfLines());
+    DD(m->GetNumberOfPolys());
+    DD(m->GetNumberOfStrips());
+
+    // Decimate
+    if (false) { // FIXME
+      vtkSmartPointer<vtkDecimatePro> psurface = vtkDecimatePro::New();
+      psurface->SetInputConnection(squares->GetOutputPort());
+      psurface->SetTargetReduction(0.5);
+      psurface->Update();
+      m = psurface->GetOutput();
+    }
+    if (true) {
+      vtkSmartPointer<vtkStripper> vs = vtkSmartPointer<vtkStripper>::New();
+      vs->SetInput(squares->GetOutput());
+      vs->Update();
+      m = vs->GetOutput();
+    }
+    
+    //vtkSmartPointer<vtkPolyData> m = squares->GetOutput();
+    contours.push_back(m);
+    DD(m->GetMaxCellSize());
+    DD(m->GetNumberOfVerts());
+    DD(m->GetNumberOfLines());
+    DD(m->GetNumberOfPolys());
+    DD(m->GetNumberOfStrips());
+    // m->Print(std::cout);
+
+    // FIXME : only add if lines>0
+    if (m->GetNumberOfLines() > 0) {
+      append->AddInput(contours[i]);
+    }
+  }
+  DD("done");
+  DD("now append");
+  // for(unsigned int i=0; i<n; i++) {
+  //   append->AddInput(contours[i]);
+  // }
+  append->Update();
+  
+  DD(" copy");
+  m_OutputMesh = vtkSmartPointer<vtkPolyData>::New();
+  m_OutputMesh->DeepCopy(append->GetOutput());
+
+  /* // NO (3D)
+  vtkSmartPointer<vtkContourFilter> pcontour = vtkContourFilter::New();
+  pcontour->SetValue(0, 0.5);
+  pcontour->SetInput(input_vtk);
+  pcontour->Update();
+  // vtkAlgorithmOutput *data = pcontour->GetOutputPort();
+  // vtkSmartPointer<vtkPolyDataMapper> skinMapper = vtkPolyDataMapper::New();
+  // skinMapper->SetInputConnection(data); //psurface->GetOutputPort()
+  // skinMapper->ScalarVisibilityOff();
+  m_OutputMesh = pcontour->GetOutput();//data
+  */
+
+  DD("end");
+  int a=12;
+  DD("erelre");
+}
+//--------------------------------------------------------------------
+