1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================*/
18 #include <vtkPoints.h>
19 #include <vtkCellArray.h>
20 #include <vtkPointData.h>
21 #include <vtkImageData.h>
22 #include <vtkMetaImageReader.h>
23 #include <vtkMetaImageWriter.h>
24 #include <vtkPNGReader.h>
25 #include <vtkPolyData.h>
26 #include <vtkCellLocator.h>
33 #include "clitkGammaIndex_ggo.h"
37 #include <vvImageReader.h>
39 void saveImage(vtkImageData *image,const std::string &filename) {
40 cout << "saving " << filename << endl;
41 vtkImageWriter *writer = vtkMetaImageWriter::New();
42 writer->SetFileName(filename.c_str());
43 writer->SetInput(image);
49 void insertTriangles(vtkCellArray *cells, vtkPoints *points, const vtkIdType ids[4]) {
50 double p0[3]; points->GetPoint(ids[0],p0);
51 double p1[3]; points->GetPoint(ids[1],p1);
52 double p2[3]; points->GetPoint(ids[2],p2);
53 double p3[3]; points->GetPoint(ids[3],p3);
54 //cout << "----------------------------------" << endl;
55 //cout << "p0=[" << p0[0] << "," << p0[1] << "," << p0[2] << "]" << endl;
56 //cout << "p1=[" << p1[0] << "," << p1[1] << "," << p1[2] << "]" << endl;
57 //cout << "p2=[" << p2[0] << "," << p2[1] << "," << p2[2] << "]" << endl;
58 //cout << "p3=[" << p3[0] << "," << p3[1] << "," << p3[2] << "]" << endl;
60 double center[] = {0,0,0};
61 for (int kk=0; kk<3; kk++) {
69 vtkIdType center_id = points->InsertNextPoint(center);
70 //cout << "center=[" << center[0] << "," << center[1] << "," << center[2] << "]" << endl;
72 cells->InsertNextCell(3);
73 cells->InsertCellPoint(ids[0]);
74 cells->InsertCellPoint(ids[1]);
75 cells->InsertCellPoint(center_id);
77 cells->InsertNextCell(3);
78 cells->InsertCellPoint(ids[1]);
79 cells->InsertCellPoint(ids[3]);
80 cells->InsertCellPoint(center_id);
82 cells->InsertNextCell(3);
83 cells->InsertCellPoint(ids[3]);
84 cells->InsertCellPoint(ids[2]);
85 cells->InsertCellPoint(center_id);
87 cells->InsertNextCell(3);
88 cells->InsertCellPoint(ids[2]);
89 cells->InsertCellPoint(ids[0]);
90 cells->InsertCellPoint(center_id);
93 double getMaximum(vtkImageData *image) {
97 for (int kk=0; kk<image->GetNumberOfPoints(); kk++) {
98 double value = image->GetPointData()->GetScalars()->GetTuple1(kk);
106 if (maximum<value) maximum = value;
113 vtkPolyData *buildPlane(vtkImageData *image,double spatial_margin,double dose_margin) {
114 vtkPoints *points = vtkPoints::New();
115 for (int kk=0; kk<image->GetNumberOfPoints(); kk++) {
116 double *point = image->GetPoint(kk);
117 double value = image->GetPointData()->GetScalars()->GetTuple1(kk);
122 point[0] /= spatial_margin;
123 point[1] /= spatial_margin;
124 point[2] /= dose_margin;
127 vtkIdType point_id = points->InsertNextPoint(point);
128 assert(kk==point_id);
130 points->InsertNextPoint(point);
134 vtkCellArray *cells = vtkCellArray::New();
135 for (int kk=0; kk<image->GetNumberOfCells(); kk++) {
136 vtkCell *cell = image->GetCell(kk);
137 assert(cell->GetNumberOfPoints()==4);
138 insertTriangles(cells,points,cell->GetPointIds()->GetPointer(0));
141 vtkPolyData *data = vtkPolyData::New();
142 data->SetPoints(points);
143 data->SetPolys(cells);
150 int main(int argc,char * argv[])
152 clitk::RegisterClitkFactories();
154 args_info_clitkGammaIndex args_info;
156 if (cmdline_parser_clitkGammaIndex(argc, argv, &args_info) != 0)
159 if (!args_info.absolute_dose_margin_given && !args_info.relative_dose_margin_given) {
160 std::cerr << "Specify either relative or absolute dose margin" << endl;
164 bool verbose = args_info.verbose_flag;
166 std::string reference_filename(args_info.reference_arg);
167 std::string target_filename(args_info.target_arg);
168 std::string gamma_filename(args_info.output_arg);
169 double space_margin = args_info.spatial_margin_arg;
170 double dose_rel_margin = args_info.relative_dose_margin_arg;
171 double dose_margin = args_info.absolute_dose_margin_arg;
172 bool use_dose_margin = args_info.absolute_dose_margin_given;
175 cout << "reference_filename=" << reference_filename << endl;
176 cout << "target_filename=" << target_filename << endl;
177 cout << "gamma_filename=" << gamma_filename << endl;
178 cout << "space_margin=" << space_margin << endl;
179 if (use_dose_margin) cout << "dose_margin=" << dose_margin << endl;
180 else cout << "dose_rel_margin=" << dose_rel_margin << endl;
184 vtkImageData* reference = NULL;
186 vvImageReader::Pointer reader = vvImageReader::New();
187 reader->SetInputFilename(reference_filename);
189 vvImage::Pointer vvimage = reader->GetOutput();
190 if (!vvimage) { cerr << "can't load " << reference_filename << endl; return 2; }
191 reference = vvimage->GetFirstVTKImageData();
195 // intensity normalisation
196 if (!use_dose_margin) {
197 dose_margin = getMaximum(reference)*dose_rel_margin;
198 if (verbose) cout << "dose_margin=" << dose_margin << endl;
202 vtkPolyData *data = buildPlane(reference,space_margin,dose_margin);
205 vtkAbstractCellLocator *locator = vtkCellLocator::New();
206 locator->SetDataSet(data);
208 locator->CacheCellBoundsOn();
209 locator->AutomaticOn();
210 locator->BuildLocator();
213 vtkImageData *target = NULL;
215 vvImageReader::Pointer reader = vvImageReader::New();
216 reader->SetInputFilename(target_filename);
218 vvImage::Pointer vvimage = reader->GetOutput();
219 if (!vvimage) { cerr << "can't load " << target_filename << endl; return 2; }
220 target = vvimage->GetFirstVTKImageData();
221 if (!target) return 2;
225 vtkImageData *output = vtkImageData::New();
226 output->SetExtent(target->GetWholeExtent());
227 output->SetOrigin(target->GetOrigin());
228 output->SetSpacing(target->GetSpacing());
229 output->SetScalarTypeToFloat();
230 output->AllocateScalars();
233 unsigned long total = 0;
234 unsigned long over_one = 0;
235 for (int kk=0; kk<target->GetNumberOfPoints(); kk++) {
236 double *point = target->GetPoint(kk);
237 double value = target->GetPointData()->GetScalars()->GetTuple1(kk);
242 point[0] /= space_margin;
243 point[1] /= space_margin;
244 point[2] /= dose_margin;
246 double closest_point[3] = {0,0,0};
247 vtkIdType cell_id = 0;
249 double squared_distance = 0;
251 locator->FindClosestPoint(point,closest_point,cell_id,foo,squared_distance);
253 double distance = sqrt(squared_distance);
254 output->GetPointData()->GetScalars()->SetTuple1(kk,distance);
256 if (value>1) over_one++;
262 cout << "total=" << total << endl;
263 cout << "over_one=" << over_one << endl;
264 cout << "ratio=" << static_cast<float>(over_one)/total << endl;
270 saveImage(output,gamma_filename);