1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
3 Main authors : XX XX XX
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
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.
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
18 =========================================================================*/
20 #include "clitkDicomRT_ROI.h"
21 #include <vtkSmartPointer.h>
22 #include <vtkAppendPolyData.h>
23 #include <vtkImageClip.h>
24 #include <vtkMarchingSquares.h>
26 #if GDCM_MAJOR_VERSION == 2
27 #include "gdcmAttribute.h"
31 //--------------------------------------------------------------------
32 clitk::DicomRT_ROI::DicomRT_ROI()
38 mColor[0] = mColor[1] = mColor[2] = 0;
39 mMeshIsUpToDate = false;
42 SetDicomUptodateFlag(false);
44 //--------------------------------------------------------------------
47 //--------------------------------------------------------------------
48 clitk::DicomRT_ROI::~DicomRT_ROI()
51 //--------------------------------------------------------------------
54 //--------------------------------------------------------------------
55 void clitk::DicomRT_ROI::SetDisplayColor(double r, double v, double b)
62 //--------------------------------------------------------------------
65 //--------------------------------------------------------------------
66 int clitk::DicomRT_ROI::GetROINumber() const
70 //--------------------------------------------------------------------
73 //--------------------------------------------------------------------
74 const std::string & clitk::DicomRT_ROI::GetName() const
78 //--------------------------------------------------------------------
81 //--------------------------------------------------------------------
82 const std::string & clitk::DicomRT_ROI::GetFilename() const
86 //--------------------------------------------------------------------
89 //--------------------------------------------------------------------
90 const std::vector<double> & clitk::DicomRT_ROI::GetDisplayColor() const
94 //--------------------------------------------------------------------
97 //--------------------------------------------------------------------
98 void clitk::DicomRT_ROI::Print(std::ostream & os) const
100 os << "ROI " << mNumber << "\t" << mName
101 << "\t(" << mColor[0] << " " << mColor[1] << " " << mColor[2] << ")"
102 << "\t Contours = " << mListOfContours.size() << std::endl;
104 //--------------------------------------------------------------------
107 //--------------------------------------------------------------------
108 void clitk::DicomRT_ROI::SetBackgroundValueLabelImage(double bg)
110 mBackgroundValue = bg;
112 //--------------------------------------------------------------------
115 //--------------------------------------------------------------------
116 double clitk::DicomRT_ROI::GetBackgroundValueLabelImage() const
118 return mBackgroundValue;
120 //--------------------------------------------------------------------
123 //--------------------------------------------------------------------
124 void clitk::DicomRT_ROI::SetForegroundValueLabelImage(double bg)
126 mForegroundValue = bg;
128 //--------------------------------------------------------------------
131 //--------------------------------------------------------------------
132 double clitk::DicomRT_ROI::GetForegroundValueLabelImage() const
134 return mForegroundValue;
136 //--------------------------------------------------------------------
139 //--------------------------------------------------------------------
140 #if GDCM_MAJOR_VERSION == 2
141 bool clitk::DicomRT_ROI::Read(gdcm::Item * itemInfo, gdcm::Item * itemContour)
144 mItemInfo = itemInfo;
145 mItemContour = itemContour;
148 // ROI number [Referenced ROI Number]
149 const gdcm::DataSet & nesteddsInfo = mItemInfo->GetNestedDataSet();
150 gdcm::Attribute<0x3006,0x0022> roinumber;
151 roinumber.SetFromDataSet( nesteddsInfo );
152 int nb1 = roinumber.GetValue();
154 // Check this is the same with the other item
155 const gdcm::DataSet & nestedds = mItemContour->GetNestedDataSet();
156 gdcm::Attribute<0x3006,0x0084> referencedroinumber;
157 referencedroinumber.SetFromDataSet( nestedds );
158 int nb2 = referencedroinumber.GetValue();
160 // Must never be different
164 FATAL("nb1 must equal nb2" << std::endl);
168 // Retrieve ROI Name (in the info item)
169 gdcm::Attribute<0x3006,0x26> roiname;
170 roiname.SetFromDataSet( nesteddsInfo );
171 mName = roiname.GetValue();
174 // ROI Color [ROI Display Color]
175 gdcm::Attribute<0x3006,0x002a> color = {};
176 color.SetFromDataSet( nestedds );
177 assert( color.GetNumberOfValues() == 3 );
178 mColor[0] = color.GetValue(0);
179 mColor[1] = color.GetValue(1);
180 mColor[2] = color.GetValue(2);
182 // Read contours [Contour Sequence]
183 gdcm::Tag tcsq(0x3006,0x0040);
184 if( !nestedds.FindDataElement( tcsq ) )
186 std::cerr << "Warning. Could not read contour for structure <" << mName << ">, number" << mNumber << " ? I ignore it" << std::endl;
187 SetDicomUptodateFlag(true);
190 const gdcm::DataElement& csq = nestedds.GetDataElement( tcsq );
191 mContoursSequenceOfItems = csq.GetValueAsSQ();
192 gdcm::SmartPointer<gdcm::SequenceOfItems> & sqi2 = mContoursSequenceOfItems;
193 if( !sqi2 || !sqi2->GetNumberOfItems() )
196 unsigned int nitems = sqi2->GetNumberOfItems();
198 for(unsigned int i = 0; i < nitems; ++i)
200 gdcm::Item & j = sqi2->GetItem(i+1); // Item start at #1
201 DicomRT_Contour::Pointer c = DicomRT_Contour::New();
202 bool b = c->Read(&j);
204 mListOfContours.push_back(c);
207 SetDicomUptodateFlag(true);
211 void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::SQItem * item)
213 // ROI number [Referenced ROI Number]
214 mNumber = atoi(item->GetEntryValue(0x3006,0x0084).c_str());
217 mName = rois[mNumber];
219 // ROI Color [ROI Display Color]
220 mColor = clitk::parse_string<double>(item->GetEntryValue(0x3006,0x002a),'\\');
222 // Read contours [Contour Sequence]
223 gdcm::SeqEntry * contours=item->GetSeqEntry(0x3006,0x0040);
226 for(gdcm::SQItem* j=contours->GetFirstSQItem(); j!=0; j=contours->GetNextSQItem()) {
227 DicomRT_Contour::Pointer c = DicomRT_Contour::New();
230 mListOfContours.push_back(c);
236 std::cerr << "Warning. Could not read contour for structure <" << mName << ">, number" << mNumber << " ? I ignore it" << std::endl;
238 SetDicomUptodateFlag(true);
241 //--------------------------------------------------------------------
244 //--------------------------------------------------------------------
245 void clitk::DicomRT_ROI::SetImage(vvImage * image)
249 //--------------------------------------------------------------------
252 //--------------------------------------------------------------------
253 vtkPolyData * clitk::DicomRT_ROI::GetMesh()
255 if (!mMeshIsUpToDate) {
256 ComputeMeshFromContour();
260 //--------------------------------------------------------------------
263 //--------------------------------------------------------------------
264 clitk::DicomRT_Contour * clitk::DicomRT_ROI::GetContour(int n)
266 return mListOfContours[n];
268 //--------------------------------------------------------------------
271 //--------------------------------------------------------------------
272 void clitk::DicomRT_ROI::ComputeMeshFromContour()
274 vtkSmartPointer<vtkAppendPolyData> append = vtkSmartPointer<vtkAppendPolyData>::New();
275 for(unsigned int i=0; i<mListOfContours.size(); i++) {
276 append->AddInput(mListOfContours[i]->GetMesh());
280 mMesh = vtkSmartPointer<vtkPolyData>::New();
281 mMesh->DeepCopy(append->GetOutput());
282 mMeshIsUpToDate = true;
284 //--------------------------------------------------------------------
287 #if GDCM_MAJOR_VERSION == 2
289 //--------------------------------------------------------------------
290 void clitk::DicomRT_ROI::UpdateDicomItem()
292 if (GetDicomUptoDateFlag()) return;
293 DD("ROI::UpdateDicomItem");
296 // From now, only some item can be modified
298 // Set ROI Name 0x3006,0x26>
299 gdcm::Attribute<0x3006,0x26> roiname;
300 roiname.SetValue(GetName());
301 gdcm::DataElement de = roiname.GetAsDataElement();
302 gdcm::DataSet & ds = mItemInfo->GetNestedDataSet();
305 // From MESH to CONTOURS
306 ComputeContoursFromImage();
309 DD(mListOfContours.size());
310 for(uint i=0; i<mListOfContours.size(); i++) {
312 DicomRT_Contour::Pointer contour = mListOfContours[i];
313 contour->UpdateDicomItem();//mItemContour);
317 unsigned int nitems = mContoursSequenceOfItems->GetNumberOfItems();
320 // Write [Contour Sequence] = 0x3006,0x0040)
321 gdcm::DataSet & dsc = mItemContour->GetNestedDataSet();
322 gdcm::Tag tcsq(0x3006,0x0040);
323 const gdcm::DataElement& csq = dsc.GetDataElement( tcsq );
324 gdcm::DataElement dec(csq);
325 dec.SetValue(*mContoursSequenceOfItems);
328 gdcm::DataSet & a = mContoursSequenceOfItems->GetItem(1).GetNestedDataSet();
329 gdcm::Attribute<0x3006,0x0050> at;
330 gdcm::Tag tcontourdata(0x3006,0x0050);
331 gdcm::DataElement contourdata = a.GetDataElement( tcontourdata );
332 at.SetFromDataElement( contourdata );
333 const double* points = at.GetValues();
337 //--------------------------------------------------------------------
340 //--------------------------------------------------------------------
341 void clitk::DicomRT_ROI::SetFromBinaryImage(vvImage * image, int n,
343 std::vector<double> color,
344 std::string filename)
347 // ROI number [Referenced ROI Number]
352 mFilename = filename;
354 // ROI Color [ROI Display Color]
357 // No contours [Contour Sequence]
358 mListOfContours.clear();
363 //--------------------------------------------------------------------
366 //--------------------------------------------------------------------
367 vvImage * clitk::DicomRT_ROI::GetImage() const
371 //--------------------------------------------------------------------
374 //--------------------------------------------------------------------
375 void clitk::DicomRT_ROI::ComputeContoursFromImage()
377 DD("ComputeMeshFromImage");
379 // Check that an image is loaded
382 // Only consider 3D here
383 if (mImage->GetNumberOfDimensions() != 3) {
384 FATAL("DicomRT_ROI::ComputeMeshFromImage only work with 3D images");
388 vtkImageData * image = mImage->GetVTKImages()[0];
390 // Get initial extend for the clipping
391 vtkSmartPointer<vtkImageClip> clipper = vtkSmartPointer<vtkImageClip>::New();
392 clipper->SetInput(image);
393 int* extent = image->GetExtent();
395 // std::vector<int> extend;
397 // Prepare the marching squares
398 vtkSmartPointer<vtkMarchingSquares> squares = vtkSmartPointer<vtkMarchingSquares>::New();
399 squares->SetInput(clipper->GetOutput());
402 uint n = image->GetDimensions()[2];
404 for(uint i=0; i<n; i++) {
405 // Clip to the current slice
406 extent[4] = extent[5] = image->GetOrigin()[2]+i*image->GetSpacing()[2];
408 clipper->SetOutputWholeExtent(extent[0],extent[1],extent[2],
409 extent[3],extent[4],extent[5]);
413 DD(squares->GetNumberOfContours());
414 mListOfContours[i]->SetMesh(squares->GetOutput());
417 //--------------------------------------------------------------------