//--------------------------------------------------------------------
void clitk::DicomRTStruct2ImageFilter::Update()
{
+ DD("DicomRTStruct2ImageFilter::Update");
if (!mROI) {
std::cerr << "Error. No ROI set, please use SetROI." << std::endl;
exit(0);
}
// Get Mesh
- vtkPolyData * mesh = mROI->GetMesh();
+ vtkPolyData * mesh = mROI->GetMesh();
// Get bounds
double *bounds=mesh->GetBounds();
// 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;
+
};
//--------------------------------------------------------------------
// 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()
{
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");
// 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");
+ */
}
//--------------------------------------------------------------------
--- /dev/null
+/*=========================================================================
+ 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
--- /dev/null
+/*=========================================================================
+ 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");
+}
+//--------------------------------------------------------------------
+