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();
std::string m_StructureSetFilename;
std::string m_DicomFolder;
std::string m_OutputFilename;
-
+ std::string m_ROIName;
+ std::string m_ROIType;
+ PixelType m_ThresholdValue;
};
//--------------------------------------------------------------------
template<class PixelType>
clitk::Image2DicomRTStructFilter<PixelType>::Image2DicomRTStructFilter()
{
- DD("Image2DicomRTStructFilter Const");
+ m_StructureSetFilename = "";
+ m_DicomFolder = "";
+ m_OutputFilename = "default-output.dcm";
+ m_ThresholdValue = 0.5;
}
//--------------------------------------------------------------------
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());
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);
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");
- */
}
//--------------------------------------------------------------------
-------------------------------------------------------------------- */
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;
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:
ImagePointer m_Input;
vtkSmartPointer<vtkPolyData> m_OutputMesh;
+ PixelType m_ThresholdValue;
private:
BinaryImageToMeshFilter(const Self&); //purposely not implemented
//--------------------------------------------------------------------
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;
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");
}
//--------------------------------------------------------------------