]> Creatis software - clitk.git/commitdiff
First working version (allow to write rt-struct)
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>
Tue, 4 Jun 2013 09:07:25 +0000 (11:07 +0200)
common/clitkImage2DicomRTStructFilter.h
common/clitkImage2DicomRTStructFilter.txx
itk/clitkBinaryImageToMeshFilter.h
itk/clitkBinaryImageToMeshFilter.txx

index 5eb6ddc7974514d70b8eea40ebfde684df01a972..924bcc01db3d458a8add1d10daf712939c0e0835 100644 (file)
@@ -46,6 +46,8 @@ namespace clitk {
     itkSetMacro(StructureSetFilename, std::string);
     itkSetMacro(DicomFolder, std::string);
     itkSetMacro(OutputFilename, std::string);
+    void SetROIName(std::string name, std::string type);
+    itkSetMacro(ThresholdValue, PixelType);
     
     // Run filter
     void Update();    
@@ -55,7 +57,9 @@ namespace clitk {
     std::string m_StructureSetFilename;
     std::string m_DicomFolder;
     std::string m_OutputFilename;
-
+    std::string m_ROIName;
+    std::string m_ROIType;
+    PixelType m_ThresholdValue;
   };
   //--------------------------------------------------------------------
 
index cc90104216d6ca2ef9d37f77e92156bf47c4fe9f..051211b6d0d325fa882875b86fc02f861035f8b3 100644 (file)
 template<class PixelType>
 clitk::Image2DicomRTStructFilter<PixelType>::Image2DicomRTStructFilter()
 {
-  DD("Image2DicomRTStructFilter Const");
+  m_StructureSetFilename = "";
+  m_DicomFolder = "";
+  m_OutputFilename = "default-output.dcm";
+  m_ThresholdValue = 0.5;
 }
 //--------------------------------------------------------------------
 
@@ -66,36 +69,40 @@ clitk::Image2DicomRTStructFilter<PixelType>::Image2DicomRTStructFilter()
 template<class PixelType>
 clitk::Image2DicomRTStructFilter<PixelType>::~Image2DicomRTStructFilter()
 {
-  DD("Image2DicomRTStructFilter Destructor");
 }
 //--------------------------------------------------------------------
 
 
 //--------------------------------------------------------------------
 template<class PixelType>
-void clitk::Image2DicomRTStructFilter<PixelType>::Update() 
+void
+clitk::Image2DicomRTStructFilter<PixelType>::SetROIName(std::string name, std::string type)
 {
-  DD("Image2DicomRTStructFilter::GenerateData");
+  m_ROIName = name;
+  m_ROIType = type;
+}
+//--------------------------------------------------------------------
 
+
+//--------------------------------------------------------------------
+template<class PixelType>
+void clitk::Image2DicomRTStructFilter<PixelType>::Update() 
+{
   // 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));  
+  if (GetVerboseFlag()) {
+    std::cout << "Number of structures in the dicom-rt-struct : " 
+              << p->GetNumberOfStructureSetROIs() << std::endl;
+  }
   
   // 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());
@@ -108,41 +115,37 @@ void clitk::Image2DicomRTStructFilter<PixelType>::Update()
   roiAlgorithms->SetNumberOfValues(numMasks);
   roiTypes->SetNumberOfValues(numMasks);
   
+  // Convert the image into a mesh
   typedef clitk::BinaryImageToMeshFilter<ImageType> BinaryImageToMeshFilterType;
   typename BinaryImageToMeshFilterType::Pointer convert = BinaryImageToMeshFilterType::New();
+  convert->SetThresholdValue(m_ThresholdValue);
   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);
+  if (GetVerboseFlag()) {
+    std::cout << "Mesh has " << mesh->GetNumberOfLines() << " lines." << std::endl;
+  }
+
+  // Copy previous contours
+  for (unsigned int i = 0; i < numMasks-1; ++i) {
+    writer->SetInput(i, reader->GetOutput(i));
+    std::string theString = reader->GetRTStructSetProperties()->GetStructureSetROIName(i);
     roiNames->InsertValue(i, theString);
-    theString = reader->GetRTStructSetProperties()->GetStructureSetROIGenerationAlgorithm(i-1);
+    theString = reader->GetRTStructSetProperties()->GetStructureSetROIGenerationAlgorithm(i);
     roiAlgorithms->InsertValue(i, theString);
-    theString = reader->GetRTStructSetProperties()->GetStructureSetRTROIInterpretedType(i-1);
+    theString = reader->GetRTStructSetProperties()->GetStructureSetRTROIInterpretedType(i);
     roiTypes->InsertValue(i, theString);
-  }
-  
+  }  
+
+  // Add new one
+  int last = numMasks-1;
+  writer->SetInput(last, mesh);
+  roiNames->InsertValue(last, m_ROIName);
+  roiAlgorithms->InsertValue(last, "CLITK_CREATED");
+  roiTypes->InsertValue(last, m_ROIType);
 
   /*
-  //  Visu
+  //  Visu DEBUG
   vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();
   cubeMapper->SetInput( mesh );
   cubeMapper->SetScalarRange(0,7);
@@ -167,80 +170,25 @@ void clitk::Image2DicomRTStructFilter<PixelType>::Update()
   renWin->Render();
   iren->Start();
   */
-  
-
   // End visu
 
-
+  // Write (need to read dicom for slice id)
   vtkRTStructSetProperties* theProperties = vtkRTStructSetProperties::New();
-  DD(p->GetStudyInstanceUID());
   writer->SetRTStructSetProperties(theProperties);
-  /*writer->InitializeRTStructSet2(p,"./",
-                                 reader->GetRTStructSetProperties()->GetStructureSetLabel(),
-                                 reader->GetRTStructSetProperties()->GetStructureSetName(),
-                                 roiNames, roiAlgorithms, roiTypes);*/  
+  if (GetVerboseFlag()) {
+    std::cout << "Looking for dicom info, study instance "
+              << p->GetStudyInstanceUID() << std::endl;
+  }
   writer->InitializeRTStructSet(m_DicomFolder,
                                 reader->GetRTStructSetProperties()->GetStructureSetLabel(),
                                 reader->GetRTStructSetProperties()->GetStructureSetName(),
-                                roiNames, roiAlgorithms, roiTypes);
-  
-  DD("after init");
+                                roiNames, roiAlgorithms, roiTypes);  
   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->ComputeContoursFromImage(); // FIXME do the set mesh for the moment (to change)
-  // roi->ComputeMeshFromContour();
-  vtkSmartPointer<vtkPolyData> mesh = roi->GetMesh();
-  DD("done");
-  
-  // Change the mesh (shift by 10);
-  // const vtkSmartPointer<vtkPoints> & points = mesh->GetPoints();
-  // for(uint i=0; i<mesh->GetNumberOfVerts (); i++) {
-  //   DD(i);
-  //   double * p = points->GetPoint(i);
-  //   p[0] += 30;
-  //   points->SetPoint(i, p);
-  // }
-  roi->SetName("TOTO");
-  roi->SetDicomUptodateFlag(true); // indicate that dicom info must be updated from the mesh.
-    
-  // Convert to dicom ?
-  DD("TODO");
-  
-  // Write
-  structset->Write("toto.dcm");
-  */
 }
 //--------------------------------------------------------------------
 
index 0a36c36dd16a1fd69f1c4bd75c7bc204a1c6cc75..e2b2198bedd2d7c8e5f4bb5526065f4c3ec5610e 100644 (file)
@@ -42,13 +42,12 @@ namespace clitk {
      -------------------------------------------------------------------- */
   
   template<class ImageType>
-  class ITK_EXPORT BinaryImageToMeshFilter:public itk::Object //:public clitk::FilterBase
+  class ITK_EXPORT BinaryImageToMeshFilter:public itk::Object
   {
 
   public:
     /** Standard class typedefs. */
-    //    typedef itk::ImageToMeshFilter<ImageType, vtkPolyData>   Superclass;
-    typedef itk::ProcessObject   Superclass;
+    typedef itk::ProcessObject            Superclass;
     typedef BinaryImageToMeshFilter       Self;
     typedef itk::SmartPointer<Self>       Pointer;
     typedef itk::SmartPointer<const Self> ConstPointer;
@@ -63,48 +62,14 @@ namespace clitk {
     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>);
+    itkSetMacro(ThresholdValue, PixelType);
 
-    // virtual void GenerateOutputInformation();
     virtual void Update();
 
   protected:
@@ -113,6 +78,7 @@ namespace clitk {
     
     ImagePointer m_Input;
     vtkSmartPointer<vtkPolyData> m_OutputMesh;
+    PixelType m_ThresholdValue;
 
   private:
     BinaryImageToMeshFilter(const Self&); //purposely not implemented
index 9ffe4a204cfd62e5722b0027ec57de3ddbff981a..8a14edc7f193d2c2125a7c0a87d4605b54f6e7a6 100644 (file)
 //--------------------------------------------------------------------
 template <class ImageType>
 clitk::BinaryImageToMeshFilter<ImageType>::
-BinaryImageToMeshFilter()//:ProcessObject()
+BinaryImageToMeshFilter():itk::Object()
 {
-  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);
+  m_ThresholdValue = 0.5; // (for image with 0=background and 1=foreground) 
 }
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-/*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;
@@ -107,88 +45,44 @@ Update()
   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;
+  // 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());
-    
+    squares->SetValue(0, m_ThresholdValue);
+    squares->Update();    
     vtkSmartPointer<vtkPolyData> m = squares->GetOutput();
 
-    DD(m->GetMaxCellSize());
-    DD(m->GetNumberOfVerts());
-    DD(m->GetNumberOfLines());
-    DD(m->GetNumberOfPolys());
-    DD(m->GetNumberOfStrips());
+    // Strip (needed)
+    vtkSmartPointer<vtkStripper> vs = vtkSmartPointer<vtkStripper>::New();
+    vs->SetInput(squares->GetOutput());
+    vs->Update();
+    m = vs->GetOutput();
 
     // Decimate
-    if (false) { // FIXME
+    if (false) { // FIXME (do not work)
       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
+    // only add if lines>0
     if (m->GetNumberOfLines() > 0) {
-      append->AddInput(contours[i]);
+      append->AddInput(m);//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");
 }
 //--------------------------------------------------------------------