]> Creatis software - clitk.git/blob - common/clitkImage2DicomRTStructFilter.txx
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
[clitk.git] / common / clitkImage2DicomRTStructFilter.txx
1 /*=========================================================================
2   Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
3   Main authors :   XX XX XX
4
5   Authors belongs to:
6   - University of LYON           http://www.universite-lyon.fr/
7   - Léon Bérard cancer center    http://www.centreleonberard.fr
8   - CREATIS CNRS laboratory      http://www.creatis.insa-lyon.fr
9
10   This software is distributed WITHOUT ANY WARRANTY; without even
11   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12   PURPOSE.  See the copyright notices for more information.
13
14   It is distributed under dual licence
15   - BSD       http://www.opensource.org/licenses/bsd-license.php
16   - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17
18   =========================================================================*/
19
20 // std
21 #include <iterator>
22 #include <algorithm>
23
24 // clitk
25 #include "clitkImage2DicomRTStructFilter.h"
26 #include "clitkBinaryImageToMeshFilter.h"
27 #include "clitkImageCommon.h"
28 #include "vvFromITK.h"
29
30 // vtk
31 #include <vtkPolyDataToImageStencil.h>
32 #include <vtkSmartPointer.h>
33 #include <vtkImageStencil.h>
34 #include <vtkLinearExtrusionFilter.h>
35 #include <vtkMetaImageWriter.h>
36 #include <vtkImageData.h>
37
38 // FIXME to remove
39 #include "vtkPolyDataMapper.h"
40 #include "vtkPolyDataMapper2D.h"
41 #include "vtkRenderWindowInteractor.h"
42 #include "vtkPolyDataReader.h"
43 #include "vtkRenderWindow.h"
44 #include "vtkRenderer.h"
45 #include "vtkCamera.h"
46 #include "vtkProperty.h"
47 #include "vtkProperty2D.h"
48 #include <vtksys/SystemTools.hxx>
49
50 // itk
51 #include <itkImage.h>
52 #include <itkVTKImageToImageFilter.h>
53
54 // gdcm
55 #include <vtkRTStructSetProperties.h>
56 #include <vtkGDCMPolyDataReader.h>
57 #include <vtkGDCMPolyDataWriter.h>
58
59 //--------------------------------------------------------------------
60 template<class PixelType>
61 clitk::Image2DicomRTStructFilter<PixelType>::Image2DicomRTStructFilter()
62 {
63   m_StructureSetFilename = "";
64   m_DicomFolder = "";
65   m_OutputFilename = "default-output.dcm";
66   m_ThresholdValue = 0.5;
67   m_SkipInitialStructuresFlag = false;
68 }
69 //--------------------------------------------------------------------
70
71
72 //--------------------------------------------------------------------
73 template<class PixelType>
74 clitk::Image2DicomRTStructFilter<PixelType>::~Image2DicomRTStructFilter()
75 {
76 }
77 //--------------------------------------------------------------------
78
79
80 //--------------------------------------------------------------------
81 template<class PixelType>
82 void
83 clitk::Image2DicomRTStructFilter<PixelType>::SetROIType(std::string type)
84 {
85   m_ROIType = type;
86 }
87 //--------------------------------------------------------------------
88
89
90 //--------------------------------------------------------------------
91 template<class PixelType>
92 void clitk::Image2DicomRTStructFilter<PixelType>::Update() 
93 {
94   // Check this is a RT-Struct
95   gdcm::Reader gdcm_reader;
96   gdcm_reader.SetFileName(m_StructureSetFilename.c_str());
97   if (!gdcm_reader.Read()) {
98     clitkExceptionMacro("Error could not open the file '" << m_StructureSetFilename << std::endl);
99   }
100   gdcm::MediaStorage ms;
101   ms.SetFromFile(gdcm_reader.GetFile());
102   if (ms != gdcm::MediaStorage::RTStructureSetStorage) {
103     clitkExceptionMacro("File '" << m_StructureSetFilename << "' is not a DICOM-RT-Struct file." << std::endl);
104   }
105
106   // Read rt struct
107   vtkSmartPointer<vtkGDCMPolyDataReader> reader = vtkGDCMPolyDataReader::New();
108   reader->SetFileName(m_StructureSetFilename.c_str());
109   reader->Update();  
110
111   // Get properties
112   vtkRTStructSetProperties * p = reader->GetRTStructSetProperties();
113   if (GetVerboseFlag()) {
114     std::cout << "Number of structures in the dicom-rt-struct : " 
115               << p->GetNumberOfStructureSetROIs() << std::endl;
116   }
117   
118
119   // number of additional contours
120   int m = m_InputFilenames.size();
121
122   // Init writer
123   vtkGDCMPolyDataWriter * writer = vtkGDCMPolyDataWriter::New();
124   int numMasks = reader->GetNumberOfOutputPorts() + m;
125
126   if (m_SkipInitialStructuresFlag) {
127     numMasks = m;
128   }
129
130   writer->SetNumberOfInputPorts(numMasks);    
131   writer->SetFileName(m_OutputFilename.c_str());
132   writer->SetMedicalImageProperties(reader->GetMedicalImageProperties());
133
134   // List of already present rois
135   vtkStringArray* roiNames = vtkStringArray::New();
136   vtkStringArray* roiAlgorithms = vtkStringArray::New();
137   vtkStringArray* roiTypes = vtkStringArray::New();
138   roiNames->SetNumberOfValues(numMasks);
139   roiAlgorithms->SetNumberOfValues(numMasks);
140   roiTypes->SetNumberOfValues(numMasks);
141   
142   // Convert the image into a mesh
143   std::vector<vtkSmartPointer<vtkPolyData> > meshes;
144   std::vector<std::string> m_ROINames;
145   meshes.resize(m);
146   m_ROINames.resize(m);
147   for(unsigned int i=0; i<m; i++) {
148     
149     // read image
150     //    typedef float PixelType;
151     //typedef itk::Image<PixelType, 3> ImageType;
152     ImagePointer input = clitk::readImage<ImageType>(m_InputFilenames[i], false);
153
154     std::ostringstream oss;
155     oss << vtksys::SystemTools::
156       GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(m_InputFilenames[i]));
157     std::string name = oss.str();
158     m_ROINames[i] = name;
159     
160     // convert to mesh
161     typedef clitk::BinaryImageToMeshFilter<ImageType> BinaryImageToMeshFilterType;
162     typename BinaryImageToMeshFilterType::Pointer convert = BinaryImageToMeshFilterType::New();
163     convert->SetThresholdValue(m_ThresholdValue);
164     convert->SetInput(input);
165     convert->Update();
166     meshes[i] = convert->GetOutputMesh();
167     if (GetVerboseFlag()) {
168       std::cout << "Mesh has " << meshes[i]->GetNumberOfLines() << " lines." << std::endl;
169     }
170     
171     /*
172     // debug mesh write  FIXME
173     vtkSmartPointer<vtkPolyDataWriter> wr = vtkSmartPointer<vtkPolyDataWriter>::New();
174     wr->SetInputConnection(convert->GetOutputPort()); //psurface->GetOutputPort()
175     wr->SetFileName("bidon.obj");
176     wr->Update();
177     wr->Write();
178     */
179   }
180     
181   // Copy previous contours
182   for (unsigned int i = 0; i < numMasks-m; ++i) {
183 #if VTK_MAJOR_VERSION <= 5
184     writer->SetInput(i, reader->GetOutput(i));
185 #else
186     writer->SetInputData(i, reader->GetOutput(i));
187 #endif
188     std::string theString = reader->GetRTStructSetProperties()->GetStructureSetROIName(i);
189     roiNames->InsertValue(i, theString);
190     theString = reader->GetRTStructSetProperties()->GetStructureSetROIGenerationAlgorithm(i);
191     roiAlgorithms->InsertValue(i, theString);
192     theString = reader->GetRTStructSetProperties()->GetStructureSetRTROIInterpretedType(i);
193     roiTypes->InsertValue(i, theString);
194   }  
195
196   // Add new ones
197   for (unsigned int i = numMasks-m; i < numMasks; ++i) {
198 #if VTK_MAJOR_VERSION <= 5
199     writer->SetInput(i, meshes[i-numMasks+m]);
200 #else
201     writer->SetInputData(i, meshes[i-numMasks+m]);
202 #endif
203     roiNames->InsertValue(i, m_ROINames[i-numMasks+m]);
204     roiAlgorithms->InsertValue(i, "CLITK_CREATED");
205     roiTypes->InsertValue(i, m_ROIType);
206   }
207     
208   /*
209   //  Visu DEBUG
210   vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();
211   cubeMapper->SetInput( mesh );
212   cubeMapper->SetScalarRange(0,7);
213   vtkActor *cubeActor = vtkActor::New();
214   cubeActor->SetMapper(cubeMapper);
215   vtkProperty * property = cubeActor->GetProperty();
216   property->SetRepresentationToWireframe();
217
218   vtkRenderer *renderer = vtkRenderer::New();
219   vtkRenderWindow *renWin = vtkRenderWindow::New();
220   renWin->AddRenderer(renderer);
221
222   vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
223   iren->SetRenderWindow(renWin);
224
225   renderer->AddActor(cubeActor);
226   renderer->ResetCamera();
227   renderer->SetBackground(1,1,1);
228
229   renWin->SetSize(300,300);
230
231   renWin->Render();
232   iren->Start();
233   */
234   // End visu
235
236   // Write (need to read dicom for slice id)
237   vtkRTStructSetProperties* theProperties = vtkRTStructSetProperties::New();
238   writer->SetRTStructSetProperties(theProperties);
239   if (GetVerboseFlag()) {
240     std::cout << "Looking for dicom info, study instance "
241               << p->GetStudyInstanceUID() << std::endl;
242   }
243   writer->InitializeRTStructSet(m_DicomFolder,
244                                 reader->GetRTStructSetProperties()->GetStructureSetLabel(),
245                                 reader->GetRTStructSetProperties()->GetStructureSetName(),
246                                 roiNames, roiAlgorithms, roiTypes);  
247   writer->Write();
248   reader->Delete();
249   roiNames->Delete();
250   roiTypes->Delete();
251   roiAlgorithms->Delete();
252   writer->Delete();
253 }
254 //--------------------------------------------------------------------
255
256
257
258