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 =========================================================================*/
24 #include "clitkDicomRTStruct2ImageFilter.h"
25 #include "clitkImageCommon.h"
28 #include <vtkPolyDataToImageStencil.h>
29 #include <vtkSmartPointer.h>
30 #include <vtkImageStencil.h>
31 #include <vtkLinearExtrusionFilter.h>
32 #include <vtkMetaImageWriter.h>
35 //--------------------------------------------------------------------
36 clitk::DicomRTStruct2ImageFilter::DicomRTStruct2ImageFilter()
42 //--------------------------------------------------------------------
45 //--------------------------------------------------------------------
46 clitk::DicomRTStruct2ImageFilter::~DicomRTStruct2ImageFilter()
50 //--------------------------------------------------------------------
53 //--------------------------------------------------------------------
54 bool clitk::DicomRTStruct2ImageFilter::ImageInfoIsSet() const
56 return mSize.size() && mSpacing.size() && mOrigin.size();
58 //--------------------------------------------------------------------
61 //--------------------------------------------------------------------
62 void clitk::DicomRTStruct2ImageFilter::SetWriteOutputFlag(bool b)
66 //--------------------------------------------------------------------
69 //--------------------------------------------------------------------
70 void clitk::DicomRTStruct2ImageFilter::SetROI(clitk::DicomRT_ROI * roi)
74 //--------------------------------------------------------------------
77 //--------------------------------------------------------------------
78 void clitk::DicomRTStruct2ImageFilter::SetCropMaskEnabled(bool b)
82 //--------------------------------------------------------------------
85 //--------------------------------------------------------------------
86 void clitk::DicomRTStruct2ImageFilter::SetOutputImageFilename(std::string s)
91 //--------------------------------------------------------------------
94 //--------------------------------------------------------------------
95 void clitk::DicomRTStruct2ImageFilter::SetImage(vvImage::Pointer image)
97 if (image->GetNumberOfDimensions() != 3) {
98 std::cerr << "Error. Please provide a 3D image." << std::endl;
104 for(unsigned int i=0; i<3; i++) {
105 mSpacing[i] = image->GetSpacing()[i];
106 mOrigin[i] = image->GetOrigin()[i];
107 mSize[i] = image->GetSize()[i];
110 //--------------------------------------------------------------------
113 //--------------------------------------------------------------------
114 void clitk::DicomRTStruct2ImageFilter::SetImageFilename(std::string f)
116 itk::ImageIOBase::Pointer header = clitk::readImageHeader(f);
117 if (header->GetNumberOfDimensions() < 3) {
118 std::cerr << "Error. Please provide a 3D image instead of " << f << std::endl;
121 if (header->GetNumberOfDimensions() > 3) {
122 std::cerr << "Warning dimension > 3 are ignored" << std::endl;
127 for(unsigned int i=0; i<3; i++) {
128 mSpacing[i] = header->GetSpacing(i);
129 mOrigin[i] = header->GetOrigin(i);
130 mSize[i] = header->GetDimensions(i);
133 //--------------------------------------------------------------------
136 //--------------------------------------------------------------------
137 void clitk::DicomRTStruct2ImageFilter::SetOutputOrigin(const double* origin)
139 std::copy(origin,origin+3,std::back_inserter(mOrigin));
141 //--------------------------------------------------------------------
144 //--------------------------------------------------------------------
145 void clitk::DicomRTStruct2ImageFilter::SetOutputSpacing(const double* spacing)
147 std::copy(spacing,spacing+3,std::back_inserter(mSpacing));
149 //--------------------------------------------------------------------
152 //--------------------------------------------------------------------
153 void clitk::DicomRTStruct2ImageFilter::SetOutputSize(const unsigned long* size)
155 std::copy(size,size+3,std::back_inserter(mSize));
157 //--------------------------------------------------------------------
160 //--------------------------------------------------------------------
161 void clitk::DicomRTStruct2ImageFilter::Update()
163 DD("DicomRTStruct2ImageFilter::Update");
165 std::cerr << "Error. No ROI set, please use SetROI." << std::endl;
168 if (!ImageInfoIsSet()) {
169 std::cerr << "Error. Please provide image info (spacing/origin) with SetImageFilename" << std::endl;
174 vtkPolyData * mesh = mROI->GetMesh();
177 double *bounds=mesh->GetBounds();
178 // for(int i=0; i<6; i++){
183 std::vector<double> origin;
185 origin[0] = floor((bounds[0]-mOrigin[0])/mSpacing[0]-2)*mSpacing[0]+mOrigin[0];
186 origin[1] = floor((bounds[2]-mOrigin[1])/mSpacing[1]-2)*mSpacing[1]+mOrigin[1];
187 origin[2] = floor((bounds[4]-mOrigin[2])/mSpacing[2]-2)*mSpacing[2]+mOrigin[2];
190 std::vector<double> extend;
192 extend[0] = ceil((bounds[1]-origin[0])/mSpacing[0]+4);
193 extend[1] = ceil((bounds[3]-origin[1])/mSpacing[1]+4);
194 extend[2] = ceil((bounds[5]-origin[2])/mSpacing[2]+4);
196 // If no crop, set initial image size/origin
198 for(int i=0; i<3; i++) {
199 origin[i] = mOrigin[i];
200 extend[i] = mSize[i]-1;
204 // Create new output image
205 mBinaryImage = vtkSmartPointer<vtkImageData>::New();
206 mBinaryImage->SetScalarTypeToUnsignedChar();
207 mBinaryImage->SetOrigin(&origin[0]);
208 mBinaryImage->SetSpacing(&mSpacing[0]);
209 mBinaryImage->SetExtent(0, extend[0],
212 mBinaryImage->AllocateScalars();
214 // for(int i=0; i<3; i++){
217 // DD(mBinaryImage->GetDimensions()[i]);
219 memset(mBinaryImage->GetScalarPointer(), 0,
220 mBinaryImage->GetDimensions()[0]*mBinaryImage->GetDimensions()[1]*mBinaryImage->GetDimensions()[2]*sizeof(unsigned char));
223 vtkSmartPointer<vtkLinearExtrusionFilter> extrude=vtkSmartPointer<vtkLinearExtrusionFilter>::New();
224 extrude->SetInput(mesh);
225 ///We extrude in the -slice_spacing direction to respect the FOCAL convention (NEEDED !)
226 extrude->SetVector(0, 0, -mSpacing[2]);
229 vtkSmartPointer<vtkPolyDataToImageStencil> sts=vtkSmartPointer<vtkPolyDataToImageStencil>::New();
230 //The following line is extremely important
231 //http://www.nabble.com/Bug-in-vtkPolyDataToImageStencil--td23368312.html#a23370933
232 sts->SetTolerance(0);
233 sts->SetInformationInput(mBinaryImage);
234 sts->SetInput(extrude->GetOutput());
235 //sts->SetInput(mesh);
237 vtkSmartPointer<vtkImageStencil> stencil=vtkSmartPointer<vtkImageStencil>::New();
238 stencil->SetStencil(sts->GetOutput());
239 stencil->SetInput(mBinaryImage);
240 stencil->ReverseStencilOn();
244 vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
245 w->SetInput(stencil->GetOutput());
246 w->SetFileName("binary2.mhd");
250 mBinaryImage->ShallowCopy(stencil->GetOutput());
253 typedef itk::Image<unsigned char, 3> ImageType;
254 typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
255 ConnectorType::Pointer connector = ConnectorType::New();
256 connector->SetInput(GetOutput());
258 clitk::writeImage<ImageType>(connector->GetOutput(), mOutputFilename);
261 //--------------------------------------------------------------------
265 //--------------------------------------------------------------------
266 vtkImageData * clitk::DicomRTStruct2ImageFilter::GetOutput()
268 assert(mBinaryImage);
271 //--------------------------------------------------------------------